seat-editor 3.4.7 → 3.5.0

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 (108) hide show
  1. package/dist/app/constant.d.ts +1 -1
  2. package/dist/app/graph-view/page.d.ts +1 -0
  3. package/dist/app/graph-view/page.js +343 -0
  4. package/dist/app/graph-view/page.jsx +445 -0
  5. package/dist/app/graph-view-new/constant.d.ts +581 -0
  6. package/dist/app/graph-view-new/constant.js +6973 -0
  7. package/dist/app/graph-view-new/page.d.ts +1 -0
  8. package/dist/app/graph-view-new/page.js +71 -0
  9. package/dist/app/graph-view-new/page.jsx +98 -0
  10. package/dist/app/new-board/page.js +43 -7
  11. package/dist/app/new-board/page.jsx +45 -12
  12. package/dist/components/button-tools/index.js +7 -5
  13. package/dist/components/button-tools/index.jsx +21 -9
  14. package/dist/components/form-tools/label.js +9 -20
  15. package/dist/components/form-tools/label.jsx +38 -28
  16. package/dist/components/form-tools/shape.js +5 -5
  17. package/dist/components/form-tools/shape.jsx +8 -8
  18. package/dist/components/layer-v3/index.js +44 -3
  19. package/dist/components/layer-v3/index.jsx +120 -3
  20. package/dist/components/layer-v4/index.js +3 -2
  21. package/dist/components/layer-v4/index.jsx +3 -2
  22. package/dist/components/layer-v5/constant.d.ts +60 -0
  23. package/dist/components/layer-v5/constant.js +93 -0
  24. package/dist/components/layer-v5/index.d.ts +24 -0
  25. package/dist/components/layer-v5/index.js +927 -0
  26. package/dist/components/layer-v5/index.jsx +1049 -0
  27. package/dist/features/board-v3/index.js +350 -72
  28. package/dist/features/board-v3/index.jsx +369 -75
  29. package/dist/features/board-v3/resize-element.js +5 -0
  30. package/dist/features/board-v3/utils.d.ts +8 -0
  31. package/dist/features/board-v3/utils.js +23 -7
  32. package/dist/features/package/index.d.ts +2 -0
  33. package/dist/features/package/index.js +1 -1
  34. package/dist/features/package/index.jsx +6 -1
  35. package/dist/features/panel/index.d.ts +8 -0
  36. package/dist/features/panel/index.js +160 -38
  37. package/dist/features/panel/index.jsx +173 -46
  38. package/dist/features/panel/polygon.d.ts +2 -0
  39. package/dist/features/panel/polygon.js +44 -0
  40. package/dist/features/panel/polygon.jsx +70 -0
  41. package/dist/features/panel/select-tool.js +3 -0
  42. package/dist/features/panel/select-tool.jsx +3 -0
  43. package/dist/features/panel/selected-group.js +24 -26
  44. package/dist/features/panel/selected-group.jsx +56 -51
  45. package/dist/features/panel/text-tool.js +17 -2
  46. package/dist/features/panel/text-tool.jsx +19 -2
  47. package/dist/features/panel/upload-tool.js +17 -3
  48. package/dist/features/panel/upload-tool.jsx +23 -4
  49. package/dist/features/side-tool/index.js +43 -6
  50. package/dist/features/side-tool/index.jsx +47 -10
  51. package/dist/features/view-only-4/connect-handle.d.ts +13 -0
  52. package/dist/features/view-only-4/connect-handle.js +23 -0
  53. package/dist/features/view-only-4/connect-handle.jsx +30 -0
  54. package/dist/features/view-only-4/connection-layer.d.ts +21 -0
  55. package/dist/features/view-only-4/connection-layer.js +219 -0
  56. package/dist/features/view-only-4/connection-layer.jsx +291 -0
  57. package/dist/features/view-only-4/index.d.ts +99 -0
  58. package/dist/features/view-only-4/index.js +684 -0
  59. package/dist/features/view-only-4/index.jsx +722 -0
  60. package/dist/features/view-only-4/integration-guide.d.ts +0 -0
  61. package/dist/features/view-only-4/integration-guide.js +0 -0
  62. package/dist/features/view-only-4/use-connection-graph.d.ts +41 -0
  63. package/dist/features/view-only-4/use-connection-graph.js +182 -0
  64. package/dist/features/view-only-4/utils.d.ts +74 -0
  65. package/dist/features/view-only-4/utils.js +106 -0
  66. package/dist/features/view-only-5/connect-handle.d.ts +30 -0
  67. package/dist/features/view-only-5/connect-handle.js +88 -0
  68. package/dist/features/view-only-5/connect-handle.jsx +96 -0
  69. package/dist/features/view-only-5/connection-layer.d.ts +34 -0
  70. package/dist/features/view-only-5/connection-layer.js +182 -0
  71. package/dist/features/view-only-5/connection-layer.jsx +265 -0
  72. package/dist/features/view-only-5/index.d.ts +102 -0
  73. package/dist/features/view-only-5/index.js +585 -0
  74. package/dist/features/view-only-5/index.jsx +614 -0
  75. package/dist/features/view-only-5/use-connection-graph.d.ts +57 -0
  76. package/dist/features/view-only-5/use-connection-graph.js +196 -0
  77. package/dist/features/view-only-5/utils.d.ts +52 -0
  78. package/dist/features/view-only-5/utils.js +80 -0
  79. package/dist/features/view-only-6/connect-handle.d.ts +13 -0
  80. package/dist/features/view-only-6/connect-handle.js +20 -0
  81. package/dist/features/view-only-6/connect-handle.jsx +21 -0
  82. package/dist/features/view-only-6/connection-layer.d.ts +22 -0
  83. package/dist/features/view-only-6/connection-layer.js +191 -0
  84. package/dist/features/view-only-6/connection-layer.jsx +244 -0
  85. package/dist/features/view-only-6/index.d.ts +99 -0
  86. package/dist/features/view-only-6/index.js +687 -0
  87. package/dist/features/view-only-6/index.jsx +724 -0
  88. package/dist/features/view-only-6/use-connection-graph.d.ts +26 -0
  89. package/dist/features/view-only-6/use-connection-graph.js +103 -0
  90. package/dist/features/view-only-6/utils.d.ts +66 -0
  91. package/dist/features/view-only-6/utils.js +96 -0
  92. package/dist/features/view-only-7/connect-handle.d.ts +13 -0
  93. package/dist/features/view-only-7/connect-handle.js +23 -0
  94. package/dist/features/view-only-7/connect-handle.jsx +30 -0
  95. package/dist/features/view-only-7/connection-layer.d.ts +22 -0
  96. package/dist/features/view-only-7/connection-layer.js +165 -0
  97. package/dist/features/view-only-7/connection-layer.jsx +217 -0
  98. package/dist/features/view-only-7/index.d.ts +99 -0
  99. package/dist/features/view-only-7/index.js +687 -0
  100. package/dist/features/view-only-7/index.jsx +724 -0
  101. package/dist/features/view-only-7/use-connection-graph.d.ts +26 -0
  102. package/dist/features/view-only-7/use-connection-graph.js +104 -0
  103. package/dist/features/view-only-7/utils.d.ts +69 -0
  104. package/dist/features/view-only-7/utils.js +144 -0
  105. package/dist/index.d.ts +2 -1
  106. package/dist/index.js +2 -1
  107. package/dist/seat-editor.css +1 -1
  108. package/package.json +1 -1
@@ -10,7 +10,7 @@ var __rest = (this && this.__rest) || function (s, e) {
10
10
  }
11
11
  return t;
12
12
  };
13
- import { useEffect, useRef, useState } from "react";
13
+ import { useEffect, createContext, useRef, useState, useContext } from "react";
14
14
  import { useAppDispatch, useAppSelector } from "../../hooks/use-redux";
15
15
  import { Form, Input } from "antd";
16
16
  import SelectToolForm from "./select-tool";
@@ -25,6 +25,7 @@ import { SEAT_SHAPES } from "../../utils/constant";
25
25
  import { adjustHeightWidthForSeatShape, getSeatCount, getSeatPosition, isSeatShape, } from "./utils";
26
26
  import SeatSquare from "./table-seat-square";
27
27
  import _ from "lodash";
28
+ const FormPlaceholderContext = createContext(null);
28
29
  const ControlPanels = (props) => {
29
30
  const { action, transform } = props;
30
31
  const dispatch = useAppDispatch();
@@ -36,29 +37,67 @@ const ControlPanels = (props) => {
36
37
  const components = useAppSelector((state) => state.board.components);
37
38
  const extraComponents = useAppSelector((state) => state.board.extraComponents);
38
39
  const svgRef = useRef(null);
40
+ const [bufferValueForm, setBufferValueForm] = useState(null);
39
41
  useEffect(() => {
40
42
  svgRef.current = document.querySelectorAll("#workspace");
41
43
  }, []);
42
44
  const { show } = useAppSelector((state) => state.panel);
43
45
  const [open, setOpen] = useState(false);
44
46
  const [form] = Form.useForm();
47
+ const [placeholders, setPlaceholders] = useState({});
48
+ const [groupBufferSelected, setGroupBufferSelected] = useState([]);
45
49
  let values = Form.useWatch([], form);
50
+ const setPlaceholder = (name, placeholder) => {
51
+ setPlaceholders((prev) => (Object.assign(Object.assign({}, prev), { [name]: placeholder })));
52
+ };
53
+ const unsetPlaceholder = (name) => {
54
+ setPlaceholders((prev) => {
55
+ const next = Object.assign({}, prev);
56
+ delete next[name];
57
+ return next;
58
+ });
59
+ };
60
+ const setPlaceholderBulk = (bulk) => {
61
+ setPlaceholders((prev) => (Object.assign(Object.assign({}, prev), bulk)));
62
+ };
63
+ const resetPlaceholders = () => setPlaceholders({});
64
+ useEffect(() => {
65
+ if (tool.active === "background" || tool.active === "image-table") {
66
+ setOpen(true);
67
+ }
68
+ else {
69
+ setOpen(false);
70
+ }
71
+ }, [tool, show]);
46
72
  useEffect(() => {
47
73
  if (selectedComponent) {
48
- form.resetFields();
74
+ const id = values === null || values === void 0 ? void 0 : values.id;
75
+ if (id !== selectedComponent.id) {
76
+ form.resetFields();
77
+ }
49
78
  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);
50
79
  const isSameIdAndSameDimensions = (selectedComponent === null || selectedComponent === void 0 ? void 0 : selectedComponent.id) === (values === null || values === void 0 ? void 0 : values.id) &&
51
80
  (selectedComponent === null || selectedComponent === void 0 ? void 0 : selectedComponent.height) === (values === null || values === void 0 ? void 0 : values.height) &&
52
81
  (selectedComponent === null || selectedComponent === void 0 ? void 0 : selectedComponent.width) === (values === null || values === void 0 ? void 0 : values.width) &&
53
82
  (selectedComponent === null || selectedComponent === void 0 ? void 0 : selectedComponent.x) === (values === null || values === void 0 ? void 0 : values.x) &&
54
83
  (selectedComponent === null || selectedComponent === void 0 ? void 0 : selectedComponent.y) === (values === null || values === void 0 ? void 0 : values.y);
55
- if (show && (isDifferentId || isSameIdAndSameDimensions)) {
84
+ const isPolygon = (selectedComponent === null || selectedComponent === void 0 ? void 0 : selectedComponent.shape) === "polygon";
85
+ if (show && (isDifferentId || isSameIdAndSameDimensions || isPolygon)) {
56
86
  setOpen(true);
57
87
  }
58
88
  form.setFieldsValue(Object.assign(Object.assign({}, selectedComponent), { opacity: (selectedComponent === null || selectedComponent === void 0 ? void 0 : selectedComponent.opacity) * 100, openSpace: (selectedComponent === null || selectedComponent === void 0 ? void 0 : selectedComponent.openSpace) * 100 }));
59
89
  }
60
90
  else if (selectedGroup) {
61
- form.resetFields();
91
+ // form.resetFields();
92
+ if (selectedGroup.length === 0) {
93
+ form.resetFields();
94
+ return;
95
+ }
96
+ const notSameGroup = (selectedGroup === null || selectedGroup === void 0 ? void 0 : selectedGroup.length) !== (groupBufferSelected === null || groupBufferSelected === void 0 ? void 0 : groupBufferSelected.length);
97
+ if (notSameGroup) {
98
+ form.resetFields();
99
+ setBufferValueForm(null);
100
+ }
62
101
  if (show)
63
102
  setOpen(true);
64
103
  if (!show)
@@ -67,53 +106,100 @@ const ControlPanels = (props) => {
67
106
  if (!arr || arr.length === 0)
68
107
  return false;
69
108
  const firstValue = arr[0][key];
70
- return arr.every((item) => item[key] === firstValue);
109
+ return arr.every((item) => (item === null || item === void 0 ? void 0 : item[key]) === firstValue);
71
110
  }
72
111
  function getValueIfSame(arr, key) {
112
+ var _a;
73
113
  if (key === "opacity") {
74
114
  return isSameAllByKey(arr, key)
75
115
  ? Number(arr[0][key]) * 100
76
116
  : undefined;
77
117
  }
78
118
  if (key === "labels") {
79
- const test = arr === null || arr === void 0 ? void 0 : arr.every((item) => _.isEqual(item[key], arr[0][key]));
80
- return (arr === null || arr === void 0 ? void 0 : arr.every((item) => _.isEqual(item[key], arr[0][key])))
81
- ? arr[0][key]
119
+ const test = arr === null || arr === void 0 ? void 0 : arr.every((item) => { var _a; return _.isEqual(item === null || item === void 0 ? void 0 : item[key], (_a = arr === null || arr === void 0 ? void 0 : arr[0]) === null || _a === void 0 ? void 0 : _a[key]); });
120
+ return (arr === null || arr === void 0 ? void 0 : arr.every((item) => { var _a; return _.isEqual(item === null || item === void 0 ? void 0 : item[key], (_a = arr === null || arr === void 0 ? void 0 : arr[0]) === null || _a === void 0 ? void 0 : _a[key]); }))
121
+ ? (_a = arr === null || arr === void 0 ? void 0 : arr[0]) === null || _a === void 0 ? void 0 : _a[key]
82
122
  : [];
83
123
  }
84
124
  return isSameAllByKey(arr, key) ? arr[0][key] : undefined;
85
125
  }
86
- form.setFieldsValue({
87
- width: getValueIfSame(selectedGroup, "width"),
88
- height: getValueIfSame(selectedGroup, "height"),
89
- x: getValueIfSame(selectedGroup, "x"),
90
- y: getValueIfSame(selectedGroup, "y"),
91
- fill: getValueIfSame(selectedGroup, "fill"),
92
- stroke: getValueIfSame(selectedGroup, "stroke"),
93
- opacity: getValueIfSame(selectedGroup, "opacity"),
94
- rotation: getValueIfSame(selectedGroup, "rotation"),
95
- strokeWidth: getValueIfSame(selectedGroup, "strokeWidth"),
96
- radius: getValueIfSame(selectedGroup, "radius"),
97
- shape: getValueIfSame(selectedGroup, "shape"),
98
- labels: getValueIfSame(selectedGroup, "labels"),
99
- seatCount: getValueIfSame(selectedGroup, "seatCount"),
100
- seatPositions: getValueIfSame(selectedGroup, "seatPositions"),
101
- seatFill: getValueIfSame(selectedGroup, "seatFill"),
102
- openSpace: getValueIfSame(selectedGroup, "openSpace"),
103
- });
104
- }
105
- else {
106
- setOpen(false);
107
- }
108
- }, [selectedComponent, selectedGroup, show]);
109
- useEffect(() => {
110
- if (tool.active === "background" || tool.active === "image-table") {
111
- setOpen(true);
126
+ function getAllValuesKey(arr, key) {
127
+ return arr
128
+ .map((item) => item === null || item === void 0 ? void 0 : item[key])
129
+ .filter((value) => value !== undefined)
130
+ .sort((a, b) => {
131
+ if (typeof a === "number" && typeof b === "number")
132
+ return a - b;
133
+ return String(a).localeCompare(String(b));
134
+ })
135
+ .filter((value, index, self) => self.indexOf(value) === index);
136
+ }
137
+ function showAllValueNotSame(arr, key) {
138
+ if (key === "opacity") {
139
+ return !isSameAllByKey(arr, key)
140
+ ? `${getAllValuesKey(arr, key)
141
+ .map((value) => Number(value) * 100)
142
+ .join(", ")}`
143
+ : `${Number(arr[0][key]) * 100}`;
144
+ }
145
+ return !isSameAllByKey(arr, key)
146
+ ? `${getAllValuesKey(arr, key)}`
147
+ : `${arr[0][key]}`;
148
+ }
149
+ const fields = [
150
+ "width",
151
+ "height",
152
+ "x",
153
+ "y",
154
+ "opacity",
155
+ "rotation",
156
+ "radius",
157
+ "fill",
158
+ "stroke",
159
+ "strokeWidth",
160
+ "shape",
161
+ "labels",
162
+ "seatCount",
163
+ "seatPositions",
164
+ "seatFill",
165
+ "openSpace",
166
+ ];
167
+ // placeholder (khusus field tertentu saja)
168
+ const placeholderFields = [
169
+ "width",
170
+ "height",
171
+ "x",
172
+ "y",
173
+ "opacity",
174
+ "rotation",
175
+ "radius",
176
+ "strokeWidth",
177
+ ];
178
+ // build placeholder
179
+ const placeholder = Object.fromEntries(placeholderFields.map((key) => [
180
+ key,
181
+ showAllValueNotSame(selectedGroup, key),
182
+ ]));
183
+ // build values
184
+ const values = Object.fromEntries(fields.map((key) => [
185
+ key,
186
+ (bufferValueForm === null || bufferValueForm === void 0 ? void 0 : bufferValueForm.key) === key
187
+ ? bufferValueForm.value
188
+ : getValueIfSame(selectedGroup, key),
189
+ ]));
190
+ // apply
191
+ setPlaceholderBulk(placeholder);
192
+ form.setFieldsValue(values);
193
+ setGroupBufferSelected(selectedGroup);
194
+ if (notSameGroup) {
195
+ form.setFieldValue(`${bufferValueForm === null || bufferValueForm === void 0 ? void 0 : bufferValueForm.key}`, getValueIfSame(selectedGroup, bufferValueForm === null || bufferValueForm === void 0 ? void 0 : bufferValueForm.key));
196
+ }
112
197
  }
113
198
  else {
114
- setOpen(false);
199
+ if (tool.active !== "background")
200
+ setOpen(false);
115
201
  }
116
- }, [tool, show]);
202
+ }, [selectedComponent, selectedGroup, show, groupBufferSelected, tool]);
117
203
  const createShape = (shape, props = {}, selectedComponent) => {
118
204
  var _a, _b, _c, _d, _e, _f, _g, _h;
119
205
  const defaults = (_a = SEAT_SHAPES[shape]) !== null && _a !== void 0 ? _a : {};
@@ -249,6 +335,7 @@ const ControlPanels = (props) => {
249
335
  switch (tool.active) {
250
336
  case "select":
251
337
  case "text":
338
+ case "polygon":
252
339
  return <SelectToolForm action={action} tranform={transform}/>;
253
340
  case "square":
254
341
  case "circle":
@@ -273,16 +360,56 @@ const ControlPanels = (props) => {
273
360
  payload: false,
274
361
  });
275
362
  };
276
- // if(!show) return null
277
- return (<div className={clsx("w-[300px] h-full absolute top-0 z-50 transition-all duration-300 overflow-y-scroll ", open ? "right-0" : "right-[-300px]")}>
278
- <div className="bg-white h-full max-h-screen w-full p-2 overflow-y-auto border-l border-gray-300">
279
- <Form layout="vertical" form={form} name="table" onValuesChange={handleChangeComponent} initialValues={{ labels: [{}] }}>
280
- <Form.Item name="id" hidden>
281
- <Input />
282
- </Form.Item>
283
- {renderFormPanel()}
284
- </Form>
363
+ return (<FormPlaceholderContext.Provider value={{
364
+ placeholders,
365
+ setPlaceholder,
366
+ unsetPlaceholder,
367
+ setPlaceholderBulk,
368
+ resetPlaceholders,
369
+ }}>
370
+ <div className={clsx("w-[300px] h-full absolute top-0 z-50 transition-all duration-300 overflow-y-scroll mt-[78px]", open ? "right-0" : "right-[-1000px]")}>
371
+ <div className="bg-white h-full max-h-screen w-full p-2 overflow-y-auto border-l border-gray-300">
372
+ <Form layout="vertical" form={form} name="table" colon={false} onValuesChange={handleChangeComponent} onFocus={(e) => {
373
+ var _a, _b, _c;
374
+ e.stopPropagation();
375
+ const name = e.target.name;
376
+ const placeholder = (_c = (_b = (_a = placeholders === null || placeholders === void 0 ? void 0 : placeholders[name]) === null || _a === void 0 ? void 0 : _a.split(",")) === null || _b === void 0 ? void 0 : _b.map(Number)) === null || _c === void 0 ? void 0 : _c.filter((item) => !_.isNaN(item));
377
+ const averageValuePlaceHolder = (placeholder === null || placeholder === void 0 ? void 0 : placeholder.reduce((a, b) => a + b, 0)) / (placeholder === null || placeholder === void 0 ? void 0 : placeholder.length);
378
+ const value = Math.round(averageValuePlaceHolder);
379
+ if (placeholder && placeholder.length > 0) {
380
+ setBufferValueForm({
381
+ key: name,
382
+ value: value,
383
+ });
384
+ form.setFieldsValue({
385
+ [name]: value,
386
+ });
387
+ }
388
+ }} onBlur={(e) => {
389
+ e.stopPropagation();
390
+ setBufferValueForm(null);
391
+ const name = e.target.name;
392
+ const value = e.target.value;
393
+ if (value) {
394
+ handleChangeComponent({ [name]: value }, form.getFieldsValue());
395
+ }
396
+ }} initialValues={{ labels: [{}] }}>
397
+ <Form.Item name="id" hidden>
398
+ <Input />
399
+ </Form.Item>
400
+ <Form.Item name="shape" hidden>
401
+ <Input />
402
+ </Form.Item>
403
+ {renderFormPanel()}
404
+ </Form>
405
+ </div>
285
406
  </div>
286
- </div>);
407
+ </FormPlaceholderContext.Provider>);
287
408
  };
288
409
  export default ControlPanels;
410
+ export const useFormPlaceholder = () => {
411
+ const ctx = useContext(FormPlaceholderContext);
412
+ if (!ctx)
413
+ throw new Error("useFormPlaceholder must be used within FormPlaceholderProvider");
414
+ return ctx;
415
+ };
@@ -0,0 +1,2 @@
1
+ declare const PolygonTool: () => import("react/jsx-runtime").JSX.Element;
2
+ export default PolygonTool;
@@ -0,0 +1,44 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { useAppDispatch, useAppSelector } from "@/hooks/use-redux";
4
+ import { Button, ColorPicker, Flex, Form, InputNumber } from "antd";
5
+ const PolygonTool = () => {
6
+ const dispatch = useAppDispatch();
7
+ const selectedComponent = useAppSelector((state) => state.panel.selectedComponent);
8
+ const deleteText = () => {
9
+ dispatch({
10
+ type: "board/removeExtraComponent",
11
+ payload: selectedComponent,
12
+ });
13
+ dispatch({ type: "board/setFlagChange", payload: true });
14
+ dispatch({ type: "board/setUpdateBy", payload: "global" });
15
+ dispatch({ type: "panel/setSelectedComponent", payload: null });
16
+ dispatch({ type: "panel/setSelectedGroup", payload: null });
17
+ dispatch({ type: "panel/setShow", payload: false });
18
+ dispatch({ type: "tool/setActiveTool", payload: "select" });
19
+ };
20
+ return (_jsxs("div", { className: "py-2", children: [_jsx("h1", { className: "heading-s", children: "Shape Polygon" }), _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 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, {}) })] }), _jsxs(Flex, { gap: 2, children: [_jsx(Form.Item, { label: "Rotation", name: "rotation", className: "w-full", children: _jsx(InputNumber, { suffix: "\u00B0", min: 0, max: 360, parser: (value) => {
21
+ if (!value)
22
+ return 0;
23
+ const num = Number(value.replace(/\D/g, ""));
24
+ if (Number.isNaN(num))
25
+ return 0;
26
+ return Math.min(360, Math.max(0, num));
27
+ } }) }), _jsx(Form.Item, { label: "opacity", name: "opacity", className: "w-full", children: _jsx(InputNumber, { step: 10, max: 100, min: 0, name: "opacity", parser: (value) => {
28
+ if (value === undefined || value === null || value === "")
29
+ return null;
30
+ const cleaned = value.replace(/[^0-9.]/g, "");
31
+ const num = Number(cleaned);
32
+ if (Number.isNaN(num))
33
+ return null;
34
+ return Math.min(100, Math.max(0, num));
35
+ }, suffix: "%" }) }), _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) => {
36
+ if (!value)
37
+ return 0;
38
+ const num = Number(value.replace(/\D/g, ""));
39
+ if (Number.isNaN(num))
40
+ return 0;
41
+ return Math.min(360, Math.max(0, num));
42
+ } }) })] }), _jsx(Button, { type: "default", onClick: deleteText, className: "w-full", children: "Delete" })] }));
43
+ };
44
+ export default PolygonTool;
@@ -0,0 +1,70 @@
1
+ "use client";
2
+ import { useAppDispatch, useAppSelector } from "@/hooks/use-redux";
3
+ import { Button, ColorPicker, Flex, Form, InputNumber } from "antd";
4
+ const PolygonTool = () => {
5
+ const dispatch = useAppDispatch();
6
+ const selectedComponent = useAppSelector((state) => state.panel.selectedComponent);
7
+ const deleteText = () => {
8
+ dispatch({
9
+ type: "board/removeExtraComponent",
10
+ payload: selectedComponent,
11
+ });
12
+ dispatch({ type: "board/setFlagChange", payload: true });
13
+ dispatch({ type: "board/setUpdateBy", payload: "global" });
14
+ dispatch({ type: "panel/setSelectedComponent", payload: null });
15
+ dispatch({ type: "panel/setSelectedGroup", payload: null });
16
+ dispatch({ type: "panel/setShow", payload: false });
17
+ dispatch({ type: "tool/setActiveTool", payload: "select" });
18
+ };
19
+ return (<div className="py-2">
20
+ <h1 className="heading-s">Shape Polygon</h1>
21
+ <Flex gap={2}>
22
+ <Form.Item label="Fill" name={"fill"} getValueFromEvent={(color) => color.toHexString()} className="w-full ">
23
+ <ColorPicker allowClear format="hex" defaultFormat="hex"/>
24
+ </Form.Item>
25
+ <Form.Item label="Stroke Fill" name={"stroke"} getValueFromEvent={(color) => color.toHexString()} className="w-full ">
26
+ <ColorPicker allowClear format="hex" defaultFormat="hex"/>
27
+ </Form.Item>
28
+ <Form.Item label="Stroke Size" name={"strokeWidth"} className="w-full">
29
+ <InputNumber />
30
+ </Form.Item>
31
+ </Flex>
32
+ <Flex gap={2}>
33
+ <Form.Item label="Rotation" name="rotation" className="w-full">
34
+ <InputNumber suffix="°" min={0} max={360} parser={(value) => {
35
+ if (!value)
36
+ return 0;
37
+ const num = Number(value.replace(/\D/g, ""));
38
+ if (Number.isNaN(num))
39
+ return 0;
40
+ return Math.min(360, Math.max(0, num));
41
+ }}/>
42
+ </Form.Item>
43
+ <Form.Item label="opacity" name={"opacity"} className="w-full">
44
+ <InputNumber step={10} max={100} min={0} name="opacity" parser={(value) => {
45
+ if (value === undefined || value === null || value === "")
46
+ return null;
47
+ const cleaned = value.replace(/[^0-9.]/g, "");
48
+ const num = Number(cleaned);
49
+ if (Number.isNaN(num))
50
+ return null;
51
+ return Math.min(100, Math.max(0, num));
52
+ }} suffix="%"/>
53
+ </Form.Item>
54
+ <Form.Item label="Rotation" name="rotation" className="w-full">
55
+ <InputNumber suffix="°" min={0} step={1} max={360} name="rotation" parser={(value) => {
56
+ if (!value)
57
+ return 0;
58
+ const num = Number(value.replace(/\D/g, ""));
59
+ if (Number.isNaN(num))
60
+ return 0;
61
+ return Math.min(360, Math.max(0, num));
62
+ }}/>
63
+ </Form.Item>
64
+ </Flex>
65
+ <Button type="default" onClick={deleteText} className="w-full">
66
+ Delete
67
+ </Button>
68
+ </div>);
69
+ };
70
+ export default PolygonTool;
@@ -7,6 +7,7 @@ import SeatSquare from "./table-seat-square";
7
7
  import UploadTool from "./upload-tool";
8
8
  import TextTool from "./text-tool";
9
9
  import SelectedGroup from "./selected-group";
10
+ import PolygonTool from "./polygon";
10
11
  const SelectToolForm = ({ title = "Title", action, tranform }) => {
11
12
  const components = useAppSelector((state) => state.board.components);
12
13
  const selectedComponent = useAppSelector((state) => state.panel.selectedComponent);
@@ -60,6 +61,8 @@ const SelectToolForm = ({ title = "Title", action, tranform }) => {
60
61
  : "component", transform: tranform }));
61
62
  case "text":
62
63
  return _jsx(TextTool, {});
64
+ case "polygon":
65
+ return _jsx(PolygonTool, {});
63
66
  default:
64
67
  return null;
65
68
  }
@@ -6,6 +6,7 @@ import SeatSquare from "./table-seat-square";
6
6
  import UploadTool from "./upload-tool";
7
7
  import TextTool from "./text-tool";
8
8
  import SelectedGroup from "./selected-group";
9
+ import PolygonTool from "./polygon";
9
10
  const SelectToolForm = ({ title = "Title", action, tranform }) => {
10
11
  const components = useAppSelector((state) => state.board.components);
11
12
  const selectedComponent = useAppSelector((state) => state.panel.selectedComponent);
@@ -59,6 +60,8 @@ const SelectToolForm = ({ title = "Title", action, tranform }) => {
59
60
  : "component"} transform={tranform}/>);
