@dragonworks/ngx-dashboard 20.0.6 → 20.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (78) hide show
  1. package/fesm2022/dragonworks-ngx-dashboard.mjs +2250 -0
  2. package/fesm2022/dragonworks-ngx-dashboard.mjs.map +1 -0
  3. package/index.d.ts +727 -0
  4. package/package.json +45 -34
  5. package/ng-package.json +0 -7
  6. package/src/lib/__tests__/dashboard-component-widget-state-integration.spec.ts +0 -537
  7. package/src/lib/cell/__tests__/cell-resize.component.spec.ts +0 -442
  8. package/src/lib/cell/__tests__/cell.component.spec.ts +0 -541
  9. package/src/lib/cell/cell-context-menu.component.ts +0 -138
  10. package/src/lib/cell/cell-context-menu.service.ts +0 -36
  11. package/src/lib/cell/cell.component.html +0 -37
  12. package/src/lib/cell/cell.component.scss +0 -198
  13. package/src/lib/cell/cell.component.ts +0 -375
  14. package/src/lib/dashboard/dashboard.component.html +0 -18
  15. package/src/lib/dashboard/dashboard.component.scss +0 -17
  16. package/src/lib/dashboard/dashboard.component.ts +0 -187
  17. package/src/lib/dashboard-editor/dashboard-editor.component.html +0 -57
  18. package/src/lib/dashboard-editor/dashboard-editor.component.scss +0 -87
  19. package/src/lib/dashboard-editor/dashboard-editor.component.ts +0 -219
  20. package/src/lib/dashboard-viewer/__tests__/dashboard-viewer.component.spec.ts +0 -258
  21. package/src/lib/dashboard-viewer/dashboard-viewer.component.html +0 -20
  22. package/src/lib/dashboard-viewer/dashboard-viewer.component.scss +0 -50
  23. package/src/lib/dashboard-viewer/dashboard-viewer.component.ts +0 -70
  24. package/src/lib/drop-zone/__tests__/drop-zone.component.spec.ts +0 -465
  25. package/src/lib/drop-zone/drop-zone.component.html +0 -20
  26. package/src/lib/drop-zone/drop-zone.component.scss +0 -67
  27. package/src/lib/drop-zone/drop-zone.component.ts +0 -122
  28. package/src/lib/internal-widgets/unknown-widget/unknown-widget.component.ts +0 -72
  29. package/src/lib/models/cell-data.ts +0 -13
  30. package/src/lib/models/cell-dialog.ts +0 -7
  31. package/src/lib/models/cell-id.ts +0 -85
  32. package/src/lib/models/cell-position.ts +0 -15
  33. package/src/lib/models/dashboard-data.dto.ts +0 -44
  34. package/src/lib/models/dashboard-data.utils.ts +0 -49
  35. package/src/lib/models/drag-data.ts +0 -6
  36. package/src/lib/models/index.ts +0 -11
  37. package/src/lib/models/reserved-space.ts +0 -24
  38. package/src/lib/models/widget-factory.ts +0 -33
  39. package/src/lib/models/widget-id.ts +0 -70
  40. package/src/lib/models/widget.ts +0 -21
  41. package/src/lib/providers/cell-settings-dialog/cell-settings-dialog.component.ts +0 -127
  42. package/src/lib/providers/cell-settings-dialog/cell-settings-dialog.provider.ts +0 -15
  43. package/src/lib/providers/cell-settings-dialog/cell-settings-dialog.tokens.ts +0 -20
  44. package/src/lib/providers/cell-settings-dialog/default-cell-settings-dialog.provider.ts +0 -32
  45. package/src/lib/providers/cell-settings-dialog/index.ts +0 -3
  46. package/src/lib/providers/index.ts +0 -1
  47. package/src/lib/services/__tests__/dashboard-bridge.service.spec.ts +0 -220
  48. package/src/lib/services/__tests__/dashboard-viewport.service.spec.ts +0 -362
  49. package/src/lib/services/dashboard-bridge.service.ts +0 -155
  50. package/src/lib/services/dashboard-viewport.service.ts +0 -148
  51. package/src/lib/services/dashboard.service.ts +0 -62
  52. package/src/lib/store/__tests__/dashboard-store-collision-detection.spec.ts +0 -756
  53. package/src/lib/store/__tests__/dashboard-store-computed-properties.spec.ts +0 -974
  54. package/src/lib/store/__tests__/dashboard-store-drag-drop.spec.ts +0 -279
  55. package/src/lib/store/__tests__/dashboard-store-export-import.spec.ts +0 -780
  56. package/src/lib/store/__tests__/dashboard-store-grid-config.spec.ts +0 -128
  57. package/src/lib/store/__tests__/dashboard-store-query-methods.spec.ts +0 -229
  58. package/src/lib/store/__tests__/dashboard-store-resize-operations.spec.ts +0 -652
  59. package/src/lib/store/__tests__/dashboard-store-widget-management.spec.ts +0 -461
  60. package/src/lib/store/__tests__/dashboard-store-widget-state-preservation.spec.ts +0 -369
  61. package/src/lib/store/dashboard-store.ts +0 -239
  62. package/src/lib/store/features/drag-drop.feature.ts +0 -140
  63. package/src/lib/store/features/grid-config.feature.ts +0 -43
  64. package/src/lib/store/features/resize.feature.ts +0 -140
  65. package/src/lib/store/features/utils/collision.utils.ts +0 -89
  66. package/src/lib/store/features/utils/grid-query-internal.utils.ts +0 -37
  67. package/src/lib/store/features/utils/resize.utils.ts +0 -165
  68. package/src/lib/store/features/widget-management.feature.ts +0 -158
  69. package/src/lib/styles/_dashboard-grid-vars.scss +0 -11
  70. package/src/lib/widget-list/__tests__/widget-list-bridge-integration.spec.ts +0 -137
  71. package/src/lib/widget-list/widget-list.component.html +0 -22
  72. package/src/lib/widget-list/widget-list.component.scss +0 -154
  73. package/src/lib/widget-list/widget-list.component.ts +0 -106
  74. package/src/public-api.ts +0 -21
  75. package/src/test-setup.ts +0 -10
  76. package/tsconfig.lib.json +0 -15
  77. package/tsconfig.lib.prod.json +0 -11
  78. package/tsconfig.spec.json +0 -14
