Reorganize files

This commit is contained in:
1ilit
2024-04-01 19:44:50 +03:00
parent d4bc5a9669
commit 9df9527950
28 changed files with 280 additions and 253 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,174 @@
import { calcPath } from "../../utils/calcPath";
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 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
)}
fill="none"
strokeWidth={1}
stroke="#ddd"
/>
))}
{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>
);
}

View File

@@ -0,0 +1,276 @@
import { useState } from "react";
import {
Checkbox,
Input,
TextArea,
Row,
Col,
Dropdown,
Button,
Popover,
Tag,
List,
RadioGroup,
Radio,
} from "@douyinfe/semi-ui";
import {
IconPlus,
IconMore,
IconDeleteStroked,
IconCaretdown,
} from "@douyinfe/semi-icons";
import { State } from "../../data/constants";
import useTasks from "../../hooks/useTasks";
import useSaveState from "../../hooks/useSaveState";
const Priority = {
NONE: 0,
LOW: 1,
MEDIUM: 2,
HIGH: 3,
};
const SortOrder = {
ORIGINAL: "My order",
PRIORITY: "Priority",
COMPLETED: "Completed",
ALPHABETICALLY: "Alphabetically",
};
export default function Todo() {
const [activeTask, setActiveTask] = useState(-1);
const [, setSortOrder] = useState(SortOrder.ORIGINAL);
const { tasks, setTasks, updateTask } = useTasks();
const { setSaveState } = useSaveState();
const priorityLabel = (p) => {
switch (p) {
case Priority.NONE:
return "None";
case Priority.LOW:
return "Low";
case Priority.MEDIUM:
return "Medium";
case Priority.HIGH:
return "High";
default:
return "";
}
};
const priorityColor = (p) => {
switch (p) {
case Priority.NONE:
return "blue";
case Priority.LOW:
return "green";
case Priority.MEDIUM:
return "yellow";
case Priority.HIGH:
return "red";
default:
return "";
}
};
const sort = (s) => {
setActiveTask(-1);
switch (s) {
case SortOrder.ORIGINAL:
setTasks((prev) => prev.sort((a, b) => a.order - b.order));
return;
case SortOrder.PRIORITY:
setTasks((prev) => prev.sort((a, b) => b.priority - a.priority));
return;
case SortOrder.COMPLETED:
setTasks((prev) =>
prev.sort((a, b) => {
if (a.complete && !b.complete) {
return 1;
} else if (!a.complete && b.complete) {
return -1;
} else {
return 0;
}
})
);
break;
case SortOrder.ALPHABETICALLY:
setTasks((prev) => prev.sort((a, b) => a.title.localeCompare(b.title)));
break;
default:
break;
}
};
return (
<>
<div className="flex justify-between items-center mx-5 mb-2 sidesheet-theme">
<Dropdown
render={
<Dropdown.Menu>
{Object.values(SortOrder).map((order) => (
<Dropdown.Item
key={order}
onClick={() => {
setSortOrder(order);
sort(order);
}}
>
{order}
</Dropdown.Item>
))}
</Dropdown.Menu>
}
trigger="click"
>
<Button
style={{ marginRight: "10px" }}
theme="borderless"
type="tertiary"
>
Sort by <IconCaretdown />
</Button>
</Dropdown>
<Button
icon={<IconPlus />}
block
onClick={() => {
setTasks((prev) => [
{
complete: false,
details: "",
title: "",
priority: Priority.NONE,
order: prev.length,
},
...prev,
]);
}}
>
Add task
</Button>
</div>
{tasks.length > 0 ? (
<List className="sidesheet-theme">
{tasks.map((t, i) => (
<List.Item
key={i}
style={{ paddingLeft: "18px", paddingRight: "18px" }}
className="hover-1"
onClick={() => setActiveTask(i)}
>
<div className="w-full">
<Row gutter={6} align="middle" type="flex" className="mb-2">
<Col span={2}>
<Checkbox
checked={t.complete}
onChange={(e) => {
updateTask(i, { complete: e.target.checked });
setSaveState(State.SAVING);
}}
></Checkbox>
</Col>
<Col span={19}>
<Input
placeholder="Title"
onChange={(v) => updateTask(i, { title: v })}
value={t.title}
onBlur={() => setSaveState(State.SAVING)}
></Input>
</Col>
<Col span={3}>
<Popover
content={
<div className="p-2 popover-theme">
<div className="mb-2 font-semibold">
Set priority:
</div>
<RadioGroup
onChange={(e) => {
updateTask(i, { priority: e.target.value });
setSaveState(State.SAVING);
}}
value={t.priority}
direction="vertical"
>
<Radio value={Priority.NONE}>
<Tag color={priorityColor(Priority.NONE)}>
{priorityLabel(Priority.NONE)}
</Tag>
</Radio>
<Radio value={Priority.LOW}>
<Tag color={priorityColor(Priority.LOW)}>
{priorityLabel(Priority.LOW)}
</Tag>
</Radio>
<Radio value={Priority.MEDIUM}>
<Tag color={priorityColor(Priority.MEDIUM)}>
{priorityLabel(Priority.MEDIUM)}
</Tag>
</Radio>
<Radio value={Priority.HIGH}>
<Tag color={priorityColor(Priority.HIGH)}>
{priorityLabel(Priority.HIGH)}
</Tag>
</Radio>
</RadioGroup>
<Button
icon={<IconDeleteStroked />}
type="danger"
block
style={{ marginTop: "12px" }}
onClick={() => {
setTasks((prev) =>
prev.filter((task, j) => i !== j)
);
setSaveState(State.SAVING);
}}
>
Delete
</Button>
</div>
}
trigger="click"
showArrow
className="w-[180px]"
>
<Button icon={<IconMore />} type="tertiary" />
</Popover>
</Col>
</Row>
{activeTask === i && (
<Row className="mb-2">
<Col span={2}></Col>
<Col span={22}>
<TextArea
placeholder="Details"
onChange={(v) => updateTask(i, { details: v })}
value={t.details}
onBlur={() => setSaveState(State.SAVING)}
></TextArea>
</Col>
</Row>
)}
<Row>
<Col span={2}></Col>
<Col span={22}>
Priority:{" "}
<Tag color={priorityColor(t.priority)}>
{priorityLabel(t.priority)}
</Tag>
</Col>
</Row>
</div>
</List.Item>
))}
</List>
) : (
<div className="m-5 sidesheet-theme">
You have no tasks yet. Add your to-dos and keep track of your
progress.
</div>
)}
</>
);
}