seat-editor 3.3.35 → 3.3.37

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 (83) hide show
  1. package/dist/app/constant.d.ts +3 -0
  2. package/dist/app/constant.js +2 -0
  3. package/dist/app/layout.d.ts +1 -1
  4. package/dist/app/layout.js +22 -0
  5. package/dist/app/new-board/page.d.ts +1 -1
  6. package/dist/app/new-board/page.js +58 -0
  7. package/dist/app/old-board/page.d.ts +1 -2
  8. package/dist/app/old-board/page.js +377 -0
  9. package/dist/app/only-view/chair.d.ts +1 -1
  10. package/dist/app/only-view/chair.js +2 -10
  11. package/dist/app/only-view/page.d.ts +1 -1
  12. package/dist/app/only-view/page.js +226 -0
  13. package/dist/app/only-view/user.d.ts +1 -1
  14. package/dist/app/only-view/user.js +2 -10
  15. package/dist/app/page.d.ts +1 -1
  16. package/dist/app/page.js +8 -0
  17. package/dist/app/test/page.d.ts +1 -2
  18. package/dist/app/test/page.js +43 -0
  19. package/dist/app/v2/page.d.ts +1 -1
  20. package/dist/app/v2/page.js +8 -0
  21. package/dist/components/button-tools/index.d.ts +1 -1
  22. package/dist/components/button-tools/index.js +11 -0
  23. package/dist/components/form-tools/label.d.ts +1 -1
  24. package/dist/components/form-tools/label.js +21 -0
  25. package/dist/components/form-tools/shape.d.ts +1 -1
  26. package/dist/components/form-tools/shape.js +69 -0
  27. package/dist/components/input/number-indicator.d.ts +1 -1
  28. package/dist/components/input/number-indicator.js +27 -0
  29. package/dist/components/joystick/index.d.ts +1 -2
  30. package/dist/components/joystick/index.js +48 -0
  31. package/dist/components/layer/index.d.ts +1 -1
  32. package/dist/components/layer/index.js +295 -0
  33. package/dist/components/layer-v2/index.d.ts +1 -1
  34. package/dist/components/layer-v2/index.js +282 -0
  35. package/dist/components/layer-v3/index.d.ts +1 -1
  36. package/dist/components/layer-v3/index.js +483 -0
  37. package/dist/components/layer-v4/index.d.ts +1 -1
  38. package/dist/components/layer-v4/index.js +924 -0
  39. package/dist/components/lib/index.d.ts +1 -1
  40. package/dist/components/lib/index.js +28 -0
  41. package/dist/components/modal-preview/index.d.ts +1 -1
  42. package/dist/components/modal-preview/index.js +10 -0
  43. package/dist/features/board/index.d.ts +1 -1
  44. package/dist/features/board/index.js +666 -0
  45. package/dist/features/board-v2/index.d.ts +1 -2
  46. package/dist/features/board-v2/index.js +807 -0
  47. package/dist/features/board-v3/icons.js +16 -0
  48. package/dist/features/board-v3/index.d.ts +1 -1
  49. package/dist/features/board-v3/index.js +1587 -0
  50. package/dist/features/navbar/index.d.ts +1 -1
  51. package/dist/features/navbar/index.js +6 -0
  52. package/dist/features/package/index.d.ts +1 -1
  53. package/dist/features/package/index.js +166 -0
  54. package/dist/features/panel/index.d.ts +1 -1
  55. package/dist/features/panel/index.js +243 -0
  56. package/dist/features/panel/select-tool.d.ts +1 -1
  57. package/dist/features/panel/select-tool.js +57 -0
  58. package/dist/features/panel/selected-group.d.ts +1 -1
  59. package/dist/features/panel/selected-group.js +35 -0
  60. package/dist/features/panel/square-circle-tool.d.ts +1 -1
  61. package/dist/features/panel/square-circle-tool.js +8 -0
  62. package/dist/features/panel/table-seat-circle.d.ts +1 -1
  63. package/dist/features/panel/table-seat-circle.js +9 -0
  64. package/dist/features/panel/table-seat-square.d.ts +1 -1
  65. package/dist/features/panel/table-seat-square.js +9 -0
  66. package/dist/features/panel/text-tool.d.ts +1 -1
  67. package/dist/features/panel/text-tool.js +22 -0
  68. package/dist/features/panel/upload-tool.d.ts +1 -1
  69. package/dist/features/panel/upload-tool.js +150 -0
  70. package/dist/features/side-tool/index.d.ts +1 -1
  71. package/dist/features/side-tool/index.js +365 -0
  72. package/dist/features/view-only/index.d.ts +1 -1
  73. package/dist/features/view-only/index.js +198 -0
  74. package/dist/features/view-only-2/index.d.ts +84 -14
  75. package/dist/features/view-only-2/index.js +558 -0
  76. package/dist/features/view-only-3/index.d.ts +1 -1
  77. package/dist/features/view-only-3/index.js +577 -0
  78. package/dist/provider/antd-provider.js +43 -0
  79. package/dist/provider/redux-provider.d.ts +1 -1
  80. package/dist/provider/redux-provider.js +7 -0
  81. package/dist/provider/store-provider.d.ts +1 -1
  82. package/dist/provider/store-provider.js +9 -0
  83. package/package.json +1 -1
