seat-editor 3.5.13 → 3.5.14

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.
Files changed (57) hide show
  1. package/dist/app/new-board/page.js +1 -0
  2. package/dist/app/new-board/page.jsx +1 -0
  3. package/dist/components/form-tools/shape.d.ts +1 -0
  4. package/dist/components/form-tools/shape.js +13 -3
  5. package/dist/components/form-tools/shape.jsx +17 -2
  6. package/dist/components/icons/camera.d.ts +1 -0
  7. package/dist/components/icons/camera.js +5 -0
  8. package/dist/components/icons/camera.jsx +26 -0
  9. package/dist/components/icons/circle.d.ts +1 -0
  10. package/dist/components/icons/circle.js +5 -0
  11. package/dist/components/icons/circle.jsx +36 -0
  12. package/dist/components/icons/index.d.ts +9 -0
  13. package/dist/components/icons/index.js +9 -0
  14. package/dist/components/icons/square.d.ts +1 -0
  15. package/dist/components/icons/square.js +5 -0
  16. package/dist/components/icons/square.jsx +26 -0
  17. package/dist/components/icons/type-1.d.ts +1 -0
  18. package/dist/components/icons/type-1.js +5 -0
  19. package/dist/components/icons/type-1.jsx +148 -0
  20. package/dist/components/icons/type-2.d.ts +1 -0
  21. package/dist/components/icons/type-2.js +5 -0
  22. package/dist/components/icons/type-2.jsx +138 -0
  23. package/dist/components/icons/type-3.d.ts +1 -0
  24. package/dist/components/icons/type-3.js +5 -0
  25. package/dist/components/icons/type-3.jsx +138 -0
  26. package/dist/components/icons/type-4.d.ts +1 -0
  27. package/dist/components/icons/type-4.js +5 -0
  28. package/dist/components/icons/type-4.jsx +98 -0
  29. package/dist/components/icons/type-5.d.ts +1 -0
  30. package/dist/components/icons/type-5.js +5 -0
  31. package/dist/components/icons/type-5.jsx +108 -0
  32. package/dist/features/board-v3/index.js +3 -1
  33. package/dist/features/board-v3/index.jsx +5 -2
  34. package/dist/features/package/index.js +1 -1
  35. package/dist/features/package/index.jsx +2 -2
  36. package/dist/features/panel/index.js +3 -1
  37. package/dist/features/panel/index.jsx +3 -1
  38. package/dist/features/panel/polygon.js +1 -1
  39. package/dist/features/panel/polygon.jsx +1 -1
  40. package/dist/features/panel/select-tool.js +1 -1
  41. package/dist/features/panel/select-tool.jsx +1 -1
  42. package/dist/features/panel/selected-group.d.ts +3 -1
  43. package/dist/features/panel/selected-group.js +9 -8
  44. package/dist/features/panel/selected-group.jsx +15 -8
  45. package/dist/features/panel/upload-group-tool.d.ts +10 -0
  46. package/dist/features/panel/upload-group-tool.js +147 -0
  47. package/dist/features/panel/upload-group-tool.jsx +180 -0
  48. package/dist/features/panel/upload-tool.d.ts +2 -2
  49. package/dist/features/panel/upload-tool.js +45 -4
  50. package/dist/features/panel/upload-tool.jsx +108 -10
  51. package/dist/features/side-tool/index.js +13 -11
  52. package/dist/features/side-tool/index.jsx +7 -2
  53. package/dist/provider/antd-provider.js +3 -0
  54. package/dist/provider/antd-provider.jsx +3 -0
  55. package/dist/utils/agent.d.ts +1 -0
  56. package/dist/utils/agent.js +8 -0
  57. package/package.json +1 -1
@@ -5,13 +5,14 @@ import { ColorPicker, Flex, Form, InputNumber, Select } from "antd";
5
5
  import { useAppSelector } from "../../hooks/use-redux";
6
6
  import { useFormPlaceholder } from ".";
7
7
  import { MIN_HEIGHT, MIN_WIDTH, MIN_X, MIN_Y } from "../board-v3/constant";
8
+ import UploadGroupTool from "./upload-group-tool";
8
9
  const { Option } = Select;
9
- const SelectedGroup = () => {
10
- var _a;
10
+ const SelectedGroup = ({ action, }) => {
11
11
  const { placeholders, setPlaceholder, unsetPlaceholder, setPlaceholderBulk, resetPlaceholders, } = useFormPlaceholder();
12
12
  const shape = Form.useWatch("shape");
13
13
  const selectedGroup = useAppSelector((state) => state.panel.selectedGroup);
14
14
  const allShapeSelected = selectedGroup.map((item) => item.shape);
15
+ const allImageSelected = allShapeSelected.every((shape) => ["image-table", "background"].includes(shape));
15
16
  const hasExtraComponent = allShapeSelected.some((shape) => ["text", "background", "polygon"].includes(shape));
16
17
  const allExtraComponent = allShapeSelected.every((shape) => ["text", "background", "polygon"].includes(shape));
17
18
  // const sameShape = [
@@ -27,7 +28,7 @@ const SelectedGroup = () => {
27
28
  // );
28
29
  const seatKey = useAppSelector((state) => state.panel.seatDefaultKey);
29
30
  const shapeAllIncludePolygon = allShapeSelected.includes("polygon");
30
- const optionsSelect = (_a = optionsShape === null || optionsShape === void 0 ? void 0 : optionsShape.slice(0, -1)) === null || _a === void 0 ? void 0 : _a.map((item) => {
31
+ const optionsSelect = optionsShape === null || optionsShape === void 0 ? void 0 : optionsShape.map((item) => {
31
32
  return Object.assign(Object.assign({}, item), { disabled: allShapeSelected.includes(item.value) });
32
33
  });
33
34
  const maxSeat = selectedGroup === null || selectedGroup === void 0 ? void 0 : selectedGroup.some((item) => (item === null || item === void 0 ? void 0 : item[seatKey]) > 4);
@@ -36,16 +37,16 @@ const SelectedGroup = () => {
36
37
  }
37
38
  return (_jsx(_Fragment, { children: _jsxs("div", { className: "py-2", children: [_jsx("h1", { className: "heading-s", children: " Group Selection" }), _jsxs("div", { className: "py-2", children: [!hasExtraComponent && (_jsx(Flex, { gap: 2, className: "w-full", children: _jsx(Form.Item, { label: "Name", name: "shape", className: "w-full", children: _jsx(Select, { className: "w-full", children: optionsSelect === null || optionsSelect === void 0 ? void 0 : optionsSelect.map((item) => {
38
39
  const disabled = item.value === "table-seat-rect-circle" && maxSeat;
39
- return (_jsx(Option, { value: item.value, disabled: disabled, children: item.value === "table-seat-rect-circle"
40
- ? `Type 5 (only for 4 ${seatKey})`
41
- : item.label }, item.value));
42
- }) }) }) })), _jsxs(Flex, { gap: 2, className: "w-full", vertical: true, children: [!shapeAllIncludePolygon && (_jsxs(_Fragment, { children: [_jsx(Form.Item, { label: "Width", name: "width", className: "w-full", layout: "horizontal", labelCol: { style: { width: 100, textAlign: "left" } }, wrapperCol: { style: { flex: 1 } }, children: _jsx(InputNumber, { suffix: "px", name: "width", min: MIN_WIDTH, placeholder: placeholders["width"], style: { width: "100%" } }) }), _jsx(Form.Item, { label: "Height", name: "height", className: "w-full", layout: "horizontal", labelCol: { style: { width: 100, textAlign: "left" } }, wrapperCol: { style: { flex: 1 } }, children: _jsx(InputNumber, { suffix: "px", name: "height", min: MIN_HEIGHT, placeholder: placeholders["height"], style: { width: "100%" } }) })] })), !(shape === null || shape === void 0 ? void 0 : shape.includes("circle")) && !shapeAllIncludePolygon && (_jsx(Form.Item, { label: "Radius", name: "radius", className: "w-full", layout: "horizontal", labelCol: { style: { width: 100, textAlign: "left" } }, wrapperCol: { style: { flex: 1 } }, children: _jsx(InputNumber, { name: "radius", suffix: "px", style: { width: "100%" }, placeholder: placeholders["radius"], parser: (value) => {
40
+ return (_jsx(Option, { value: item.value, disabled: disabled, className: "flex w-full justify-between items-center", children: _jsxs(Flex, { gap: 5, align: "center", justify: "between", children: [item.icon, _jsx("span", { children: item.value === "table-seat-rect-circle"
41
+ ? `Type 5 (only for 4 ${seatKey})`
42
+ : item.label })] }) }, item.value));
43
+ }) }) }) })), allImageSelected && (_jsx(UploadGroupTool, { type: "component", name: "image-table", action: action })), _jsxs(Flex, { gap: 2, className: "w-full", vertical: true, children: [!shapeAllIncludePolygon && (_jsxs(_Fragment, { children: [_jsx(Form.Item, { label: "Width", name: "width", className: "w-full", layout: "horizontal", labelCol: { style: { width: 100, textAlign: "left" } }, wrapperCol: { style: { flex: 1 } }, children: _jsx(InputNumber, { suffix: "px", name: "width", min: MIN_WIDTH, placeholder: placeholders["width"], style: { width: "100%" } }) }), _jsx(Form.Item, { label: "Height", name: "height", className: "w-full", layout: "horizontal", labelCol: { style: { width: 100, textAlign: "left" } }, wrapperCol: { style: { flex: 1 } }, children: _jsx(InputNumber, { suffix: "px", name: "height", min: MIN_HEIGHT, placeholder: placeholders["height"], style: { width: "100%" } }) })] })), !(shape === null || shape === void 0 ? void 0 : shape.includes("circle")) && !shapeAllIncludePolygon && (_jsx(Form.Item, { label: "Radius", name: "radius", className: "w-full", layout: "horizontal", labelCol: { style: { width: 100, textAlign: "left" } }, wrapperCol: { style: { flex: 1 } }, children: _jsx(InputNumber, { name: "radius", suffix: "px", style: { width: "100%" }, placeholder: placeholders["radius"], parser: (value) => {
43
44
  var _a;
44
45
  const onlyNumber = (_a = value === null || value === void 0 ? void 0 : value.replace(/\D/g, "")) !== null && _a !== void 0 ? _a : "";
45
46
  return onlyNumber === ""
46
47
  ? 1
47
48
  : Math.max(1, Number(onlyNumber));
48
- } }) }))] }), !shapeAllIncludePolygon && (_jsx(_Fragment, { children: _jsxs(Flex, { gap: 2, vertical: true, children: [_jsx(Form.Item, { label: "Position X", name: "x", className: "w-full", layout: "horizontal", labelCol: { style: { width: 100, textAlign: "left" } }, wrapperCol: { style: { flex: 1 } }, children: _jsx(InputNumber, { placeholder: placeholders["x"], style: { width: "100%" }, min: MIN_X, suffix: "px", name: "x" }) }), _jsx(Form.Item, { label: "Position Y", name: "y", className: "w-full", layout: "horizontal", labelCol: { style: { width: 100, textAlign: "left" } }, wrapperCol: { style: { flex: 1 } }, children: _jsx(InputNumber, { suffix: "px", name: "y", min: MIN_Y, placeholder: placeholders["y"], style: { width: "100%" } }) }), _jsx(Form.Item, { label: "Rotation", name: "rotation", className: "w-full", layout: "horizontal", labelCol: { style: { width: 100, textAlign: "left" } }, wrapperCol: { style: { flex: 1 } }, children: _jsx(InputNumber, { name: "rotation", suffix: "\u00B0", max: 360, min: 0, style: { width: "100%" }, placeholder: placeholders["rotation"] }) })] }) })), _jsxs(Flex, { gap: 2, children: [_jsx(Form.Item, { label: "Fill", name: "fill", getValueFromEvent: (color) => color.toHexString(), className: "w-full ", children: _jsx(ColorPicker, { allowClear: true, format: "hex", defaultFormat: "hex" }) }), _jsx(Form.Item, { label: "Stroke", name: "stroke", getValueFromEvent: (color) => color.toHexString(), className: "w-full ", children: _jsx(ColorPicker, { allowClear: true, format: "hex", defaultFormat: "hex" }) })] }), _jsxs(Flex, { vertical: true, children: [_jsx(Form.Item, { label: "Stroke Size", name: "strokeWidth", className: "w-full", layout: "horizontal", labelCol: { style: { width: 100, textAlign: "left" } }, wrapperCol: { style: { flex: 1 } }, children: _jsx(InputNumber, { name: "strokeWidth", suffix: "px", style: { width: "100%" }, placeholder: placeholders["strokeWidth"] }) }), _jsx(Form.Item, { label: "opacity", name: "opacity", className: "w-full", layout: "horizontal", labelCol: { style: { width: 100, textAlign: "left" } }, wrapperCol: { style: { flex: 1 } }, children: _jsx(InputNumber, { style: { width: "100%" }, step: 10, max: 100, min: 0, placeholder: placeholders["opacity"], parser: (value) => {
49
+ } }) }))] }), !shapeAllIncludePolygon && (_jsx(_Fragment, { children: _jsxs(Flex, { gap: 2, vertical: true, children: [_jsx(Form.Item, { label: "Position X", name: "x", className: "w-full", layout: "horizontal", labelCol: { style: { width: 100, textAlign: "left" } }, wrapperCol: { style: { flex: 1 } }, children: _jsx(InputNumber, { placeholder: placeholders["x"], style: { width: "100%" }, min: MIN_X, suffix: "px", name: "x" }) }), _jsx(Form.Item, { label: "Position Y", name: "y", className: "w-full", layout: "horizontal", labelCol: { style: { width: 100, textAlign: "left" } }, wrapperCol: { style: { flex: 1 } }, children: _jsx(InputNumber, { suffix: "px", name: "y", min: MIN_Y, placeholder: placeholders["y"], style: { width: "100%" } }) }), _jsx(Form.Item, { label: "Rotation", name: "rotation", className: "w-full", layout: "horizontal", labelCol: { style: { width: 100, textAlign: "left" } }, wrapperCol: { style: { flex: 1 } }, children: _jsx(InputNumber, { name: "rotation", suffix: "\u00B0", max: 360, min: 0, style: { width: "100%" }, placeholder: placeholders["rotation"] }) })] }) })), _jsxs(Flex, { gap: 2, children: [!allImageSelected && (_jsx(Form.Item, { label: "Fill", name: "fill", getValueFromEvent: (color) => color.toHexString(), className: "w-full ", children: _jsx(ColorPicker, { allowClear: true, format: "hex", defaultFormat: "hex" }) })), _jsx(Form.Item, { label: "Stroke", name: "stroke", getValueFromEvent: (color) => color.toHexString(), className: "w-full ", children: _jsx(ColorPicker, { allowClear: true, format: "hex", defaultFormat: "hex" }) })] }), _jsxs(Flex, { vertical: true, children: [_jsx(Form.Item, { label: "Stroke Size", name: "strokeWidth", className: "w-full", layout: "horizontal", labelCol: { style: { width: 100, textAlign: "left" } }, wrapperCol: { style: { flex: 1 } }, children: _jsx(InputNumber, { name: "strokeWidth", suffix: "px", style: { width: "100%" }, placeholder: placeholders["strokeWidth"] }) }), _jsx(Form.Item, { label: "opacity", name: "opacity", className: "w-full", layout: "horizontal", labelCol: { style: { width: 100, textAlign: "left" } }, wrapperCol: { style: { flex: 1 } }, children: _jsx(InputNumber, { style: { width: "100%" }, step: 10, max: 100, min: 0, placeholder: placeholders["opacity"], parser: (value) => {
49
50
  if (value === undefined || value === null || value === "")
50
51
  return null;
51
52
  const cleaned = value.replace(/[^0-9.]/g, "");
@@ -4,13 +4,14 @@ import { ColorPicker, Flex, Form, InputNumber, Select } from "antd";
4
4
  import { useAppSelector } from "../../hooks/use-redux";
5
5
  import { useFormPlaceholder } from ".";
6
6
  import { MIN_HEIGHT, MIN_WIDTH, MIN_X, MIN_Y } from "../board-v3/constant";
7
+ import UploadGroupTool from "./upload-group-tool";
7
8
  const { Option } = Select;
8
- const SelectedGroup = () => {
9
- var _a;
9
+ const SelectedGroup = ({ action, }) => {
10
10
  const { placeholders, setPlaceholder, unsetPlaceholder, setPlaceholderBulk, resetPlaceholders, } = useFormPlaceholder();
11
11
  const shape = Form.useWatch("shape");
12
12
  const selectedGroup = useAppSelector((state) => state.panel.selectedGroup);
13
13
  const allShapeSelected = selectedGroup.map((item) => item.shape);
14
+ const allImageSelected = allShapeSelected.every((shape) => ["image-table", "background"].includes(shape));
14
15
  const hasExtraComponent = allShapeSelected.some((shape) => ["text", "background", "polygon"].includes(shape));
15
16
  const allExtraComponent = allShapeSelected.every((shape) => ["text", "background", "polygon"].includes(shape));
16
17
  // const sameShape = [
@@ -26,7 +27,7 @@ const SelectedGroup = () => {
26
27
  // );
27
28
  const seatKey = useAppSelector((state) => state.panel.seatDefaultKey);
28
29
  const shapeAllIncludePolygon = allShapeSelected.includes("polygon");
29
- const optionsSelect = (_a = optionsShape === null || optionsShape === void 0 ? void 0 : optionsShape.slice(0, -1)) === null || _a === void 0 ? void 0 : _a.map((item) => {
30
+ const optionsSelect = optionsShape === null || optionsShape === void 0 ? void 0 : optionsShape.map((item) => {
30
31
  return Object.assign(Object.assign({}, item), { disabled: allShapeSelected.includes(item.value) });
31
32
  });
32
33
  const maxSeat = selectedGroup === null || selectedGroup === void 0 ? void 0 : selectedGroup.some((item) => (item === null || item === void 0 ? void 0 : item[seatKey]) > 4);
@@ -48,15 +49,21 @@ const SelectedGroup = () => {
48
49
  <Select className="w-full">
49
50
  {optionsSelect === null || optionsSelect === void 0 ? void 0 : optionsSelect.map((item) => {
50
51
  const disabled = item.value === "table-seat-rect-circle" && maxSeat;
51
- return (<Option key={item.value} value={item.value} disabled={disabled}>
52
- {item.value === "table-seat-rect-circle"
52
+ return (<Option key={item.value} value={item.value} disabled={disabled} className="flex w-full justify-between items-center">
53
+ <Flex gap={5} align="center" justify="between">
54
+ {item.icon}
55
+ <span>
56
+ {item.value === "table-seat-rect-circle"
53
57
  ? `Type 5 (only for 4 ${seatKey})`
54
58
  : item.label}
59
+ </span>
60
+ </Flex>
55
61
  </Option>);
56
62
  })}
57
63
  </Select>
58
64
  </Form.Item>
59
65
  </Flex>)}
66
+ {allImageSelected && (<UploadGroupTool type="component" name="image-table" action={action}/>)}
60
67
  {/* <Flex gap={2} className="w-full">
61
68
  {["table-seat-circle", "table-seat-rect-circle"].includes(
62
69
  shape
@@ -103,9 +110,9 @@ const SelectedGroup = () => {
103
110
  </Flex>
104
111
  </>)}
105
112
  <Flex gap={2}>
106
- <Form.Item label="Fill" name={"fill"} getValueFromEvent={(color) => color.toHexString()} className="w-full ">
107
- <ColorPicker allowClear format="hex" defaultFormat="hex"/>
108
- </Form.Item>
113
+ {!allImageSelected && (<Form.Item label="Fill" name={"fill"} getValueFromEvent={(color) => color.toHexString()} className="w-full ">
114
+ <ColorPicker allowClear format="hex" defaultFormat="hex"/>
115
+ </Form.Item>)}
109
116
  <Form.Item label="Stroke" name={"stroke"} getValueFromEvent={(color) => color.toHexString()} className="w-full ">
110
117
  <ColorPicker allowClear format="hex" defaultFormat="hex"/>
111
118
  </Form.Item>
@@ -0,0 +1,10 @@
1
+ import { PropertiesProps } from "../../dto/table";
2
+ interface UploadToolProps {
3
+ name: string;
4
+ type?: "component" | "background" | "assets";
5
+ action?: (file: File) => Promise<string>;
6
+ defaultValue?: PropertiesProps;
7
+ transform?: any;
8
+ }
9
+ declare const UploadTool: ({ name, type, action, transform, }: UploadToolProps) => import("react/jsx-runtime").JSX.Element;
10
+ export default UploadTool;
@@ -0,0 +1,147 @@
1
+ "use client";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
12
+ import { useState, useEffect } from "react";
13
+ import { Upload, Image, Button, Form, Flex } from "antd";
14
+ import { InboxOutlined, LoadingOutlined } from "@ant-design/icons";
15
+ import { useAppDispatch, useAppSelector } from "../../hooks/use-redux";
16
+ const { Dragger } = Upload;
17
+ const UploadTool = ({ name, type, action, transform, }) => {
18
+ // const src = Form.useWatch("src");
19
+ // const height = Form.useWatch("height");
20
+ // const width = Form.useWatch("width");
21
+ // const x = Form.useWatch("x");
22
+ // const y = Form.useWatch("y");
23
+ // const shape = Form.useWatch("shape");
24
+ var _a, _b, _c;
25
+ const selectedGroup = useAppSelector((state) => state.panel.selectedGroup);
26
+ const transformState = (_a = transform === null || transform === void 0 ? void 0 : transform.instance) === null || _a === void 0 ? void 0 : _a.transformState;
27
+ const [defaultSrc, setDefaultSrc] = useState(null);
28
+ const [isEdit, setIsEdit] = useState(true);
29
+ const [loading, setLoading] = useState(false);
30
+ useEffect(() => {
31
+ var _a, _b;
32
+ const allSameSrc = selectedGroup === null || selectedGroup === void 0 ? void 0 : selectedGroup.every((item) => item.src === selectedGroup[0].src);
33
+ if (allSameSrc && ((_a = selectedGroup === null || selectedGroup === void 0 ? void 0 : selectedGroup[0]) === null || _a === void 0 ? void 0 : _a.shape) === name) {
34
+ setDefaultSrc((_b = selectedGroup === null || selectedGroup === void 0 ? void 0 : selectedGroup[0]) === null || _b === void 0 ? void 0 : _b.src);
35
+ setIsEdit(true);
36
+ setLoading(false);
37
+ }
38
+ }, [selectedGroup]);
39
+ const dispatch = useAppDispatch();
40
+ const widthWorkspace = ((_b = document === null || document === void 0 ? void 0 : document.getElementById("workspace")) === null || _b === void 0 ? void 0 : _b.clientWidth) || 0;
41
+ const heightWorkspace = ((_c = document === null || document === void 0 ? void 0 : document.getElementById("workspace")) === null || _c === void 0 ? void 0 : _c.clientHeight) || 0;
42
+ const defaultFormatValue = (width, height, src, id, x, y) => ({
43
+ id: id ? String(id) : `${Date.now()}`,
44
+ x: x || Math.abs(transformState === null || transformState === void 0 ? void 0 : transformState.positionX),
45
+ y: y || Math.abs(transformState === null || transformState === void 0 ? void 0 : transformState.positionY),
46
+ width: width < 1 ? 200 : width,
47
+ height: height < 1 ? 200 : height,
48
+ rotation: 0,
49
+ shape: name,
50
+ src,
51
+ opacity: 1,
52
+ });
53
+ const propsUpload = {
54
+ name: "file",
55
+ multiple: true,
56
+ maxCount: 1,
57
+ showUploadList: false,
58
+ onChange: (info) => __awaiter(void 0, void 0, void 0, function* () {
59
+ setLoading(true);
60
+ if (info.file) {
61
+ const file = info.file;
62
+ const img = new window.Image();
63
+ let srcFromResponse = "";
64
+ try {
65
+ // ⬇️ IF ada custom action (upload ke server)
66
+ if (action) {
67
+ const src = yield action(file);
68
+ // updateComponentsBulk
69
+ if (isEdit) {
70
+ const payload = selectedGroup === null || selectedGroup === void 0 ? void 0 : selectedGroup.map((item) => (Object.assign({}, defaultFormatValue(item.width, item.height, src, String(item.id), item.x, item.y))));
71
+ dispatch({
72
+ type: "board/updateComponentsBulk",
73
+ payload,
74
+ });
75
+ dispatch({
76
+ type: "panel/setSelectedGroup",
77
+ payload,
78
+ });
79
+ setDefaultSrc(src);
80
+ dispatch({ type: "board/setFlagChange", payload: true });
81
+ dispatch({ type: "board/setUpdateBy", payload: "global" });
82
+ }
83
+ }
84
+ // ⬇️ IF local upload
85
+ else {
86
+ img.onload = () => {
87
+ const scaleX = widthWorkspace / img.width;
88
+ const scaleY = heightWorkspace / img.height;
89
+ const scale = Math.min(1, scaleX, scaleY);
90
+ const width = img.width * scale;
91
+ const height = img.height * scale;
92
+ if (isEdit) {
93
+ const payload = selectedGroup === null || selectedGroup === void 0 ? void 0 : selectedGroup.map((item) => (Object.assign({}, defaultFormatValue(item.width, item.height, img.src, String(item.id), item.x, item.y))));
94
+ dispatch({
95
+ type: "board/updateComponentsBulk",
96
+ payload,
97
+ });
98
+ dispatch({
99
+ type: "panel/setSelectedGroup",
100
+ payload,
101
+ });
102
+ setDefaultSrc(img.src);
103
+ dispatch({ type: "board/setFlagChange", payload: true });
104
+ dispatch({ type: "board/setUpdateBy", payload: "global" });
105
+ }
106
+ else {
107
+ dispatch({
108
+ type: type === "component"
109
+ ? "board/addComponent"
110
+ : "board/setExtraComponent",
111
+ payload: Object.assign({}, defaultFormatValue(width, height, img.src)),
112
+ });
113
+ }
114
+ setDefaultSrc(img.src);
115
+ dispatch({ type: "board/setFlagChange", payload: true });
116
+ dispatch({ type: "board/setUpdateBy", payload: "global" });
117
+ // message.success(`${info.file.name} uploaded successfully.`);
118
+ };
119
+ // Set img src AFTER onload
120
+ img.src = URL.createObjectURL(file);
121
+ }
122
+ }
123
+ catch (e) {
124
+ // message.error("Upload failed, please try again.");
125
+ }
126
+ }
127
+ }),
128
+ };
129
+ const handleDelete = () => {
130
+ setDefaultSrc(null);
131
+ };
132
+ // const deleteImages = () => {
133
+ // setLoading(true);
134
+ // dispatch({
135
+ // type: "board/removeExtraComponent",
136
+ // payload: selectedComponent,
137
+ // });
138
+ // dispatch({ type: "board/setFlagChange", payload: true });
139
+ // dispatch({ type: "board/setUpdateBy", payload: "global" });
140
+ // dispatch({ type: "panel/setSelectedComponent", payload: null });
141
+ // dispatch({ type: "panel/setSelectedGroup", payload: null });
142
+ // dispatch({ type: "panel/setShow", payload: false });
143
+ // dispatch({ type: "tool/setActiveTool", payload: "select" });
144
+ // };
145
+ return (_jsx(Form.Item, { label: "", name: "src", className: "w-full", children: defaultSrc ? (_jsxs(_Fragment, { children: [_jsx("div", { className: "w-full flex flex-col items-center gap-2 max-h-[200px] overflow-y-auto", children: _jsx(Image, { src: defaultSrc }) }), _jsx(Flex, { vertical: true, gap: 5, children: _jsx(Button, { type: "default", onClick: handleDelete, className: "w-full mt-4", loading: loading, children: "Edit" }) })] })) : (_jsx(Dragger, Object.assign({ beforeUpload: () => false }, propsUpload, { children: loading ? (_jsx("div", { className: "w-full flex flex-col items-center gap-2 max-h-[200px]", children: _jsx(LoadingOutlined, {}) })) : (_jsxs(_Fragment, { children: [_jsx("p", { className: "ant-upload-drag-icon", children: _jsx(InboxOutlined, {}) }), _jsx("p", { className: "ant-upload-text", children: "Click or drag file to this area to upload" }), _jsx("p", { className: "ant-upload-hint", children: "Support for a single or bulk upload. Strictly prohibited from uploading company data or other banned files." })] })) }))) }));
146
+ };
147
+ export default UploadTool;
@@ -0,0 +1,180 @@
1
+ "use client";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ import { useState, useEffect } from "react";
12
+ import { Upload, Image, Button, Form, Flex } from "antd";
13
+ import { InboxOutlined, LoadingOutlined } from "@ant-design/icons";
14
+ import { useAppDispatch, useAppSelector } from "../../hooks/use-redux";
15
+ const { Dragger } = Upload;
16
+ const UploadTool = ({ name, type, action, transform, }) => {
17
+ // const src = Form.useWatch("src");
18
+ // const height = Form.useWatch("height");
19
+ // const width = Form.useWatch("width");
20
+ // const x = Form.useWatch("x");
21
+ // const y = Form.useWatch("y");
22
+ // const shape = Form.useWatch("shape");
23
+ var _a, _b, _c;
24
+ const selectedGroup = useAppSelector((state) => state.panel.selectedGroup);
25
+ const transformState = (_a = transform === null || transform === void 0 ? void 0 : transform.instance) === null || _a === void 0 ? void 0 : _a.transformState;
26
+ const [defaultSrc, setDefaultSrc] = useState(null);
27
+ const [isEdit, setIsEdit] = useState(true);
28
+ const [loading, setLoading] = useState(false);
29
+ useEffect(() => {
30
+ var _a, _b;
31
+ const allSameSrc = selectedGroup === null || selectedGroup === void 0 ? void 0 : selectedGroup.every((item) => item.src === selectedGroup[0].src);
32
+ if (allSameSrc && ((_a = selectedGroup === null || selectedGroup === void 0 ? void 0 : selectedGroup[0]) === null || _a === void 0 ? void 0 : _a.shape) === name) {
33
+ setDefaultSrc((_b = selectedGroup === null || selectedGroup === void 0 ? void 0 : selectedGroup[0]) === null || _b === void 0 ? void 0 : _b.src);
34
+ setIsEdit(true);
35
+ setLoading(false);
36
+ }
37
+ }, [selectedGroup]);
38
+ const dispatch = useAppDispatch();
39
+ const widthWorkspace = ((_b = document === null || document === void 0 ? void 0 : document.getElementById("workspace")) === null || _b === void 0 ? void 0 : _b.clientWidth) || 0;
40
+ const heightWorkspace = ((_c = document === null || document === void 0 ? void 0 : document.getElementById("workspace")) === null || _c === void 0 ? void 0 : _c.clientHeight) || 0;
41
+ const defaultFormatValue = (width, height, src, id, x, y) => ({
42
+ id: id ? String(id) : `${Date.now()}`,
43
+ x: x || Math.abs(transformState === null || transformState === void 0 ? void 0 : transformState.positionX),
44
+ y: y || Math.abs(transformState === null || transformState === void 0 ? void 0 : transformState.positionY),
45
+ width: width < 1 ? 200 : width,
46
+ height: height < 1 ? 200 : height,
47
+ rotation: 0,
48
+ shape: name,
49
+ src,
50
+ opacity: 1,
51
+ });
52
+ const propsUpload = {
53
+ name: "file",
54
+ multiple: true,
55
+ maxCount: 1,
56
+ showUploadList: false,
57
+ onChange: (info) => __awaiter(void 0, void 0, void 0, function* () {
58
+ setLoading(true);
59
+ if (info.file) {
60
+ const file = info.file;
61
+ const img = new window.Image();
62
+ let srcFromResponse = "";
63
+ try {
64
+ // ⬇️ IF ada custom action (upload ke server)
65
+ if (action) {
66
+ const src = yield action(file);
67
+ // updateComponentsBulk
68
+ if (isEdit) {
69
+ const payload = selectedGroup === null || selectedGroup === void 0 ? void 0 : selectedGroup.map((item) => (Object.assign({}, defaultFormatValue(item.width, item.height, src, String(item.id), item.x, item.y))));
70
+ dispatch({
71
+ type: "board/updateComponentsBulk",
72
+ payload,
73
+ });
74
+ dispatch({
75
+ type: "panel/setSelectedGroup",
76
+ payload,
77
+ });
78
+ setDefaultSrc(src);
79
+ dispatch({ type: "board/setFlagChange", payload: true });
80
+ dispatch({ type: "board/setUpdateBy", payload: "global" });
81
+ }
82
+ }
83
+ // ⬇️ IF local upload
84
+ else {
85
+ img.onload = () => {
86
+ const scaleX = widthWorkspace / img.width;
87
+ const scaleY = heightWorkspace / img.height;
88
+ const scale = Math.min(1, scaleX, scaleY);
89
+ const width = img.width * scale;
90
+ const height = img.height * scale;
91
+ if (isEdit) {
92
+ const payload = selectedGroup === null || selectedGroup === void 0 ? void 0 : selectedGroup.map((item) => (Object.assign({}, defaultFormatValue(item.width, item.height, img.src, String(item.id), item.x, item.y))));
93
+ dispatch({
94
+ type: "board/updateComponentsBulk",
95
+ payload,
96
+ });
97
+ dispatch({
98
+ type: "panel/setSelectedGroup",
99
+ payload,
100
+ });
101
+ setDefaultSrc(img.src);
102
+ dispatch({ type: "board/setFlagChange", payload: true });
103
+ dispatch({ type: "board/setUpdateBy", payload: "global" });
104
+ }
105
+ else {
106
+ dispatch({
107
+ type: type === "component"
108
+ ? "board/addComponent"
109
+ : "board/setExtraComponent",
110
+ payload: Object.assign({}, defaultFormatValue(width, height, img.src)),
111
+ });
112
+ }
113
+ setDefaultSrc(img.src);
114
+ dispatch({ type: "board/setFlagChange", payload: true });
115
+ dispatch({ type: "board/setUpdateBy", payload: "global" });
116
+ // message.success(`${info.file.name} uploaded successfully.`);
117
+ };
118
+ // Set img src AFTER onload
119
+ img.src = URL.createObjectURL(file);
120
+ }
121
+ }
122
+ catch (e) {
123
+ // message.error("Upload failed, please try again.");
124
+ }
125
+ }
126
+ }),
127
+ };
128
+ const handleDelete = () => {
129
+ setDefaultSrc(null);
130
+ };
131
+ // const deleteImages = () => {
132
+ // setLoading(true);
133
+ // dispatch({
134
+ // type: "board/removeExtraComponent",
135
+ // payload: selectedComponent,
136
+ // });
137
+ // dispatch({ type: "board/setFlagChange", payload: true });
138
+ // dispatch({ type: "board/setUpdateBy", payload: "global" });
139
+ // dispatch({ type: "panel/setSelectedComponent", payload: null });
140
+ // dispatch({ type: "panel/setSelectedGroup", payload: null });
141
+ // dispatch({ type: "panel/setShow", payload: false });
142
+ // dispatch({ type: "tool/setActiveTool", payload: "select" });
143
+ // };
144
+ return (<Form.Item label="" name="src" className="w-full">
145
+ {defaultSrc ? (<>
146
+ <div className="w-full flex flex-col items-center gap-2 max-h-[200px] overflow-y-auto">
147
+ <Image src={defaultSrc}/>
148
+ </div>
149
+ <Flex vertical gap={5}>
150
+ <Button type="default" onClick={handleDelete} className="w-full mt-4" loading={loading}>
151
+ Edit
152
+ </Button>
153
+ {/* <Button
154
+ type="primary"
155
+ onClick={deleteImages}
156
+ className="w-full"
157
+ loading={loading}
158
+ >
159
+ Delete
160
+ </Button> */}
161
+ </Flex>
162
+ </>) : (<Dragger beforeUpload={() => false} {...propsUpload}>
163
+ {loading ? (<div className="w-full flex flex-col items-center gap-2 max-h-[200px]">
164
+ <LoadingOutlined />
165
+ </div>) : (<>
166
+ <p className="ant-upload-drag-icon">
167
+ <InboxOutlined />
168
+ </p>
169
+ <p className="ant-upload-text">
170
+ Click or drag file to this area to upload
171
+ </p>
172
+ <p className="ant-upload-hint">
173
+ Support for a single or bulk upload. Strictly prohibited from
174
+ uploading company data or other banned files.
175
+ </p>
176
+ </>)}
177
+ </Dragger>)}
178
+ </Form.Item>);
179
+ };
180
+ export default UploadTool;
@@ -6,5 +6,5 @@ interface UploadToolProps {
6
6
  defaultValue?: PropertiesProps;
7
7
  transform?: any;
8
8
  }
9
- declare const UploadTool: ({ name, type, action, defaultValue, transform, }: UploadToolProps) => import("react/jsx-runtime").JSX.Element;
10
- export default UploadTool;
9
+ declare const UploadToolForm: (props: UploadToolProps) => import("react/jsx-runtime").JSX.Element;
10
+ export default UploadToolForm;
@@ -10,10 +10,11 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
10
10
  };
11
11
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
12
12
  import { useState, useEffect } from "react";
13
- import { Upload, Image, Button, Form, Flex } from "antd";
13
+ import { Upload, Image as ImageAntd, Button, Form, Flex, Select, InputNumber, ColorPicker, } from "antd";
14
14
  import { InboxOutlined, LoadingOutlined } from "@ant-design/icons";
15
15
  import { useAppDispatch, useAppSelector } from "../../hooks/use-redux";
16
- import SectionShape from "../../components/form-tools/shape";
16
+ import { MIN_HEIGHT, MIN_WIDTH, MIN_X, MIN_Y } from "../board-v3/constant";
17
+ import { optionsShape } from "@/components/form-tools/shape";
17
18
  const { Dragger } = Upload;
18
19
  const UploadTool = ({ name, type, action, defaultValue, transform, }) => {
19
20
  // const src = Form.useWatch("src");
@@ -160,6 +161,46 @@ const UploadTool = ({ name, type, action, defaultValue, transform, }) => {
160
161
  dispatch({ type: "panel/setShow", payload: false });
161
162
  dispatch({ type: "tool/setActiveTool", payload: "select" });
162
163
  };
163
- return (_jsxs(Form.Item, { label: "", name: "src", className: "w-full", children: [defaultSrc ? (_jsxs(_Fragment, { children: [_jsx("div", { className: "w-full flex flex-col items-center gap-2 max-h-[200px] overflow-y-auto", children: _jsx(Image, { src: defaultSrc }) }), _jsxs(Flex, { vertical: true, gap: 5, children: [_jsx(Button, { type: "primary", onClick: handleDelete, className: "w-full mt-4", loading: loading, children: "Edit" }), _jsx(Button, { type: "default", onClick: deleteImages, className: "w-full", loading: loading, children: "Delete" })] })] })) : (_jsx(Dragger, Object.assign({ beforeUpload: () => false }, propsUpload, { children: loading ? (_jsx("div", { className: "w-full flex flex-col items-center gap-2 max-h-[200px]", children: _jsx(LoadingOutlined, {}) })) : (_jsxs(_Fragment, { children: [_jsx("p", { className: "ant-upload-drag-icon", children: _jsx(InboxOutlined, {}) }), _jsx("p", { className: "ant-upload-text", children: "Click or drag file to this area to upload" }), _jsx("p", { className: "ant-upload-hint", children: "Support for a single or bulk upload. Strictly prohibited from uploading company data or other banned files." })] })) }))), (selectedComponent === null || selectedComponent === void 0 ? void 0 : selectedComponent.id) && (_jsx(_Fragment, { children: _jsx(SectionShape, { allowChangeShape: type === "component" }) }))] }));
164
+ return (_jsx(Form.Item, { label: "", name: "src", className: "w-full", children: defaultSrc ? (_jsxs(_Fragment, { children: [_jsx("div", { className: "w-full flex flex-col items-center gap-2 max-h-[200px] overflow-y-auto", children: _jsx(ImageAntd, { src: defaultSrc }) }), _jsxs(Flex, { vertical: true, gap: 5, children: [_jsx(Button, { type: "default", onClick: handleDelete, className: "w-full mt-4", loading: loading, children: "Edit" }), _jsx(Button, { type: "primary", onClick: deleteImages, className: "w-full", loading: loading, children: "Delete" })] })] })) : (_jsx(Dragger, Object.assign({ beforeUpload: () => false }, propsUpload, { children: loading ? (_jsx("div", { className: "w-full flex flex-col items-center gap-2 max-h-[200px]", children: _jsx(LoadingOutlined, {}) })) : (_jsxs(_Fragment, { children: [_jsx("p", { className: "ant-upload-drag-icon", children: _jsx(InboxOutlined, {}) }), _jsx("p", { className: "ant-upload-text", children: "Click or drag file to this area to upload" }), _jsx("p", { className: "ant-upload-hint", children: "Support for a single or bulk upload. Strictly prohibited from uploading company data or other banned files." })] })) }))) }));
164
165
  };
165
- export default UploadTool;
166
+ const { Option } = Select;
167
+ const UploadToolForm = (props) => {
168
+ const shape = Form.useWatch("shape");
169
+ const seatKey = useAppSelector((state) => state.panel.seatDefaultKey);
170
+ const selectedComponent = useAppSelector((state) => state.panel.selectedComponent);
171
+ const maxSeat = (selectedComponent === null || selectedComponent === void 0 ? void 0 : selectedComponent[seatKey]) || 0;
172
+ return (_jsxs("div", { className: "py-2", children: [_jsx("h1", { className: "heading-s", children: "Shape" }), _jsx(Flex, { gap: 2, className: "w-full", children: _jsx(Form.Item, { label: "Name", name: "shape", className: "w-full", children: _jsx(Select, { className: "w-full", children: optionsShape === null || optionsShape === void 0 ? void 0 : optionsShape.map((item) => {
173
+ const disabled = item.value === "table-seat-rect-circle" && maxSeat > 4;
174
+ return (_jsx(Option, { value: item.value, disabled: disabled, className: "flex w-full items-center", children: _jsxs(Flex, { gap: 5, align: "center", justify: "between", children: [item.icon, _jsx("span", { children: item.value === "table-seat-rect-circle"
175
+ ? `Type 5 (only for 4 ${seatKey})`
176
+ : item.label })] }) }, item.value));
177
+ }) }) }) }), _jsx(UploadTool, Object.assign({}, props)), _jsxs(Flex, { gap: 2, className: "w-full", children: [_jsx(Form.Item, { label: "Width", name: "width", className: "w-full", children: _jsx(InputNumber, { suffix: "px", controls: true, name: "width", min: MIN_WIDTH, step: 1, parser: (value) => {
178
+ var _a;
179
+ const onlyNumber = (_a = value === null || value === void 0 ? void 0 : value.replace(/\D/g, "")) !== null && _a !== void 0 ? _a : "";
180
+ return onlyNumber === "" ? 1 : Math.max(1, Number(onlyNumber));
181
+ } }) }), _jsx(Form.Item, { label: "Height", name: "height", className: "w-full", children: _jsx(InputNumber, { suffix: "px", controls: true, step: 1, name: "height", min: MIN_HEIGHT, parser: (value) => {
182
+ var _a;
183
+ const onlyNumber = (_a = value === null || value === void 0 ? void 0 : value.replace(/\D/g, "")) !== null && _a !== void 0 ? _a : "";
184
+ return onlyNumber === "" ? 1 : Math.max(1, Number(onlyNumber));
185
+ } }) }), !(shape === null || shape === void 0 ? void 0 : shape.includes("circle")) && (_jsx(Form.Item, { label: "Radius", name: "radius", className: "w-full", children: _jsx(InputNumber, { suffix: "px", name: "radius", parser: (value) => {
186
+ var _a;
187
+ const onlyNumber = (_a = value === null || value === void 0 ? void 0 : value.replace(/\D/g, "")) !== null && _a !== void 0 ? _a : "";
188
+ return onlyNumber === "" ? 1 : Math.max(1, Number(onlyNumber));
189
+ } }) }))] }), _jsxs(Flex, { gap: 2, children: [_jsx(Form.Item, { label: "Position X", name: "x", className: "w-full", children: _jsx(InputNumber, { name: "x", step: 1, min: MIN_X }) }), _jsx(Form.Item, { label: "Position Y", name: "y", className: "w-full", children: _jsx(InputNumber, { name: "y", step: 1, min: MIN_Y }) }), _jsx(Form.Item, { label: "Rotation", name: "rotation", className: "w-full", children: _jsx(InputNumber, { suffix: "\u00B0", min: 0, step: 1, max: 360, name: "rotation", parser: (value) => {
190
+ if (!value)
191
+ return 0;
192
+ const num = Number(value.replace(/\D/g, ""));
193
+ if (Number.isNaN(num))
194
+ return 0;
195
+ return Math.min(360, Math.max(0, num));
196
+ } }) })] }), _jsxs(Flex, { gap: 2, children: [_jsx(Form.Item, { label: "Stroke Fill", name: "stroke", getValueFromEvent: (color) => color.toHexString(), className: "w-full ", children: _jsx(ColorPicker, { allowClear: true, format: "hex", defaultFormat: "hex" }) }), _jsx(Form.Item, { label: "Stroke Size", name: "strokeWidth", className: "w-full", children: _jsx(InputNumber, {}) })] }), _jsx(Flex, { children: _jsx(Form.Item, { label: "opacity", name: "opacity", className: "w-full", children: _jsx(InputNumber, { step: 10, max: 100, min: 0, name: "opacity", parser: (value) => {
197
+ if (value === undefined || value === null || value === "")
198
+ return null;
199
+ const cleaned = value.replace(/[^0-9.]/g, "");
200
+ const num = Number(cleaned);
201
+ if (Number.isNaN(num))
202
+ return null;
203
+ return Math.min(100, Math.max(0, num));
204
+ }, suffix: "%" }) }) })] }));
205
+ };
206
+ export default UploadToolForm;