getting rid of some code duplication
This commit is contained in:
parent
0266675f29
commit
970b9d850e
21 changed files with 325 additions and 302 deletions
|
|
@ -4,7 +4,12 @@
|
|||
color: var(--background-color);
|
||||
}
|
||||
|
||||
.greeter {
|
||||
/* border-top: 1px var(--separator-color) solid; */
|
||||
background-color: var(--greeter-bg-color);
|
||||
}
|
||||
|
||||
.bottom {
|
||||
border-top: 1px var(--separator-color) solid;
|
||||
background-color: var(--bottom-panel-bg-color);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,14 +1,20 @@
|
|||
import { useEffect, useState } from "react";
|
||||
import { Dispatch, useEffect, useState } from "react";
|
||||
import { TraceableError } from "../../statecharts/parser";
|
||||
|
||||
import "./BottomPanel.css";
|
||||
|
||||
import { PersistentDetailsLocalStorage } from "../PersistentDetails";
|
||||
import { PersistentDetailsLocalStorage } from "../Components/PersistentDetails";
|
||||
import { Logo } from "@/App/Logo/Logo";
|
||||
import { AppState } from "../App";
|
||||
import { FindReplace } from "./FindReplace";
|
||||
import { VisualEditorState } from "../VisualEditor/VisualEditor";
|
||||
import { Setters } from "../makePartialSetter";
|
||||
|
||||
export function BottomPanel(props: {errors: TraceableError[]}) {
|
||||
import gitRev from "@/git-rev.txt";
|
||||
|
||||
export function BottomPanel(props: {errors: TraceableError[], setEditorState: Dispatch<(state: VisualEditorState) => VisualEditorState>} & AppState & Setters<AppState>) {
|
||||
const [greeting, setGreeting] = useState(
|
||||
<div style={{textAlign:'center'}}>
|
||||
<div className="greeter" style={{textAlign:'center'}}>
|
||||
<span style={{fontSize: 18, fontStyle: 'italic'}}>
|
||||
Welcome to <Logo/>
|
||||
</span>
|
||||
|
|
@ -21,19 +27,22 @@ export function BottomPanel(props: {errors: TraceableError[]}) {
|
|||
}, []);
|
||||
|
||||
return <div className="toolbar bottom">
|
||||
{greeting}
|
||||
{props.errors.length > 0 &&
|
||||
<div className="errorStatus">
|
||||
<PersistentDetailsLocalStorage initiallyOpen={false} localStorageKey="errorsExpanded">
|
||||
<summary>{props.errors.length} errors</summary>
|
||||
<div style={{maxHeight: '25vh', overflow: 'auto'}}>
|
||||
{props.errors.map(({message, shapeUid})=>
|
||||
<div>
|
||||
{shapeUid}: {message}
|
||||
</div>)}
|
||||
</div>
|
||||
</PersistentDetailsLocalStorage>
|
||||
{/* {props.showFindReplace &&
|
||||
<div>
|
||||
<FindReplace setCS={props.setEditorState} hide={() => props.setShowFindReplace(false)}/>
|
||||
</div>
|
||||
}
|
||||
} */}
|
||||
<div className={"statusBar" + props.errors.length ? " error" : ""}>
|
||||
<PersistentDetailsLocalStorage initiallyOpen={false} localStorageKey="errorsExpanded">
|
||||
<summary>{props.errors.length} errors</summary>
|
||||
<div style={{maxHeight: '25vh', overflow: 'auto'}}>
|
||||
{props.errors.map(({message, shapeUid})=>
|
||||
<div>
|
||||
{shapeUid}: {message}
|
||||
</div>)}
|
||||
</div>
|
||||
</PersistentDetailsLocalStorage>
|
||||
</div>
|
||||
{greeting}
|
||||
</div>;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
59
src/App/BottomPanel/FindReplace.tsx
Normal file
59
src/App/BottomPanel/FindReplace.tsx
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
import { Dispatch, useCallback, useEffect } from "react";
|
||||
import { VisualEditorState } from "../VisualEditor/VisualEditor";
|
||||
import { usePersistentState } from "@/hooks/usePersistentState";
|
||||
|
||||
import CloseIcon from '@mui/icons-material/Close';
|
||||
import SwapHorizIcon from '@mui/icons-material/SwapHoriz';
|
||||
|
||||
type FindReplaceProps = {
|
||||
setCS: Dispatch<(oldState: VisualEditorState) => VisualEditorState>,
|
||||
// setModal: (modal: null) => void;
|
||||
hide: () => void,
|
||||
};
|
||||
|
||||
export function FindReplace({setCS, hide}: FindReplaceProps) {
|
||||
const [findTxt, setFindText] = usePersistentState("findTxt", "");
|
||||
const [replaceTxt, setReplaceTxt] = usePersistentState("replaceTxt", "");
|
||||
|
||||
const onReplace = useCallback(() => {
|
||||
setCS(cs => {
|
||||
return {
|
||||
...cs,
|
||||
texts: cs.texts.map(txt => ({
|
||||
...txt,
|
||||
text: txt.text.replaceAll(findTxt, replaceTxt)
|
||||
})),
|
||||
};
|
||||
});
|
||||
}, [findTxt, replaceTxt]);
|
||||
|
||||
const onKeyDown = useCallback((e: KeyboardEvent) => {
|
||||
if (e.key === "Enter") {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
onReplace();
|
||||
// setModal(null);
|
||||
}
|
||||
}, [onReplace]);
|
||||
|
||||
const onSwap = useCallback(() => {
|
||||
setReplaceTxt(findTxt);
|
||||
setFindText(replaceTxt);
|
||||
}, [findTxt, replaceTxt]);
|
||||
|
||||
useEffect(() => {
|
||||
window.addEventListener("keydown", onKeyDown);
|
||||
return () => {
|
||||
window.removeEventListener("keydown", onKeyDown);
|
||||
}
|
||||
}, [])
|
||||
|
||||
return <div className="toolbar toolbarGroup" style={{display: 'flex'}}>
|
||||
<input placeholder="find" value={findTxt} onChange={e => setFindText(e.target.value)} style={{width:300}}/>
|
||||
<button tabIndex={-1} onClick={onSwap}><SwapHorizIcon fontSize="small"/></button>
|
||||
<input tabIndex={0} placeholder="replace" value={replaceTxt} onChange={(e => setReplaceTxt(e.target.value))} style={{width:300}}/>
|
||||
|
||||
<button onClick={onReplace}>replace all</button>
|
||||
<button onClick={hide} style={{marginLeft: 'auto'}}><CloseIcon fontSize="small"/></button>
|
||||
</div>;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue