polarvo-layout 1.0.19 → 1.0.21

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 (28) hide show
  1. package/package.json +1 -1
  2. package/src/components/FastMenu/DesignFastmenu.vue +2 -2
  3. package/src/components/FastMenu/DisplayFastMenu.vue +2 -2
  4. package/src/components/FastMenu/LayoutFastMenu.vue +18 -10
  5. package/src/components/Layout/CanvasContainer.vue +30 -6
  6. package/src/components/SideBar/ElementSideBar.vue +2 -2
  7. package/src/components/SideBar/LayoutSettingSideBar.vue +18 -10
  8. package/src/components/SideBar/LayoutSideBar.vue +19 -8
  9. package/src/configs/index.js +1 -0
  10. package/src/core/engines/DisplayEngine.js +72 -64
  11. package/src/core/engines/FreeDropEngine.js +40 -42
  12. package/src/core/engines/GridDropEngine.js +33 -43
  13. package/src/core/engines/HistoryEngine.js +55 -51
  14. package/src/core/engines/LayoutEngine.js +89 -68
  15. package/src/core/engines/originals/FreeDropEngine_0402.js +786 -0
  16. package/src/core/engines/originals/GridDropEngine_0402.js +557 -0
  17. package/src/core/managers/EngineManager.js +93 -131
  18. package/src/core/managers/originals/EngineManager_0402.js +826 -0
  19. package/src/library/DisplayLibrary.js +14 -17
  20. package/src/library/FreeDropLibrary.js +6 -4
  21. package/src/library/GridDropLibrary.js +3 -5
  22. package/src/library/LayoutLibrary.js +45 -48
  23. package/src/library/originals/DisplayLibrary_0402.js +137 -0
  24. package/src/library/originals/FreeDropLibrary_0402.js +185 -0
  25. package/src/library/originals/GridDropLibrary_0402.js +202 -0
  26. package/src/library/originals/HistoryLibrary_0402.js +98 -0
  27. package/src/library/originals/LayoutLibrary_0402.js +264 -0
  28. package/src/utils/index.js +8 -3
