Skip to content

Commit

Permalink
Refactor structure of modal component
Browse files Browse the repository at this point in the history
  • Loading branch information
phamhieu275 committed May 23, 2024
1 parent bf74463 commit fc018dc
Show file tree
Hide file tree
Showing 26 changed files with 987 additions and 871 deletions.
191 changes: 25 additions & 166 deletions src/components/EditorHeader/ControlPanel.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,8 @@ import {
Toast,
Popconfirm,
} from "@douyinfe/semi-ui";
import { toPng, toJpeg, toSvg } from "html-to-image";
import { toPng, toJpeg } from "html-to-image";
import { saveAs } from "file-saver";
import {
jsonToMySQL,
jsonToPostgreSQL,
jsonToSQLite,
jsonToMariaDB,
jsonToSQLServer,
} from "../../utils/toSQL";
import {
ObjectType,
Action,
Expand Down Expand Up @@ -60,8 +53,8 @@ import useSaveState from "../../hooks/useSaveState";
import { IconAddArea, IconAddNote, IconAddTable } from "../../icons";
import LayoutDropdown from "./LayoutDropdown";
import Sidesheet from "./SideSheet/Sidesheet";
import Modal from "./Modal/Modal";
import { useTranslation } from "react-i18next";
import ModalManager from "./ModalManager";

export default function ControlPanel({
diagramId,
Expand All @@ -72,13 +65,7 @@ export default function ControlPanel({
}) {
const [modal, setModal] = useState(MODAL.NONE);
const [sidesheet, setSidesheet] = useState(SIDESHEET.NONE);
const [prevTitle, setPrevTitle] = useState(title);
const [showEditName, setShowEditName] = useState(false);
const [exportData, setExportData] = useState({
data: null,
filename: `${title}_${new Date().toISOString()}`,
extension: "",
});
const { saveState, setSaveState } = useSaveState();
const { layout, setLayout } = useLayout();
const { settings, setSettings } = useSettings();
Expand Down Expand Up @@ -452,7 +439,7 @@ export default function ControlPanel({
}
};

const fileImport = () => setModal(MODAL.IMPORT);
const importDiagram = () => setModal(MODAL.IMPORT_DIAGRAM);
const viewGrid = () =>
setSettings((prev) => ({ ...prev, showGrid: !prev.showGrid }));
const zoomIn = () =>
Expand Down Expand Up @@ -704,7 +691,6 @@ export default function ControlPanel({
rename: {
function: () => {
setModal(MODAL.RENAME);
setPrevTitle(title);
},
},
delete_diagram: {
Expand All @@ -730,7 +716,7 @@ export default function ControlPanel({
},
},
import_diagram: {
function: fileImport,
function: importDiagram,
shortcut: "Ctrl+I",
},
import_from_source: {
Expand All @@ -739,66 +725,8 @@ export default function ControlPanel({
export_as: {
children: [
{
PNG: () => {
toPng(document.getElementById("canvas")).then(function (dataUrl) {
setExportData((prev) => ({
...prev,
data: dataUrl,
extension: "png",
}));
});
setModal(MODAL.IMG);
},
},
{
JPEG: () => {
toJpeg(document.getElementById("canvas"), { quality: 0.95 }).then(
function (dataUrl) {
setExportData((prev) => ({
...prev,
data: dataUrl,
extension: "jpeg",
}));
},
);
setModal(MODAL.IMG);
},
},
{
JSON: () => {
setModal(MODAL.CODE);
const result = JSON.stringify(
{
tables: tables,
relationships: relationships,
notes: notes,
subjectAreas: areas,
types: types,
title: title,
},
null,
2,
);
setExportData((prev) => ({
...prev,
data: result,
extension: "json",
}));
},
},
{
SVG: () => {
const filter = (node) => node.tagName !== "i";
toSvg(document.getElementById("canvas"), { filter: filter }).then(
function (dataUrl) {
setExportData((prev) => ({
...prev,
data: dataUrl,
extension: "svg",
}));
},
);
setModal(MODAL.IMG);
IMAGE: () => {
setModal(MODAL.EXPORT_IMG);
},
},
{
Expand All @@ -817,10 +745,20 @@ export default function ControlPanel({
canvas.offsetWidth,
canvas.offsetHeight,
);
doc.save(`${exportData.filename}.pdf`);
doc.save(`${title}_${new Date().toISOString()}.pdf`);
});
},
},
{
SQL: () => {
setModal(MODAL.EXPORT_SQL);
},
},
{
JSON: () => {
setModal(MODAL.EXPORT_JSON);
},
},
{
DRAWDB: () => {
const result = JSON.stringify(
Expand All @@ -840,87 +778,7 @@ export default function ControlPanel({
const blob = new Blob([result], {
type: "text/plain;charset=utf-8",
});
saveAs(blob, `${exportData.filename}.ddb`);
},
},
],
function: () => {},
},
export_source: {
children: [
{
MySQL: () => {
setModal(MODAL.CODE);
const src = jsonToMySQL({
tables: tables,
references: relationships,
types: types,
});
setExportData((prev) => ({
...prev,
data: src,
extension: "sql",
}));
},
},
{
PostgreSQL: () => {
setModal(MODAL.CODE);
const src = jsonToPostgreSQL({
tables: tables,
references: relationships,
types: types,
});
setExportData((prev) => ({
...prev,
data: src,
extension: "sql",
}));
},
},
{
SQLite: () => {
setModal(MODAL.CODE);
const src = jsonToSQLite({
tables: tables,
references: relationships,
types: types,
});
setExportData((prev) => ({
...prev,
data: src,
extension: "sql",
}));
},
},
{
MariaDB: () => {
setModal(MODAL.CODE);
const src = jsonToMariaDB({
tables: tables,
references: relationships,
types: types,
});
setExportData((prev) => ({
...prev,
data: src,
extension: "sql",
}));
},
},
{
MSSQL: () => {
setModal(MODAL.CODE);
const src = jsonToSQLServer({
tables: tables,
references: relationships,
types: types,
});
setExportData((prev) => ({
...prev,
data: src,
extension: "sql",
}));
saveAs(blob, `${title}_${new Date().toISOString()}.ddb`);
},
},
],
Expand Down Expand Up @@ -1166,7 +1024,7 @@ export default function ControlPanel({
},
};

useHotkeys("ctrl+i, meta+i", fileImport, { preventDefault: true });
useHotkeys("ctrl+i, meta+i", importDiagram, { preventDefault: true });
useHotkeys("ctrl+z, meta+z", undo, { preventDefault: true });
useHotkeys("ctrl+y, meta+y", redo, { preventDefault: true });
useHotkeys("ctrl+s, meta+s", save, { preventDefault: true });
Expand Down Expand Up @@ -1196,20 +1054,21 @@ export default function ControlPanel({
});
useHotkeys("ctrl+alt+w, meta+alt+w", fitWindow, { preventDefault: true });

const hideModal = () => {
setModal(MODAL.NONE);
};

return (
<>
{layout.header && header()}
{layout.toolbar && toolbar()}
<Modal
<ModalManager
modal={modal}
exportData={exportData}
setExportData={setExportData}
hideModal={hideModal}
title={title}
setTitle={setTitle}
setPrevTitle={setPrevTitle}
setDiagramId={setDiagramId}
setModal={setModal}
prevTitle={prevTitle}
/>
<Sidesheet
type={sidesheet}
Expand Down
34 changes: 34 additions & 0 deletions src/components/EditorHeader/Modal/BaseModal.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { Modal as SemiUIModal } from "@douyinfe/semi-ui";
import { useTranslation } from "react-i18next";

export default function Modal({
children,
modalTitle,
okText,
onOk,
onCancel,
okBtnDisabled,
width,
}) {
const { t } = useTranslation();

return (
<SemiUIModal
title={modalTitle || ""}
visible={true}
onOk={onOk}
onCancel={onCancel}
centered
closeOnEsc={true}
okText={okText || t("confirm")}
okButtonProps={{
disabled: okBtnDisabled,
}}
cancelText={t("cancel")}
width={width || 600}
// bodyStyle={{ maxHeight: window.innerHeight - 280, overflow: "auto" }}
>
{children}
</SemiUIModal>
);
}
80 changes: 80 additions & 0 deletions src/components/EditorHeader/Modal/ExportImage.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import { useEffect, useState } from "react";
import { toPng, toJpeg, toSvg } from "html-to-image";
import { Image, Select, Spin } from "@douyinfe/semi-ui";
import { useTranslation } from "react-i18next";
import { IMAGE_TYPES } from "../../../data/constants";
import ExportModal from "./ExportModal";

export default function ExportImage({ title, hideModal }) {
const { t } = useTranslation();
const [exportData, setExportData] = useState({
data: null,
filename: `${title}_${new Date().toISOString()}`,
extension: IMAGE_TYPES[0],
});

const changeType = async (type) => {
setExportData((prev) => ({
...prev,
data: null,
extension: type,
}));

const canvasElm = document.getElementById("canvas");

let dataUrl;
switch (type) {
case "png":
dataUrl = await toPng(canvasElm);
break;
case "jpeg":
dataUrl = await toJpeg(canvasElm, { quality: 0.95 });
break;
case "svg":
dataUrl = await toSvg(canvasElm, {
filter: (node) => node.tagName !== "i",
});
break;
}

setExportData((prev) => ({
...prev,
data: dataUrl,
}));
};

useEffect(() => {
changeType(IMAGE_TYPES[0]);
}, []);

return (
<ExportModal
modalTitle={t("export_image")}
onCancel={hideModal}
exportData={exportData}
setExportData={setExportData}
>
<div className="font-semibold mb-1">{t("format")}:</div>
<Select
className="w-full mb-2"
optionList={IMAGE_TYPES.map((type) => ({
label: type.toUpperCase(),
value: type,
}))}
value={exportData.extension}
onChange={changeType}
/>
<div className="text-center my-3 h-[280px] flex flex-col justify-center items-center">
{exportData.data ? (
<Image
src={exportData.data}
alt="Diagram"
className="overflow-auto"
/>
) : (
<Spin size="large" />
)}
</div>
</ExportModal>
);
}
Loading

0 comments on commit fc018dc

Please sign in to comment.