Rename diagram

This commit is contained in:
1ilit 2023-10-21 19:45:13 +03:00
parent 69dd120c0d
commit b41942c794
3 changed files with 245 additions and 174 deletions

View File

@ -1,21 +1,11 @@
{ {
"short_name": "React App", "short_name": "drawDB",
"name": "Create React App Sample", "name": "drawDB",
"icons": [ "icons": [
{ {
"src": "favicon.ico", "src": "favicon.ico",
"sizes": "64x64 32x32 24x24 16x16", "sizes": "64x64 32x32 24x24 16x16",
"type": "image/x-icon" "type": "image/x-icon"
},
{
"src": "logo192.png",
"type": "image/png",
"sizes": "192x192"
},
{
"src": "logo512.png",
"type": "image/png",
"sizes": "512x512"
} }
], ],
"start_url": ".", "start_url": ".",

View File

@ -12,7 +12,7 @@ function App() {
<Router> <Router>
<Routes> <Routes>
<Route path="/" element={<LandingPage />} /> <Route path="/" element={<LandingPage />} />
<Route path="/editor" element={<Editor name="Untitled" />} /> <Route path="/editor" element={<Editor />} />
<Route path="/survey" element={<Survey />} /> <Route path="/survey" element={<Survey />} />
<Route path="/shortcuts" element={<Shortcuts />} /> <Route path="/shortcuts" element={<Shortcuts />} />
<Route path="/bug_report" element={<BugReport />} /> <Route path="/bug_report" element={<BugReport />} />

View File

@ -10,6 +10,7 @@ import {
IconUndo, IconUndo,
IconRedo, IconRedo,
IconRowsStroked, IconRowsStroked,
IconEdit,
} from "@douyinfe/semi-icons"; } from "@douyinfe/semi-icons";
import { Link } from "react-router-dom"; import { Link } from "react-router-dom";
import icon from "../assets/icon_dark_64.png"; import icon from "../assets/icon_dark_64.png";
@ -65,6 +66,7 @@ export default function ControlPanel(props) {
IMG: 1, IMG: 1,
CODE: 2, CODE: 2,
IMPORT: 3, IMPORT: 3,
RENAME: 4,
}; };
const STATUS = { const STATUS = {
NONE: 0, NONE: 0,
@ -73,6 +75,9 @@ export default function ControlPanel(props) {
OK: 3, OK: 3,
}; };
const [visible, setVisible] = useState(MODAL.NONE); const [visible, setVisible] = useState(MODAL.NONE);
const [title, setTitle] = useState("Untitled Diagram");
const [prevTitle, setPrevTitle] = useState(title);
const [showEditName, setShowEditName] = useState(false);
const [exportData, setExportData] = useState({ const [exportData, setExportData] = useState({
data: null, data: null,
filename: `diagram_${new Date().toISOString()}`, filename: `diagram_${new Date().toISOString()}`,
@ -672,7 +677,10 @@ export default function ControlPanel(props) {
function: () => {}, function: () => {},
}, },
Rename: { Rename: {
function: () => {}, function: () => {
setVisible(MODAL.RENAME);
setPrevTitle(title);
},
}, },
Import: { Import: {
function: fileImport, function: fileImport,
@ -1009,25 +1017,50 @@ export default function ControlPanel(props) {
}); });
useHotkeys("ctrl+alt+w, meta+alt+w", fitWindow, { preventDefault: true }); useHotkeys("ctrl+alt+w, meta+alt+w", fitWindow, { preventDefault: true });
return ( const getModalTitle = () => {
<> switch (visible) {
{layout.header && header()} case MODAL.IMPORT:
{toolbar()} return "Import diagram";
<Modal case MODAL.CODE:
title={`${visible === MODAL.IMPORT ? "Import" : "Export"} diagram`} return "Export diagram";
visible={visible !== MODAL.NONE} case MODAL.IMG:
onOk={() => { return "Export image";
if (visible === MODAL.IMG) { case MODAL.RENAME:
return "Rename diagram";
default:
return "";
}
};
const getOkText = () => {
switch (visible) {
case MODAL.IMPORT:
return "Import";
case MODAL.CODE:
case MODAL.IMG:
return "Export";
case MODAL.RENAME:
return "Rename";
default:
return "";
}
};
const getModalOnOk = () => {
switch (visible) {
case MODAL.IMG:
saveAs( saveAs(
exportData.data, exportData.data,
`${exportData.filename}.${exportData.extension}` `${exportData.filename}.${exportData.extension}`
); );
} else if (visible === MODAL.CODE) { return;
case MODAL.CODE:
const blob = new Blob([exportData.data], { const blob = new Blob([exportData.data], {
type: "application/json", type: "application/json",
}); });
saveAs(blob, `${exportData.filename}.${exportData.extension}`); saveAs(blob, `${exportData.filename}.${exportData.extension}`);
} else if (visible === MODAL.IMPORT) { return;
case MODAL.IMPORT:
if (error.type !== STATUS.ERROR) { if (error.type !== STATUS.ERROR) {
setSettings((prev) => ({ ...prev, pan: { x: 0, y: 0 } })); setSettings((prev) => ({ ...prev, pan: { x: 0, y: 0 } }));
overwriteDiagram(); overwriteDiagram();
@ -1036,36 +1069,16 @@ export default function ControlPanel(props) {
setUndoStack([]); setUndoStack([]);
setRedoStack([]); setRedoStack([]);
} }
return;
default:
setVisible(MODAL.NONE);
return;
} }
}} };
afterClose={() => {
setExportData((prev) => ({ const importModalBody = () => {
data: "", return (
extension: "", <>
filename: `diagram_${new Date().toISOString()}`,
}));
setError({
type: STATUS.NONE,
message: "",
});
setData(null);
}}
onCancel={() => setVisible(MODAL.NONE)}
centered
closeOnEsc={true}
okText={`${visible === MODAL.IMPORT ? "Import" : "Export"}`}
okButtonProps={{
disabled:
(visible === MODAL.IMPORT &&
(error.type === STATUS.ERROR || !data)) ||
((visible === MODAL.IMG || visible === MODAL.CODE) &&
!exportData.data),
}}
cancelText="Cancel"
width={600}
>
{visible === MODAL.IMPORT ? (
<div>
<Upload <Upload
action="#" action="#"
beforeUpload={({ file, fileList }) => { beforeUpload={({ file, fileList }) => {
@ -1128,8 +1141,8 @@ export default function ControlPanel(props) {
}; };
}} }}
draggable={true} draggable={true}
dragMainText="Click to upload the file or drag and drop the file here" dragMainText="Drag and drop the file here or click to upload."
dragSubText="Support json" dragSubText="Support json and ddb"
accept="application/json,.ddb" accept="application/json,.ddb"
onRemove={() => onRemove={() =>
setError({ setError({
@ -1149,9 +1162,7 @@ export default function ControlPanel(props) {
<Banner <Banner
type="danger" type="danger"
fullMode={false} fullMode={false}
description={ description={<div className="text-red-800">{error.message}</div>}
<div className="text-red-800">{error.message}</div>
}
/> />
) : error.type === STATUS.OK ? ( ) : error.type === STATUS.OK ? (
<Banner <Banner
@ -1168,8 +1179,25 @@ export default function ControlPanel(props) {
/> />
) )
)} )}
</div> </>
) : exportData.data !== "" || exportData.data ? ( );
};
const getModalBody = () => {
if (visible === MODAL.IMPORT) {
return importModalBody();
}
if (visible === MODAL.RENAME) {
return (
<Input
placeholder="Diagram name"
value={title}
onChange={(v) => setTitle(v)}
/>
);
}
if (exportData.data !== "" || exportData.data) {
return (
<> <>
{visible === MODAL.IMG ? ( {visible === MODAL.IMG ? (
<Image src={exportData.data} alt="Diagram" height={280} /> <Image src={exportData.data} alt="Diagram" height={280} />
@ -1193,11 +1221,54 @@ export default function ControlPanel(props) {
field="filename" field="filename"
/> />
</> </>
) : ( );
} else {
return (
<div className="text-center my-3"> <div className="text-center my-3">
<Spin tip="Loading..." size="large" /> <Spin tip="Loading..." size="large" />
</div> </div>
)} );
}
};
return (
<>
{layout.header && header()}
{toolbar()}
<Modal
title={getModalTitle()}
visible={visible !== MODAL.NONE}
onOk={getModalOnOk}
afterClose={() => {
setExportData((prev) => ({
data: "",
extension: "",
filename: `diagram_${new Date().toISOString()}`,
}));
setError({
type: STATUS.NONE,
message: "",
});
setData(null);
}}
onCancel={() => {
if (visible === MODAL.RENAME) setTitle(prevTitle);
setVisible(MODAL.NONE);
}}
centered
closeOnEsc={true}
okText={getOkText()}
okButtonProps={{
disabled:
(visible === MODAL.IMPORT &&
(error.type === STATUS.ERROR || !data)) ||
((visible === MODAL.IMG || visible === MODAL.CODE) &&
!exportData.data),
}}
cancelText="Cancel"
width={600}
>
{getModalBody()}
</Modal> </Modal>
</> </>
); );
@ -1360,7 +1431,17 @@ export default function ControlPanel(props) {
/> />
</Link> </Link>
<div className="ms-1 mt-1"> <div className="ms-1 mt-1">
<div className="text-xl ms-3">Project1 / Untitled</div> <div className="flex items-center">
<div
className="text-xl ms-3 me-1"
onMouseEnter={() => setShowEditName(true)}
onMouseLeave={() => setShowEditName(false)}
onClick={() => setVisible(MODAL.RENAME)}
>
{title}
</div>
{(showEditName || visible === MODAL.RENAME) && <IconEdit />}
</div>
<div className="flex justify-between items-center"> <div className="flex justify-between items-center">
<div className="flex justify-start text-md select-none me-2"> <div className="flex justify-start text-md select-none me-2">
{Object.keys(menu).map((category) => ( {Object.keys(menu).map((category) => (