@@ -0,0 +1,1587 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
+ import { useEffect, useImperativeHandle, useRef, useState } from "react";
4
+ import { TransformWrapper, TransformComponent, } from "react-zoom-pan-pinch";
5
+ import { useAppSelector, useAppDispatch } from "../../hooks/use-redux";
6
+ import Layers from "../../components/layer-v3";
7
+ import { isEmpty, isPlainObject, isUndefined } from "lodash";
8
+ import ModalPreview from "../../components/modal-preview";
9
+ import LayerView from "../view-only-3";
10
+ import { isEqual, debounce } from "lodash";
11
+ import { ZoomIn, ZoomOut } from "lucide-react";
12
+ import { Button, Radio } from "antd";
13
+ import { getAttributeElement, getAttributeElements } from "./resize-element";
14
+ import { applyResizeToSvgElement, arrayToSvgPointsAttr, createTableGhost, getGlobalBBox, getRotation, getSvgElementSize, getTranslate, isClosingPolygon, normalizeAngle, pointsStringToArray, resizeBox, resizeSeatCircle, resizeSeatRectCircle, resizeSeatRectSquare, resizeSeatSide, resizeSeatSquare, stabilizeRotation, stabilizeTranslateOnRotate, updateManyComponents, updateSelectionBox, updateSelectionGuides, updateSingleComponent, } from "./utils";
15
+ const toolElement = ["square", "circle", "table-seat-circle"];
16
+ const idSelectionBoxGhost = "selection-box-ghost";
17
+ const nameShapeSelectionBoxGhost = "selection-box";
18
+ const BoardTemplate = ({ refs, loadingRender }) => {
19
+ const dispatch = useAppDispatch();
20
+ const backgroundColor = useAppSelector((state) => state.board.backgroundColor);
21
+ const selectedComponentProps = useAppSelector((state) => state.panel.selectedComponent);
22
+ const activeTool = useAppSelector((state) => state.tool.active);
23
+ const grid = useAppSelector((state) => state.tool.grid);
24
+ const lockBackground = useAppSelector((state) => state.tool.lockBackground);
25
+ const transformRef = useRef(null);
26
+ const svgRef = useRef(null);
27
+ const containerRef = useRef(null);
28
+ const releaseGroupRef = useRef(false);
29
+ useImperativeHandle(refs, () => ({
30
+ svgRef: svgRef === null || svgRef === void 0 ? void 0 : svgRef.current,
31
+ transformRef: transformRef === null || transformRef === void 0 ? void 0 : transformRef.current,
32
+ containerRef: containerRef === null || containerRef === void 0 ? void 0 : containerRef.current,
33
+ }));
34
+ const widthBoardRef = useRef(20000);
35
+ const heightBoardRef = useRef(20000);
36
+ const widthBoard = widthBoardRef.current;
37
+ const heightBoard = heightBoardRef.current;
38
+ const [scale, setScale] = useState(1);
39
+ const boardSizeRef = useRef({ width: 20000, height: 20000 });
40
+ const boardSize = boardSizeRef.current;
41
+ const minCoordsRef = useRef({ x: 0, y: 0 });
42
+ const minCoords = minCoordsRef.current;
43
+ const [hasInitialized, setHasInitialzed] = useState(false);
44
+ const [componentsState, setComponentsState] = useState([]);
45
+ const [extraComponentsState, setExtraComponentsState] = useState([]);
46
+ const [selectedComponent, setSelectedComponent] = useState(null);
47
+ const isSyncingFromRedux = useRef(false);
48
+ const isDragging = useRef(false);
49
+ const moveComponent = useRef(false);
50
+ const ghostRotateElement = useRef(0);
51
+ const isResizeRef = useRef(false);
52
+ const isResizeSelectionRef = useRef(false);
53
+ const hadSelectionRef = useRef(false);
54
+ //FLAGE EVERY HANDLE EVENT
55
+ //CREATE
56
+ const isCreateElementRef = useRef(false);
57
+ //RESIZE
58
+ const onResizeSelectionRef = useRef(false);
59
+ //ROTATE
60
+ const isRotatingRef = useRef(false);
61
+ const rotationSelectionRef = useRef(0);
62
+ //DRAG/MOVE
63
+ //SELECTION
64
+ const onMakeSelectionRef = useRef(false);
65
+ const onMoveSelectionBoxRef = useRef(false);
66
+ const dataElementSelectionGroupRef = useRef([]);
67
+ //polygon
68
+ const polygonElementRef = useRef([]);
69
+ const isOnMakePolygonRef = useRef(false);
70
+ const { components: componentsProps, extraComponents: extraComponentsProps, boundingBox, flagChange, updateBy, isShowTagType, } = useAppSelector((state) => state.board);
71
+ const { selectionLines } = useAppSelector((state) => state.panel);
72
+ const [selectedLines, setSelectedLines] = useState(null);
73
+ useEffect(() => {
74
+ if (activeTool === "select" || activeTool !== "select") {
75
+ handleUnSelectComponent();
76
+ }
77
+ }, [activeTool]);
78
+ useEffect(() => {
79
+ if (selectionLines) {
80
+ setSelectedLines(selectionLines);
81
+ const idSelected = dataElementSelectionGroupRef.current.map((item) => item.id);
82
+ const newSelectionData = [
83
+ ...componentsState,
84
+ ...extraComponentsState,
85
+ ].filter((comp) => idSelected.includes(comp.id));
86
+ dataElementSelectionGroupRef.current = newSelectionData;
87
+ }
88
+ }, [selectionLines]);
89
+ useEffect(() => {
90
+ var _a, _b, _c, _d, _e, _f, _g;
91
+ if (hasInitialized)
92
+ return;
93
+ let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity;
94
+ // let widthMinX = 0;
95
+ // let heightMinY = 0;
96
+ componentsProps === null || componentsProps === void 0 ? void 0 : componentsProps.forEach((_, i) => {
97
+ let values = _;
98
+ if (values === null || values === void 0 ? void 0 : values.shape) {
99
+ minX = Math.min(minX, values.x);
100
+ minY = Math.min(minY, values.y);
101
+ maxX = Math.max(maxX, values.x + values.width);
102
+ maxY = Math.max(maxY, values.y + values.height);
103
+ }
104
+ if (i === componentsProps.length - 1) {
105
+ minX = minX > 10 ? minX - 10 : minX;
106
+ minY = minY > 10 ? minY - 10 : minY;
107
+ maxX = maxX + 10;
108
+ maxY = maxY + 10;
109
+ }
110
+ });
111
+ extraComponentsProps === null || extraComponentsProps === void 0 ? void 0 : extraComponentsProps.forEach((values, i) => {
112
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j;
113
+ if (values === null || values === void 0 ? void 0 : values.shape) {
114
+ minX = Math.min(minX, values.x - ((_a = values === null || values === void 0 ? void 0 : values.width) !== null && _a !== void 0 ? _a : 0));
115
+ minY = Math.min(minY, values.y - ((_b = values === null || values === void 0 ? void 0 : values.height) !== null && _b !== void 0 ? _b : 0));
116
+ maxX = Math.max(maxX, values.x + ((_c = values === null || values === void 0 ? void 0 : values.width) !== null && _c !== void 0 ? _c : 0));
117
+ maxY = Math.max(maxY, values.y + ((_d = values === null || values === void 0 ? void 0 : values.height) !== null && _d !== void 0 ? _d : 0));
118
+ }
119
+ if ((_e = values === null || values === void 0 ? void 0 : values.shape) === null || _e === void 0 ? void 0 : _e.includes("polygon")) {
120
+ minX = Math.min(minX, (_f = values === null || values === void 0 ? void 0 : values.points) === null || _f === void 0 ? void 0 : _f.reduce((min, point) => Math.min(min, point.x), Infinity));
121
+ minY = Math.min(minY, (_g = values === null || values === void 0 ? void 0 : values.points) === null || _g === void 0 ? void 0 : _g.reduce((min, point) => Math.min(min, point.y), Infinity));
122
+ maxX = Math.max(maxX, (_h = values === null || values === void 0 ? void 0 : values.points) === null || _h === void 0 ? void 0 : _h.reduce((max, point) => Math.max(max, point.x), -Infinity));
123
+ maxY = Math.max(maxY, (_j = values === null || values === void 0 ? void 0 : values.points) === null || _j === void 0 ? void 0 : _j.reduce((max, point) => Math.max(max, point.y), -Infinity));
124
+ }
125
+ });
126
+ let backgroundHasOne = false;
127
+ if ((extraComponentsProps === null || extraComponentsProps === void 0 ? void 0 : extraComponentsProps.length) === 1 &&
128
+ ((_b = (_a = extraComponentsProps === null || extraComponentsProps === void 0 ? void 0 : extraComponentsProps[0]) === null || _a === void 0 ? void 0 : _a.shape) === null || _b === void 0 ? void 0 : _b.includes("background"))) {
129
+ backgroundHasOne = true;
130
+ minX = (_c = extraComponentsProps === null || extraComponentsProps === void 0 ? void 0 : extraComponentsProps[0]) === null || _c === void 0 ? void 0 : _c.x;
131
+ minY = (_d = extraComponentsProps === null || extraComponentsProps === void 0 ? void 0 : extraComponentsProps[0]) === null || _d === void 0 ? void 0 : _d.y;
132
+ maxX = (_e = extraComponentsProps === null || extraComponentsProps === void 0 ? void 0 : extraComponentsProps[0]) === null || _e === void 0 ? void 0 : _e.width;
133
+ maxY = (_f = extraComponentsProps === null || extraComponentsProps === void 0 ? void 0 : extraComponentsProps[0]) === null || _f === void 0 ? void 0 : _f.height;
134
+ }
135
+ // if (
136
+ // extraComponentsProps?.length < 1 &&
137
+ // ["background", "text"].includes(componentsProps?.[0]?.shape)
138
+ // ) {
139
+ // minX = minX;
140
+ // minY = minY;
141
+ // maxX = maxX;
142
+ // maxY = maxY;
143
+ // }
144
+ const hasBoundingBox = !isEmpty(boundingBox);
145
+ if (hasBoundingBox) {
146
+ minX = boundingBox.x;
147
+ minY = boundingBox.y;
148
+ }
149
+ if ((minX !== Infinity || minY !== Infinity) && !activeTool) {
150
+ // console.log("initialized");
151
+ (_g = transformRef.current) === null || _g === void 0 ? void 0 : _g.setTransform(-minX, -minY, scale);
152
+ setHasInitialzed(true);
153
+ }
154
+ }, [componentsProps, extraComponentsProps]);
155
+ const queueUpdateComponents = (data) => {
156
+ dispatch({
157
+ type: "board/updateComponentsBulk",
158
+ payload: data,
159
+ });
160
+ };
161
+ const queueUpdateExtraComponents = (data) => {
162
+ dispatch({
163
+ type: "board/setNewExtraComponents",
164
+ payload: data,
165
+ });
166
+ };
167
+ const debouncedSyncExtraComponents = useRef(debounce((data) => {
168
+ dispatch({
169
+ type: "board/setNewExtraComponents",
170
+ payload: data,
171
+ });
172
+ }, 1000));
173
+ // Redux → Local
174
+ useEffect(() => {
175
+ if (flagChange && updateBy === "global") {
176
+ if (!isEqual(selectedComponentProps, selectedComponent)) {
177
+ isSyncingFromRedux.current = true;
178
+ setSelectedComponent(selectedComponentProps !== null && selectedComponentProps !== void 0 ? selectedComponentProps : []);
179
+ setSelectedLines(selectionLines);
180
+ }
181
+ if (!isEqual(componentsProps, componentsState)) {
182
+ isSyncingFromRedux.current = true;
183
+ setComponentsState(componentsProps !== null && componentsProps !== void 0 ? componentsProps : []);
184
+ }
185
+ if (!isEqual(extraComponentsProps, extraComponentsState)) {
186
+ isSyncingFromRedux.current = true;
187
+ setExtraComponentsState(extraComponentsProps !== null && extraComponentsProps !== void 0 ? extraComponentsProps : []);
188
+ }
189
+ dispatch({ type: "board/setFlagChange", payload: false });
190
+ }
191
+ }, [componentsProps, extraComponentsProps, selectedComponentProps]);
192
+ const updateComponentAttribute = (component) => {
193
+ if (!component)
194
+ return;
195
+ const updatedComponents = updateSingleComponent(componentsState, component, setComponentsState);
196
+ if (updatedComponents) {
197
+ dispatch({ type: "board/setUpdateBy", payload: "local" });
198
+ queueUpdateComponents(updatedComponents);
199
+ }
200
+ const updatedExtra = updateSingleComponent(extraComponentsState, component, setExtraComponentsState);
201
+ if (updatedExtra) {
202
+ dispatch({ type: "board/setUpdateBy", payload: "local" });
203
+ queueUpdateComponents(updatedExtra);
204
+ }
205
+ };
206
+ const updateComponentsAttribute = (components) => {
207
+ if (!components.length)
208
+ return;
209
+ const nextExtraComponents = updateManyComponents(extraComponentsState, components, setExtraComponentsState);
210
+ if (nextExtraComponents) {
211
+ queueUpdateComponents(nextExtraComponents);
212
+ }
213
+ const nextComponents = updateManyComponents(componentsState, components, setComponentsState);
214
+ if (nextComponents) {
215
+ queueUpdateComponents(nextComponents);
216
+ }
217
+ dispatch({ type: "board/setUpdateBy", payload: "local" });
218
+ };
219
+ const addComponents = (component) => {
220
+ const index = extraComponentsState.findIndex((c) => (c === null || c === void 0 ? void 0 : c.shape) === "bounding-box");
221
+ const nextExtraComponents = index !== -1
222
+ ? extraComponentsState.map((item, i) => i === index ? component : item)
223
+ : [...extraComponentsState, component];
224
+ setExtraComponentsState(nextExtraComponents);
225
+ dispatch({
226
+ type: "board/setNewExtraComponents",
227
+ payload: nextExtraComponents,
228
+ });
229
+ dispatch({ type: "board/setUpdateBy", payload: "local" });
230
+ };
231
+ const getSvgCoords = (e) => {
232
+ var _a;
233
+ const svg = svgRef.current;
234
+ const point = svg.createSVGPoint();
235
+ point.x = e.clientX;
236
+ point.y = e.clientY;
237
+ const transformed = point.matrixTransform((_a = svg.getScreenCTM()) === null || _a === void 0 ? void 0 : _a.inverse());
238
+ return { x: transformed.x, y: transformed.y };
239
+ };
240
+ const getCursorStyle = () => {
241
+ if (activeTool === "select" && moveComponent.current) {
242
+ return "grabbing";
243
+ }
244
+ else if (activeTool === "select") {
245
+ return "grab";
246
+ }
247
+ else if (activeTool === "grab") {
248
+ return "grab";
249
+ }
250
+ else if (activeTool === "ruler") {
251
+ return "crosshair";
252
+ }
253
+ };
254
+ const handelZoomIn = () => {
255
+ var _a;
256
+ if (activeTool !== "grab") {
257
+ dispatch({
258
+ type: "tool/setActiveTool",
259
+ payload: "grab",
260
+ });
261
+ }
262
+ (_a = transformRef.current) === null || _a === void 0 ? void 0 : _a.zoomIn();
263
+ };
264
+ const handleZoomOut = () => {
265
+ var _a;
266
+ if (activeTool !== "grab") {
267
+ dispatch({
268
+ type: "tool/setActiveTool",
269
+ payload: "grab",
270
+ });
271
+ }
272
+ (_a = transformRef.current) === null || _a === void 0 ? void 0 : _a.zoomOut();
273
+ };
274
+ const handleUnSelectComponent = () => {
275
+ dispatch({ type: "panel/setSelectedComponent", payload: null });
276
+ setSelectedComponent(null);
277
+ setSelectedLines(null);
278
+ dispatch({ type: "panel/setShow", payload: false });
279
+ dataElementSelectionGroupRef.current = [];
280
+ };
281
+ const stillHoldShift = useRef(false);
282
+ useEffect(() => {
283
+ var _a, _b;
284
+ if (stillHoldShift.current && dataElementSelectionGroupRef.current) {
285
+ const selectionLines = (_a = svgRef.current) === null || _a === void 0 ? void 0 : _a.querySelector("#selection-lines");
286
+ selectionLines === null || selectionLines === void 0 ? void 0 : selectionLines.setAttribute("pointer-events", "none");
287
+ }
288
+ if (!stillHoldShift.current && dataElementSelectionGroupRef.current) {
289
+ const selectionLines = (_b = svgRef.current) === null || _b === void 0 ? void 0 : _b.querySelector("#selection-lines");
290
+ selectionLines === null || selectionLines === void 0 ? void 0 : selectionLines.setAttribute("pointer-events", "all");
291
+ }
292
+ }, [stillHoldShift.current, dataElementSelectionGroupRef.current]);
293
+ useEffect(() => {
294
+ const handleKeyDown = (e) => {
295
+ var _a, _b;
296
+ // setPressedKey(e.key);
297
+ const selectionLines = (_a = svgRef.current) === null || _a === void 0 ? void 0 : _a.querySelector("#selection-lines");
298
+ (_b = svgRef.current) === null || _b === void 0 ? void 0 : _b.querySelector("#selection-lines");
299
+ if (e.key === "Shift") {
300
+ stillHoldShift.current = true;
301
+ selectionLines === null || selectionLines === void 0 ? void 0 : selectionLines.setAttribute("pointer-events", "none");
302
+ }
303
+ };
304
+ const handleKeyUp = () => {
305
+ var _a;
306
+ const selectionLines = (_a = svgRef.current) === null || _a === void 0 ? void 0 : _a.querySelector("#selection-lines");
307
+ stillHoldShift.current = false;
308
+ selectionLines === null || selectionLines === void 0 ? void 0 : selectionLines.setAttribute("pointer-events", "all");
309
+ };
310
+ window.addEventListener("keydown", handleKeyDown);
311
+ window.addEventListener("keyup", handleKeyUp);
312
+ return () => {
313
+ window.removeEventListener("keydown", handleKeyDown);
314
+ window.removeEventListener("keyup", handleKeyUp);
315
+ };
316
+ }, [dataElementSelectionGroupRef.current]);
317
+ const handlePointerDown = (e) => {
318
+ var _a, _b, _c, _d, _e, _f, _g, _h;
319
+ const shiftActive = e.shiftKey;
320
+ if (activeTool === "grab") {
321
+ return;
322
+ }
323
+ const svg = svgRef.current;
324
+ if (!e.isPrimary)
325
+ return;
326
+ if (!svg)
327
+ return;
328
+ isDragging.current = false;
329
+ let hasMoved = false;
330
+ releaseGroupRef.current = false;
331
+ const startX = e.clientX;
332
+ const startY = e.clientY;
333
+ const pt = svg.createSVGPoint();
334
+ pt.x = e.clientX;
335
+ pt.y = e.clientY;
336
+ const { x, y } = getSvgCoords(e);
337
+ //CREATE ELEMENT
338
+ const isInitialCreateElemente = toolElement.includes(activeTool) && !isCreateElementRef.current;
339
+ const isInitialCreateBoundingBox = activeTool === "bounding-box";
340
+ const isInitialCreateText = activeTool === "text" && !isCreateElementRef.current;
341
+ if (isInitialCreateElemente) {
342
+ const tables = createTableGhost({
343
+ x,
344
+ y,
345
+ width: 1,
346
+ height: 1,
347
+ fill: "red",
348
+ shape: activeTool,
349
+ });
350
+ // setGhostCreateElement(tables);
351
+ (_a = svgRef.current) === null || _a === void 0 ? void 0 : _a.appendChild(tables);
352
+ isCreateElementRef.current = true;
353
+ }
354
+ else if (isInitialCreateBoundingBox) {
355
+ const tables = createTableGhost({
356
+ x,
357
+ y,
358
+ width: 1,
359
+ height: 1,
360
+ fill: "transparent",
361
+ shape: activeTool,
362
+ });
363
+ (_b = svgRef.current) === null || _b === void 0 ? void 0 : _b.appendChild(tables);
364
+ isCreateElementRef.current = true;
365
+ }
366
+ else if (isInitialCreateText) {
367
+ const tables = createTableGhost({
368
+ x,
369
+ y,
370
+ width: 100 * scale,
371
+ height: 50 * scale,
372
+ fill: "#000000",
373
+ shape: activeTool,
374
+ });
375
+ (_c = svgRef.current) === null || _c === void 0 ? void 0 : _c.appendChild(tables);
376
+ isCreateElementRef.current = true;
377
+ }
378
+ const targetSelection = e.target.closest("g[id='selection-lines']");
379
+ //ROTATE
380
+ const targetRotate = e.target.closest("circle[data-role]");
381
+ if (targetRotate) {
382
+ isRotatingRef.current = true;
383
+ }
384
+ const targetSelectionBox = e.target.closest("g[id='selection-lines']");
385
+ // RESIZE
386
+ const targetGroup = e.target.closest("g[data-id]");
387
+ const targetPointPolygon = e.target.closest("circle[data-point]");
388
+ // TARGET ELEMENT
389
+ let idTargetElement = JSON.parse((targetGroup === null || targetGroup === void 0 ? void 0 : targetGroup.getAttribute("data-id")) || "{}");
390
+ const selectionTarget = (_e = (_d = targetSelection === null || targetSelection === void 0 ? void 0 : targetSelection.dataset) === null || _d === void 0 ? void 0 : _d.selection) === null || _e === void 0 ? void 0 : _e.replace("selection-", "");
391
+ const activeId = selectionTarget !== null && selectionTarget !== void 0 ? selectionTarget : idTargetElement;
392
+ const isInSelectionTarget = !isUndefined(selectionTarget);
393
+ const isInTargetElement = !isPlainObject(idTargetElement);
394
+ const isSingleSelection = isInSelectionTarget && (selectedComponent === null || selectedComponent === void 0 ? void 0 : selectedComponent.id) == activeId;
395
+ const { g } = getAttributeElement(svg, activeId);
396
+ if (targetGroup && shiftActive) {
397
+ const findById = [...componentsState, ...extraComponentsState].find((comp) => comp.id == activeId);
398
+ const currentSelection = (_f = dataElementSelectionGroupRef.current) !== null && _f !== void 0 ? _f : [];
399
+ const alreadySelected = currentSelection.some((comp) => comp.id == activeId);
400
+ let newSelection;
401
+ if (alreadySelected) {
402
+ newSelection = currentSelection.filter((comp) => comp.id != activeId);
403
+ }
404
+ else {
405
+ newSelection = [...currentSelection, findById];
406
+ }
407
+ dataElementSelectionGroupRef.current = newSelection;
408
+ }
409
+ const { x: initialXG, y: initialYG } = getTranslate(g);
410
+ const targetDragPosition = e.target.closest("circle[data-position]");
411
+ const { clientX, clientY } = e;
412
+ const hitPoint = document.elementFromPoint(clientX, clientY);
413
+ // CHECK FOR HIT ON SVG FOR SELECTION BOX
414
+ // MAKE AND UNMAKE SELECTION BOX START ------
415
+ const hadSelectionBox = ((_g = dataElementSelectionGroupRef.current) === null || _g === void 0 ? void 0 : _g.length) > 0 && !isSingleSelection;
416
+ const downInSelectionBox = hadSelectionBox && (hitPoint === null || hitPoint === void 0 ? void 0 : hitPoint.nodeName) !== "svg";
417
+ const downOutSelectionBox = hadSelectionBox && (hitPoint === null || hitPoint === void 0 ? void 0 : hitPoint.nodeName) === "svg";
418
+ const downBeforeHasSelectionBox = !downInSelectionBox &&
419
+ (hitPoint === null || hitPoint === void 0 ? void 0 : hitPoint.nodeName) === "svg" &&
420
+ activeTool === "select";
421
+ const isRotateSelectionBox = targetRotate && hadSelectionBox;
422
+ let currentRotation = 0;
423
+ if (isRotateSelectionBox) {
424
+ currentRotation = rotationSelectionRef.current;
425
+ }
426
+ //move tanpa ada selection single element dan bisa move juga ketika ada selection box
427
+ //JIKA PUNYA SELECTION TAPI DOWN DI ELEMENT LAIN
428
+ if (downInSelectionBox) {
429
+ hadSelectionRef.current = true;
430
+ }
431
+ if (downOutSelectionBox) {
432
+ hadSelectionRef.current = false;
433
+ onMoveSelectionBoxRef.current = false;
434
+ handleUnSelectComponent();
435
+ }
436
+ if (downBeforeHasSelectionBox) {
437
+ // RELEASE SELECT
438
+ releaseGroupRef.current = true;
439
+ // MAKING SELECTION BOX DOWN
440
+ onMakeSelectionRef.current = true;
441
+ onMoveSelectionBoxRef.current = false;
442
+ handleUnSelectComponent();
443
+ const boxSelection = createTableGhost({
444
+ x,
445
+ y,
446
+ width: 1,
447
+ height: 1,
448
+ fill: "transparent",
449
+ shape: nameShapeSelectionBoxGhost,
450
+ id: idSelectionBoxGhost,
451
+ });
452
+ (_h = svgRef.current) === null || _h === void 0 ? void 0 : _h.appendChild(boxSelection);
453
+ }
454
+ // MAKE AND UNMAKE SELECTION BOX END ------
455
+ // RESIZE SELECTION BOX
456
+ const resizeSide = (targetDragPosition === null || targetDragPosition === void 0 ? void 0 : targetDragPosition.dataset.position) || "{}";
457
+ const downAtResizePosition = resizeSide !== "{}";
458
+ const downOutResizePosition = resizeSide === "{}";
459
+ //down in selection box (need check element didalammnya)
460
+ const downOutResizePositionAndInSelectionBox = downOutResizePosition &&
461
+ hadSelectionBox &&
462
+ !downOutSelectionBox &&
463
+ isInSelectionTarget &&
464
+ !isSingleSelection &&
465
+ !isInTargetElement &&
466
+ !isInitialCreateBoundingBox;
467
+ const downAtResizePositionAndHasSelectionBox = downAtResizePosition &&
468
+ hadSelectionBox &&
469
+ !isRotateSelectionBox &&
470
+ !isInitialCreateBoundingBox;
471
+ const isMightResizeElement = !isEmpty(selectedComponent) &&
472
+ downAtResizePosition &&
473
+ downAtResizePosition &&
474
+ !hadSelectionBox &&
475
+ !isInitialCreateBoundingBox;
476
+ const isMightMove = activeId &&
477
+ !targetPointPolygon &&
478
+ isInTargetElement &&
479
+ !isMightResizeElement &&
480
+ !isInitialCreateBoundingBox;
481
+ const isMightMoveOneElementSelection = isSingleSelection && !isMightResizeElement && !isInitialCreateBoundingBox;
482
+ if (downOutResizePositionAndInSelectionBox) {
483
+ onMoveSelectionBoxRef.current = true;
484
+ }
485
+ if (downAtResizePosition) {
486
+ onResizeSelectionRef.current = true;
487
+ }
488
+ const offset = {
489
+ x: x - initialXG,
490
+ y: y - initialYG,
491
+ };
492
+ // create polygon
493
+ const isInitialPolyGon = activeTool === "polygon" && !isCreateElementRef.current;
494
+ if (isInitialPolyGon && (selectedComponent === null || selectedComponent === void 0 ? void 0 : selectedComponent.shape) !== "polygon") {
495
+ const newPolygon = {
496
+ id: `${Date.now()}`,
497
+ shape: "polygon",
498
+ fill: "red",
499
+ points: [{ x, y }],
500
+ rotation: 0,
501
+ };
502
+ polygonElementRef.current = newPolygon;
503
+ // addComponents(newPolygon);
504
+ setSelectedComponent(newPolygon);
505
+ dispatch({
506
+ type: "panel/setSelectedComponent",
507
+ payload: newPolygon,
508
+ });
509
+ dispatch({
510
+ type: "panel/setSelectedGroup",
511
+ payload: null,
512
+ });
513
+ isOnMakePolygonRef.current = true;
514
+ }
515
+ // const selectionLines = svgRef.current?.querySelector(
516
+ // "#selection-lines"
517
+ // ) as SVGGElement;
518
+ // const boxSelection = svgRef.current?.querySelector(
519
+ // "#rect-box-selection"
520
+ // ) as SVGRectElement;
521
+ // const allElementInSelection = svgRef.current?.querySelectorAll(
522
+ // "#ghost-element-has-selection"
523
+ // );
524
+ const pointerHandleMove = (ev) => {
525
+ var _a;
526
+ //SVG POINTER
527
+ const pt = svg.createSVGPoint();
528
+ pt.x = ev.clientX;
529
+ pt.y = ev.clientY;
530
+ const pos = pt.matrixTransform(svg.getScreenCTM().inverse());
531
+ //RESIZE POLYGON
532
+ const onResizePolygon = (pos) => {
533
+ var _a, _b;
534
+ const dx = pos.x - x;
535
+ const dy = pos.y - y;
536
+ const { inner, element } = getAttributeElement(svg, activeId);
537
+ const angleDeg = getRotation(inner.transform.baseVal); // 0–360
538
+ const angleRad = (angleDeg * Math.PI) / 180;
539
+ const cos = Math.cos(-angleRad);
540
+ const sin = Math.sin(-angleRad);
541
+ const localDx = dx * cos - dy * sin;
542
+ const localDy = dx * sin + dy * cos;
543
+ const index = Number(targetPointPolygon.getAttribute("id"));
544
+ const points = element === null || element === void 0 ? void 0 : element.getAttribute("points");
545
+ let arrayPoints = pointsStringToArray(points);
546
+ const pointsStart = (selectedComponent === null || selectedComponent === void 0 ? void 0 : selectedComponent.points) || [];
547
+ arrayPoints[index] = {
548
+ x: ((_a = pointsStart[index]) === null || _a === void 0 ? void 0 : _a.x) + localDx,
549
+ y: ((_b = pointsStart[index]) === null || _b === void 0 ? void 0 : _b.y) + localDy,
550
+ };
551
+ const newPointsAttr = arrayToSvgPointsAttr(arrayPoints);
552
+ element === null || element === void 0 ? void 0 : element.setAttribute("points", newPointsAttr);
553
+ };
554
+ if (targetPointPolygon && targetGroup) {
555
+ onResizePolygon(pos);
556
+ }
557
+ //ROTATE SELECTION BOX
558
+ const onRotateSelectionBox = (pos) => {
559
+ var _a, _b, _c, _d;
560
+ const selectionLines = (_a = svgRef.current) === null || _a === void 0 ? void 0 : _a.querySelector("#selection-lines");
561
+ const circleHelper = svg.querySelector("#circle-help");
562
+ const lineHelper = svg.querySelector("#line-help");
563
+ const inner = (_b = selectionLines === null || selectionLines === void 0 ? void 0 : selectionLines.children) === null || _b === void 0 ? void 0 : _b[0];
564
+ const x0 = (selectedLines === null || selectedLines === void 0 ? void 0 : selectedLines.x) || 0;
565
+ const y0 = (selectedLines === null || selectedLines === void 0 ? void 0 : selectedLines.y) || 0;
566
+ const w0 = (selectedLines === null || selectedLines === void 0 ? void 0 : selectedLines.width) || 0;
567
+ const h0 = (selectedLines === null || selectedLines === void 0 ? void 0 : selectedLines.height) || 0;
568
+ const bbox = getGlobalBBox(svg, inner);
569
+ const cx = bbox.x + bbox.width / 2;
570
+ const cy = bbox.y + bbox.height / 2;
571
+ //start center
572
+ const dx0 = x - cx;
573
+ const dy0 = y - cy;
574
+ // ✅ ANGLE DARI CENTER
575
+ const dx = pos.x - cx;
576
+ const dy = pos.y - cy;
577
+ //start angle
578
+ const startAngle = Math.atan2(dy0, dx0);
579
+ const currentAngle = Math.atan2(dy, dx);
580
+ const newAngle = normalizeAngle(0 + ((currentAngle - startAngle) * 180) / Math.PI);
581
+ const angle = (0 * Math.PI) / 180;
582
+ // helper line
583
+ const centerX = w0 / 2;
584
+ const centerY = h0 / 2;
585
+ const cos = Math.cos(angle);
586
+ const sin = Math.sin(angle);
587
+ // GLOBAL → LOCAL
588
+ const localDx = dx * cos + dy * sin;
589
+ const localDy = -dx * sin + dy * cos;
590
+ // helper (LOCAL SPACE)
591
+ const x2 = centerX + localDx;
592
+ const y2 = centerY + localDy;
593
+ lineHelper === null || lineHelper === void 0 ? void 0 : lineHelper.setAttribute("x1", `${centerX}`);
594
+ lineHelper === null || lineHelper === void 0 ? void 0 : lineHelper.setAttribute("y1", `${centerY}`);
595
+ lineHelper === null || lineHelper === void 0 ? void 0 : lineHelper.setAttribute("x2", `${x2}`);
596
+ lineHelper === null || lineHelper === void 0 ? void 0 : lineHelper.setAttribute("y2", `${y2}`);
597
+ circleHelper === null || circleHelper === void 0 ? void 0 : circleHelper.setAttribute("cx", `${x2}`);
598
+ circleHelper === null || circleHelper === void 0 ? void 0 : circleHelper.setAttribute("cy", `${y2}`);
599
+ (_c = selectionLines === null || selectionLines === void 0 ? void 0 : selectionLines.children) === null || _c === void 0 ? void 0 : _c[0].setAttribute("transform", `rotate(${newAngle}, 0, 0)`);
600
+ const { tx, ty } = stabilizeRotation(x0, y0, w0, h0, 0, newAngle);
601
+ selectionLines === null || selectionLines === void 0 ? void 0 : selectionLines.setAttribute("transform", `translate(${tx}, ${ty}) `);
602
+ // ROTATE ALL ELEMENT IN SELECTION
603
+ const allID = (_d = dataElementSelectionGroupRef.current) === null || _d === void 0 ? void 0 : _d.map((el) => String(el.id));
604
+ const deltaAngle = newAngle - 0;
605
+ const rad = (deltaAngle * Math.PI) / 180;
606
+ const cosA = Math.cos(rad);
607
+ const sinA = Math.sin(rad);
608
+ const allGroupsAtrribute = getAttributeElements(svg, allID);
609
+ allGroupsAtrribute.forEach(({ g, inner }, i) => {
610
+ var _a;
611
+ const el = (_a = dataElementSelectionGroupRef.current) === null || _a === void 0 ? void 0 : _a[i];
612
+ if (!el)
613
+ return;
614
+ const rotateBefore = normalizeAngle(el.rotation);
615
+ const ex = el.x;
616
+ const ey = el.y;
617
+ // 🔑 ROTATE AROUND SELECTION CENTER
618
+ const dx = ex - cx;
619
+ const dy = ey - cy;
620
+ const nx = cx + dx * cosA - dy * sinA;
621
+ const ny = cy + dx * sinA + dy * cosA;
622
+ g.setAttribute("data-is-rotating", "1");
623
+ inner.setAttribute("transform", `rotate(${normalizeAngle(rotateBefore + deltaAngle)}, 0, 0)`);
624
+ g.setAttribute("transform", `translate(${nx}, ${ny})`);
625
+ });
626
+ };
627
+ if (isRotateSelectionBox) {
628
+ onRotateSelectionBox(pos);
629
+ }
630
+ //RESIZE SELECTION BOX
631
+ const onResizeSelectionBox = () => {
632
+ var _a, _b;
633
+ const dx = pos.x - x;
634
+ const dy = pos.y - y;
635
+ isResizeSelectionRef.current = true;
636
+ const oldSel = {
637
+ x: selectedLines === null || selectedLines === void 0 ? void 0 : selectedLines.x,
638
+ y: selectedLines === null || selectedLines === void 0 ? void 0 : selectedLines.y,
639
+ width: selectedLines === null || selectedLines === void 0 ? void 0 : selectedLines.width,
640
+ height: selectedLines === null || selectedLines === void 0 ? void 0 : selectedLines.height,
641
+ };
642
+ const allID = (_a = dataElementSelectionGroupRef.current) === null || _a === void 0 ? void 0 : _a.map((el) => String(el.id));
643
+ const allDataRealSelection = (_b = [
644
+ ...componentsState,
645
+ ...(lockBackground ? [] : extraComponentsState),
646
+ ]) === null || _b === void 0 ? void 0 : _b.filter((el) => allID.includes(String(el.id)));
647
+ const allGroupsAttribute = getAttributeElements(svg, allID);
648
+ const resultSelection = resizeBox({
649
+ box: oldSel,
650
+ dx,
651
+ dy,
652
+ rotate: 0,
653
+ handle: resizeSide,
654
+ });
655
+ updateSelectionBox(svg, resultSelection);
656
+ const scaleX = resultSelection.width / oldSel.width;
657
+ const scaleY = resultSelection.height / oldSel.height;
658
+ allGroupsAttribute.forEach(({ g, element, seatGroup, seats }, i) => {
659
+ var _a, _b;
660
+ const activeId = JSON.parse(g === null || g === void 0 ? void 0 : g.getAttribute("data-id"));
661
+ const elementOld = allDataRealSelection === null || allDataRealSelection === void 0 ? void 0 : allDataRealSelection.find((el) => el.id == activeId);
662
+ const newWidth = (elementOld === null || elementOld === void 0 ? void 0 : elementOld.width) * scaleX;
663
+ const newHeight = (elementOld === null || elementOld === void 0 ? void 0 : elementOld.height) * scaleY;
664
+ // Jarak relatif element dari pojok kiri atas selection (sebelum resize)
665
+ const relativeX = (elementOld === null || elementOld === void 0 ? void 0 : elementOld.x) - oldSel.x;
666
+ const relativeY = (elementOld === null || elementOld === void 0 ? void 0 : elementOld.y) - oldSel.y;
667
+ // Jarak relatif baru (sesudah resize)
668
+ const newX = resultSelection.x + relativeX * scaleX;
669
+ const newY = resultSelection.y + relativeY * scaleY;
670
+ const relativePoinst = ((_a = elementOld === null || elementOld === void 0 ? void 0 : elementOld.points) === null || _a === void 0 ? void 0 : _a.length) !== 0 &&
671
+ ((_b = elementOld === null || elementOld === void 0 ? void 0 : elementOld.points) === null || _b === void 0 ? void 0 : _b.map((point) => {
672
+ const { x, y } = point;
673
+ const relativeX = x - oldSel.x;
674
+ const relativeY = y - oldSel.y;
675
+ return {
676
+ x: resultSelection.x + relativeX * scaleX,
677
+ y: resultSelection.y + relativeY * scaleY,
678
+ };
679
+ }));
680
+ const newElement = {
681
+ x: newX,
682
+ y: newY,
683
+ width: newWidth,
684
+ height: newHeight,
685
+ points: relativePoinst,
686
+ };
687
+ if (seats.length !== 0) {
688
+ const seatsPositions = elementOld === null || elementOld === void 0 ? void 0 : elementOld.seatPositions;
689
+ const openSpace = elementOld === null || elementOld === void 0 ? void 0 : elementOld.openSpace;
690
+ if ((elementOld === null || elementOld === void 0 ? void 0 : elementOld.shape) === "table-seat-circle") {
691
+ resizeSeatCircle({
692
+ seatCount: elementOld === null || elementOld === void 0 ? void 0 : elementOld.seatCount,
693
+ r: 10,
694
+ openSpace,
695
+ newElement,
696
+ seats,
697
+ seatGroup,
698
+ });
699
+ }
700
+ else if ((elementOld === null || elementOld === void 0 ? void 0 : elementOld.shape) === "table-seat-square") {
701
+ resizeSeatSquare({
702
+ seatsPositions,
703
+ r: 10,
704
+ openSpace,
705
+ newElement,
706
+ seats,
707
+ seatGroup,
708
+ });
709
+ }
710
+ }
711
+ applyResizeToSvgElement(element, g, newElement);
712
+ });
713
+ };
714
+ if (downAtResizePositionAndHasSelectionBox)
715
+ onResizeSelectionBox();
716
+ //SELECTION BOX MOVE
717
+ const onMoveSelectionBox = () => {
718
+ var _a, _b;
719
+ const allID = (_a = dataElementSelectionGroupRef.current) === null || _a === void 0 ? void 0 : _a.map((el) => el.id);
720
+ const allDataRealSelection = (_b = [
721
+ ...componentsState,
722
+ ...(lockBackground ? [] : extraComponentsState),
723
+ ]) === null || _b === void 0 ? void 0 : _b.filter((el) => allID.includes(el.id));
724
+ allDataRealSelection.forEach((item) => {
725
+ const { g } = getAttributeElement(svg, String(item.id));
726
+ const newX = pos.x - x;
727
+ const newY = pos.y - y;
728
+ g.setAttribute("transform", `translate(${item.x + newX}, ${item.y + newY})`);
729
+ });
730
+ const newX = pos.x - x;
731
+ const newY = pos.y - y;
732
+ const selection = {
733
+ x: (selectedLines === null || selectedLines === void 0 ? void 0 : selectedLines.x) + newX,
734
+ y: (selectedLines === null || selectedLines === void 0 ? void 0 : selectedLines.y) + newY,
735
+ width: selectedLines === null || selectedLines === void 0 ? void 0 : selectedLines.width,
736
+ height: selectedLines === null || selectedLines === void 0 ? void 0 : selectedLines.height,
737
+ };
738
+ updateSelectionBox(svg, selection);
739
+ updateSelectionGuides(svg, selection, {
740
+ vLeft: "v-left",
741
+ vCenter: "v-center",
742
+ vRight: "v-right",
743
+ hTop: "h-top",
744
+ hCenter: "h-center",
745
+ hBottom: "h-bottom",
746
+ });
747
+ };
748
+ if (downOutResizePositionAndInSelectionBox && !isRotateSelectionBox)
749
+ onMoveSelectionBox();
750
+ // MAKING SELECTION BOX MOVE
751
+ const onMakeSelectionBox = (ev) => {
752
+ var _a, _b;
753
+ let selectionBoxGhost = svg.querySelector("#selection-box-ghost");
754
+ const selX = Math.min(pos.x, x);
755
+ const selY = Math.min(pos.y, y);
756
+ const selW = Math.abs(pos.x - x);
757
+ const selH = Math.abs(pos.y - y);
758
+ selectionBoxGhost === null || selectionBoxGhost === void 0 ? void 0 : selectionBoxGhost.setAttribute("x", String(selX));
759
+ selectionBoxGhost === null || selectionBoxGhost === void 0 ? void 0 : selectionBoxGhost.setAttribute("y", String(selY));
760
+ selectionBoxGhost === null || selectionBoxGhost === void 0 ? void 0 : selectionBoxGhost.setAttribute("width", String(selW));
761
+ selectionBoxGhost === null || selectionBoxGhost === void 0 ? void 0 : selectionBoxGhost.setAttribute("height", String(selH));
762
+ // FIND ALL COMPONENTS INSIDE SELECTION BOX
763
+ const allGroups = (_a = svgRef.current) === null || _a === void 0 ? void 0 : _a.querySelectorAll("g[data-id]");
764
+ const selLeft = selX;
765
+ const selTop = selY;
766
+ const selectedIds = [...allGroups]
767
+ .map((g) => JSON === null || JSON === void 0 ? void 0 : JSON.parse((g === null || g === void 0 ? void 0 : g.getAttribute("data-id")) || "{}"))
768
+ .filter((d) => {
769
+ const { element } = getAttributeElement(svg, d);
770
+ const box = getGlobalBBox(svg, element);
771
+ return ((box === null || box === void 0 ? void 0 : box.x) < selLeft + selW &&
772
+ (box === null || box === void 0 ? void 0 : box.x) + box.width > selLeft &&
773
+ (box === null || box === void 0 ? void 0 : box.y) < selTop + selH &&
774
+ (box === null || box === void 0 ? void 0 : box.y) + box.height > selTop);
775
+ })
776
+ .map((d) => `${d}`);
777
+ if (selectedIds.length === 0)
778
+ return;
779
+ const selectedComps = (_b = [
780
+ ...componentsState,
781
+ ...(lockBackground ? [] : extraComponentsState),
782
+ ]
783
+ .filter((c) => selectedIds.map(String).includes(String(c.id)))) === null || _b === void 0 ? void 0 : _b.map((item) => {
784
+ const { g } = getAttributeElement(svg, String(item.id));
785
+ // const { x, y } = getTranslate(g);
786
+ const box = getGlobalBBox(svg, g);
787
+ return Object.assign(Object.assign({}, item), {
788
+ // x: box.x,
789
+ // y: box.y,
790
+ width: box.width, height: box.height });
791
+ });
792
+ dataElementSelectionGroupRef.current = selectedComps;
793
+ };
794
+ if (downBeforeHasSelectionBox)
795
+ onMakeSelectionBox(ev);
796
+ const onCreateBoudingBox = () => {
797
+ let selectionBoxGhost = svg.querySelector("#selection-box-ghost");
798
+ const selX = Math.min(pos.x, x);
799
+ const selY = Math.min(pos.y, y);
800
+ const selW = Math.abs(pos.x - x);
801
+ const selH = Math.abs(pos.y - y);
802
+ selectionBoxGhost === null || selectionBoxGhost === void 0 ? void 0 : selectionBoxGhost.setAttribute("x", String(selX));
803
+ selectionBoxGhost === null || selectionBoxGhost === void 0 ? void 0 : selectionBoxGhost.setAttribute("y", String(selY));
804
+ selectionBoxGhost === null || selectionBoxGhost === void 0 ? void 0 : selectionBoxGhost.setAttribute("width", String(selW));
805
+ selectionBoxGhost === null || selectionBoxGhost === void 0 ? void 0 : selectionBoxGhost.setAttribute("height", String(selH));
806
+ };
807
+ if (isInitialCreateBoundingBox) {
808
+ onCreateBoudingBox();
809
+ }
810
+ // CREATE GHOST ELEMENT ---
811
+ const onDrawNewElements = (toolElement.includes(activeTool) || activeTool === "bounding-box") &&
812
+ isCreateElementRef.current;
813
+ if (onDrawNewElements) {
814
+ const ghost = (_a = svgRef.current) === null || _a === void 0 ? void 0 : _a.querySelector("#ghost-element-create");
815
+ if (!ghost)
816
+ return;
817
+ const data = JSON.parse(ghost.getAttribute("data-table") || "{}");
818
+ const { x: ox, y: oy } = data;
819
+ // ---- HITUNG RECT BARU ----
820
+ const x1 = Math.min(ox, pos.x);
821
+ const y1 = Math.min(oy, pos.y);
822
+ const x2 = Math.max(ox, pos.x);
823
+ const y2 = Math.max(oy, pos.y);
824
+ const newX = x1;
825
+ const newY = y1;
826
+ const newW = x2 - x1;
827
+ const newH = y2 - y1;
828
+ // ---- RECT ----
829
+ if (["square", "table-seat-circle", "bounding-box"].includes(activeTool)) {
830
+ ghost.setAttribute("x", String(newX));
831
+ ghost.setAttribute("y", String(newY));
832
+ ghost.setAttribute("width", String(newW));
833
+ ghost.setAttribute("height", String(newH));
834
+ }
835
+ // ---- CIRCLE (ambil dari bounding box) ----
836
+ if (activeTool === "circle") {
837
+ const cx = newX + newW / 2;
838
+ const cy = newY + newH / 2;
839
+ const r = Math.min(newW, newH) / 2;
840
+ ghost.setAttribute("cx", String(cx));
841
+ ghost.setAttribute("cy", String(cy));
842
+ ghost.setAttribute("r", String(r));
843
+ }
844
+ // ---- UPDATE DATA TABLE ----
845
+ ghost.setAttribute("data-table", JSON.stringify(Object.assign(Object.assign({}, data), { x: newX, y: newY, width: newW, height: newH })));
846
+ }
847
+ // RESIZE GHOST SINGLE ELEMENT ---
848
+ const onResize = () => {
849
+ var _a, _b;
850
+ const activeId = selectedComponent === null || selectedComponent === void 0 ? void 0 : selectedComponent.id;
851
+ const svg = svgRef.current;
852
+ const { g, element, seats, seatGroup } = getAttributeElement(svg, activeId);
853
+ const elementSelect = {
854
+ x: selectedComponent === null || selectedComponent === void 0 ? void 0 : selectedComponent.x,
855
+ y: selectedComponent === null || selectedComponent === void 0 ? void 0 : selectedComponent.y,
856
+ width: selectedComponent === null || selectedComponent === void 0 ? void 0 : selectedComponent.width,
857
+ height: selectedComponent === null || selectedComponent === void 0 ? void 0 : selectedComponent.height,
858
+ seatPositions: selectedComponent === null || selectedComponent === void 0 ? void 0 : selectedComponent.seatPositions,
859
+ seatCount: selectedComponent === null || selectedComponent === void 0 ? void 0 : selectedComponent.seatCount,
860
+ openSpace: selectedComponent === null || selectedComponent === void 0 ? void 0 : selectedComponent.openSpace,
861
+ points: selectedComponent === null || selectedComponent === void 0 ? void 0 : selectedComponent.points,
862
+ };
863
+ const oldSel = {
864
+ x: selectedLines === null || selectedLines === void 0 ? void 0 : selectedLines.x,
865
+ y: selectedLines === null || selectedLines === void 0 ? void 0 : selectedLines.y,
866
+ width: selectedLines === null || selectedLines === void 0 ? void 0 : selectedLines.width,
867
+ height: selectedLines === null || selectedLines === void 0 ? void 0 : selectedLines.height,
868
+ };
869
+ const dx = pos.x - x;
870
+ const dy = pos.y - y;
871
+ const resultSelection = resizeBox({
872
+ box: oldSel,
873
+ dx,
874
+ dy,
875
+ rotate: 0,
876
+ handle: resizeSide,
877
+ });
878
+ updateSelectionGuides(svg, resultSelection, {
879
+ vLeft: "v-left",
880
+ vCenter: "v-center",
881
+ vRight: "v-right",
882
+ hTop: "h-top",
883
+ hCenter: "h-center",
884
+ hBottom: "h-bottom",
885
+ });
886
+ updateSelectionBox(svg, resultSelection, activeId);
887
+ const scaleX = resultSelection.width / oldSel.width;
888
+ const scaleY = resultSelection.height / oldSel.height;
889
+ const newWidth = elementSelect.width * scaleX;
890
+ const newHeight = elementSelect.height * scaleY;
891
+ // Jarak relatif element dari pojok kiri atas selection (sebelum resize)
892
+ const relativeX = elementSelect.x - oldSel.x;
893
+ const relativeY = elementSelect.y - oldSel.y;
894
+ // Jarak relatif baru (sesudah resize)
895
+ const newX = resultSelection.x + relativeX * scaleX;
896
+ const newY = resultSelection.y + relativeY * scaleY;
897
+ const relativePoinst = ((_a = elementSelect === null || elementSelect === void 0 ? void 0 : elementSelect.points) === null || _a === void 0 ? void 0 : _a.length) !== 0 &&
898
+ ((_b = elementSelect === null || elementSelect === void 0 ? void 0 : elementSelect.points) === null || _b === void 0 ? void 0 : _b.map((point) => {
899
+ const { x, y } = point;
900
+ const relativeX = x - oldSel.x;
901
+ const relativeY = y - oldSel.y;
902
+ return {
903
+ x: resultSelection.x + relativeX * scaleX,
904
+ y: resultSelection.y + relativeY * scaleY,
905
+ };
906
+ }));
907
+ const newElement = {
908
+ x: newX,
909
+ y: newY,
910
+ width: newWidth,
911
+ height: newHeight,
912
+ points: relativePoinst,
913
+ };
914
+ if (seats.length !== 0) {
915
+ if ((selectedComponent === null || selectedComponent === void 0 ? void 0 : selectedComponent.shape) === "table-seat-circle") {
916
+ resizeSeatCircle({
917
+ seatCount: elementSelect === null || elementSelect === void 0 ? void 0 : elementSelect.seatCount,
918
+ r: 10,
919
+ openSpace: elementSelect === null || elementSelect === void 0 ? void 0 : elementSelect.openSpace,
920
+ newElement,
921
+ seats,
922
+ seatGroup,
923
+ });
924
+ }
925
+ else if ((selectedComponent === null || selectedComponent === void 0 ? void 0 : selectedComponent.shape) === "table-seat-square") {
926
+ resizeSeatSquare({
927
+ seatsPositions: elementSelect.seatPositions,
928
+ r: 10,
929
+ newElement,
930
+ openSpace: elementSelect.openSpace,
931
+ seats,
932
+ seatGroup,
933
+ });
934
+ }
935
+ else if ((selectedComponent === null || selectedComponent === void 0 ? void 0 : selectedComponent.shape) === "table-seat-half-square") {
936
+ resizeSeatSide({
937
+ seatsPositions: elementSelect.seatPositions,
938
+ r: 10,
939
+ newElement,
940
+ openSpace: elementSelect.openSpace,
941
+ seats,
942
+ seatGroup,
943
+ });
944
+ }
945
+ else if ((selectedComponent === null || selectedComponent === void 0 ? void 0 : selectedComponent.shape) === "table-seat-rect-square") {
946
+ resizeSeatRectSquare({
947
+ seatsPositions: elementSelect.seatPositions,
948
+ r: 10,
949
+ newElement,
950
+ openSpace: elementSelect.openSpace,
951
+ seats,
952
+ seatGroup,
953
+ });
954
+ }
955
+ else if ((selectedComponent === null || selectedComponent === void 0 ? void 0 : selectedComponent.shape) === "table-seat-rect-circle") {
956
+ resizeSeatRectCircle({
957
+ seatsPositions: elementSelect.seatPositions,
958
+ r: 10,
959
+ newElement,
960
+ openSpace: elementSelect.openSpace,
961
+ seats,
962
+ seatGroup,
963
+ });
964
+ }
965
+ }
966
+ applyResizeToSvgElement(element, g, newElement);
967
+ isResizeRef.current = true;
968
+ };
969
+ // const hasSelectedOneElement =
970
+ // !isEmpty(selectedComponent) &&
971
+ // onResizeSelectionRef.current &&
972
+ // downAtResizePosition;
973
+ if (!isEmpty(selectedComponent) && isMightResizeElement)
974
+ onResize();
975
+ //ROTATE
976
+ const onRotate = () => {
977
+ const svg = svgRef.current;
978
+ if (!svg || !selectedComponent)
979
+ return;
980
+ const lineHelper = svg.querySelector("#line-help");
981
+ const circleHelper = svg.querySelector("#circle-help");
982
+ const { inner, g } = getAttributeElement(svg, String(selectedComponent === null || selectedComponent === void 0 ? void 0 : selectedComponent.id));
983
+ if (!inner || !g)
984
+ return;
985
+ // mouse → SVG space
986
+ // 🔴 GLOBAL BBOX (INI KUNCI)
987
+ const bbox = getGlobalBBox(svg, inner);
988
+ const boxSelection = getGlobalBBox(svg, g);
989
+ if (!bbox)
990
+ return;
991
+ const cx = bbox.x + bbox.width / 2;
992
+ const cy = bbox.y + bbox.height / 2;
993
+ // vector awal & sekarang (GLOBAL)
994
+ const dx0 = x - cx;
995
+ const dy0 = y - cy;
996
+ const dx = pos.x - cx;
997
+ const dy = pos.y - cy;
998
+ const startAngle = Math.atan2(dy0, dx0);
999
+ const currentAngle = Math.atan2(dy, dx);
1000
+ const newAngle = (selectedComponent === null || selectedComponent === void 0 ? void 0 : selectedComponent.rotation) +
1001
+ ((currentAngle - startAngle) * 180) / Math.PI;
1002
+ // helper line
1003
+ const centerX = selectedLines.width / 2;
1004
+ const centerY = selectedLines.height / 2;
1005
+ const angle = (0 * Math.PI) / 180;
1006
+ const cos = Math.cos(angle);
1007
+ const sin = Math.sin(angle);
1008
+ // GLOBAL → LOCAL
1009
+ const localDx = dx * cos + dy * sin;
1010
+ const localDy = -dx * sin + dy * cos;
1011
+ // helper (LOCAL SPACE)
1012
+ const x2 = centerX + localDx;
1013
+ const y2 = centerY + localDy;
1014
+ lineHelper === null || lineHelper === void 0 ? void 0 : lineHelper.setAttribute("x1", `${centerX}`);
1015
+ lineHelper === null || lineHelper === void 0 ? void 0 : lineHelper.setAttribute("y1", `${centerY}`);
1016
+ lineHelper === null || lineHelper === void 0 ? void 0 : lineHelper.setAttribute("x2", `${x2}`);
1017
+ lineHelper === null || lineHelper === void 0 ? void 0 : lineHelper.setAttribute("y2", `${y2}`);
1018
+ circleHelper === null || circleHelper === void 0 ? void 0 : circleHelper.setAttribute("cx", `${x2}`);
1019
+ circleHelper === null || circleHelper === void 0 ? void 0 : circleHelper.setAttribute("cy", `${y2}`);
1020
+ // rotate di local space
1021
+ inner.setAttribute("transform", `rotate(${newAngle}, 0, 0)`);
1022
+ // stabilize translate
1023
+ const { tx, ty } = selectedComponent.shape === "polygon"
1024
+ ? stabilizeTranslateOnRotate({
1025
+ points: selectedComponentProps === null || selectedComponentProps === void 0 ? void 0 : selectedComponentProps.points,
1026
+ oldAngle: selectedComponent.rotation,
1027
+ newAngle,
1028
+ tx: selectedComponent.x,
1029
+ ty: selectedComponent.y,
1030
+ })
1031
+ : stabilizeRotation(selectedComponent.x, selectedComponent.y, selectedComponent.width, selectedComponent.height, selectedComponent.rotation, newAngle);
1032
+ g.setAttribute("transform", `translate(${tx}, ${ty})`);
1033
+ updateSelectionGuides(svg, boxSelection, {
1034
+ vLeft: "v-left",
1035
+ vCenter: "v-center",
1036
+ vRight: "v-right",
1037
+ hTop: "h-top",
1038
+ hCenter: "h-center",
1039
+ hBottom: "h-bottom",
1040
+ });
1041
+ ghostRotateElement.current = newAngle;
1042
+ updateSelectionBox(svg, boxSelection, selectedComponent === null || selectedComponent === void 0 ? void 0 : selectedComponent.id, true);
1043
+ };
1044
+ if (targetRotate && !isRotateSelectionBox)
1045
+ onRotate();
1046
+ const onMove = (ev) => {
1047
+ // const selectionLines = svg.querySelector("#selection-lines");
1048
+ const dx = ev.clientX - startX;
1049
+ const dy = ev.clientY - startY;
1050
+ const distance = Math.sqrt(dx * dx + dy * dy);
1051
+ // onPanning(ev);
1052
+ if (!hasMoved && distance > 0) {
1053
+ // only move ghost if the mouse has moved more than 5 pixels
1054
+ hasMoved = true;
1055
+ }
1056
+ const newX = pos.x - offset.x;
1057
+ const newY = pos.y - offset.y;
1058
+ // let activeId = JSON.parse(targetGroup?.getAttribute("data-id") || "{}");
1059
+ const isMatchWithSelection = activeId === (selectedComponent === null || selectedComponent === void 0 ? void 0 : selectedComponent.id);
1060
+ const { g } = getAttributeElement(svg, activeId);
1061
+ const boxSelection = getGlobalBBox(svg, g);
1062
+ g === null || g === void 0 ? void 0 : g.setAttribute("transform", `translate(${newX}, ${newY})`);
1063
+ updateSelectionGuides(svg, boxSelection, {
1064
+ vLeft: "v-left",
1065
+ vCenter: "v-center",
1066
+ vRight: "v-right",
1067
+ hTop: "h-top",
1068
+ hCenter: "h-center",
1069
+ hBottom: "h-bottom",
1070
+ });
1071
+ if (isMatchWithSelection) {
1072
+ updateSelectionBox(svg, boxSelection, activeId);
1073
+ }
1074
+ };
1075
+ const moveSingleElement = (isMightMove &&
1076
+ !(!isEmpty(selectedComponent) && !isMightResizeElement) &&
1077
+ !targetRotate) ||
1078
+ (isMightMoveOneElementSelection && !isMightResizeElement) ||
1079
+ (isMightMove && !isEmpty(selectedComponent) && !isMightResizeElement);
1080
+ if (moveSingleElement) {
1081
+ onMove(ev);
1082
+ }
1083
+ };
1084
+ const pointerHandleUp = (e) => {
1085
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s;
1086
+ updateSelectionGuides(svg, {
1087
+ x: 0,
1088
+ y: 0,
1089
+ width: 0,
1090
+ height: 0,
1091
+ }, {
1092
+ vLeft: "v-left",
1093
+ vCenter: "v-center",
1094
+ vRight: "v-right",
1095
+ hTop: "h-top",
1096
+ hCenter: "h-center",
1097
+ hBottom: "h-bottom",
1098
+ });
1099
+ //POLYGON RESIZE
1100
+ if (targetSelection) {
1101
+ //show
1102
+ dispatch({ type: "panel/setShow", payload: true });
1103
+ }
1104
+ if (targetPointPolygon && targetGroup) {
1105
+ const { element } = getAttributeElement(svg, targetGroup.dataset.id);
1106
+ const points = element === null || element === void 0 ? void 0 : element.getAttribute("points");
1107
+ const pointsArray = pointsStringToArray(points);
1108
+ const findById = [...componentsState, ...extraComponentsState].find((c) => c.id == targetGroup.dataset.id);
1109
+ const newDataComponent = Object.assign(Object.assign({}, findById), { points: pointsArray });
1110
+ updateComponentAttribute(newDataComponent);
1111
+ setSelectedComponent(newDataComponent);
1112
+ dispatch({
1113
+ type: "panel/setSelectedComponent",
1114
+ payload: newDataComponent,
1115
+ });
1116
+ dispatch({
1117
+ type: "panel/setSelectedGroup",
1118
+ payload: null,
1119
+ });
1120
+ }
1121
+ //POLYGON
1122
+ const isInitialPolyGon = activeTool === "polygon" && (selectedComponent === null || selectedComponent === void 0 ? void 0 : selectedComponent.shape) === "polygon";
1123
+ if (isInitialPolyGon) {
1124
+ const closing = isClosingPolygon(x, y, selectedComponent === null || selectedComponent === void 0 ? void 0 : selectedComponent.points);
1125
+ const newCoord = closing
1126
+ ? {
1127
+ x: (_a = selectedComponent === null || selectedComponent === void 0 ? void 0 : selectedComponent.points[0]) === null || _a === void 0 ? void 0 : _a.x,
1128
+ y: (_b = selectedComponent === null || selectedComponent === void 0 ? void 0 : selectedComponent.points[0]) === null || _b === void 0 ? void 0 : _b.y,
1129
+ }
1130
+ : { x, y };
1131
+ const newPoints = Object.assign(Object.assign({}, selectedComponent), { points: [...selectedComponent === null || selectedComponent === void 0 ? void 0 : selectedComponent.points, newCoord] });
1132
+ (_c = svg.querySelector("#polyline-helper")) === null || _c === void 0 ? void 0 : _c.setAttribute("opacity", "1");
1133
+ if (closing && ((_d = selectedComponent === null || selectedComponent === void 0 ? void 0 : selectedComponent.points) === null || _d === void 0 ? void 0 : _d.length) > 2) {
1134
+ const { g, inner } = getAttributeElement(svg, String(selectedComponent === null || selectedComponent === void 0 ? void 0 : selectedComponent.id));
1135
+ const { height, width } = getGlobalBBox(svg, inner);
1136
+ isOnMakePolygonRef.current = false;
1137
+ setSelectedComponent(null);
1138
+ dispatch({
1139
+ type: "panel/setSelectedComponent",
1140
+ payload: null,
1141
+ });
1142
+ polygonElementRef.current = [];
1143
+ addComponents(Object.assign(Object.assign({}, newPoints), { x: 0, y: 0, width, height }));
1144
+ (_e = svg.querySelector("#selection-box-ghost")) === null || _e === void 0 ? void 0 : _e.remove();
1145
+ const polyline = svg.querySelector("#polyline-helper");
1146
+ (_f = svg.querySelector("#polyline-helper")) === null || _f === void 0 ? void 0 : _f.setAttribute("opacity", "0");
1147
+ }
1148
+ else {
1149
+ setSelectedComponent(newPoints);
1150
+ dispatch({
1151
+ type: "panel/setSelectedComponent",
1152
+ payload: newPoints,
1153
+ });
1154
+ dispatch({
1155
+ type: "panel/setSelectedGroup",
1156
+ payload: null,
1157
+ });
1158
+ polygonElementRef.current = newPoints;
1159
+ }
1160
+ }
1161
+ // ROTATE
1162
+ if (targetRotate && !isRotateSelectionBox) {
1163
+ const activeId = selectedComponent === null || selectedComponent === void 0 ? void 0 : selectedComponent.id;
1164
+ const { g } = getAttributeElement(svg, String(activeId));
1165
+ const boxLines = getGlobalBBox(svg, g);
1166
+ const findById = [...componentsState, ...extraComponentsState].find((c) => c.id == activeId);
1167
+ const { x, y } = getTranslate(g);
1168
+ const newDataComponent = Object.assign(Object.assign({}, findById), { x,
1169
+ y, rotation: ghostRotateElement.current });
1170
+ const boxSelection = Object.assign(Object.assign(Object.assign({ shape: "selection-box", id: `${Date.now()}` }, findById), boxLines), { rotation: 0 });
1171
+ if (boxLines)
1172
+ setSelectedLines(boxSelection);
1173
+ updateComponentAttribute(newDataComponent);
1174
+ setSelectedComponent(newDataComponent);
1175
+ dispatch({
1176
+ type: "panel/setSelectedComponent",
1177
+ payload: newDataComponent,
1178
+ });
1179
+ dispatch({
1180
+ type: "panel/setSelectedGroup",
1181
+ payload: null,
1182
+ });
1183
+ //LOGIC FOR SET SHOW
1184
+ dispatch({ type: "panel/setShow", payload: false });
1185
+ }
1186
+ //CREATE NEW ELEMENT
1187
+ if (toolElement.includes(activeTool) && isCreateElementRef.current) {
1188
+ const ghostElementNew = (_g = svgRef.current) === null || _g === void 0 ? void 0 : _g.querySelector("#ghost-element-create");
1189
+ if (!ghostElementNew)
1190
+ return;
1191
+ const dataOriginal = JSON.parse(ghostElementNew.getAttribute("data-table") || "{}");
1192
+ const newComponent = Object.assign(Object.assign({ id: `${Date.now()}` }, dataOriginal), { seatCount: 4 });
1193
+ const newExtraComponent = [...extraComponentsState, newComponent];
1194
+ //ADD TO REDUX
1195
+ setExtraComponentsState(newExtraComponent);
1196
+ // setComponentsState(newComponentState);
1197
+ addComponents(newComponent);
1198
+ // syncFromLocalToRedux(newComponentState);
1199
+ //REMOVE GHOST ELEMENT
1200
+ (_h = svgRef.current) === null || _h === void 0 ? void 0 : _h.querySelectorAll("#ghost-element-create").forEach((el) => el.remove());
1201
+ isCreateElementRef.current = false;
1202
+ }
1203
+ // CREATE POLYGON
1204
+ const hasSelectedOneElement = !isEmpty(selectedComponent) &&
1205
+ onResizeSelectionRef.current &&
1206
+ downAtResizePosition;
1207
+ const idDataset = targetGroup === null || targetGroup === void 0 ? void 0 : targetGroup.dataset.id;
1208
+ const isSelectElement = !hasMoved &&
1209
+ !releaseGroupRef.current &&
1210
+ !targetRotate &&
1211
+ !hasSelectedOneElement &&
1212
+ idDataset &&
1213
+ activeTool === "select";
1214
+ if (isSelectElement) {
1215
+ //KLIK UP
1216
+ const findById = [...componentsState, ...extraComponentsState].find((component) => component.id == idDataset);
1217
+ if (!findById) {
1218
+ return;
1219
+ }
1220
+ const { g } = getAttributeElement(svg, idDataset);
1221
+ if (shiftActive) {
1222
+ const allElementSelectionGroup = dataElementSelectionGroupRef.current;
1223
+ // HITUNG BOUNDING BOX
1224
+ let xs = [];
1225
+ let ys = [];
1226
+ let x2 = [];
1227
+ let y2 = [];
1228
+ allElementSelectionGroup.forEach((element) => {
1229
+ const activeId = element.id;
1230
+ const { g } = getAttributeElement(svg, String(activeId));
1231
+ const { x, y, width, height } = getGlobalBBox(svg, g);
1232
+ xs.push(x);
1233
+ ys.push(y);
1234
+ x2.push(x + width);
1235
+ y2.push(y + height);
1236
+ });
1237
+ const selectionBox = {
1238
+ x: Math.min(...xs),
1239
+ y: Math.min(...ys),
1240
+ width: Math.max(...x2) - Math.min(...xs),
1241
+ height: Math.max(...y2) - Math.min(...ys),
1242
+ stroke: "red",
1243
+ shape: "selection-box",
1244
+ fill: "transparent",
1245
+ id: `${Date.now()}`,
1246
+ rotation: 0,
1247
+ };
1248
+ setSelectedLines(selectionBox);
1249
+ dispatch({
1250
+ type: "panel/setSelectedGroup",
1251
+ payload: allElementSelectionGroup,
1252
+ });
1253
+ setSelectedComponent(null);
1254
+ dispatch({
1255
+ type: "panel/setSelectedComponent",
1256
+ payload: null,
1257
+ });
1258
+ }
1259
+ else {
1260
+ dataElementSelectionGroupRef.current = [];
1261
+ const boxGroup = getGlobalBBox(svg, g);
1262
+ let boxSelection = Object.assign(Object.assign(Object.assign({}, findById), boxGroup), { shape: "selection-box", rotation: 0 });
1263
+ if ((boxSelection === null || boxSelection === void 0 ? void 0 : boxSelection.width) && (boxSelection === null || boxSelection === void 0 ? void 0 : boxSelection.height)) {
1264
+ setSelectedLines(boxSelection);
1265
+ setSelectedComponent(findById);
1266
+ dispatch({
1267
+ type: "panel/setSelectedComponent",
1268
+ payload: findById,
1269
+ });
1270
+ dispatch({
1271
+ type: "panel/setSelectedGroup",
1272
+ payload: null,
1273
+ });
1274
+ }
1275
+ }
1276
+ //LOGIC FOR SET SHOW
1277
+ dispatch({ type: "panel/setShow", payload: true });
1278
+ }
1279
+ //UPDATE DATASET TO STATE IF RESIZE
1280
+ if (isMightResizeElement) {
1281
+ const activeId = selectedComponent === null || selectedComponent === void 0 ? void 0 : selectedComponent.id;
1282
+ const svg = svgRef.current;
1283
+ const { g, element, points } = getAttributeElement(svg, String(activeId));
1284
+ const selectionBox = getGlobalBBox(svg, g);
1285
+ const { width, height } = getSvgElementSize(element);
1286
+ const { x, y } = getTranslate(g);
1287
+ const newSelectedComponent = Object.assign(Object.assign({}, selectedComponent), { x: x, y: y, width: width, height: height, points: points });
1288
+ const newSelection = Object.assign({ shape: "selection-box", id: `${Date.now()}` }, selectionBox);
1289
+ setSelectedLines(newSelection);
1290
+ // dragGhostRef.current = false;
1291
+ setSelectedComponent(newSelectedComponent);
1292
+ dispatch({
1293
+ type: "panel/setSelectedComponent",
1294
+ payload: newSelectedComponent,
1295
+ });
1296
+ dispatch({
1297
+ type: "panel/setSelectedGroup",
1298
+ payload: null,
1299
+ });
1300
+ updateComponentAttribute(newSelectedComponent);
1301
+ //LOGIC FOR SET SHOW
1302
+ dispatch({ type: "panel/setShow", payload: false });
1303
+ // isResizeRef.current = false;
1304
+ }
1305
+ //MAKING SELECTION BOX UP
1306
+ const isMakingSelectionBoxUp = downBeforeHasSelectionBox && activeTool === "select";
1307
+ if (isMakingSelectionBoxUp) {
1308
+ const allElementSelectionGroup = dataElementSelectionGroupRef.current;
1309
+ let xs = [];
1310
+ let ys = [];
1311
+ let x2 = [];
1312
+ let y2 = [];
1313
+ allElementSelectionGroup.forEach((element) => {
1314
+ const activeId = element.id;
1315
+ const { g, inner, element: el } = getAttributeElement(svg, String(activeId));
1316
+ const { x, y, width, height } = getGlobalBBox(svg, g);
1317
+ xs.push(x);
1318
+ ys.push(y);
1319
+ x2.push(x + width);
1320
+ y2.push(y + height);
1321
+ });
1322
+ const selectionBox = {
1323
+ x: Math.min(...xs),
1324
+ y: Math.min(...ys),
1325
+ width: Math.max(...x2) - Math.min(...xs),
1326
+ height: Math.max(...y2) - Math.min(...ys),
1327
+ stroke: "red",
1328
+ shape: "selection-box",
1329
+ fill: "transparent",
1330
+ id: `${Date.now()}`,
1331
+ rotation: 0,
1332
+ };
1333
+ function hasInvalidNumber(obj) {
1334
+ return Object.values(obj).some((v) => typeof v === "number" && !Number.isFinite(v));
1335
+ }
1336
+ if (!hasInvalidNumber(selectionBox)) {
1337
+ setSelectedLines(selectionBox);
1338
+ dispatch({
1339
+ type: "panel/setSelectedGroup",
1340
+ payload: allElementSelectionGroup,
1341
+ });
1342
+ }
1343
+ setSelectedComponent(null);
1344
+ dispatch({
1345
+ type: "panel/setSelectedComponent",
1346
+ payload: null,
1347
+ });
1348
+ rotationSelectionRef.current = 0;
1349
+ (_k = (_j = svgRef.current) === null || _j === void 0 ? void 0 : _j.querySelectorAll("#selection-box-ghost")) === null || _k === void 0 ? void 0 : _k.forEach((el) => el.remove());
1350
+ isCreateElementRef.current = false;
1351
+ }
1352
+ if (isInitialCreateBoundingBox) {
1353
+ const ghost = svg.querySelector("#ghost-element-create");
1354
+ const getBBox = getGlobalBBox(svg, ghost);
1355
+ dispatch({
1356
+ type: "board/setBoundingBox",
1357
+ payload: Object.assign(Object.assign({}, getBBox), { id: `${Date.now()}`, shape: "bounding-box", fill: "transparent" }),
1358
+ });
1359
+ (_m = (_l = svgRef.current) === null || _l === void 0 ? void 0 : _l.querySelectorAll("#ghost-element-create")) === null || _m === void 0 ? void 0 : _m.forEach((el) => el.remove());
1360
+ }
1361
+ if (isInitialCreateText) {
1362
+ const ghost = svg.querySelector("#ghost-element-create");
1363
+ const getBBox = getGlobalBBox(svg, ghost);
1364
+ const text = Object.assign(Object.assign({}, getBBox), { id: `${Date.now()}`, shape: "text", fill: "#000000", text: "Text", fontSize: 14 });
1365
+ addComponents(text);
1366
+ dispatch({
1367
+ type: "panel/setShow",
1368
+ payload: true,
1369
+ });
1370
+ dispatch({
1371
+ type: "panel/setSelectedComponent",
1372
+ payload: text,
1373
+ });
1374
+ (_p = (_o = svgRef.current) === null || _o === void 0 ? void 0 : _o.querySelectorAll("#ghost-element-create")) === null || _p === void 0 ? void 0 : _p.forEach((el) => el.remove());
1375
+ isCreateElementRef.current = false;
1376
+ }
1377
+ //RESIZE SELECTION BOX UP
1378
+ if (downAtResizePositionAndHasSelectionBox || isRotateSelectionBox) {
1379
+ isResizeSelectionRef.current = false;
1380
+ const results = (_q = dataElementSelectionGroupRef.current) === null || _q === void 0 ? void 0 : _q.map((item) => {
1381
+ const { g, element, inner, points } = getAttributeElement(svg, String(item.id));
1382
+ const { x, y } = getTranslate(g);
1383
+ const { width, height } = getSvgElementSize(element);
1384
+ const rotate = getRotation(inner.transform.baseVal);
1385
+ const selectionBox = getGlobalBBox(svg, g);
1386
+ const newDataComponent = Object.assign(Object.assign({}, item), { points,
1387
+ x,
1388
+ y,
1389
+ width,
1390
+ height, rotation: rotate });
1391
+ const newDataSelection = Object.assign(Object.assign({}, newDataComponent), { x: selectionBox.x, y: selectionBox.y, width: selectionBox.width, height: selectionBox.height, shape: "selection-box", id: `${Date.now()}`, rotate: 0 });
1392
+ return {
1393
+ newDataComponent,
1394
+ newDataSelection,
1395
+ };
1396
+ });
1397
+ const newDataComponent = results.map((r) => r.newDataComponent);
1398
+ const dataSelection = results.map((r) => r.newDataSelection);
1399
+ updateComponentsAttribute(newDataComponent);
1400
+ const newDataSelection = {
1401
+ x: Math.min(...dataSelection.map((d) => d.x)),
1402
+ y: Math.min(...dataSelection.map((d) => d.y)),
1403
+ width: Math.max(...dataSelection.map((d) => d.x + d.width)) -
1404
+ Math.min(...dataSelection.map((d) => d.x)),
1405
+ height: Math.max(...dataSelection.map((d) => d.y + d.height)) -
1406
+ Math.min(...dataSelection.map((d) => d.y)),
1407
+ shape: "selection-box",
1408
+ id: `${Date.now()}`,
1409
+ };
1410
+ dispatch({
1411
+ type: "panel/setSelectedGroup",
1412
+ payload: newDataComponent,
1413
+ });
1414
+ setSelectedComponent(null);
1415
+ dispatch({
1416
+ type: "panel/setSelectedComponent",
1417
+ payload: null,
1418
+ });
1419
+ setSelectedLines(newDataSelection);
1420
+ dataElementSelectionGroupRef.current = newDataComponent;
1421
+ hadSelectionRef.current = false;
1422
+ }
1423
+ //MOVE SELECTION BOX UP
1424
+ if (downOutResizePositionAndInSelectionBox &&
1425
+ !shiftActive &&
1426
+ !isRotateSelectionBox) {
1427
+ isResizeSelectionRef.current = false;
1428
+ const results = (_r = dataElementSelectionGroupRef.current) === null || _r === void 0 ? void 0 : _r.map((item) => {
1429
+ const { g } = getAttributeElement(svg, String(item.id));
1430
+ const { x, y } = getTranslate(g);
1431
+ const getBBox = getGlobalBBox(svg, g);
1432
+ const findComponent = [
1433
+ ...componentsState,
1434
+ ...extraComponentsState,
1435
+ ].find((c) => c.id == item.id);
1436
+ const newDataComponent = Object.assign(Object.assign({}, findComponent), { x,
1437
+ y });
1438
+ const newDataSelection = Object.assign({}, getBBox);
1439
+ return {
1440
+ newDataComponent,
1441
+ newDataSelection,
1442
+ };
1443
+ });
1444
+ const newDataComponent = results.map((r) => r.newDataComponent);
1445
+ const dataSelection = results.map((r) => r.newDataSelection);
1446
+ const newSelection = {
1447
+ x: Math.min(...dataSelection.map((d) => d.x)),
1448
+ y: Math.min(...dataSelection.map((d) => d.y)),
1449
+ width: Math.max(...dataSelection.map((d) => d.x + d.width)) -
1450
+ Math.min(...dataSelection.map((d) => d.x)),
1451
+ height: Math.max(...dataSelection.map((d) => d.y + d.height)) -
1452
+ Math.min(...dataSelection.map((d) => d.y)),
1453
+ };
1454
+ updateComponentsAttribute(newDataComponent);
1455
+ const newDataSelection = Object.assign(Object.assign({}, newSelection), { shape: "selection-box", id: `${Date.now()}-from-move`, rotation: 0 });
1456
+ dispatch({
1457
+ type: "panel/setSelectedGroup",
1458
+ payload: newDataComponent,
1459
+ });
1460
+ setSelectedComponent(null);
1461
+ dispatch({
1462
+ type: "panel/setSelectedComponent",
1463
+ payload: null,
1464
+ });
1465
+ setSelectedLines(newDataSelection);
1466
+ dataElementSelectionGroupRef.current = newDataComponent;
1467
+ hadSelectionRef.current = false;
1468
+ }
1469
+ //DELETE GHOST ELEMENT BISA MEMBU
1470
+ (_s = svgRef.current) === null || _s === void 0 ? void 0 : _s.querySelectorAll("#ghost-element").forEach((el) => el.remove());
1471
+ //UPDATE DATASET TO STATE IF MOVEk
1472
+ // if (releaseGroupRef.current) return;
1473
+ if ((isMightMove &&
1474
+ !isMakingSelectionBoxUp &&
1475
+ !isSelectElement &&
1476
+ !isMightResizeElement) ||
1477
+ isMightMoveOneElementSelection) {
1478
+ const findData = [...componentsState, ...extraComponentsState].find((item) => item.id == activeId);
1479
+ const { g } = getAttributeElement(svg, activeId);
1480
+ const bbox = getGlobalBBox(svg, g);
1481
+ const bboxSelection = getTranslate(g);
1482
+ const updateComponent = Object.assign(Object.assign({}, findData), { x: bboxSelection === null || bboxSelection === void 0 ? void 0 : bboxSelection.x, y: bboxSelection === null || bboxSelection === void 0 ? void 0 : bboxSelection.y });
1483
+ const selectionLines = Object.assign(Object.assign(Object.assign({}, selectedLines), bbox), { shape: "selection-box" });
1484
+ if (findData) {
1485
+ if (isSingleSelection) {
1486
+ setSelectedLines(selectionLines);
1487
+ setSelectedComponent(updateComponent);
1488
+ dispatch({
1489
+ type: "panel/updateSelectedComponent",
1490
+ payload: updateComponent,
1491
+ });
1492
+ }
1493
+ updateComponentAttribute(updateComponent);
1494
+ }
1495
+ }
1496
+ window.removeEventListener("pointermove", pointerHandleMove);
1497
+ window.removeEventListener("pointerup", pointerHandleUp);
1498
+ };
1499
+ window.addEventListener("pointermove", pointerHandleMove);
1500
+ window.addEventListener("pointerup", pointerHandleUp);
1501
+ };
1502
+ const positionRef = useRef({ x: 0, y: 0 });
1503
+ const handlePointerMove = (e) => {
1504
+ const svg = svgRef.current;
1505
+ const pt = svg.createSVGPoint();
1506
+ pt.x = e.clientX;
1507
+ pt.y = e.clientY;
1508
+ const pos = pt.matrixTransform(svg.getScreenCTM().inverse());
1509
+ // const lineHorizontal = svg?.querySelector("#line-horizontal");
1510
+ // const lineVertical = svg?.querySelector("#line-vertical");
1511
+ // lineHorizontal?.setAttribute("x1", `${-10000}`);
1512
+ // lineHorizontal?.setAttribute("x2", `${10000}`);
1513
+ // lineHorizontal?.setAttribute("y1", `${pos.y}`);
1514
+ // lineHorizontal?.setAttribute("y2", `${pos.y}`);
1515
+ // lineVertical?.setAttribute("y1", `${-10000}`);
1516
+ // lineVertical?.setAttribute("y2", `${10000}`);
1517
+ // lineVertical?.setAttribute("x1", `${pos.x}`);
1518
+ // lineVertical?.setAttribute("x2", `${pos.x}`);
1519
+ if (isOnMakePolygonRef === null || isOnMakePolygonRef === void 0 ? void 0 : isOnMakePolygonRef.current) {
1520
+ const polylineHelper = svg === null || svg === void 0 ? void 0 : svg.querySelector("#polyline-helper");
1521
+ // const startPoint =
1522
+ // selectedComponent?.points[selectedComponent?.points?.length - 1];
1523
+ const newPoints = [...selectedComponent === null || selectedComponent === void 0 ? void 0 : selectedComponent.points, { x: pos.x, y: pos.y }];
1524
+ const points = newPoints.map((item) => `${item.x},${item.y}`).join(" ");
1525
+ polylineHelper === null || polylineHelper === void 0 ? void 0 : polylineHelper.setAttribute("points", points);
1526
+ //lin helper from start to move
1527
+ }
1528
+ };
1529
+ const handleCheckPreview = (e) => {
1530
+ const type = e.target.value;
1531
+ if (type === "type-1") {
1532
+ dispatch({
1533
+ type: "board/setTagType",
1534
+ payload: type,
1535
+ });
1536
+ }
1537
+ if (type === "type-2") {
1538
+ dispatch({
1539
+ type: "board/setTagType",
1540
+ payload: type,
1541
+ });
1542
+ }
1543
+ if (type === "default") {
1544
+ dispatch({
1545
+ type: "board/setTagType",
1546
+ payload: type,
1547
+ });
1548
+ }
1549
+ };
1550
+ return (_jsxs(_Fragment, { children: [_jsxs(ModalPreview, { children: [_jsx(LayerView, { statusKey: "status", loadingRender: loadingRender }), _jsx("div", { className: "flex gap-2 mt-2", children: _jsxs(Radio.Group, { value: isShowTagType, onChange: handleCheckPreview, children: [_jsx(Radio, { value: "default", children: "Default" }), _jsx(Radio, { value: "type-1", children: "Type 1" }), _jsx(Radio, { value: "type-2", children: "Type 2" })] }) })] }), _jsxs("div", { className: "relative w-full h-screen flex-1 overflow-hidden", ref: containerRef, children: [_jsx("div", { className: "absolute bottom-5 left-1/2 transform -translate-x-1/2 z-10", children: _jsxs("div", { className: "flex gap-2", children: [_jsx(Button, { icon: _jsx(ZoomIn, {}), onClick: handelZoomIn }), _jsx(Button, { icon: _jsx(ZoomOut, {}), onClick: handleZoomOut })] }) }), _jsx(TransformWrapper, { ref: transformRef,
1551
+ // limitToBounds={true}
1552
+ panning: {
1553
+ disabled: [
1554
+ "node",
1555
+ "select",
1556
+ "square",
1557
+ "circle",
1558
+ "table-seat-circle",
1559
+ "table-seat-square",
1560
+ "bounding-box",
1561
+ ""
1562
+ ].includes(activeTool),
1563
+ },
1564
+ // centerZoomedOut={true}
1565
+ // onTransformed={handleTransformed}
1566
+ minScale: 0.1, maxScale: 1000, initialScale: scale, pinch: { step: 1 }, wheel: { disabled: true }, smooth: true, doubleClick: { step: 1, disabled: activeTool === "select" }, disablePadding: true, centerOnInit: true, children: _jsx(TransformComponent, { wrapperStyle: {
1567
+ width: "100%",
1568
+ height: "100%",
1569
+ }, contentStyle: { width: boardSize.width, height: boardSize.height }, children: _jsxs("svg", { id: "workspace", ref: svgRef, width: boardSize.width, height: boardSize.height, viewBox: `${minCoords.x} ${minCoords.y} ${boardSize.width} ${boardSize.height}`, onPointerDown: handlePointerDown, onPointerMove: handlePointerMove, xmlns: "http://www.w3.org/2000/svg", preserveAspectRatio: "xMidYMid meet", style: {
1570
+ background: backgroundColor,
1571
+ display: "block",
1572
+ cursor: activeTool === "ruler" ? "crosshair" : "auto",
1573
+ touchAction: "none",
1574
+ pointerEvents: "all",
1575
+ userSelect: "none",
1576
+ }, children: [_jsx(Layers, { components: [
1577
+ ...extraComponentsState,
1578
+ ...componentsState,
1579
+ polygonElementRef === null || polygonElementRef === void 0 ? void 0 : polygonElementRef.current,
1580
+ ...(!isEmpty(boundingBox) ? [boundingBox] : []),
1581
+ ],
1582
+ // style={{
1583
+ // cursor: getCursorStyle(),
1584
+ // }}
1585
+ selectedComponent: selectedComponent, selectionLines: selectedLines, activeTool: activeTool }), activeTool === "polygon" && (_jsx("polyline", { id: "polyline-helper", stroke: "#4a90e2", fill: "transparent", strokeWidth: 2 })), activeTool === "ruler" && (_jsxs(_Fragment, { children: [_jsxs("g", { id: "horizontal-ruler", children: [_jsx("rect", { x: "0", y: "0", width: window.innerWidth, height: "30", fill: "#e0e0e0" }), _jsx("g", { stroke: "#888", "font-size": "10", "text-anchor": "middle", children: Array.from({ length: window.innerWidth / 50 }, (_, i) => (_jsxs("g", { children: [_jsx("line", { x1: i * 50, y1: "0", x2: i * 50, y2: "10" }), _jsx("text", { x: i * 50, y: "15", children: i * 50 })] }, i))) })] }), _jsxs("g", { id: "vertical-ruler", children: [_jsx("rect", { x: "0", y: "0", width: "30", height: window.innerHeight, fill: "#e0e0e0" }), _jsx("g", { stroke: "#888", "font-size": "10", "text-anchor": "middle", children: Array.from({ length: window.innerHeight / 10 }, (_, i) => (_jsxs("g", { children: [_jsx("line", { x1: "0", y1: i * 50, x2: "10", y2: i * 50 }), _jsx("text", { x: "15", y: i * 50, children: i * 50 })] }, i))) })] })] })), grid && (_jsxs("g", { stroke: "#ddd", strokeWidth: 0.5, children: [Array.from({ length: widthBoard / (10 * scale) }, (_, i) => (_jsx("line", { x1: i * 10 * scale, y1: 0, x2: i * 10 * scale, y2: heightBoard / scale }, `v-${i}`))), Array.from({ length: heightBoard / (10 * scale) }, (_, i) => (_jsx("line", { x1: 0, y1: i * 10 * scale, x2: widthBoard / scale, y2: i * 10 * scale }, `h-${i}`)))] })), _jsxs("g", { id: "selection-guides", stroke: "#4A90E2", strokeWidth: 1, pointerEvents: "none", children: [_jsx("line", { id: "v-left" }), _jsx("line", { id: "v-center" }), _jsx("line", { id: "v-right" }), _jsx("line", { id: "h-top" }), _jsx("line", { id: "h-center" }), _jsx("line", { id: "h-bottom" })] })] }) }) })] })] }));
1586
+ };
1587
+ export default BoardTemplate;