seat-editor 1.2.6 → 1.2.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +80 -0
- package/dist/app/layout.d.ts +1 -1
- package/dist/app/layout.jsx +27 -0
- package/dist/app/new-board/page.d.ts +1 -1
- package/dist/app/new-board/page.jsx +12 -0
- package/dist/app/old-board/page.d.ts +2 -1
- package/dist/app/old-board/page.jsx +515 -0
- package/dist/app/only-view/page.d.ts +1 -1
- package/dist/app/page.d.ts +1 -1
- package/dist/app/page.jsx +13 -0
- package/dist/components/button-tools/index.d.ts +1 -1
- package/dist/components/button-tools/index.jsx +17 -0
- package/dist/components/form-tools/label.d.ts +1 -1
- package/dist/components/form-tools/label.jsx +44 -0
- package/dist/components/form-tools/shape.d.ts +1 -1
- package/dist/components/form-tools/shape.jsx +43 -0
- package/dist/components/input/number-indicator.d.ts +1 -1
- package/dist/components/input/number-indicator.jsx +36 -0
- package/dist/components/layer/index.d.ts +3 -1
- package/dist/components/layer/index.jsx +22 -11
- package/dist/components/lib/index.d.ts +1 -1
- package/dist/components/lib/index.jsx +33 -0
- package/dist/components/modal-preview/index.d.ts +1 -1
- package/dist/components/modal-preview/index.jsx +11 -0
- package/dist/features/board/index.d.ts +1 -1
- package/dist/features/board/index.jsx +290 -0
- package/dist/features/navbar/index.d.ts +1 -1
- package/dist/features/navbar/index.jsx +5 -0
- package/dist/features/package/index.d.ts +1 -1
- package/dist/features/package/index.jsx +39 -0
- package/dist/features/panel/index.d.ts +1 -1
- package/dist/features/panel/index.jsx +91 -0
- package/dist/features/panel/select-tool.d.ts +1 -1
- package/dist/features/panel/select-tool.jsx +45 -0
- package/dist/features/panel/square-circle-tool.d.ts +1 -1
- package/dist/features/panel/square-circle-tool.jsx +10 -0
- package/dist/features/panel/table-seat-circle.d.ts +1 -1
- package/dist/features/panel/table-seat-circle.jsx +31 -0
- package/dist/features/panel/text-tool.d.ts +1 -1
- package/dist/features/panel/text-tool.jsx +22 -0
- package/dist/features/panel/upload-tool.d.ts +1 -1
- package/dist/features/panel/upload-tool.jsx +80 -0
- package/dist/features/side-tool/index.d.ts +1 -1
- package/dist/features/side-tool/index.jsx +211 -0
- package/dist/features/view/index.d.ts +1 -1
- package/dist/features/view/index.jsx +4 -5
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/provider/antd-provider.jsx +30 -0
- package/dist/provider/redux-provider.d.ts +1 -1
- package/dist/provider/redux-provider.jsx +6 -0
- package/dist/provider/store-provider.d.ts +1 -1
- package/dist/provider/store-provider.jsx +8 -0
- package/package.json +1 -1
|
@@ -13,5 +13,5 @@ export interface TableEditorProps {
|
|
|
13
13
|
];
|
|
14
14
|
statusKey: string;
|
|
15
15
|
}
|
|
16
|
-
declare const TableEditor: (props: TableEditorProps) => import("react
|
|
16
|
+
declare const TableEditor: (props: TableEditorProps) => import("react").JSX.Element;
|
|
17
17
|
export default TableEditor;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useEffect } from "react";
|
|
3
|
+
import Board from "../board";
|
|
4
|
+
import SideTool from "../side-tool";
|
|
5
|
+
import ControlPanels from "../panel";
|
|
6
|
+
import { useAppDispatch, useAppSelector } from "../../hooks/use-redux";
|
|
7
|
+
const TableEditor = (props) => {
|
|
8
|
+
const { componentProps, extraComponentProps, onCurrentStateChange } = props;
|
|
9
|
+
const { components, extraComponents } = useAppSelector((state) => state.board);
|
|
10
|
+
const dispatch = useAppDispatch();
|
|
11
|
+
useEffect(() => {
|
|
12
|
+
onCurrentStateChange && onCurrentStateChange({
|
|
13
|
+
components,
|
|
14
|
+
extraComponents,
|
|
15
|
+
});
|
|
16
|
+
}, [components, extraComponents]);
|
|
17
|
+
useEffect(() => {
|
|
18
|
+
if ((componentProps === null || componentProps === void 0 ? void 0 : componentProps.length) > 0) {
|
|
19
|
+
dispatch({
|
|
20
|
+
type: "board/setNewComponents",
|
|
21
|
+
payload: componentProps,
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
if ((extraComponentProps === null || extraComponentProps === void 0 ? void 0 : extraComponentProps.length) > 0) {
|
|
25
|
+
dispatch({
|
|
26
|
+
type: "board/setNewExtraComponent",
|
|
27
|
+
payload: extraComponentProps,
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
}, [componentProps, extraComponentProps]);
|
|
31
|
+
return (<>
|
|
32
|
+
<div className="w-full h-screen flex relative">
|
|
33
|
+
<SideTool />
|
|
34
|
+
<Board onSelectComponent={props.onSelectComponent}/>
|
|
35
|
+
<ControlPanels />
|
|
36
|
+
</div>
|
|
37
|
+
</>);
|
|
38
|
+
};
|
|
39
|
+
export default TableEditor;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
declare const ControlPanels: () => import("react
|
|
1
|
+
declare const ControlPanels: () => import("react").JSX.Element;
|
|
2
2
|
export default ControlPanels;
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useEffect, useState } from "react";
|
|
3
|
+
import { useAppDispatch, useAppSelector } from "../../hooks/use-redux";
|
|
4
|
+
import { Form, Drawer, Input } from "antd";
|
|
5
|
+
import SelectToolForm from "./select-tool";
|
|
6
|
+
import SquareToolForm from "./square-circle-tool";
|
|
7
|
+
import SeatCircle from "./table-seat-circle";
|
|
8
|
+
import UploadTool from "./upload-tool";
|
|
9
|
+
const ControlPanels = () => {
|
|
10
|
+
const dispatch = useAppDispatch();
|
|
11
|
+
const tool = useAppSelector((state) => state.tool);
|
|
12
|
+
const selectedComponent = useAppSelector((state) => state.panel.selectedComponent);
|
|
13
|
+
const { show } = useAppSelector((state) => state.panel);
|
|
14
|
+
const [open, setOpen] = useState(false);
|
|
15
|
+
const [form] = Form.useForm();
|
|
16
|
+
let values = Form.useWatch([], form);
|
|
17
|
+
useEffect(() => {
|
|
18
|
+
console.log("masuuuuk");
|
|
19
|
+
if (selectedComponent) {
|
|
20
|
+
const isDifferentId = (selectedComponent === null || selectedComponent === void 0 ? void 0 : selectedComponent.id) !== (values === null || values === void 0 ? void 0 : values.id) || !(values === null || values === void 0 ? void 0 : values.id);
|
|
21
|
+
const isSameIdAndSameDimensions = (selectedComponent === null || selectedComponent === void 0 ? void 0 : selectedComponent.id) === (values === null || values === void 0 ? void 0 : values.id) &&
|
|
22
|
+
(selectedComponent === null || selectedComponent === void 0 ? void 0 : selectedComponent.height) === (values === null || values === void 0 ? void 0 : values.height) &&
|
|
23
|
+
(selectedComponent === null || selectedComponent === void 0 ? void 0 : selectedComponent.width) === (values === null || values === void 0 ? void 0 : values.width) &&
|
|
24
|
+
(selectedComponent === null || selectedComponent === void 0 ? void 0 : selectedComponent.x) === (values === null || values === void 0 ? void 0 : values.x) &&
|
|
25
|
+
(selectedComponent === null || selectedComponent === void 0 ? void 0 : selectedComponent.y) === (values === null || values === void 0 ? void 0 : values.y);
|
|
26
|
+
console.log({ isDifferentId, isSameIdAndSameDimensions, show });
|
|
27
|
+
if (show && (isDifferentId || isSameIdAndSameDimensions)) {
|
|
28
|
+
setOpen(true);
|
|
29
|
+
}
|
|
30
|
+
console.log("turee");
|
|
31
|
+
form.setFieldsValue(selectedComponent);
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
console.log("false");
|
|
35
|
+
setOpen(false);
|
|
36
|
+
}
|
|
37
|
+
}, [selectedComponent]);
|
|
38
|
+
useEffect(() => {
|
|
39
|
+
if (tool.active === "background" || tool.active === "image-table") {
|
|
40
|
+
setOpen(true);
|
|
41
|
+
}
|
|
42
|
+
}, [tool]);
|
|
43
|
+
const handleChangeComponent = (values, allValues) => {
|
|
44
|
+
dispatch({
|
|
45
|
+
type: "board/updateComponent",
|
|
46
|
+
payload: Object.assign(Object.assign({}, (selectedComponent || {})), allValues),
|
|
47
|
+
});
|
|
48
|
+
dispatch({
|
|
49
|
+
type: "panel/updateSelectedComponent",
|
|
50
|
+
payload: Object.assign(Object.assign({}, (selectedComponent || {})), allValues),
|
|
51
|
+
});
|
|
52
|
+
};
|
|
53
|
+
const renderFormPanel = () => {
|
|
54
|
+
switch (tool.active) {
|
|
55
|
+
case "select":
|
|
56
|
+
return <SelectToolForm />;
|
|
57
|
+
case "square":
|
|
58
|
+
case "circle":
|
|
59
|
+
return <SquareToolForm />;
|
|
60
|
+
case "table-seat-circle":
|
|
61
|
+
return <SeatCircle />;
|
|
62
|
+
case "image-table":
|
|
63
|
+
return <UploadTool name={tool.active} type="component"/>;
|
|
64
|
+
case "background":
|
|
65
|
+
return <UploadTool name={tool.active} type="background"/>;
|
|
66
|
+
default:
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
const handleClose = () => {
|
|
71
|
+
setOpen(false);
|
|
72
|
+
dispatch({
|
|
73
|
+
type: "panel/setShow",
|
|
74
|
+
payload: false,
|
|
75
|
+
});
|
|
76
|
+
};
|
|
77
|
+
// if(!show) return null
|
|
78
|
+
return (<Drawer open={show} onClose={handleClose} title="Panel">
|
|
79
|
+
<div className="bg-white h-full max-h-screen overflow-y-auto w-[300px]">
|
|
80
|
+
<Form layout="vertical" form={form} name="table" onFinish={(values) => {
|
|
81
|
+
console.log(values);
|
|
82
|
+
}} onValuesChange={handleChangeComponent} initialValues={{ labels: [{}] }}>
|
|
83
|
+
<Form.Item name="id" hidden>
|
|
84
|
+
<Input />
|
|
85
|
+
</Form.Item>
|
|
86
|
+
{renderFormPanel()}
|
|
87
|
+
</Form>
|
|
88
|
+
</div>
|
|
89
|
+
</Drawer>);
|
|
90
|
+
};
|
|
91
|
+
export default ControlPanels;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useAppSelector } from "../../hooks/use-redux";
|
|
3
|
+
import SquareToolForm from "./square-circle-tool";
|
|
4
|
+
import SeatCircle from "./table-seat-circle";
|
|
5
|
+
import UploadTool from "./upload-tool";
|
|
6
|
+
import TextTool from "./text-tool";
|
|
7
|
+
const SelectToolForm = ({ title = "Title" }) => {
|
|
8
|
+
const components = useAppSelector((state) => state.board.components);
|
|
9
|
+
const selectedComponent = useAppSelector((state) => state.panel.selectedComponent);
|
|
10
|
+
const SummaryComponents = () => {
|
|
11
|
+
const countByShape = components === null || components === void 0 ? void 0 : components.reduce((acc, item) => {
|
|
12
|
+
acc[item.shape] = (acc[item.shape] || 0) + 1;
|
|
13
|
+
return acc;
|
|
14
|
+
}, {});
|
|
15
|
+
return (<div className="flex flex-col">
|
|
16
|
+
<h1 className="heading-s">{title}</h1>
|
|
17
|
+
<div className="flex flex-col gap-2 mt-5">
|
|
18
|
+
{Object.entries(countByShape).map(([shape, count]) => (<div key={shape}>
|
|
19
|
+
<span className="font-bold">{shape}:</span> {count}
|
|
20
|
+
</div>))}
|
|
21
|
+
</div>
|
|
22
|
+
</div>);
|
|
23
|
+
};
|
|
24
|
+
const renderComponent = () => {
|
|
25
|
+
switch (selectedComponent === null || selectedComponent === void 0 ? void 0 : selectedComponent.shape) {
|
|
26
|
+
case "square":
|
|
27
|
+
case "circle":
|
|
28
|
+
return <SquareToolForm />;
|
|
29
|
+
case "table-seat-circle":
|
|
30
|
+
return <SeatCircle />;
|
|
31
|
+
case "image-table":
|
|
32
|
+
case "background":
|
|
33
|
+
return <UploadTool name={selectedComponent === null || selectedComponent === void 0 ? void 0 : selectedComponent.name}/>;
|
|
34
|
+
case "text":
|
|
35
|
+
return <TextTool />;
|
|
36
|
+
default:
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
return (<div className="flex flex-col gap-2">
|
|
41
|
+
<SummaryComponents />
|
|
42
|
+
{renderComponent()}
|
|
43
|
+
</div>);
|
|
44
|
+
};
|
|
45
|
+
export default SelectToolForm;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
declare const SquareToolForm: () => import("react
|
|
1
|
+
declare const SquareToolForm: () => import("react").JSX.Element;
|
|
2
2
|
export default SquareToolForm;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import SectionLabel from "../../components/form-tools/label";
|
|
3
|
+
import SectionShape from "../../components/form-tools/shape";
|
|
4
|
+
const SquareToolForm = () => {
|
|
5
|
+
return (<>
|
|
6
|
+
<SectionShape />
|
|
7
|
+
<SectionLabel />
|
|
8
|
+
</>);
|
|
9
|
+
};
|
|
10
|
+
export default SquareToolForm;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
declare const SeatCircle: () => import("react
|
|
1
|
+
declare const SeatCircle: () => import("react").JSX.Element;
|
|
2
2
|
export default SeatCircle;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { ColorPicker, Flex, Form, InputNumber } from "antd";
|
|
3
|
+
import SectionLabel from "../../components/form-tools/label";
|
|
4
|
+
import SectionShape from "../../components/form-tools/shape";
|
|
5
|
+
const SeatCircle = () => {
|
|
6
|
+
return (<>
|
|
7
|
+
<div className="py-2">
|
|
8
|
+
<h1 className="heading-s"> Round table</h1>
|
|
9
|
+
<Flex>
|
|
10
|
+
<Form.Item name="seatCount" label="Seat Count" className="w-full">
|
|
11
|
+
<InputNumber />
|
|
12
|
+
</Form.Item>
|
|
13
|
+
<Form.Item name="openSpace" label="Open Space" className="w-full">
|
|
14
|
+
<InputNumber max={1} min={0} step={0.1}/>
|
|
15
|
+
</Form.Item>
|
|
16
|
+
|
|
17
|
+
</Flex>
|
|
18
|
+
<Flex gap={2}>
|
|
19
|
+
<Form.Item label="Seat Fill" name={"seatFill"} getValueFromEvent={(color) => color.toHexString()} className="w-full ">
|
|
20
|
+
<ColorPicker allowClear format="hex" defaultFormat="hex"/>
|
|
21
|
+
</Form.Item>
|
|
22
|
+
<Form.Item label="Table Fill" name={"fill"} getValueFromEvent={(color) => color.toHexString()} className="w-full ">
|
|
23
|
+
<ColorPicker allowClear format="hex" defaultFormat="hex"/>
|
|
24
|
+
</Form.Item>
|
|
25
|
+
</Flex>
|
|
26
|
+
<SectionShape />
|
|
27
|
+
<SectionLabel />
|
|
28
|
+
</div>
|
|
29
|
+
</>);
|
|
30
|
+
};
|
|
31
|
+
export default SeatCircle;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
declare const TextTool: () => import("react
|
|
1
|
+
declare const TextTool: () => import("react").JSX.Element;
|
|
2
2
|
export default TextTool;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { ColorPicker, Form, Input, InputNumber } from "antd";
|
|
3
|
+
const TextTool = () => {
|
|
4
|
+
return (<div className="py-2">
|
|
5
|
+
<Form.Item name="text" label="Text">
|
|
6
|
+
<Input />
|
|
7
|
+
</Form.Item>
|
|
8
|
+
<Form.Item name={"fontColor"} label="Color" getValueFromEvent={(color) => color.toHexString()}>
|
|
9
|
+
<ColorPicker allowClear format="hex" defaultFormat="hex"/>
|
|
10
|
+
</Form.Item>
|
|
11
|
+
<Form.Item name={"x"} label="X">
|
|
12
|
+
<InputNumber />
|
|
13
|
+
</Form.Item>
|
|
14
|
+
<Form.Item name={"y"} label="Y">
|
|
15
|
+
<InputNumber />
|
|
16
|
+
</Form.Item>
|
|
17
|
+
<Form.Item name={"fontSize"} label="Size">
|
|
18
|
+
<InputNumber suffix="px"/>
|
|
19
|
+
</Form.Item>
|
|
20
|
+
</div>);
|
|
21
|
+
};
|
|
22
|
+
export default TextTool;
|
|
@@ -2,5 +2,5 @@ interface UploadToolProps {
|
|
|
2
2
|
name: string;
|
|
3
3
|
type?: "component" | "background";
|
|
4
4
|
}
|
|
5
|
-
declare const UploadTool: ({ name, type }: UploadToolProps) => import("react
|
|
5
|
+
declare const UploadTool: ({ name, type }: UploadToolProps) => import("react").JSX.Element;
|
|
6
6
|
export default UploadTool;
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { Upload, message, } from "antd";
|
|
3
|
+
import { InboxOutlined } from "@ant-design/icons";
|
|
4
|
+
import { useAppDispatch } from "../../hooks/use-redux";
|
|
5
|
+
import { useState } from "react";
|
|
6
|
+
import SectionLabel from "../../components/form-tools/label";
|
|
7
|
+
import SectionShape from "../../components/form-tools/shape";
|
|
8
|
+
const { Dragger } = Upload;
|
|
9
|
+
const UploadTool = ({ name, type }) => {
|
|
10
|
+
var _a, _b;
|
|
11
|
+
const [imageUrl, setImageUrl] = useState(null);
|
|
12
|
+
const dispatch = useAppDispatch();
|
|
13
|
+
const widthWorkspace = ((_a = document === null || document === void 0 ? void 0 : document.getElementById("workspace")) === null || _a === void 0 ? void 0 : _a.clientWidth) || 0;
|
|
14
|
+
const heightWorkspace = ((_b = document === null || document === void 0 ? void 0 : document.getElementById("workspace")) === null || _b === void 0 ? void 0 : _b.clientHeight) || 0;
|
|
15
|
+
const props = {
|
|
16
|
+
name: "file",
|
|
17
|
+
multiple: false,
|
|
18
|
+
maxCount: 1,
|
|
19
|
+
showUploadList: false,
|
|
20
|
+
onChange(info) {
|
|
21
|
+
const { status } = info.file;
|
|
22
|
+
if (status !== "uploading" && info.file.originFileObj) {
|
|
23
|
+
const file = info.file.originFileObj;
|
|
24
|
+
if (file) {
|
|
25
|
+
const img = new window.Image();
|
|
26
|
+
img.onload = () => {
|
|
27
|
+
const scaleX = widthWorkspace / img.width;
|
|
28
|
+
const scaleY = heightWorkspace / img.height;
|
|
29
|
+
// Ambil skala terkecil supaya semua image masuk workspace
|
|
30
|
+
const scale = Math.min(1, scaleX, scaleY); // maksimum 1 (jangan perbesar)
|
|
31
|
+
// Terapkan skala ke dimensi gambar
|
|
32
|
+
const width = img.width * scale;
|
|
33
|
+
const height = img.height * scale;
|
|
34
|
+
dispatch({
|
|
35
|
+
type: type === "component" ? "board/addComponent" : "board/setExtraComponent",
|
|
36
|
+
payload: {
|
|
37
|
+
id: new Date().getTime(),
|
|
38
|
+
x: 0,
|
|
39
|
+
y: 0,
|
|
40
|
+
width,
|
|
41
|
+
height,
|
|
42
|
+
rotation: 0,
|
|
43
|
+
shape: name,
|
|
44
|
+
src: img.src,
|
|
45
|
+
},
|
|
46
|
+
});
|
|
47
|
+
};
|
|
48
|
+
img.src = URL.createObjectURL(file);
|
|
49
|
+
setImageUrl(img.src);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
if (status === "done") {
|
|
53
|
+
message.success(`${info.file.name} file uploaded successfully.`);
|
|
54
|
+
}
|
|
55
|
+
else if (status === "error") {
|
|
56
|
+
message.error(`${info.file.name} file upload failed.`);
|
|
57
|
+
}
|
|
58
|
+
},
|
|
59
|
+
onDrop(e) {
|
|
60
|
+
console.log("Dropped files", e.dataTransfer.files);
|
|
61
|
+
},
|
|
62
|
+
};
|
|
63
|
+
return (<>
|
|
64
|
+
<Dragger {...props}>
|
|
65
|
+
<p className="ant-upload-drag-icon">
|
|
66
|
+
<InboxOutlined />
|
|
67
|
+
</p>
|
|
68
|
+
<p className="ant-upload-text">
|
|
69
|
+
Click or drag file to this area to upload
|
|
70
|
+
</p>
|
|
71
|
+
<p className="ant-upload-hint">
|
|
72
|
+
Support for a single or bulk upload. Strictly prohibited from
|
|
73
|
+
uploading company data or other banned files.
|
|
74
|
+
</p>
|
|
75
|
+
</Dragger>
|
|
76
|
+
<SectionShape />
|
|
77
|
+
<SectionLabel />
|
|
78
|
+
</>);
|
|
79
|
+
};
|
|
80
|
+
export default UploadTool;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
declare const SideTool: () => import("react
|
|
1
|
+
declare const SideTool: () => import("react").JSX.Element;
|
|
2
2
|
export default SideTool;
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { Circle, CopyPlus, Eye, EyeOff, Image, Layers2, MousePointer, PaintBucket, Ratio, SquareMousePointer, Trash, Type, Upload, } from "lucide-react";
|
|
3
|
+
import ButtonTools from "../../components/button-tools";
|
|
4
|
+
import { Divider, ColorPicker, Button, } from "antd";
|
|
5
|
+
import { useAppDispatch, useAppSelector } from "../../hooks/use-redux";
|
|
6
|
+
import { useState } from "react";
|
|
7
|
+
const SideTool = () => {
|
|
8
|
+
const [color, setColor] = useState("#000000");
|
|
9
|
+
const dispatch = useAppDispatch();
|
|
10
|
+
const { active } = useAppSelector((state) => state.tool);
|
|
11
|
+
const { selectedComponent } = useAppSelector((state) => state.panel);
|
|
12
|
+
const { components } = useAppSelector((state) => state.board);
|
|
13
|
+
const [preview, setPreview] = useState(false);
|
|
14
|
+
const tools = [
|
|
15
|
+
{
|
|
16
|
+
id: "select",
|
|
17
|
+
name: "Select Tool",
|
|
18
|
+
icon: <MousePointer />,
|
|
19
|
+
},
|
|
20
|
+
];
|
|
21
|
+
const actionsTools = [
|
|
22
|
+
// {
|
|
23
|
+
// id: "table-split",
|
|
24
|
+
// name: "Table Split",
|
|
25
|
+
// icon: <TableCellsSplit />,
|
|
26
|
+
// },
|
|
27
|
+
{
|
|
28
|
+
id: "square",
|
|
29
|
+
name: "Square",
|
|
30
|
+
icon: <SquareMousePointer />,
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
id: "circle",
|
|
34
|
+
name: "Circle",
|
|
35
|
+
icon: <Circle />,
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
id: "table-seat-circle",
|
|
39
|
+
name: "Table Seat Circle",
|
|
40
|
+
icon: <Ratio />,
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
id: "image-table",
|
|
44
|
+
name: "Image Table",
|
|
45
|
+
icon: <Upload />,
|
|
46
|
+
},
|
|
47
|
+
// {
|
|
48
|
+
// id: "table-seat-square",
|
|
49
|
+
// name: "Table Seat Square",
|
|
50
|
+
// icon: <Dock />,
|
|
51
|
+
// },
|
|
52
|
+
// {
|
|
53
|
+
// id: "diamond",
|
|
54
|
+
// name: "Diamond",
|
|
55
|
+
// icon: <Diamond />,
|
|
56
|
+
// },
|
|
57
|
+
];
|
|
58
|
+
const controlTools = [
|
|
59
|
+
{
|
|
60
|
+
id: "background",
|
|
61
|
+
name: "Background",
|
|
62
|
+
icon: <Image />,
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
id: "text",
|
|
66
|
+
name: "Text",
|
|
67
|
+
icon: <Type />,
|
|
68
|
+
},
|
|
69
|
+
// {
|
|
70
|
+
// id: "background-color",
|
|
71
|
+
// name: "Background Color",
|
|
72
|
+
// icon: <PaintBucket/>
|
|
73
|
+
// }
|
|
74
|
+
];
|
|
75
|
+
const hanldeSelectTool = (id) => {
|
|
76
|
+
if (id === "background" || id === "text" || id === "image-table") {
|
|
77
|
+
dispatch({
|
|
78
|
+
type: "panel/setShow",
|
|
79
|
+
payload: true
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
dispatch({
|
|
83
|
+
type: "tool/setActiveTool",
|
|
84
|
+
payload: id,
|
|
85
|
+
});
|
|
86
|
+
};
|
|
87
|
+
const handleChangeColorBackground = (color) => {
|
|
88
|
+
setColor(color.toHexString());
|
|
89
|
+
dispatch({
|
|
90
|
+
type: "board/setBackgroundColor",
|
|
91
|
+
payload: color.toHexString(),
|
|
92
|
+
});
|
|
93
|
+
};
|
|
94
|
+
const handleOpenModalPreview = () => {
|
|
95
|
+
dispatch({
|
|
96
|
+
type: "tool/setTooglePreview",
|
|
97
|
+
payload: true,
|
|
98
|
+
});
|
|
99
|
+
};
|
|
100
|
+
const handleRemoveComponent = () => {
|
|
101
|
+
dispatch({
|
|
102
|
+
type: "board/removeComponent",
|
|
103
|
+
payload: selectedComponent,
|
|
104
|
+
});
|
|
105
|
+
};
|
|
106
|
+
const handleDuplicateComponent = () => {
|
|
107
|
+
const newComponent = Object.assign(Object.assign({}, selectedComponent), { x: selectedComponent.x + 20, y: selectedComponent.y + 20, id: Date.now() });
|
|
108
|
+
dispatch({
|
|
109
|
+
type: "board/addComponent",
|
|
110
|
+
payload: newComponent
|
|
111
|
+
});
|
|
112
|
+
dispatch({
|
|
113
|
+
type: "panel/setSelectedComponent",
|
|
114
|
+
payload: newComponent
|
|
115
|
+
});
|
|
116
|
+
};
|
|
117
|
+
function swapOneStepById(arr, id, direction) {
|
|
118
|
+
const index = arr.findIndex(item => (item === null || item === void 0 ? void 0 : item.id) === id);
|
|
119
|
+
if (index === -1)
|
|
120
|
+
return arr; // id tidak ditemukan
|
|
121
|
+
const newArr = [...arr];
|
|
122
|
+
if (direction === 'left' && index > 0) {
|
|
123
|
+
[newArr[index - 1], newArr[index]] = [newArr[index], newArr[index - 1]];
|
|
124
|
+
}
|
|
125
|
+
if (direction === 'right' && index < arr.length - 1) {
|
|
126
|
+
[newArr[index + 1], newArr[index]] = [newArr[index], newArr[index + 1]];
|
|
127
|
+
}
|
|
128
|
+
return newArr;
|
|
129
|
+
}
|
|
130
|
+
const handleOverride = () => {
|
|
131
|
+
const newArr = swapOneStepById(components, selectedComponent === null || selectedComponent === void 0 ? void 0 : selectedComponent.id, 'right');
|
|
132
|
+
dispatch({
|
|
133
|
+
type: "board/setNewComponents",
|
|
134
|
+
payload: newArr
|
|
135
|
+
});
|
|
136
|
+
};
|
|
137
|
+
return (<div className="h-screen left-0 flex flex-col items-center border-r-2 border-gray-300 bg-white px-2 pt-4">
|
|
138
|
+
{tools === null || tools === void 0 ? void 0 : tools.map((tool) => (<ButtonTools key={tool.id} buttonProps={{
|
|
139
|
+
icon: tool.icon,
|
|
140
|
+
type: "text",
|
|
141
|
+
name: tool.name,
|
|
142
|
+
onClick: () => hanldeSelectTool(tool.id),
|
|
143
|
+
style: active === tool.id ? { color: "red" } : {},
|
|
144
|
+
}} popoverProps={{
|
|
145
|
+
content: <div>{tool.name}</div>,
|
|
146
|
+
trigger: "hover",
|
|
147
|
+
placement: "right",
|
|
148
|
+
}} items={[]}/>))}
|
|
149
|
+
<ButtonTools buttonProps={{
|
|
150
|
+
icon: <CopyPlus />,
|
|
151
|
+
type: "text",
|
|
152
|
+
name: "duplicate",
|
|
153
|
+
onClick: () => handleDuplicateComponent(),
|
|
154
|
+
}} items={[]} popoverProps={{
|
|
155
|
+
content: <div>Duplicate</div>,
|
|
156
|
+
trigger: "hover",
|
|
157
|
+
placement: "right",
|
|
158
|
+
}}/>
|
|
159
|
+
<ButtonTools buttonProps={{
|
|
160
|
+
onClick: () => handleRemoveComponent(),
|
|
161
|
+
icon: <Trash />,
|
|
162
|
+
type: "text",
|
|
163
|
+
name: "trash",
|
|
164
|
+
}} items={[]} popoverProps={{
|
|
165
|
+
content: <div>Trash</div>,
|
|
166
|
+
trigger: "hover",
|
|
167
|
+
placement: "right",
|
|
168
|
+
}}/>
|
|
169
|
+
<ButtonTools buttonProps={{
|
|
170
|
+
onClick: () => handleOverride(),
|
|
171
|
+
icon: <Layers2 />,
|
|
172
|
+
type: "text",
|
|
173
|
+
name: "override",
|
|
174
|
+
}} items={[]} popoverProps={{
|
|
175
|
+
content: <div>Override</div>,
|
|
176
|
+
trigger: "hover",
|
|
177
|
+
placement: "right",
|
|
178
|
+
}}/>
|
|
179
|
+
|
|
180
|
+
<Divider />
|
|
181
|
+
{actionsTools === null || actionsTools === void 0 ? void 0 : actionsTools.map((tool) => (<ButtonTools key={tool.id} buttonProps={{
|
|
182
|
+
icon: tool.icon,
|
|
183
|
+
type: "text",
|
|
184
|
+
name: tool.name,
|
|
185
|
+
onClick: () => hanldeSelectTool(tool.id),
|
|
186
|
+
style: active === tool.id ? { color: "red" } : {},
|
|
187
|
+
}} popoverProps={{
|
|
188
|
+
content: <div>{tool.name}</div>,
|
|
189
|
+
trigger: "hover",
|
|
190
|
+
placement: "right",
|
|
191
|
+
}} items={[]}/>))}
|
|
192
|
+
|
|
193
|
+
<Divider />
|
|
194
|
+
{controlTools === null || controlTools === void 0 ? void 0 : controlTools.map((tool) => (<ButtonTools key={tool.id} buttonProps={{
|
|
195
|
+
icon: tool.icon,
|
|
196
|
+
type: "text",
|
|
197
|
+
name: tool.name,
|
|
198
|
+
onClick: () => hanldeSelectTool(tool.id),
|
|
199
|
+
style: active === tool.id ? { color: "red" } : {},
|
|
200
|
+
}} popoverProps={{
|
|
201
|
+
content: <div>{tool.name}</div>,
|
|
202
|
+
trigger: "hover",
|
|
203
|
+
placement: "right",
|
|
204
|
+
}} items={[]}/>))}
|
|
205
|
+
<ColorPicker value={color} onChange={handleChangeColorBackground}>
|
|
206
|
+
<Button icon={<PaintBucket />} type="text" name="Background Color" onClick={() => hanldeSelectTool("background-color")} style={active === "background-color" ? { color: "red" } : {}}/>
|
|
207
|
+
</ColorPicker>
|
|
208
|
+
<Button icon={preview ? <EyeOff /> : <Eye />} type="text" name="Preview" onClick={handleOpenModalPreview} style={active === "preview" ? { color: "red" } : {}}/>
|
|
209
|
+
</div>);
|
|
210
|
+
};
|
|
211
|
+
export default SideTool;
|
|
@@ -11,5 +11,5 @@ export interface LayerViewProps {
|
|
|
11
11
|
}[];
|
|
12
12
|
statusKey: string;
|
|
13
13
|
}
|
|
14
|
-
declare const LayerView: (props: LayerViewProps) => import("react
|
|
14
|
+
declare const LayerView: (props: LayerViewProps) => import("react").JSX.Element;
|
|
15
15
|
export default LayerView;
|
|
@@ -103,18 +103,17 @@ const LayerView = (props) => {
|
|
|
103
103
|
console.log({ elementEditor });
|
|
104
104
|
const renderElements = (elementEditor, mappingKey, colorMatchKey) => {
|
|
105
105
|
return elementEditor.map((editorItem, i) => {
|
|
106
|
-
var _a, _b, _c;
|
|
106
|
+
var _a, _b, _c, _d;
|
|
107
107
|
const isUsingMapping = mappingKey &&
|
|
108
108
|
typeof editorItem[mappingKey] === "object" &&
|
|
109
109
|
editorItem[mappingKey] !== null;
|
|
110
110
|
const finalProps = isUsingMapping ? editorItem[mappingKey] : editorItem;
|
|
111
111
|
if (colorMatchKey) {
|
|
112
112
|
if (isUsingMapping) {
|
|
113
|
-
return Object.assign(Object.assign({}, finalProps), { fill: (_a = colorMatchKey.find((item) => item.key == (editorItem === null || editorItem === void 0 ? void 0 : editorItem[statusKey]))) === null || _a === void 0 ? void 0 : _a.color });
|
|
113
|
+
return Object.assign(Object.assign({}, finalProps), { fill: (_b = (_a = colorMatchKey.find((item) => item.key == (editorItem === null || editorItem === void 0 ? void 0 : editorItem[statusKey]))) === null || _a === void 0 ? void 0 : _a.color) !== null && _b !== void 0 ? _b : finalProps.fill });
|
|
114
114
|
}
|
|
115
115
|
else {
|
|
116
|
-
|
|
117
|
-
return Object.assign(Object.assign({}, finalProps), { fill: (_c = (_b = colorMatchKey.find((item) => item.key == (editorItem === null || editorItem === void 0 ? void 0 : editorItem[statusKey]))) === null || _b === void 0 ? void 0 : _b.color) !== null && _c !== void 0 ? _c : finalProps.fill });
|
|
116
|
+
return Object.assign(Object.assign({}, finalProps), { fill: (_d = (_c = colorMatchKey.find((item) => item.key == (editorItem === null || editorItem === void 0 ? void 0 : editorItem[statusKey]))) === null || _c === void 0 ? void 0 : _c.color) !== null && _d !== void 0 ? _d : finalProps.fill });
|
|
118
117
|
}
|
|
119
118
|
}
|
|
120
119
|
return finalProps;
|
|
@@ -134,7 +133,7 @@ const LayerView = (props) => {
|
|
|
134
133
|
background: backgroundColor,
|
|
135
134
|
display: "block",
|
|
136
135
|
}}>
|
|
137
|
-
<Layers components={[
|
|
136
|
+
<Layers mode="view" components={[
|
|
138
137
|
...extraComponentsEditor,
|
|
139
138
|
...renderElements(componentsEditor, mappingKey, colorMatchKey),
|
|
140
139
|
]} onClick={handleSelectComponent} selectedTable={selectedTable} selectedTableColor={selectedTableColor}/>
|
package/dist/index.d.ts
CHANGED
|
@@ -4,4 +4,4 @@ import SideTool from "./features/side-tool";
|
|
|
4
4
|
import ControlPanels from "./features/panel";
|
|
5
5
|
import LayerView, { type LayerViewProps } from "./features/view";
|
|
6
6
|
import TableEditor from "./features/package";
|
|
7
|
-
export { StoreProvider as ProviderSeatEditor, Board, SideTool, ControlPanels, LayerView, LayerViewProps, TableEditor };
|
|
7
|
+
export { StoreProvider as ProviderSeatEditor, Board, SideTool, ControlPanels, LayerView, LayerViewProps, TableEditor as SeatEditor };
|
package/dist/index.js
CHANGED
|
@@ -4,4 +4,4 @@ import SideTool from "./features/side-tool";
|
|
|
4
4
|
import ControlPanels from "./features/panel";
|
|
5
5
|
import LayerView from "./features/view";
|
|
6
6
|
import TableEditor from "./features/package";
|
|
7
|
-
export { StoreProvider as ProviderSeatEditor, Board, SideTool, ControlPanels, LayerView, TableEditor };
|
|
7
|
+
export { StoreProvider as ProviderSeatEditor, Board, SideTool, ControlPanels, LayerView, TableEditor as SeatEditor };
|