60
61
  case "text":
61
62
  return <TextTool />;
63
+ case "polygon":
64
+ return <PolygonTool />;
62
65
  default:
63
66
  return null;
64
67
  }
@@ -1,17 +1,19 @@
1
1
  "use client";
2
- import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import { optionsShape } from "../../components/form-tools/shape";
4
4
  import { ColorPicker, Flex, Form, InputNumber, Select } from "antd";
5
- import SeatCircle from "./table-seat-circle";
6
- import SeatSquare from "./table-seat-square";
7
5
  import { useAppSelector } from "../../hooks/use-redux";
8
6
  import SectionLabel from "../../components/form-tools/label";
7
+ import { useFormPlaceholder } from ".";
9
8
  const { Option } = Select;
10
9
  const SelectedGroup = () => {
11
10
  var _a;
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 hasExtraComponent = allShapeSelected.some((shape) => ["text", "background", "polygon"].includes(shape));
16
+ console.log({ hasExtraComponent });
15
17
  const sameShape = [
16
18
  "table-seat-circle",
17
19
  "table-seat-rect-circle",
@@ -27,29 +29,25 @@ const SelectedGroup = () => {
27
29
  return Object.assign(Object.assign({}, item), { disabled: allShapeSelected.includes(item.value) });
28
30
  });
29
31
  const maxSeat = selectedGroup === null || selectedGroup === void 0 ? void 0 : selectedGroup.some((item) => (item === null || item === void 0 ? void 0 : item[seatKey]) > 4);
30
- return (_jsx(_Fragment, { children: _jsxs("div", { className: "py-2", children: [_jsx("h1", { className: "heading-s", children: " Group Selection" }), _jsxs("div", { className: "py-2", children: [_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) => {
32
+ 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) => {
31
33
  const disabled = item.value === "table-seat-rect-circle" && maxSeat;
32
- return (_jsx(Option, { value: item.value, disabled: disabled, children: item.value === "table-seat-rect-circle" ?
33
- `Type 5 (only for 4 ${seatKey})` : item.label }, item.value));
34
- }) }) }) }), _jsxs(Flex, { gap: 2, className: "w-full", children: [["table-seat-circle", "table-seat-rect-circle"].includes(shape) && _jsx(SeatCircle, {}), [
35
- "table-seat-square",
36
- "table-seat-square",
37
- "table-seat-rect-square",
38
- "table-seat-half-square",
39
- ].includes(shape) && _jsx(SeatSquare, {})] }), !sameShape && (_jsxs(_Fragment, { children: [_jsxs(Flex, { gap: 2, className: "w-full", children: [!shapeAllIncludePolygon && (_jsxs(_Fragment, { children: [_jsx(Form.Item, { label: "Width", name: "width", className: "w-full", children: _jsx(InputNumber, { suffix: "px" }) }), _jsx(Form.Item, { label: "Height", name: "height", className: "w-full", children: _jsx(InputNumber, { suffix: "px" }) })] })), !(shape === null || shape === void 0 ? void 0 : shape.includes("circle")) && !shapeAllIncludePolygon && (_jsx(Form.Item, { label: "Radius", name: "radius", className: "w-full", children: _jsx(InputNumber, { suffix: "px", parser: (value) => {
40
- var _a;
41
- const onlyNumber = (_a = value === null || value === void 0 ? void 0 : value.replace(/\D/g, "")) !== null && _a !== void 0 ? _a : "";
42
- return onlyNumber === ""
43
- ? 1
44
- : Math.max(1, Number(onlyNumber));
45
- } }) }))] }), !shapeAllIncludePolygon && (_jsx(_Fragment, { children: _jsxs(Flex, { gap: 2, children: [_jsx(Form.Item, { label: "Position X", name: "x", className: "w-full", children: _jsx(InputNumber, {}) }), _jsx(Form.Item, { label: "Position Y", name: "y", className: "w-full", children: _jsx(InputNumber, {}) }), _jsx(Form.Item, { label: "Rotation", name: "rotation", className: "w-full", children: _jsx(InputNumber, { max: 360, min: 0 }) })] }) })), _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, { children: [_jsx(Form.Item, { label: "Stroke Width", name: "strokeWidth", className: "w-full", children: _jsx(InputNumber, {}) }), _jsx(Form.Item, { label: "opacity", name: "opacity", className: "w-full", children: _jsx(InputNumber, { step: 10, max: 100, min: 0, parser: (value) => {
46
- if (value === undefined || value === null || value === "")
47
- return null;
48
- const cleaned = value.replace(/[^0-9.]/g, "");
49
- const num = Number(cleaned);
50
- if (Number.isNaN(num))
51
- return null;
52
- return Math.min(100, Math.max(0, num));
53
- }, suffix: "%" }) })] }), _jsx(SectionLabel, {})] }))] })] }) }));
34
+ return (_jsx(Option, { value: item.value, disabled: disabled, children: item.value === "table-seat-rect-circle"
35
+ ? `Type 5 (only for 4 ${seatKey})`
36
+ : item.label }, item.value));
37
+ }) }) }) })), _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", 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", 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) => {
38
+ var _a;
39
+ const onlyNumber = (_a = value === null || value === void 0 ? void 0 : value.replace(/\D/g, "")) !== null && _a !== void 0 ? _a : "";
40
+ return onlyNumber === ""
41
+ ? 1
42
+ : Math.max(1, Number(onlyNumber));
43
+ } }) }))] }), !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%" }, 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", 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) => {
44
+ if (value === undefined || value === null || value === "")
45
+ return null;
46
+ const cleaned = value.replace(/[^0-9.]/g, "");
47
+ const num = Number(cleaned);
48
+ if (Number.isNaN(num))
49
+ return null;
50
+ return Math.min(100, Math.max(0, num));
51
+ }, suffix: "%" }) })] }), _jsx(SectionLabel, {})] })] }) }));
54
52
  };
55
53
  export default SelectedGroup;