seat-editor 3.2.7 → 3.2.10

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.
@@ -1,118 +1,128 @@
1
1
  "use client";
2
2
  import { isEmpty, omit } from "lodash";
3
3
  import { arcByDirection, distributeWithSpacing } from "../layer-v3/utils";
4
+ import { PRIVILEGED_TAGS, tagsDummy } from "./constant";
5
+ import { useAppSelector } from "@/hooks/use-redux";
4
6
  const Layers = ({ components, selectedTable, iconTags, eventMatchTable, onHighlightGroup, onForceRestoreGroup, selectedTableColor, privilegedTags, }) => {
7
+ const { isShowTagType } = useAppSelector((state) => state.board);
8
+ const showLabels = !(["type-1", "type-2"].includes(isShowTagType)) && !iconTags;
5
9
  const renderShape = (item) => {
6
10
  var _a, _b, _c, _d, _e, _f;
7
11
  const { id, x, y, width, height, fill, opacity, rotate = 0, rotation, shape, text, stroke, strokeWidth, labels, fontSize, fontColor, seatFill, src, tags, gapTags, label, points, seatPositions, radius, } = item;
8
- const renderTags = (tags) => {
9
- const gapBetweenTags = Number(gapTags || 20);
10
- const defaultFontSize = Number(fontSize || 12);
11
- // Hitung total tinggi semua grup tag (buat center vertikal)
12
- const totalTagHeight = (tags === null || tags === void 0 ? void 0 : tags.filter((tag) => privilegedTags === null || privilegedTags === void 0 ? void 0 : privilegedTags.find((p) => p.key === tag.key)).reduce((sum, tag) => {
13
- var _a;
14
- const items = tag.items || [];
15
- const isColumn = (_a = tag.direction) === null || _a === void 0 ? void 0 : _a.includes("column");
16
- const tagHeight = isColumn
17
- ? items.length * defaultFontSize +
18
- (items.length - 1) * (Number(tag.gap) || 2)
19
- : defaultFontSize; // horizontal = 1 line
20
- return sum + tagHeight + gapBetweenTags;
21
- }, 0)) - gapBetweenTags;
22
- const startY = Number(height) / 3 - totalTagHeight / 3; // titik awal supaya semua di tengah
23
- let currentY = startY;
24
- return tags
25
- .filter((tag) => privilegedTags === null || privilegedTags === void 0 ? void 0 : privilegedTags.find((p) => p.key === tag.key))
26
- .map((tag, tagIndex) => {
27
- var _a;
28
- const itemsPriv = privilegedTags[tagIndex].items;
29
- const direction = ((_a = tag.direction) === null || _a === void 0 ? void 0 : _a.includes("column"))
30
- ? "column"
31
- : "flex";
32
- const gap = Number(tag.gap || 2);
33
- const items = tag.items || [];
34
- const fontSize = Number(defaultFontSize);
35
- const isColumn = direction === "column";
36
- const groupHeight = isColumn
37
- ? items.length * fontSize + (items.length - 1) * gap
38
- : fontSize;
39
- const centerX = width / 2;
40
- const centerY = currentY + groupHeight;
41
- // naikkan posisi Y untuk grup berikutnya
42
- currentY += groupHeight + gapBetweenTags;
43
- // kumpulkan elemen yang akan dirender (bisa mix text + icon)
44
- const elements = items
45
- .filter((item) => itemsPriv.includes(item.type))
46
- .map((item, i) => {
47
- var _a, _b;
48
- const offsetY = isColumn
49
- ? i * (fontSize + gap) - groupHeight / 2 + fontSize / 2
50
- : 0;
51
- const offsetX = !isColumn
52
- ? i * (fontSize + gap) -
53
- ((items.length - 1) * (fontSize + gap)) / 2
54
- : 0;
55
- const posX = centerX + offsetX + Number((_a = tag.offsetX) !== null && _a !== void 0 ? _a : 0);
56
- const posY = centerY + offsetY + Number((_b = tag.offsetY) !== null && _b !== void 0 ? _b : 0);
57
- const renderSymbol = (symbol) => {
58
- if (!symbol)
59
- return null;
60
- const { position = "right", size = (item === null || item === void 0 ? void 0 : item.fontSize) || 12, gap: symbolGap = 0, } = symbol;
61
- let offsetSymbolX = 0;
62
- let offsetSymbolY = 0;
63
- switch (position) {
64
- case "right":
65
- offsetSymbolX = size + symbolGap;
66
- break;
67
- case "left":
68
- offsetSymbolX = -(size + symbolGap);
69
- break;
70
- case "top":
71
- offsetSymbolY = -(size + symbolGap);
72
- break;
73
- case "bottom":
74
- offsetSymbolY = size + symbolGap;
75
- break;
76
- case "right-top":
77
- offsetSymbolX = size + symbolGap;
78
- offsetSymbolY = -(size / 4);
79
- break;
80
- case "right-bottom":
81
- offsetSymbolX = size + symbolGap;
82
- offsetSymbolY = size / 4;
83
- break;
84
- case "left-top":
85
- offsetSymbolX = -size - symbolGap;
86
- offsetSymbolY = -(size / 4);
87
- break;
88
- case "left-bottom":
89
- offsetSymbolX = -size - symbolGap;
90
- offsetSymbolY = size / 4;
91
- break;
12
+ const renderTags = (data) => {
13
+ const tags = data !== null && data !== void 0 ? data : tagsDummy("tes");
14
+ const privileged = (privilegedTags !== null && privilegedTags !== void 0 ? privilegedTags : isShowTagType === "type-1") ? PRIVILEGED_TAGS["CURRENT_TIME"] : isShowTagType === "type-2" ? PRIVILEGED_TAGS["NEXT_3_RESERVATION"] : undefined;
15
+ if (tags && (tags === null || tags === void 0 ? void 0 : tags.length) > 0) {
16
+ const gapBetweenTags = Number(gapTags || 20);
17
+ const defaultFontSize = Number(fontSize || 12);
18
+ // Hitung total tinggi semua grup tag (buat center vertikal)
19
+ const totalTagHeight = (tags === null || tags === void 0 ? void 0 : tags.filter((tag) => privileged === null || privileged === void 0 ? void 0 : privileged.find((p) => p.key === tag.key)).reduce((sum, tag) => {
20
+ var _a;
21
+ const items = tag.items || [];
22
+ const isColumn = (_a = tag.direction) === null || _a === void 0 ? void 0 : _a.includes("column");
23
+ const tagHeight = isColumn
24
+ ? items.length * defaultFontSize +
25
+ (items.length - 1) * (Number(tag.gap) || 2)
26
+ : defaultFontSize; // horizontal = 1 line
27
+ return sum + tagHeight + gapBetweenTags;
28
+ }, 0)) - gapBetweenTags;
29
+ const startY = Number(height) / 3 - totalTagHeight / 3; // titik awal supaya semua di tengah
30
+ let currentY = startY;
31
+ return tags
32
+ .filter((tag) => privileged === null || privileged === void 0 ? void 0 : privileged.find((p) => p.key === tag.key))
33
+ .map((tag, tagIndex) => {
34
+ var _a;
35
+ const itemsPriv = privileged[tagIndex].items;
36
+ const direction = ((_a = tag.direction) === null || _a === void 0 ? void 0 : _a.includes("column"))
37
+ ? "column"
38
+ : "flex";
39
+ const gap = Number(tag.gap || 2);
40
+ const items = tag.items || [];
41
+ const fontSize = Number(defaultFontSize);
42
+ const isColumn = direction === "column";
43
+ const groupHeight = isColumn
44
+ ? items.length * fontSize + (items.length - 1) * gap
45
+ : fontSize;
46
+ const centerX = width / 2;
47
+ const centerY = currentY + groupHeight;
48
+ // naikkan posisi Y untuk grup berikutnya
49
+ currentY += groupHeight + gapBetweenTags;
50
+ // kumpulkan elemen yang akan dirender (bisa mix text + icon)
51
+ const elements = items
52
+ .filter((item) => itemsPriv.includes(item.type))
53
+ .map((item, i) => {
54
+ var _a, _b;
55
+ const offsetY = isColumn
56
+ ? i * (fontSize + gap) - groupHeight / 2 + fontSize / 2
57
+ : 0;
58
+ const offsetX = !isColumn
59
+ ? i * (fontSize + gap) -
60
+ ((items.length - 1) * (fontSize + gap)) / 2
61
+ : 0;
62
+ const posX = centerX + offsetX + Number((_a = tag.offsetX) !== null && _a !== void 0 ? _a : 0);
63
+ const posY = centerY + offsetY + Number((_b = tag.offsetY) !== null && _b !== void 0 ? _b : 0);
64
+ const renderSymbol = (symbol) => {
65
+ if (!symbol)
66
+ return null;
67
+ const { position = "right", size = (item === null || item === void 0 ? void 0 : item.fontSize) || 12, gap: symbolGap = 0, } = symbol;
68
+ let offsetSymbolX = 0;
69
+ let offsetSymbolY = 0;
70
+ switch (position) {
71
+ case "right":
72
+ offsetSymbolX = size + symbolGap;
73
+ break;
74
+ case "left":
75
+ offsetSymbolX = -(size + symbolGap);
76
+ break;
77
+ case "top":
78
+ offsetSymbolY = -(size + symbolGap);
79
+ break;
80
+ case "bottom":
81
+ offsetSymbolY = size + symbolGap;
82
+ break;
83
+ case "right-top":
84
+ offsetSymbolX = size + symbolGap;
85
+ offsetSymbolY = -(size / 4);
86
+ break;
87
+ case "right-bottom":
88
+ offsetSymbolX = size + symbolGap;
89
+ offsetSymbolY = size / 4;
90
+ break;
91
+ case "left-top":
92
+ offsetSymbolX = -size - symbolGap;
93
+ offsetSymbolY = -(size / 4);
94
+ break;
95
+ case "left-bottom":
96
+ offsetSymbolX = -size - symbolGap;
97
+ offsetSymbolY = size / 4;
98
+ break;
99
+ }
100
+ return (<g transform={`rotate(${-rotation}, ${width / 2}, ${height / 2})`}>
101
+ <tspan {...symbol} key={`symbol-${tagIndex}-${i}`} x={posX + offsetSymbolX} y={posY + offsetSymbolY} textAnchor="middle" dominantBaseline="middle" transform={`rotate(${rotate} ${posX} ${posY})`}>
102
+ {symbol.value}
103
+ </tspan>
104
+ </g>);
105
+ };
106
+ if (item.type === "icon") {
107
+ const iconTag = iconTags === null || iconTags === void 0 ? void 0 : iconTags.find((icon) => icon.key === item.value);
108
+ if (!iconTag)
109
+ return null;
110
+ return (<g {...item} key={`icon-${tagIndex}-${i}`} transform={`translate(${posX - 10}, ${posY - 10})`}>
111
+ {iconTag.icon}
112
+ </g>);
113
+ }
114
+ if (item.type === "text") {
115
+ return (<text {...item} key={`text-${tagIndex}-${i}`} x={posX} y={posY} textAnchor="middle" dominantBaseline="middle" fontSize={(Number(defaultFontSize) * 3) / 4}>
116
+ {item.value} {renderSymbol(item === null || item === void 0 ? void 0 : item.symbol)}
117
+ </text>);
92
118
  }
93
- return (<g transform={`rotate(${-rotation}, ${width / 2}, ${height / 2})`}>
94
- <tspan {...symbol} key={`symbol-${tagIndex}-${i}`} x={posX + offsetSymbolX} y={posY + offsetSymbolY} textAnchor="middle" dominantBaseline="middle" transform={`rotate(${rotate} ${posX} ${posY})`}>
95
- {symbol.value}
96
- </tspan>
97
- </g>);
98
- };
99
- if (item.type === "icon") {
100
- const iconTag = iconTags === null || iconTags === void 0 ? void 0 : iconTags.find((icon) => icon.key === item.value);
101
- if (!iconTag)
102
- return null;
103
- return (<g {...item} key={`icon-${tagIndex}-${i}`} transform={`translate(${posX - 10}, ${posY - 10})`}>
104
- {iconTag.icon}
105
- </g>);
106
- }
107
- if (item.type === "text") {
108
- return (<text {...item} key={`text-${tagIndex}-${i}`} x={posX} y={posY} textAnchor="middle" dominantBaseline="middle" fontSize={(Number(defaultFontSize) * 3) / 4}>
109
- {item.value} {renderSymbol(item === null || item === void 0 ? void 0 : item.symbol)}
110
- </text>);
111
- }
112
- return null;
119
+ return null;
120
+ });
121
+ return (<g key={`group-${tagIndex}`} pointerEvents="none">
122
+ {elements}
123
+ </g>);
113
124
  });
114
- return <g key={`group-${tagIndex}`} pointerEvents="none">{elements}</g>;
115
- });
125
+ }
116
126
  };
117
127
  let commonProps = {
118
128
  fill,
@@ -238,12 +248,9 @@ const Layers = ({ components, selectedTable, iconTags, eventMatchTable, onHighli
238
248
  unhighlightGroup(group);
239
249
  }}>
240
250
  <g transform={`rotate(${rotation}, 0,0)`}>
241
- <rect key={`${id}-rect`} width={width} height={height} fill={fill}
242
- // className="blink-2"
243
- {...omit(item, ["x", "y", "label", "points"])} {...commonProps}/>
244
-
251
+ <rect key={`${id}-rect`} width={width} height={height} fill={fill} rx={radius} {...omit(item, ["x", "y", "label", "points"])} {...commonProps}/>
245
252
  {renderTags(tags)}
246
- {!iconTags && (<g transform={`rotate(${-rotation}, ${width / 2}, ${height / 2})`} pointerEvents="none">
253
+ {showLabels && (<g transform={`rotate(${-rotation}, ${width / 2}, ${height / 2})`} pointerEvents="none">
247
254
  {labels === null || labels === void 0 ? void 0 : labels.map((_, index) => {
248
255
  var _a, _b, _c, _d, _e, _f, _g;
249
256
  const cx = width / 2 + ((_a = _ === null || _ === void 0 ? void 0 : _.x) !== null && _a !== void 0 ? _a : 0);
@@ -309,7 +316,7 @@ const Layers = ({ components, selectedTable, iconTags, eventMatchTable, onHighli
309
316
  <g transform={`rotate(${-rotation}, 0, 0)`}>
310
317
  <circle key={id} cx={width / 2} cy={height / 2} r={Math.min(height, width) / 2} fill={fill} {...commonProps}/>
311
318
  {renderTags(tags)}
312
- {!iconTags && (<g transform={`rotate(${-rotation}, ${width / 2}, ${height / 2})`}>
319
+ {showLabels && (<g transform={`rotate(${-rotation}, ${width / 2}, ${height / 2})`}>
313
320
  {labels === null || labels === void 0 ? void 0 : labels.map((_, index) => {
314
321
  var _a, _b, _c, _d, _e, _f, _g;
315
322
  const cx = width / 2 + ((_a = _ === null || _ === void 0 ? void 0 : _.x) !== null && _a !== void 0 ? _a : 0);
@@ -390,7 +397,7 @@ const Layers = ({ components, selectedTable, iconTags, eventMatchTable, onHighli
390
397
  </g>
391
398
 
392
399
  {renderTags(tags)}
393
- {!iconTags && (<g transform={`rotate(${-rotation}, ${width / 2}, ${height / 2})`}>
400
+ {showLabels && (<g transform={`rotate(${-rotation}, ${width / 2}, ${height / 2})`}>
394
401
  {labels === null || labels === void 0 ? void 0 : labels.map((_, index) => {
395
402
  var _a, _b, _c, _d;
396
403
  return (<text key={`${id}-label-${index}`} x={x + width / 2 + ((_a = _ === null || _ === void 0 ? void 0 : _.x) !== null && _a !== void 0 ? _a : 0)} y={y + height / 2 + ((_b = _ === null || _ === void 0 ? void 0 : _.y) !== null && _b !== void 0 ? _b : 0)} fill={(_c = _ === null || _ === void 0 ? void 0 : _.fontColor) !== null && _c !== void 0 ? _c : "black"} fontSize={`${(_d = _ === null || _ === void 0 ? void 0 : _.fontSize) !== null && _d !== void 0 ? _d : 10}px`} fontWeight="bold" textAnchor="middle" dominantBaseline="middle" transform={transformRotate}>
@@ -529,7 +536,7 @@ const Layers = ({ components, selectedTable, iconTags, eventMatchTable, onHighli
529
536
  {seats === null || seats === void 0 ? void 0 : seats.map(({ height, width, x, y, id }, i) => (<rect x={x} y={y} key={`${id}-seat-${i}`} id={`seat-${id}`} height={height} width={width} rx={radius / 4} fill={seatFill}/>))}
530
537
  </g>
531
538
  {renderTags(tags)}
532
- {!iconTags && (<g transform={`rotate(${-rotation}, ${width / 2}, ${height / 2})`}>
539
+ {showLabels && (<g transform={`rotate(${-rotation}, ${width / 2}, ${height / 2})`}>
533
540
  {labels === null || labels === void 0 ? void 0 : labels.map((_, index) => {
534
541
  var _a, _b, _c, _d, _e, _f, _g;
535
542
  const cx = width / 2 + ((_a = _ === null || _ === void 0 ? void 0 : _.x) !== null && _a !== void 0 ? _a : 0);
@@ -647,7 +654,7 @@ const Layers = ({ components, selectedTable, iconTags, eventMatchTable, onHighli
647
654
  <g key={`${id}-seats`} data-seat={`${id}-seats`} transform={`translate(${-x}, ${-y})`}>
648
655
  {[...topSeats, ...bottomSeats, ...leftSeats, ...rightSeats].map(({ cx, cy, id }, i) => (<circle key={`${id}-seat-${i}`} id={`seat-${id}`} cx={cx} cy={cy} r={r} fill={seatFill}/>))}
649
656
  </g>
650
- {!iconTags && (<g transform={`rotate(${-rotation}, ${width / 2}, ${height / 2})`}>
657
+ {showLabels && (<g transform={`rotate(${-rotation}, ${width / 2}, ${height / 2})`}>
651
658
  {labels === null || labels === void 0 ? void 0 : labels.map((_, index) => {
652
659
  var _a, _b, _c, _d, _e, _f, _g;
653
660
  const cx = width / 2 + ((_a = _ === null || _ === void 0 ? void 0 : _.x) !== null && _a !== void 0 ? _a : 0);
@@ -767,7 +774,7 @@ const Layers = ({ components, selectedTable, iconTags, eventMatchTable, onHighli
767
774
  {seats === null || seats === void 0 ? void 0 : seats.map(({ d, id }, i) => (<path key={`${id}-seat-${i}`} id={`seat-${id}`} d={d} fill="white"/>))}
768
775
  </g>
769
776
  {renderTags(tags)}
770
- {!iconTags && (<g transform={`rotate(${-rotation}, ${width / 2}, ${height / 2})`}>
777
+ {showLabels && (<g transform={`rotate(${-rotation}, ${width / 2}, ${height / 2})`}>
771
778
  {labels === null || labels === void 0 ? void 0 : labels.map((_, index) => {
772
779
  var _a, _b, _c, _d, _e, _f, _g;
773
780
  const cx = width / 2 + ((_a = _ === null || _ === void 0 ? void 0 : _.x) !== null && _a !== void 0 ? _a : 0);
@@ -911,7 +918,7 @@ const Layers = ({ components, selectedTable, iconTags, eventMatchTable, onHighli
911
918
  {seats === null || seats === void 0 ? void 0 : seats.map(({ height, width, x, y, id }, i) => (<rect x={x} y={y} key={`${id}-seat-${i}`} id={`seat-${id}`} height={height} width={width} rx={radius / 4} fill={seatFill}/>))}
912
919
  </g>
913
920
  {renderTags(tags)}
914
- {!iconTags && (<g transform={`rotate(${-rotation}, ${width / 2}, ${height / 2})`}>
921
+ {showLabels && (<g transform={`rotate(${-rotation}, ${width / 2}, ${height / 2})`}>
915
922
  {labels === null || labels === void 0 ? void 0 : labels.map((_, index) => {
916
923
  var _a, _b, _c, _d, _e, _f, _g;
917
924
  const cx = width / 2 + ((_a = _ === null || _ === void 0 ? void 0 : _.x) !== null && _a !== void 0 ? _a : 0);
@@ -972,7 +979,7 @@ const Layers = ({ components, selectedTable, iconTags, eventMatchTable, onHighli
972
979
  <g transform={`rotate(${rotation}, 0, 0)`}>
973
980
  <image href={src} width={width} height={height} transform={transformRotate} {...commonProps}/>
974
981
  {renderTags(tags)}
975
- {!iconTags && (<g transform={`rotate(${-rotation}, ${width / 2}, ${height / 2})`}>
982
+ {showLabels && (<g transform={`rotate(${-rotation}, ${width / 2}, ${height / 2})`}>
976
983
  {labels === null || labels === void 0 ? void 0 : labels.map((_, index) => {
977
984
  var _a, _b, _c, _d;
978
985
  return (<text key={index} x={x + width / 2 + ((_a = _ === null || _ === void 0 ? void 0 : _.x) !== null && _a !== void 0 ? _a : 0)} y={y + height / 2 + ((_b = _ === null || _ === void 0 ? void 0 : _.y) !== null && _b !== void 0 ? _b : 0)} fill={(_c = _ === null || _ === void 0 ? void 0 : _.fontColor) !== null && _c !== void 0 ? _c : "black"} fontSize={`${(_d = _ === null || _ === void 0 ? void 0 : _.fontSize) !== null && _d !== void 0 ? _d : 10}px`} fontWeight="bold" textAnchor="middle" dominantBaseline="middle" transform={transformRotate}>
@@ -11,6 +11,7 @@ export interface InitialState {
11
11
  historyChanges: any[];
12
12
  pointer: number;
13
13
  updateBy: "global" | "local";
14
+ isShowTagType: "default" | "type-1" | "type-2";
14
15
  }
15
16
  export declare const addComponent: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "board/addComponent">, removeComponent: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "board/removeComponent">, updateComponent: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "board/updateComponent">, setBackgroundColor: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "board/setBackgroundColor">, removeExtraComponent: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "board/removeExtraComponent">;
16
17
  declare const _default: import("redux").Reducer<InitialState>;
@@ -1,4 +1,5 @@
1
1
  import { createSlice, current } from "@reduxjs/toolkit";
2
+ import { forEach } from "lodash";
2
3
  const initialState = {
3
4
  components: [],
4
5
  backgroundColor: "#FFFFFF",
@@ -8,12 +9,16 @@ const initialState = {
8
9
  historyChanges: [],
9
10
  pointer: 0,
10
11
  updateBy: "global",
12
+ isShowTagType: "default",
11
13
  };
12
14
  const MAX_HISTORY_CHANGES = 20;
13
15
  const boardSlice = createSlice({
14
16
  name: "board",
15
17
  initialState,
16
18
  reducers: {
19
+ setTagType: (state, action) => {
20
+ state.isShowTagType = action.payload;
21
+ },
17
22
  setUpdateBy: (state, action) => {
18
23
  state.updateBy = action.payload;
19
24
  },
@@ -23,17 +28,17 @@ const boardSlice = createSlice({
23
28
  if (currentPointer < totalHistory) {
24
29
  state.historyChanges = state.historyChanges.slice(0, currentPointer + 1);
25
30
  }
26
- const component = state.components;
27
- const extraComponent = state.extraComponents;
28
- state.historyChanges.push({
29
- component,
30
- extraComponent
31
- });
32
31
  if (state.historyChanges.length > MAX_HISTORY_CHANGES) {
33
32
  state.historyChanges.shift();
34
33
  }
35
34
  state.pointer += 1;
36
35
  state.components.push(action.payload);
36
+ const component = state.components;
37
+ const extraComponent = state.extraComponents;
38
+ state.historyChanges.push({
39
+ component,
40
+ extraComponent,
41
+ });
37
42
  },
38
43
  removeComponent: (state, action) => {
39
44
  state.components = state.components.filter((component) => (component === null || component === void 0 ? void 0 : component.id) !== action.payload.id);
@@ -44,11 +49,10 @@ const boardSlice = createSlice({
44
49
  updateComponent: (state, action) => {
45
50
  const index = state.components.findIndex((component) => component.id === action.payload.id);
46
51
  const indexExtra = state.extraComponents.findIndex((extraComponent) => extraComponent.id === action.payload.id);
47
- state.historyChanges.push(state.components);
48
- if (state.historyChanges.length > MAX_HISTORY_CHANGES) {
49
- state.historyChanges.shift();
50
- }
51
- state.pointer += 1;
52
+ // state.historyChanges.push({
53
+ // components: [...state.components],
54
+ // extraComponents: [...state.extraComponents],
55
+ // });
52
56
  if (index !== -1) {
53
57
  // Update component biasa
54
58
  state.components[index] = Object.assign(Object.assign({}, state.components[index]), action.payload);
@@ -57,10 +61,6 @@ const boardSlice = createSlice({
57
61
  // Update extraComponent
58
62
  state.extraComponents[indexExtra] = Object.assign(Object.assign({}, state.extraComponents[indexExtra]), action.payload);
59
63
  }
60
- },
61
- updateComponentsBulk: (state, action) => {
62
- const updates = action.payload;
63
- // Simpan snapshot untuk undo (deep clone lebih aman)
64
64
  state.historyChanges.push({
65
65
  components: [...state.components],
66
66
  extraComponents: [...state.extraComponents],
@@ -69,6 +69,9 @@ const boardSlice = createSlice({
69
69
  state.historyChanges.shift();
70
70
  }
71
71
  state.pointer += 1;
72
+ },
73
+ updateComponentsBulk: (state, action) => {
74
+ const updates = action.payload;
72
75
  updates.forEach((update) => {
73
76
  const index = state.components.findIndex((component) => component.id === update.id);
74
77
  const indexExtra = state.extraComponents.findIndex((extra) => extra.id === update.id);
@@ -79,26 +82,32 @@ const boardSlice = createSlice({
79
82
  state.extraComponents[indexExtra] = Object.assign(Object.assign({}, state.extraComponents[indexExtra]), update);
80
83
  }
81
84
  });
85
+ if (state.pointer < state.historyChanges.length - 1) {
86
+ state.historyChanges = state.historyChanges.slice(0, state.pointer + 1);
87
+ }
88
+ state.historyChanges.push({
89
+ components: [...state.components],
90
+ extraComponents: [...state.extraComponents],
91
+ });
92
+ if (state.historyChanges.length > MAX_HISTORY_CHANGES) {
93
+ state.historyChanges.shift();
94
+ }
95
+ state.pointer += 1;
96
+ },
97
+ updateSelectedGroupComponent: (state, action) => {
98
+ const allComponents = action.payload;
99
+ forEach(allComponents, (component) => {
100
+ const index = state.components.findIndex((c) => c.id === component.id);
101
+ if (index !== -1) {
102
+ state.components[index] = Object.assign(Object.assign({}, state.components[index]), component);
103
+ }
104
+ });
105
+ state.historyChanges.push(state.components);
106
+ if (state.historyChanges.length > MAX_HISTORY_CHANGES) {
107
+ state.historyChanges.shift();
108
+ }
109
+ state.pointer += 1;
82
110
  },
83
- // updateAllComponents: (state, action) => {
84
- // const allComponents = action.payload;
85
- // forEach(allComponents, (component) => {
86
- // const index = state.components.findIndex(
87
- // (c) => c.id === component.id
88
- // );
89
- // if (index !== -1) {
90
- // state.components[index] = {
91
- // ...state.components[index],
92
- // ...component,
93
- // };
94
- // }
95
- // });
96
- // state.historyChanges.push(state.components);
97
- // if (state.historyChanges.length > MAX_HISTORY_CHANGES) {
98
- // state.historyChanges.shift();
99
- // }
100
- // state.pointer += 1
101
- // },
102
111
  setBackgroundColor: (state, action) => {
103
112
  state.backgroundColor = action.payload;
104
113
  },
@@ -140,17 +149,17 @@ const boardSlice = createSlice({
140
149
  if (currentPointer < totalHistory) {
141
150
  state.historyChanges = state.historyChanges.slice(0, currentPointer + 1);
142
151
  }
152
+ if (state.historyChanges.length > MAX_HISTORY_CHANGES) {
153
+ state.historyChanges.shift();
154
+ }
155
+ state.pointer += 1;
156
+ state.extraComponents.push(action.payload);
143
157
  const component = state.components;
144
158
  const extraComponent = state.extraComponents;
145
159
  state.historyChanges.push({
146
160
  components: [...component],
147
161
  extraComponents: [...extraComponent],
148
162
  });
149
- if (state.historyChanges.length > MAX_HISTORY_CHANGES) {
150
- state.historyChanges.shift();
151
- }
152
- state.pointer += 1;
153
- state.extraComponents.push(action.payload);
154
163
  },
155
164
  setFlagChange: (state, action) => {
156
165
  state.flagChange = action.payload;
@@ -166,7 +175,6 @@ const boardSlice = createSlice({
166
175
  state.pointer -= 1;
167
176
  }
168
177
  const prev = state.historyChanges[state.pointer];
169
- console.log({ prev });
170
178
  state.components = current(prev === null || prev === void 0 ? void 0 : prev.components);
171
179
  state.extraComponents = current(prev === null || prev === void 0 ? void 0 : prev.extraComponents);
172
180
  }
@@ -192,12 +200,14 @@ const boardSlice = createSlice({
192
200
  state.extraComponents = extraComponents;
193
201
  state.pointer = 0;
194
202
  state.backgroundColor = backgroundColor;
195
- state.historyChanges = [{
203
+ state.historyChanges = [
204
+ {
196
205
  components,
197
- extraComponents
198
- }];
199
- }
206
+ extraComponents,
207
+ },
208
+ ];
209
+ },
200
210
  },
201
211
  });
202
- export const { addComponent, removeComponent, updateComponent, setBackgroundColor, removeExtraComponent } = boardSlice.actions;
212
+ export const { addComponent, removeComponent, updateComponent, setBackgroundColor, removeExtraComponent, } = boardSlice.actions;
203
213
  export default boardSlice.reducer;