package/package.json CHANGED
@@ -1,34 +1,45 @@
1
- {
2
- "name": "@dragonworks/ngx-dashboard",
3
- "version": "20.0.6",
4
- "description": "Angular library for building drag-and-drop grid dashboards with resizable cells and customizable widgets",
5
- "peerDependencies": {
6
- "@angular/common": "^20.0.0",
7
- "@angular/core": "^20.0.0",
8
- "@angular/material": "^20.0.0",
9
- "@angular/cdk": "^20.0.0"
10
- },
11
- "dependencies": {
12
- "tslib": "^2.3.0"
13
- },
14
- "sideEffects": false,
15
- "repository": {
16
- "type": "git",
17
- "url": "git+https://github.com/TobyBackstrom/ngx-dashboard.git"
18
- },
19
- "author": "Toby Backstrom",
20
- "license": "MIT",
21
- "bugs": {
22
- "url": "https://github.com/TobyBackstrom/ngx-dashboard/issues"
23
- },
24
- "homepage": "https://dragonworks.dev",
25
- "keywords": [
26
- "angular",
27
- "dashboard",
28
- "widgets",
29
- "grid",
30
- "drag-drop",
31
- "material-design",
32
- "md3"
33
- ]
34
- }
1
+ {
2
+ "name": "@dragonworks/ngx-dashboard",
3
+ "version": "20.1.0",
4
+ "description": "Angular library for building drag-and-drop grid dashboards with resizable cells and customizable widgets",
5
+ "peerDependencies": {
6
+ "@angular/common": "^20.2.0",
7
+ "@angular/core": "^20.2.0",
8
+ "@angular/material": "^20.2.0",
9
+ "@angular/cdk": "^20.2.0"
10
+ },
11
+ "dependencies": {
12
+ "tslib": "^2.3.0"
13
+ },
14
+ "sideEffects": false,
15
+ "repository": {
16
+ "type": "git",
17
+ "url": "git+https://github.com/TobyBackstrom/ngx-dashboard.git"
18
+ },
19
+ "author": "Toby Backstrom",
20
+ "license": "MIT",
21
+ "bugs": {
22
+ "url": "https://github.com/TobyBackstrom/ngx-dashboard/issues"
23
+ },
24
+ "homepage": "https://dragonworks.dev",
25
+ "keywords": [
26
+ "angular",
27
+ "dashboard",
28
+ "widgets",
29
+ "grid",
30
+ "drag-drop",
31
+ "material-design",
32
+ "md3"
33
+ ],
34
+ "module": "fesm2022/dragonworks-ngx-dashboard.mjs",
35
+ "typings": "index.d.ts",
36
+ "exports": {
37
+ "./package.json": {
38
+ "default": "./package.json"
39
+ },
40
+ ".": {
41
+ "types": "./index.d.ts",
42
+ "default": "./fesm2022/dragonworks-ngx-dashboard.mjs"
43
+ }
44
+ }
45
+ }
package/ng-package.json DELETED
@@ -1,7 +0,0 @@
1
- {
2
- "$schema": "../../node_modules/ng-packagr/ng-package.schema.json",
3
- "dest": "../../dist/ngx-dashboard",
4
- "lib": {
5
- "entryFile": "src/public-api.ts"
6
- }
7
- }
@@ -1,537 +0,0 @@
1
- import { ComponentFixture, TestBed } from '@angular/core/testing';
2
- import { Component, signal, ViewContainerRef } from '@angular/core';
3
- import { DashboardComponent } from '../dashboard/dashboard.component';
4
- import { DashboardService } from '../services/dashboard.service';
5
- import { CellIdUtils, WidgetFactory, DashboardDataDto, Widget, WidgetMetadata } from '../models';
6
- import { createEmptyDashboard } from '../models/dashboard-data.utils';
7
-
8
- // Mock widget with state that can be modified after initialization
9
- interface TestWidgetState {
10
- value: string;
11
- counter: number;
12
- modified: boolean;
13
- }
14
-
15
- @Component({
16
- selector: 'test-widget',
17
- template: `
18
- <div class="test-widget">
19
- <p>Value: {{ state().value }}</p>
20
- <p>Counter: {{ state().counter }}</p>
21
- <p>Modified: {{ state().modified ? 'Yes' : 'No' }}</p>
22
- <button (click)="updateValue()">Update Value</button>
23
- <button (click)="incrementCounter()">Increment Counter</button>
24
- </div>
25
- `,
26
- })
27
- class TestWidgetComponent implements Widget {
28
- static metadata: WidgetMetadata = {
29
- widgetTypeid: 'test-widget',
30
- name: 'Test Widget',
31
- description: 'A test widget for state preservation tests',
32
- svgIcon: '<svg><rect width="10" height="10"/></svg>',
33
- };
34
-
35
- state = signal<TestWidgetState>({
36
- value: 'initial',
37
- counter: 0,
38
- modified: false,
39
- });
40
-
41
- dashboardSetState(state?: unknown) {
42
- if (state) {
43
- this.state.update((current) => ({
44
- ...current,
45
- ...(state as TestWidgetState),
46
- }));
47
- }
48
- }
49
-
50
- dashboardGetState(): TestWidgetState {
51
- return { ...this.state() };
52
- }
53
-
54
- // Methods to simulate user interactions that modify widget state
55
- updateValue() {
56
- this.state.update(current => ({
57
- ...current,
58
- value: `updated-${Date.now()}`,
59
- modified: true,
60
- }));
61
- }
62
-
63
- incrementCounter() {
64
- this.state.update(current => ({
65
- ...current,
66
- counter: current.counter + 1,
67
- modified: true,
68
- }));
69
- }
70
- }
71
-
72
- describe('DashboardComponent - Widget State Integration', () => {
73
- let component: DashboardComponent;
74
- let fixture: ComponentFixture<DashboardComponent>;
75
- let dashboardService: jasmine.SpyObj<DashboardService>;
76
- let testWidgetFactory: WidgetFactory;
77
-
78
- beforeEach(async () => {
79
- const dashboardServiceSpy = jasmine.createSpyObj('DashboardService', [
80
- 'getFactory',
81
- 'registerWidgetType',
82
- 'getAllFactories',
83
- ]);
84
-
85
- await TestBed.configureTestingModule({
86
- imports: [DashboardComponent, TestWidgetComponent],
87
- providers: [
88
- { provide: DashboardService, useValue: dashboardServiceSpy },
89
- ],
90
- }).compileComponents();
91
-
92
- fixture = TestBed.createComponent(DashboardComponent);
93
- component = fixture.componentInstance;
94
- dashboardService = TestBed.inject(DashboardService) as jasmine.SpyObj<DashboardService>;
95
-
96
- // Setup mock widget factory
97
- testWidgetFactory = {
98
- widgetTypeid: 'test-widget',
99
- name: 'Test Widget',
100
- description: 'A test widget',
101
- svgIcon: '<svg><rect width="10" height="10"/></svg>',
102
- createInstance: jasmine.createSpy('createInstance').and.callFake((container: ViewContainerRef, state?: unknown) => {
103
- const componentRef = container.createComponent(TestWidgetComponent);
104
- if (state) {
105
- componentRef.instance.dashboardSetState(state);
106
- }
107
- return componentRef;
108
- }),
109
- };
110
-
111
- dashboardService.getFactory.and.returnValue(testWidgetFactory);
112
- });
113
-
114
- describe('Widget state preservation during export', () => {
115
- it('should export initial widget state without modifications', async () => {
116
- const initialState: TestWidgetState = {
117
- value: 'initial',
118
- counter: 0,
119
- modified: false,
120
- };
121
-
122
- // Create dashboard with a widget
123
- const dashboardData: DashboardDataDto = {
124
- version: '1.0.0',
125
- dashboardId: 'test-dashboard',
126
- rows: 5,
127
- columns: 8,
128
- gutterSize: '1em',
129
- cells: [
130
- {
131
- row: 2,
132
- col: 3,
133
- rowSpan: 2,
134
- colSpan: 3,
135
- widgetTypeid: 'test-widget',
136
- widgetState: initialState,
137
- },
138
- ],
139
- };
140
-
141
- // Set the dashboard data
142
- fixture.componentRef.setInput('dashboardData', dashboardData);
143
- fixture.detectChanges();
144
-
145
- // Wait for async operations
146
- await fixture.whenStable();
147
-
148
- // Export dashboard
149
- const exported = component.exportDashboard();
150
-
151
- expect(exported.cells).toHaveSize(1);
152
- expect(exported.cells[0].widgetState).toEqual(initialState);
153
- });
154
-
155
- it('should export live widget state after modifications', async () => {
156
- const initialState: TestWidgetState = {
157
- value: 'initial',
158
- counter: 0,
159
- modified: false,
160
- };
161
-
162
- // Create dashboard with a widget
163
- const dashboardData: DashboardDataDto = {
164
- version: '1.0.0',
165
- dashboardId: 'test-dashboard',
166
- rows: 5,
167
- columns: 8,
168
- gutterSize: '1em',
169
- cells: [
170
- {
171
- row: 1,
172
- col: 1,
173
- rowSpan: 1,
174
- colSpan: 1,
175
- widgetTypeid: 'test-widget',
176
- widgetState: initialState,
177
- },
178
- ],
179
- };
180
-
181
- // Set the dashboard data
182
- fixture.componentRef.setInput('dashboardData', dashboardData);
183
- fixture.detectChanges();
184
-
185
- // Wait for the component to initialize
186
- await fixture.whenStable();
187
-
188
- // Find the widget component and modify its state
189
- const widgetElement = fixture.debugElement.query(
190
- (el) => el.componentInstance instanceof TestWidgetComponent
191
- );
192
-
193
- if (widgetElement) {
194
- const widgetComponent = widgetElement.componentInstance as TestWidgetComponent;
195
-
196
- // Modify the widget state
197
- widgetComponent.updateValue();
198
- widgetComponent.incrementCounter();
199
-
200
- // Detect changes
201
- fixture.detectChanges();
202
- await fixture.whenStable();
203
-
204
- // Export dashboard and check if live state is captured
205
- const exported = component.exportDashboard();
206
-
207
- expect(exported.cells).toHaveSize(1);
208
-
209
- const exportedState = exported.cells[0].widgetState as TestWidgetState;
210
- expect(exportedState.modified).toBe(true);
211
- expect(exportedState.counter).toBe(1);
212
- expect(exportedState.value).toContain('updated-');
213
- expect(exportedState.value).not.toBe('initial');
214
- } else {
215
- fail('Widget component not found in the DOM');
216
- }
217
- });
218
-
219
- it('should handle widgets that do not implement dashboardGetState', async () => {
220
- // Create a widget that doesn't implement dashboardGetState
221
- @Component({
222
- selector: 'simple-widget',
223
- template: '<div>Simple Widget</div>',
224
- })
225
- class SimpleWidgetComponent implements Widget {
226
- // Intentionally not implementing dashboardGetState
227
- }
228
-
229
- const simpleWidgetFactory: WidgetFactory = {
230
- widgetTypeid: 'simple-widget',
231
- name: 'Simple Widget',
232
- description: 'A simple widget',
233
- svgIcon: '<svg><circle r="5"/></svg>',
234
- createInstance: jasmine.createSpy('createInstance').and.callFake((container: ViewContainerRef, state?: unknown) => {
235
- return container.createComponent(SimpleWidgetComponent);
236
- }),
237
- };
238
-
239
- dashboardService.getFactory.and.returnValue(simpleWidgetFactory);
240
-
241
- const dashboardData: DashboardDataDto = {
242
- version: '1.0.0',
243
- dashboardId: 'test-dashboard-simple',
244
- rows: 3,
245
- columns: 4,
246
- gutterSize: '1em',
247
- cells: [
248
- {
249
- row: 1,
250
- col: 1,
251
- rowSpan: 1,
252
- colSpan: 1,
253
- widgetTypeid: 'simple-widget',
254
- widgetState: { simple: 'data' },
255
- },
256
- ],
257
- };
258
-
259
- fixture.componentRef.setInput('dashboardData', dashboardData);
260
- fixture.detectChanges();
261
- await fixture.whenStable();
262
-
263
- const exported = component.exportDashboard();
264
-
265
- expect(exported.cells).toHaveSize(1);
266
- expect(exported.cells[0].widgetState).toEqual({ simple: 'data' });
267
- });
268
-
269
- it('should handle multiple widgets with different state scenarios', async () => {
270
- const dashboardData: DashboardDataDto = {
271
- version: '1.0.0',
272
- dashboardId: 'test-dashboard-multiple',
273
- rows: 8,
274
- columns: 8,
275
- gutterSize: '1em',
276
- cells: [
277
- {
278
- row: 1,
279
- col: 1,
280
- rowSpan: 1,
281
- colSpan: 1,
282
- widgetTypeid: 'test-widget',
283
- widgetState: { value: 'widget1', counter: 1, modified: false },
284
- },
285
- {
286
- row: 2,
287
- col: 2,
288
- rowSpan: 1,
289
- colSpan: 1,
290
- widgetTypeid: 'test-widget',
291
- widgetState: { value: 'widget2', counter: 2, modified: false },
292
- },
293
- {
294
- row: 3,
295
- col: 3,
296
- rowSpan: 1,
297
- colSpan: 1,
298
- widgetTypeid: 'test-widget',
299
- widgetState: { value: 'widget3', counter: 3, modified: false },
300
- },
301
- ],
302
- };
303
-
304
- fixture.componentRef.setInput('dashboardData', dashboardData);
305
- fixture.detectChanges();
306
- await fixture.whenStable();
307
-
308
- // Find all widget components (top-level only)
309
- const widgetElements = fixture.debugElement.queryAll(
310
- (el) => el.componentInstance instanceof TestWidgetComponent && el.nativeElement.tagName === 'TEST-WIDGET'
311
- );
312
-
313
- expect(widgetElements).toHaveSize(3);
314
-
315
- // Modify only the first and third widgets
316
- if (widgetElements[0]) {
317
- (widgetElements[0].componentInstance as TestWidgetComponent).updateValue();
318
- (widgetElements[0].componentInstance as TestWidgetComponent).incrementCounter();
319
- }
320
-
321
- if (widgetElements[2]) {
322
- (widgetElements[2].componentInstance as TestWidgetComponent).incrementCounter();
323
- (widgetElements[2].componentInstance as TestWidgetComponent).incrementCounter();
324
- }
325
-
326
- fixture.detectChanges();
327
- await fixture.whenStable();
328
-
329
- const exported = component.exportDashboard();
330
-
331
- expect(exported.cells).toHaveSize(3);
332
-
333
- // Check that the modified widgets have live state
334
- const cell1 = exported.cells.find(c => c.row === 1 && c.col === 1);
335
- const cell2 = exported.cells.find(c => c.row === 2 && c.col === 2);
336
- const cell3 = exported.cells.find(c => c.row === 3 && c.col === 3);
337
-
338
- expect(cell1?.widgetState).toEqual(
339
- jasmine.objectContaining({
340
- modified: true,
341
- counter: 2,
342
- })
343
- );
344
-
345
- expect(cell2?.widgetState).toEqual(
346
- jasmine.objectContaining({
347
- value: 'widget2',
348
- counter: 2,
349
- modified: false,
350
- })
351
- );
352
-
353
- expect(cell3?.widgetState).toEqual(
354
- jasmine.objectContaining({
355
- value: 'widget3',
356
- counter: 5,
357
- modified: true,
358
- })
359
- );
360
- });
361
- });
362
-
363
- describe('Widget state preservation during mode switching', () => {
364
- it('should preserve widget state when switching from edit to view mode', async () => {
365
- const initialState: TestWidgetState = {
366
- value: 'initial',
367
- counter: 0,
368
- modified: false,
369
- };
370
-
371
- // Create dashboard with a widget
372
- const dashboardData: DashboardDataDto = {
373
- version: '1.0.0',
374
- dashboardId: 'test-dashboard-mode-switch',
375
- rows: 5,
376
- columns: 8,
377
- gutterSize: '1em',
378
- cells: [
379
- {
380
- row: 2,
381
- col: 3,
382
- rowSpan: 1,
383
- colSpan: 1,
384
- widgetTypeid: 'test-widget',
385
- widgetState: initialState,
386
- },
387
- ],
388
- };
389
-
390
- // Set the dashboard data in edit mode
391
- fixture.componentRef.setInput('dashboardData', dashboardData);
392
- fixture.componentRef.setInput('editMode', true);
393
- fixture.detectChanges();
394
- await fixture.whenStable();
395
-
396
- // Find the widget component and modify its state in edit mode
397
- const widgetElementInEdit = fixture.debugElement.query(
398
- (el) => el.componentInstance instanceof TestWidgetComponent
399
- );
400
-
401
- expect(widgetElementInEdit).toBeTruthy();
402
-
403
- if (widgetElementInEdit) {
404
- const widgetComponent = widgetElementInEdit.componentInstance as TestWidgetComponent;
405
-
406
- // Modify the widget state
407
- widgetComponent.updateValue();
408
- widgetComponent.incrementCounter();
409
-
410
- // Detect changes
411
- fixture.detectChanges();
412
- await fixture.whenStable();
413
-
414
- // Verify the state was modified
415
- const currentState = widgetComponent.dashboardGetState();
416
- expect(currentState.modified).toBe(true);
417
- expect(currentState.counter).toBe(1);
418
- expect(currentState.value).toContain('updated-');
419
-
420
- // Now switch to view mode
421
- fixture.componentRef.setInput('editMode', false);
422
- fixture.detectChanges();
423
- await fixture.whenStable();
424
-
425
- // Find the widget component in view mode
426
- const widgetElementInView = fixture.debugElement.query(
427
- (el) => el.componentInstance instanceof TestWidgetComponent
428
- );
429
-
430
- expect(widgetElementInView).toBeTruthy();
431
-
432
- if (widgetElementInView) {
433
- const widgetComponentInView = widgetElementInView.componentInstance as TestWidgetComponent;
434
-
435
- // Check if the widget state was preserved
436
- const viewModeState = widgetComponentInView.dashboardGetState();
437
-
438
- // This is the current bug - the state is lost when switching modes
439
- // The widget gets recreated with the original state from the store
440
- expect(viewModeState.modified).toBe(true); // This will currently fail
441
- expect(viewModeState.counter).toBe(1); // This will currently fail
442
- expect(viewModeState.value).toContain('updated-'); // This will currently fail
443
- } else {
444
- fail('Widget component not found in view mode');
445
- }
446
- } else {
447
- fail('Widget component not found in edit mode');
448
- }
449
- });
450
-
451
- it('should preserve widget state when switching from view to edit mode', async () => {
452
- const initialState: TestWidgetState = {
453
- value: 'initial',
454
- counter: 5,
455
- modified: false,
456
- };
457
-
458
- // Create dashboard with a widget
459
- const dashboardData: DashboardDataDto = {
460
- version: '1.0.0',
461
- dashboardId: 'test-dashboard-view-to-edit',
462
- rows: 5,
463
- columns: 8,
464
- gutterSize: '1em',
465
- cells: [
466
- {
467
- row: 1,
468
- col: 1,
469
- rowSpan: 1,
470
- colSpan: 1,
471
- widgetTypeid: 'test-widget',
472
- widgetState: initialState,
473
- },
474
- ],
475
- };
476
-
477
- // Set the dashboard data in view mode first
478
- fixture.componentRef.setInput('dashboardData', dashboardData);
479
- fixture.componentRef.setInput('editMode', false);
480
- fixture.detectChanges();
481
- await fixture.whenStable();
482
-
483
- // Find the widget component and modify its state in view mode
484
- const widgetElementInView = fixture.debugElement.query(
485
- (el) => el.componentInstance instanceof TestWidgetComponent
486
- );
487
-
488
- expect(widgetElementInView).toBeTruthy();
489
-
490
- if (widgetElementInView) {
491
- const widgetComponent = widgetElementInView.componentInstance as TestWidgetComponent;
492
-
493
- // Modify the widget state
494
- widgetComponent.updateValue();
495
- widgetComponent.incrementCounter();
496
-
497
- // Detect changes
498
- fixture.detectChanges();
499
- await fixture.whenStable();
500
-
501
- // Verify the state was modified
502
- const currentState = widgetComponent.dashboardGetState();
503
- expect(currentState.modified).toBe(true);
504
- expect(currentState.counter).toBe(6);
505
- expect(currentState.value).toContain('updated-');
506
-
507
- // Now switch to edit mode
508
- fixture.componentRef.setInput('editMode', true);
509
- fixture.detectChanges();
510
- await fixture.whenStable();
511
-
512
- // Find the widget component in edit mode
513
- const widgetElementInEdit = fixture.debugElement.query(
514
- (el) => el.componentInstance instanceof TestWidgetComponent
515
- );
516
-
517
- expect(widgetElementInEdit).toBeTruthy();
518
-
519
- if (widgetElementInEdit) {
520
- const widgetComponentInEdit = widgetElementInEdit.componentInstance as TestWidgetComponent;
521
-
522
- // Check if the widget state was preserved
523
- const editModeState = widgetComponentInEdit.dashboardGetState();
524
-
525
- // This is the current bug - the state is lost when switching modes
526
- expect(editModeState.modified).toBe(true); // This will currently fail
527
- expect(editModeState.counter).toBe(6); // This will currently fail
528
- expect(editModeState.value).toContain('updated-'); // This will currently fail
529
- } else {
530
- fail('Widget component not found in edit mode');
531
- }
532
- } else {
533
- fail('Widget component not found in view mode');
534
- }
535
- });
536
- });
537
- });