@@ -14,8 +14,10 @@ class FreeDropEngine {
14
14
  this._elementsUpdate = false; // 원본 요소 목록 변경 플래그
15
15
  this._freeElements = []; // 로컬에서 사용하는 요소 목록
16
16
 
17
- this._activeData = null;
18
17
  this._activeSection = null;
18
+ this._activeMode = null;
19
+ this._activeConfig = null;
20
+
19
21
  this._activeElement = null; // 드래그 중인 배치요소
20
22
 
21
23
  this.guides = { x: null, y: null, w: null, h: null }; // 가이드 라인 위치
@@ -50,43 +52,43 @@ class FreeDropEngine {
50
52
  /** [내부함수] 구독 설정 */
51
53
  _setupSubscriptions() {
52
54
  // 초기화 완료 이벤트 구독 - from DisplayEngine
53
- this._subscribe('display:engineInitialized', ({ displaySize }) => {
54
- const { gridSize } = displaySize;
55
+ this._subscribe('display:engineInitialized', ({ $displaySize }) => {
56
+ const { gridSize } = $displaySize;
55
57
  this._gridSize = gridSize;
56
58
 
57
59
  this._initialize();
58
60
  });
59
61
 
60
- this._subscribe('display:enginesReset', ({ displaySize }) => {
61
- const { gridSize } = displaySize;
62
+ this._subscribe('display:enginesReset', ({ $displaySize }) => {
63
+ const { gridSize } = $displaySize;
62
64
  this._gridSize = gridSize;
63
65
 
64
66
  this._initialize();
65
67
  });
66
68
 
67
69
  // displayMode 변경 감지 (displaySize가 함께 초기화됨)
68
- this._subscribe('display:updateDisplayMode', ({ displaySize }) => {
69
- const { gridSize } = displaySize;
70
+ this._subscribe('display:displayChanged', ({ $displaySize }) => {
71
+ const { gridSize } = $displaySize;
70
72
  this._gridSize = gridSize;
71
73
  });
72
74
 
73
75
  // layoutName 변경 감지 (gridNumber가 함께 초기화됨)
74
- this._subscribe('layout:setLayoutName', ({ gridNumber }) => {
75
- this._gridNumber = gridNumber;
76
+ this._subscribe('layout:setLayoutName', ({ $gridNumber }) => {
77
+ this._gridNumber = $gridNumber;
76
78
  });
77
- this._subscribe('layout:updateLayoutName', ({ gridNumber }) => {
78
- this._gridNumber = gridNumber;
79
+ this._subscribe('layout:updateLayoutName', ({ $gridNumber }) => {
80
+ this._gridNumber = $gridNumber;
79
81
  });
80
82
 
81
- // activeSection 변경 감지 (activeData가 함께 초기화됨)
82
- this._subscribe('system:updateActiveSection', ({ activeSection, activeData }) => {
83
- this._activeSection = activeSection;
84
- this._activeData = activeData;
85
- // this.setActiveElement(null);
83
+ // activeSection 변경 감지
84
+ this._subscribe('system:updateActiveSection', ({ $section, $mode, $config }) => {
85
+ this._activeSection = $section;
86
+ this._activeMode = $mode;
87
+ this._activeConfig = $config;
86
88
  });
87
89
 
88
- this._subscribe('system:setElements', ({ elements }) => {
89
- this._elements = elements;
90
+ this._subscribe('system:setElements', ({ $elements }) => {
91
+ this._elements = $elements;
90
92
  this._elementsUpdate = true;
91
93
 
92
94
  // 활성화 요소 초기화
@@ -98,23 +100,16 @@ class FreeDropEngine {
98
100
  });
99
101
  });
100
102
 
101
- // sectionConfig 변경 감지 (free 모드인 경우에만 activeData 갱신)
102
- this._subscribe('system:updateActiveSectionConfig', ({ activeData }) => {
103
- if (activeData?.mode == 'free') {
104
- this._activeData = activeData;
105
- }
103
+ this._subscribe('layout:updateLayoutData', ({ $mode, $config }) => {
104
+ this._activeMode = $mode;
105
+ this._activeConfig = $config;
106
106
  });
107
107
 
108
- this._subscribe('system:requestUpdateData', ({ elements, elementId, activeData }) => {
109
- this._elements = elements;
108
+ this._subscribe('system:requestUpdateElement', ({ $elements, $elementId }) => {
109
+ this._elements = $elements;
110
110
  this._elementsUpdate = true;
111
111
 
112
- this.setActiveElement(this._elements.find((x) => x.id === elementId));
113
-
114
- if (activeData?.mode == 'free') {
115
- this._activeData = activeData;
116
- }
117
-
112
+ this.setActiveElement(this._elements.find((x) => x.id === $elementId));
118
113
  this.eventBus.emit('freeDrop:requestUpdateData', {
119
114
  elements: cloneDeep(this.freeElements),
120
115
  guides: this.guides,
@@ -138,8 +133,8 @@ class FreeDropEngine {
138
133
  });
139
134
  });
140
135
 
141
- this._subscribe('system:requestUpdateElements', ({ elements }) => {
142
- this._elements = elements;
136
+ this._subscribe('system:requestElementsScale', ({ $elements }) => {
137
+ this._elements = $elements;
143
138
  this._elementsUpdate = true;
144
139
  });
145
140
 
@@ -155,6 +150,11 @@ class FreeDropEngine {
155
150
  });
156
151
  }
157
152
 
153
+ /** 엔진 초기화 */
154
+ reset() {
155
+ this._initialize();
156
+ }
157
+
158
158
  /** 삭제 및 정리 */
159
159
  destroy() {
160
160
  this._subscriptions.forEach((unsubscribe) => {
@@ -163,7 +163,8 @@ class FreeDropEngine {
163
163
  }
164
164
  });
165
165
 
166
- this._initialize();
166
+ this.reset();
167
+
167
168
  this._subscriptions = [];
168
169
  this.eventBus = null;
169
170
  this.resource = null;
@@ -223,8 +224,9 @@ class FreeDropEngine {
223
224
  this._startSize = { w: 0, h: 0 };
224
225
  this._offsetPos = { x: 0, y: 0 };
225
226
 
226
- this._activeData = null;
227
227
  this._activeSection = null;
228
+ this._activeMode = null;
229
+ this._activeConfig = null;
228
230
  this._activeElement = null;
229
231
  this._alreadyExist = false;
230
232
 
@@ -309,8 +311,8 @@ class FreeDropEngine {
309
311
  * @return {boolean} - 가이드라인 표시 여부
310
312
  */
311
313
  _getGuideLineConfig() {
312
- if (this._activeData && this._activeData.config) {
313
- return this._activeData?.config?.showGuideLine;
314
+ if (this._activeConfig) {
315
+ return this._activeConfig?.showGuideLine;
314
316
  } else {
315
317
  return false;
316
318
  }
@@ -337,11 +339,7 @@ class FreeDropEngine {
337
339
  * @param {string} elName - 추가할 아이템 이름
338
340
  */
339
341
  addElement(event, elName) {
340
- if (!this._activeData) {
341
- console.error('[FreeDropEngine] 활성화된 데이터가 없습니다.');
342
- return;
343
- }
344
- if (this._activeData.mode !== 'free') return;
342
+ if (this._activeMode !== 'free') return;
345
343
 
346
344
  this._startPos = { x: event.clientX, y: event.clientY };
347
345
 
@@ -1,4 +1,4 @@
1
- import { cloneDeep, debounce } from 'lodash-es';
1
+ import { cloneDeep } from 'lodash-es';
2
2
 
3
3
  // event 발행 시 'gridDrop'으로 시작하는 이름 사용
4
4
  class GridDropEngine {
@@ -10,9 +10,10 @@ class GridDropEngine {
10
10
  this._elementsUpdate = false; // 원본 요소 목록 변경 플래그
11
11
  this._gridElements = []; // 로컬에서 사용하는 요소 목록
12
12
 
13
- this._layoutData = null;
14
- this._activeData = null;
13
+ // this._activeData = null;
15
14
  this._activeSection = null;
15
+ this._activeMode = null;
16
+ this._activeConfig = null;
16
17
  this._activeElement = null;
17
18
 
18
19
  this._targetCell = null; // 드래그 대상 셀
@@ -50,25 +51,15 @@ class GridDropEngine {
50
51
  this._initialize();
51
52
  });
52
53
 
53
- this._subscribe('system:enginesReset', () => {
54
- this._initialize();
55
- });
56
-
57
- // layoutData 변경 감지
58
- this._subscribe('system:updateLayoutData', ({ layoutData, activeData }) => {
59
- this._layoutData = layoutData;
60
- this._activeData = activeData;
61
- });
62
-
63
54
  // activeSection 변경 감지 (activeData가 함께 초기화됨)
64
- this._subscribe('system:updateActiveSection', ({ activeSection, activeData }) => {
65
- this._activeSection = activeSection;
66
- this._activeData = activeData;
67
- // this.setActiveElement(null);
55
+ this._subscribe('system:updateActiveSection', ({ $section, $mode, $config }) => {
56
+ this._activeSection = $section;
57
+ this._activeMode = $mode;
58
+ this._activeConfig = $config;
68
59
  });
69
60
 
70
- this._subscribe('system:setElements', ({ elements }) => {
71
- this._elements = elements;
61
+ this._subscribe('system:setElements', ({ $elements }) => {
62
+ this._elements = $elements;
72
63
  this._elementsUpdate = true;
73
64
 
74
65
  // 활성화 요소 초기화
@@ -80,22 +71,15 @@ class GridDropEngine {
80
71
  });
81
72
  });
82
73
 
83
- this._subscribe('system:updateActiveSectionConfig', ({ layoutData, activeData }) => {
84
- if (activeData?.mode == 'grid') {
85
- this._layoutData = layoutData;
86
- this._activeData = activeData;
87
- }
74
+ this._subscribe('layout:updateLayoutData', ({ $mode, $config }) => {
75
+ this._activeMode = $mode;
76
+ this._activeConfig = $config;
88
77
  });
89
78
 
90
- this._subscribe('system:requestUpdateData', ({ action, elements, elementId, layoutData, activeData }) => {
91
- this._elements = elements;
79
+ this._subscribe('system:requestUpdateElement', ({ action, $elements, $elementId }) => {
80
+ this._elements = $elements;
92
81
  this._elementsUpdate = true;
93
- this.setActiveElement(this._elements.find((x) => x.id === elementId) || null, action);
94
-
95
- if (activeData?.mode == 'grid') {
96
- this._layoutData = layoutData;
97
- this._activeData = activeData;
98
- }
82
+ this.setActiveElement(this._elements.find((x) => x.id === $elementId) || null, action);
99
83
 
100
84
  this.eventBus.emit('gridDrop:requestUpdateData', {
101
85
  elements: cloneDeep(this.gridElements),
@@ -119,13 +103,12 @@ class GridDropEngine {
119
103
  });
120
104
  });
121
105
 
122
- this._subscribe('system:requestUpdateElements', ({ elements }) => {
123
- this._elements = elements;
106
+ this._subscribe('system:requestElementsScale', ({ $elements }) => {
107
+ this._elements = $elements;
124
108
  this._elementsUpdate = true;
125
109
  });
126
110
 
127
111
  this._subscribe('system:restoredState', ({ stateData }) => {
128
- this._layoutData = stateData.layoutData;
129
112
  this._elements = stateData.elements;
130
113
  this._elementsUpdate = true;
131
114
  this.setActiveElement(null);
@@ -137,6 +120,11 @@ class GridDropEngine {
137
120
  });
138
121
  }
139
122
 
123
+ /** 엔진 초기화 */
124
+ reset() {
125
+ this._initialize();
126
+ }
127
+
140
128
  /** 삭제 및 정리 */
141
129
  destroy() {
142
130
  this._subscriptions.forEach((unsubscribe) => {
@@ -145,7 +133,7 @@ class GridDropEngine {
145
133
  }
146
134
  });
147
135
 
148
- this._initialize();
136
+ this.reset();
149
137
 
150
138
  this._subscriptions = [];
151
139
  this.eventBus = null;
@@ -203,8 +191,10 @@ class GridDropEngine {
203
191
  this._startPos = { x: 0, y: 0 };
204
192
  this._startSize = { w: 0, h: 0 };
205
193
 
206
- this._activeData = null;
194
+ // this._activeData = null;
207
195
  this._activeSection = null;
196
+ this._activeMode = null;
197
+ this._activeConfig = null;
208
198
  this._activeElement = null;
209
199
 
210
200
  this._elementsUpdate = false;
@@ -270,7 +260,7 @@ class GridDropEngine {
270
260
  * @returns {object} - 드래그된 셀 수 ({ dx: , dy: })
271
261
  */
272
262
  _calculateDrag(currentPos, cellSize) {
273
- const { gridGap } = this._activeData.config;
263
+ const { gridGap } = this._activeConfig;
274
264
 
275
265
  const dx = Math.round((currentPos.x - this._startPos.x) / (cellSize.w + gridGap));
276
266
  const dy = Math.round((currentPos.y - this._startPos.y) / (cellSize.h + gridGap));
@@ -283,7 +273,7 @@ class GridDropEngine {
283
273
  * @returns {number} - 그리드 셀 너비
284
274
  */
285
275
  _getGridCellWidth(element) {
286
- const { gridGap, gridColumns } = this._activeData.config;
276
+ const { gridGap, gridColumns } = this._activeConfig;
287
277
  const totalWidth = element.clientWidth - gridGap * (gridColumns - 1);
288
278
  return totalWidth / gridColumns;
289
279
  }
@@ -293,7 +283,7 @@ class GridDropEngine {
293
283
  * @returns {number} - 그리드 셀 높이
294
284
  */
295
285
  _getGridCellHeight(element) {
296
- const { gridGap, gridRows } = this._activeData.config;
286
+ const { gridGap, gridRows } = this._activeConfig;
297
287
  const totalHeight = element.clientHeight - gridGap * (gridRows - 1);
298
288
  return totalHeight / gridRows;
299
289
  }
@@ -331,11 +321,11 @@ class GridDropEngine {
331
321
  * @param {string} elName - 추가할 아이템 이름
332
322
  */
333
323
  addElement(elName) {
334
- if (!this._activeData || !this._dragState.activeCell) {
324
+ if (!this._dragState.activeCell) {
335
325
  console.error('[GridDropEngine] 활성화된 데이터가 없습니다.');
336
326
  return;
337
327
  }
338
- if (this._activeData.mode !== 'grid') return;
328
+ if (this._activeMode !== 'grid') return;
339
329
 
340
330
  const element = {
341
331
  id: elName + '_' + Date.now().toString(36) + Math.random().toString(36).slice(2, 7),
@@ -507,7 +497,7 @@ class GridDropEngine {
507
497
  // 리사이징 중인 경우에만 드래그 가능
508
498
  if (!this._dragState.isResizing) return;
509
499
 
510
- const { gridColumns, gridRows } = this._activeData.config;
500
+ const { gridColumns, gridRows } = this._activeConfig;
511
501
 
512
502
  const activeSection = document.querySelector('.section-active');
513
503
  const { dx, dy } = this._calculateDrag(
@@ -34,106 +34,108 @@ class HistoryEngine {
34
34
  this._initialize();
35
35
  });
36
36
 
37
- this._subscribe('system:enginesReset', () => {
38
- this._initialize();
39
- });
40
-
41
37
  // 초기 상태 저장 - elements 설정 시점
42
- this._subscribe('system:setElements', ({ layoutData, elements }) => {
38
+ this._subscribe('system:setElements', ({ $elements }) => {
43
39
  this._addHistory({
44
40
  engine: 'all',
45
41
  stateData: {
46
- layoutData,
47
- elements,
42
+ elements: $elements,
48
43
  },
49
44
  });
50
45
  });
51
46
 
52
47
  // layoutEngine
53
- this._subscribe('layout:updateLayoutName', ({ layoutName, layoutData, gridNumber, gridRatio }) => {
48
+ this._subscribe('layout:updateLayoutName', ({ $layoutName, $layoutData, $gridNumber, $gridRatio, $gapSize }) => {
54
49
  this._addHistory({
55
50
  engine: 'layout',
56
51
  stateData: {
57
- layoutName,
58
- layoutData,
59
- gridNumber,
60
- gridRatio,
52
+ layoutName: $layoutName,
53
+ layoutData: $layoutData,
54
+ gridNumber: $gridNumber,
55
+ gridRatio: $gridRatio,
56
+ gapSize: $gapSize,
61
57
  },
62
58
  });
63
59
  });
64
60
 
65
- this._subscribe('layout:updateGapSize', ({ gapSize }) => {
61
+ this._subscribe('layout:updateGapSize', ({ $gapSize }) => {
66
62
  this._addHistory({
67
63
  engine: 'layout',
68
64
  stateData: {
69
- gapSize,
65
+ gapSize: $gapSize,
70
66
  },
71
67
  });
72
68
  });
73
69
 
74
- this._subscribe('layout:updateRatio', ({ gridRatio }) => {
70
+ this._subscribe('layout:updateRatio', ({ $gridRatio }) => {
75
71
  this._addHistory({
76
72
  engine: 'layout',
77
73
  stateData: {
78
- gridRatio,
74
+ gridRatio: $gridRatio,
79
75
  },
80
76
  });
81
77
  });
82
78
 
83
79
  // DisplayEngine
84
- this._subscribe('display:updateDisplayMode', ({ displayMode, displaySize }) => {
85
- this._addHistory({
86
- engine: 'display',
87
- stateData: {
88
- displayMode,
89
- displaySize,
90
- },
91
- });
92
- });
93
-
94
- this._subscribe('display:updateDisplaySize', ({ displaySize }) => {
95
- this._addHistory({
96
- engine: 'display',
97
- stateData: {
98
- displaySize,
99
- },
100
- });
80
+ this._subscribe('display:displayChanged', ({ type, $displayMode, $displaySize }) => {
81
+ if (type === 'mode') {
82
+ this._addHistory({
83
+ engine: 'display',
84
+ stateData: {
85
+ displayMode: $displayMode,
86
+ displaySize: $displaySize,
87
+ },
88
+ });
89
+ } else if (type === 'size') {
90
+ this._addHistory({
91
+ engine: 'display',
92
+ stateData: {
93
+ displaySize: $displaySize,
94
+ },
95
+ });
96
+ }
101
97
  });
102
98
 
103
99
  // engineManager
104
- this._subscribe('system:updateActiveSectionConfig', ({ activeData }) => {
100
+ this._subscribe('system:updateActiveSectionConfig', ({ $section, changes }) => {
105
101
  this._addHistory({
106
102
  engine: 'engineManager',
107
103
  stateData: {
108
- activeData,
104
+ section: $section,
105
+ changes,
109
106
  },
110
107
  });
111
108
  });
112
109
 
113
110
  // 요소 추가 또는 삭제
114
- this._subscribe('layout:requestUpdateData', ({ layoutData, activeData, elements, activeSection }) => {
115
- this._addHistory({
116
- engine: 'engineManager',
117
- stateData: {
118
- layoutData,
119
- activeData,
120
- elements,
121
- activeSection,
122
- },
123
- });
124
- });
125
-
126
- this._subscribe('system:requestUpdateElements', ({ historyEvent, elements }) => {
111
+ // this._subscribe('layout:requestUpdateData', ({ layoutData, activeData, elements, activeSection }) => {
112
+ // this._addHistory({
113
+ // engine: 'engineManager',
114
+ // stateData: {
115
+ // layoutData,
116
+ // activeData,
117
+ // elements,
118
+ // activeSection,
119
+ // },
120
+ // });
121
+ // });
122
+
123
+ this._subscribe('system:requestElementsScale', ({ historyEvent, $elements }) => {
127
124
  if (!historyEvent) return;
128
125
  this._addHistory({
129
126
  engine: 'engineManager',
130
127
  stateData: {
131
- elements,
128
+ elements: $elements,
132
129
  },
133
130
  });
134
131
  });
135
132
  }
136
133
 
134
+ /** 엔진 초기화 */
135
+ reset() {
136
+ this._initialize();
137
+ }
138
+
137
139
  /** 삭제 및 정리 */
138
140
  destroy() {
139
141
  this._subscriptions.forEach((unsubscribe) => {
@@ -142,6 +144,8 @@ class HistoryEngine {
142
144
  }
143
145
  });
144
146
 
147
+ this.reset();
148
+
145
149
  this._subscriptions = [];
146
150
  this.eventBus = null;
147
151
 
@@ -176,8 +180,8 @@ class HistoryEngine {
176
180
 
177
181
  // engineManager 상태 저장
178
182
  const managerState = this.manager.getState();
179
- managerState.layoutData = cloneDeep(stateData.layoutData);
180
- managerState.elements = cloneDeep(stateData.elements);
183
+ managerState.layoutData = stateData.layoutData;
184
+ managerState.elements = stateData.elements;
181
185
  allStates['engineManager'] = managerState;
182
186
 
183
187
  // 각 엔진 상태 저장