Add thumbnails to create new
modal
This commit is contained in:
parent
c578374857
commit
38943d80f2
@ -10,7 +10,6 @@ import {
|
|||||||
IconRedo,
|
IconRedo,
|
||||||
IconRowsStroked,
|
IconRowsStroked,
|
||||||
IconEdit,
|
IconEdit,
|
||||||
IconPlus,
|
|
||||||
} 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";
|
||||||
@ -71,6 +70,7 @@ import { db } from "../data/db";
|
|||||||
import { useLiveQuery } from "dexie-react-hooks";
|
import { useLiveQuery } from "dexie-react-hooks";
|
||||||
import { Parser } from "node-sql-parser";
|
import { Parser } from "node-sql-parser";
|
||||||
import Todo from "./Todo";
|
import Todo from "./Todo";
|
||||||
|
import { Thumbnail } from "./Thumbnail";
|
||||||
|
|
||||||
export default function ControlPanel({
|
export default function ControlPanel({
|
||||||
diagramId,
|
diagramId,
|
||||||
@ -81,6 +81,7 @@ export default function ControlPanel({
|
|||||||
setState,
|
setState,
|
||||||
lastSaved,
|
lastSaved,
|
||||||
}) {
|
}) {
|
||||||
|
const defaultTemplates = useLiveQuery(() => db.templates.toArray());
|
||||||
const MODAL = {
|
const MODAL = {
|
||||||
NONE: 0,
|
NONE: 0,
|
||||||
IMG: 1,
|
IMG: 1,
|
||||||
@ -1012,7 +1013,7 @@ export default function ControlPanel({
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"MSSQL": () => {
|
MSSQL: () => {
|
||||||
setVisible(MODAL.CODE);
|
setVisible(MODAL.CODE);
|
||||||
const src = jsonToSQLServer({
|
const src = jsonToSQLServer({
|
||||||
tables: tables,
|
tables: tables,
|
||||||
@ -1256,7 +1257,7 @@ export default function ControlPanel({
|
|||||||
case MODAL.SAVEAS:
|
case MODAL.SAVEAS:
|
||||||
return "Save as";
|
return "Save as";
|
||||||
case MODAL.NEW:
|
case MODAL.NEW:
|
||||||
return "New diagram";
|
return "Create new diagram";
|
||||||
default:
|
default:
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
@ -1820,32 +1821,28 @@ export default function ControlPanel({
|
|||||||
|
|
||||||
const newModalBody = () => (
|
const newModalBody = () => (
|
||||||
<div className="h-[360px] grid grid-cols-3 gap-2 overflow-auto px-1">
|
<div className="h-[360px] grid grid-cols-3 gap-2 overflow-auto px-1">
|
||||||
<div>
|
<div onClick={() => setSelectedTemplateId(0)}>
|
||||||
<div
|
<div
|
||||||
className={`h-[180px] w-full bg-blue-400 bg-opacity-30 flex justify-center items-center rounded hover:bg-opacity-40 hover:border-2 hover:border-dashed ${
|
className={`rounded-md h-[180px] border-2 hover:border-dashed ${
|
||||||
settings.mode === "light"
|
selectedTemplateId === 0 ? "border-blue-400" : "border-zinc-100"
|
||||||
? "hover:border-blue-500"
|
}`}
|
||||||
: "hover:border-white"
|
|
||||||
} ${selectedTemplateId === 0 && "border-2 border-blue-500"}`}
|
|
||||||
onClick={() => setSelectedTemplateId(0)}
|
|
||||||
>
|
>
|
||||||
<IconPlus style={{ color: "#fff" }} size="extra-large" />
|
<Thumbnail i={0} diagram={{}} zoom={0.24} />
|
||||||
</div>
|
</div>
|
||||||
<div className="text-center mt-1">Blank</div>
|
<div className="text-center mt-1">Blank</div>
|
||||||
</div>
|
</div>
|
||||||
{[1, 2, 3, 4, 5, 6, 7, 8].map((i) => (
|
{defaultTemplates.map((temp, i) => (
|
||||||
<div key={i}>
|
<div key={i} onClick={() => setSelectedTemplateId(temp.id)}>
|
||||||
<div
|
<div
|
||||||
className={`h-[180px] w-full bg-blue-400 bg-opacity-30 flex justify-center items-center rounded hover:bg-opacity-40 hover:border-2 hover:border-dashed ${
|
className={`rounded-md h-[180px] border-2 hover:border-dashed ${
|
||||||
settings.mode === "light"
|
selectedTemplateId === temp.id
|
||||||
? "hover:border-blue-500"
|
? "border-blue-400"
|
||||||
: "hover:border-white"
|
: "border-zinc-100"
|
||||||
} ${selectedTemplateId === i && "border-2 border-blue-500"}`}
|
}`}
|
||||||
onClick={() => setSelectedTemplateId(i)}
|
|
||||||
>
|
>
|
||||||
+
|
<Thumbnail i={temp.id} diagram={temp} zoom={0.24} />
|
||||||
</div>
|
</div>
|
||||||
<div className="text-center mt-1">Template {i}</div>
|
<div className="text-center mt-1">{temp.title}</div>
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
@ -2021,7 +2018,7 @@ export default function ControlPanel({
|
|||||||
(visible === MODAL.IMPORT_SRC && data.src === ""),
|
(visible === MODAL.IMPORT_SRC && data.src === ""),
|
||||||
}}
|
}}
|
||||||
cancelText="Cancel"
|
cancelText="Cancel"
|
||||||
width={600}
|
width={visible === MODAL.NEW ? 740 : 600}
|
||||||
>
|
>
|
||||||
{getModalBody()}
|
{getModalBody()}
|
||||||
</Modal>
|
</Modal>
|
||||||
|
178
src/components/Thumbnail.jsx
Normal file
178
src/components/Thumbnail.jsx
Normal file
@ -0,0 +1,178 @@
|
|||||||
|
import { calcPath } from "../utils";
|
||||||
|
|
||||||
|
export function Thumbnail({ diagram, i, zoom }) {
|
||||||
|
const translateX = 32 * zoom;
|
||||||
|
const translateY = 32 * zoom;
|
||||||
|
const theme = localStorage.getItem("theme");
|
||||||
|
return (
|
||||||
|
<svg
|
||||||
|
className={`${
|
||||||
|
theme === "dark" ? "bg-[#222229]" : "bg-white"
|
||||||
|
} w-full h-full rounded-md text-color`}
|
||||||
|
>
|
||||||
|
<defs>
|
||||||
|
<pattern
|
||||||
|
id={"pattern-circles-" + i}
|
||||||
|
x="0"
|
||||||
|
y="0"
|
||||||
|
width="10"
|
||||||
|
height="10"
|
||||||
|
patternUnits="userSpaceOnUse"
|
||||||
|
patternContentUnits="userSpaceOnUse"
|
||||||
|
>
|
||||||
|
<circle
|
||||||
|
id={"pattern-circle-" + i}
|
||||||
|
cx="2"
|
||||||
|
cy="2"
|
||||||
|
r="0.4"
|
||||||
|
fill="rgb(99, 152, 191)"
|
||||||
|
></circle>
|
||||||
|
</pattern>
|
||||||
|
</defs>
|
||||||
|
<rect
|
||||||
|
x="0"
|
||||||
|
y="0"
|
||||||
|
width="100%"
|
||||||
|
height="100%"
|
||||||
|
fill={"url(#pattern-circles-" + i + ")"}
|
||||||
|
></rect>
|
||||||
|
<g
|
||||||
|
style={{
|
||||||
|
transform: `translate(${translateX}px, ${translateY}px) scale(${zoom})`,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{diagram.subjectAreas?.map((a) => (
|
||||||
|
<foreignObject
|
||||||
|
key={a.id}
|
||||||
|
x={a.x}
|
||||||
|
y={a.y}
|
||||||
|
width={a.width > 0 ? a.width : 0}
|
||||||
|
height={a.height > 0 ? a.height : 0}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className={`border border-slate-400 w-full h-full rounded-sm relative`}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="opacity-40 w-fill h-full"
|
||||||
|
style={{ backgroundColor: a.color }}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="text-color absolute top-1 left-2 select-none">
|
||||||
|
{a.name}
|
||||||
|
</div>
|
||||||
|
</foreignObject>
|
||||||
|
))}
|
||||||
|
{diagram.tables?.map((table, i) => {
|
||||||
|
const height = table.fields.length * 36 + 50 + 7;
|
||||||
|
return (
|
||||||
|
<foreignObject
|
||||||
|
x={table.x}
|
||||||
|
y={table.y}
|
||||||
|
width={200}
|
||||||
|
height={height}
|
||||||
|
key={i}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className={`border rounded-md ${
|
||||||
|
theme === "dark"
|
||||||
|
? "bg-zinc-800"
|
||||||
|
: "border-zinc-300 bg-zinc-100"
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="h-2 w-full rounded-t-sm"
|
||||||
|
style={{ backgroundColor: table.color }}
|
||||||
|
></div>
|
||||||
|
<div className="rounded-b-[3px]">
|
||||||
|
<div
|
||||||
|
className={`font-bold py-1 px-2 border-b ${
|
||||||
|
theme === "dark" ? "bg-zinc-900" : "bg-zinc-200"
|
||||||
|
} border-gray-300`}
|
||||||
|
>
|
||||||
|
{table.name}
|
||||||
|
</div>
|
||||||
|
{table.fields.map((f, j) => (
|
||||||
|
<div
|
||||||
|
className={`flex justify-between items-center py-1 px-2 ${
|
||||||
|
j < table.fields.length - 1 ? "border-b" : ""
|
||||||
|
}`}
|
||||||
|
key={j}
|
||||||
|
>
|
||||||
|
<div className="flex items-center justify-start">
|
||||||
|
<div
|
||||||
|
className={`w-[6px] h-[6px] bg-[#2f68ad] opacity-80 z-50 rounded-full me-2`}
|
||||||
|
></div>
|
||||||
|
<div>{f.name}</div>
|
||||||
|
</div>
|
||||||
|
<div className="text-zinc-500">{f.type}</div>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</foreignObject>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
{diagram.relationships?.map((e, i) => (
|
||||||
|
<path
|
||||||
|
key={i}
|
||||||
|
d={calcPath(
|
||||||
|
e.startX,
|
||||||
|
e.endX,
|
||||||
|
e.startY - translateY / zoom,
|
||||||
|
e.endY - (translateY / zoom) * 0.5,
|
||||||
|
e.startFieldId,
|
||||||
|
e.endFieldId
|
||||||
|
)}
|
||||||
|
fill="none"
|
||||||
|
strokeWidth={1}
|
||||||
|
stroke="gray"
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
{diagram.notes?.map((n) => {
|
||||||
|
const x = n.x;
|
||||||
|
const y = n.y;
|
||||||
|
const w = 180;
|
||||||
|
const r = 3;
|
||||||
|
const fold = 24;
|
||||||
|
const h = n.height;
|
||||||
|
return (
|
||||||
|
<g key={n.id}>
|
||||||
|
<path
|
||||||
|
d={`M${x + fold} ${y} L${x + w - r} ${y} A${r} ${r} 0 0 1 ${
|
||||||
|
x + w
|
||||||
|
} ${y + r} L${x + w} ${y + h - r} A${r} ${r} 0 0 1 ${
|
||||||
|
x + w - r
|
||||||
|
} ${y + h} L${x + r} ${y + h} A${r} ${r} 0 0 1 ${x} ${
|
||||||
|
y + h - r
|
||||||
|
} L${x} ${y + fold}`}
|
||||||
|
fill={n.color}
|
||||||
|
stroke="rgb(168 162 158)"
|
||||||
|
strokeLinejoin="round"
|
||||||
|
strokeWidth="0.5"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
d={`M${x} ${y + fold} L${x + fold - r} ${
|
||||||
|
y + fold
|
||||||
|
} A${r} ${r} 0 0 0 ${x + fold} ${y + fold - r} L${
|
||||||
|
x + fold
|
||||||
|
} ${y} L${x} ${y + fold} Z`}
|
||||||
|
fill={n.color}
|
||||||
|
stroke={"rgb(168 162 158)"}
|
||||||
|
strokeLinejoin="round"
|
||||||
|
strokeWidth="0.5"
|
||||||
|
/>
|
||||||
|
<foreignObject x={x} y={y} width={w} height={h}>
|
||||||
|
<div className="text-gray-900 w-full h-full px-4 py-2">
|
||||||
|
<label htmlFor={`note_${n.id}`} className="ms-4">
|
||||||
|
{n.title}
|
||||||
|
</label>
|
||||||
|
<div className="mt-[2px]">{n.content}</div>
|
||||||
|
</div>
|
||||||
|
</foreignObject>
|
||||||
|
</g>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
);
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user