@dragonworks/ngx-dashboard 20.0.5 → 20.0.6
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.
- package/ng-package.json +7 -0
- package/package.json +34 -45
- package/src/lib/__tests__/dashboard-component-widget-state-integration.spec.ts +537 -0
- package/src/lib/cell/__tests__/cell-resize.component.spec.ts +442 -0
- package/src/lib/cell/__tests__/cell.component.spec.ts +541 -0
- package/src/lib/cell/cell-context-menu.component.ts +138 -0
- package/src/lib/cell/cell-context-menu.service.ts +36 -0
- package/src/lib/cell/cell.component.html +37 -0
- package/src/lib/cell/cell.component.scss +198 -0
- package/src/lib/cell/cell.component.ts +375 -0
- package/src/lib/dashboard/dashboard.component.html +18 -0
- package/src/lib/dashboard/dashboard.component.scss +17 -0
- package/src/lib/dashboard/dashboard.component.ts +187 -0
- package/src/lib/dashboard-editor/dashboard-editor.component.html +57 -0
- package/src/lib/dashboard-editor/dashboard-editor.component.scss +87 -0
- package/src/lib/dashboard-editor/dashboard-editor.component.ts +219 -0
- package/src/lib/dashboard-viewer/__tests__/dashboard-viewer.component.spec.ts +258 -0
- package/src/lib/dashboard-viewer/dashboard-viewer.component.html +20 -0
- package/src/lib/dashboard-viewer/dashboard-viewer.component.scss +50 -0
- package/src/lib/dashboard-viewer/dashboard-viewer.component.ts +70 -0
- package/src/lib/drop-zone/__tests__/drop-zone.component.spec.ts +465 -0
- package/src/lib/drop-zone/drop-zone.component.html +20 -0
- package/src/lib/drop-zone/drop-zone.component.scss +67 -0
- package/src/lib/drop-zone/drop-zone.component.ts +122 -0
- package/src/lib/internal-widgets/unknown-widget/unknown-widget.component.ts +72 -0
- package/src/lib/models/cell-data.ts +13 -0
- package/src/lib/models/cell-dialog.ts +7 -0
- package/src/lib/models/cell-id.ts +85 -0
- package/src/lib/models/cell-position.ts +15 -0
- package/src/lib/models/dashboard-data.dto.ts +44 -0
- package/src/lib/models/dashboard-data.utils.ts +49 -0
- package/src/lib/models/drag-data.ts +6 -0
- package/src/lib/models/index.ts +11 -0
- package/src/lib/models/reserved-space.ts +24 -0
- package/src/lib/models/widget-factory.ts +33 -0
- package/src/lib/models/widget-id.ts +70 -0
- package/src/lib/models/widget.ts +21 -0
- package/src/lib/providers/cell-settings-dialog/cell-settings-dialog.component.ts +127 -0
- package/src/lib/providers/cell-settings-dialog/cell-settings-dialog.provider.ts +15 -0
- package/src/lib/providers/cell-settings-dialog/cell-settings-dialog.tokens.ts +20 -0
- package/src/lib/providers/cell-settings-dialog/default-cell-settings-dialog.provider.ts +32 -0
- package/src/lib/providers/cell-settings-dialog/index.ts +3 -0
- package/src/lib/providers/index.ts +1 -0
- package/src/lib/services/__tests__/dashboard-bridge.service.spec.ts +220 -0
- package/src/lib/services/__tests__/dashboard-viewport.service.spec.ts +362 -0
- package/src/lib/services/dashboard-bridge.service.ts +155 -0
- package/src/lib/services/dashboard-viewport.service.ts +148 -0
- package/src/lib/services/dashboard.service.ts +62 -0
- package/src/lib/store/__tests__/dashboard-store-collision-detection.spec.ts +756 -0
- package/src/lib/store/__tests__/dashboard-store-computed-properties.spec.ts +974 -0
- package/src/lib/store/__tests__/dashboard-store-drag-drop.spec.ts +279 -0
- package/src/lib/store/__tests__/dashboard-store-export-import.spec.ts +780 -0
- package/src/lib/store/__tests__/dashboard-store-grid-config.spec.ts +128 -0
- package/src/lib/store/__tests__/dashboard-store-query-methods.spec.ts +229 -0
- package/src/lib/store/__tests__/dashboard-store-resize-operations.spec.ts +652 -0
- package/src/lib/store/__tests__/dashboard-store-widget-management.spec.ts +461 -0
- package/src/lib/store/__tests__/dashboard-store-widget-state-preservation.spec.ts +369 -0
- package/src/lib/store/dashboard-store.ts +239 -0
- package/src/lib/store/features/drag-drop.feature.ts +140 -0
- package/src/lib/store/features/grid-config.feature.ts +43 -0
- package/src/lib/store/features/resize.feature.ts +140 -0
- package/src/lib/store/features/utils/collision.utils.ts +89 -0
- package/src/lib/store/features/utils/grid-query-internal.utils.ts +37 -0
- package/src/lib/store/features/utils/resize.utils.ts +165 -0
- package/src/lib/store/features/widget-management.feature.ts +158 -0
- package/src/lib/styles/_dashboard-grid-vars.scss +11 -0
- package/src/lib/widget-list/__tests__/widget-list-bridge-integration.spec.ts +137 -0
- package/src/lib/widget-list/widget-list.component.html +22 -0
- package/src/lib/widget-list/widget-list.component.scss +154 -0
- package/src/lib/widget-list/widget-list.component.ts +106 -0
- package/src/public-api.ts +21 -0
- package/src/test-setup.ts +10 -0
- package/tsconfig.lib.json +15 -0
- package/tsconfig.lib.prod.json +11 -0
- package/tsconfig.spec.json +14 -0
- package/fesm2022/dragonworks-ngx-dashboard.mjs +0 -2178
- package/fesm2022/dragonworks-ngx-dashboard.mjs.map +0 -1
- package/index.d.ts +0 -678
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import { TestBed } from '@angular/core/testing';
|
|
2
|
+
import { DashboardService } from '../../services/dashboard.service';
|
|
3
|
+
import { DashboardStore } from '../dashboard-store';
|
|
4
|
+
|
|
5
|
+
describe('DashboardStore - Grid Configuration', () => {
|
|
6
|
+
let store: InstanceType<typeof DashboardStore>;
|
|
7
|
+
let mockDashboardService: jasmine.SpyObj<DashboardService>;
|
|
8
|
+
|
|
9
|
+
beforeEach(() => {
|
|
10
|
+
const dashboardServiceSpy = jasmine.createSpyObj('DashboardService', ['getFactory']);
|
|
11
|
+
|
|
12
|
+
TestBed.configureTestingModule({
|
|
13
|
+
providers: [
|
|
14
|
+
DashboardStore,
|
|
15
|
+
{ provide: DashboardService, useValue: dashboardServiceSpy }
|
|
16
|
+
]
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
store = TestBed.inject(DashboardStore);
|
|
20
|
+
mockDashboardService = TestBed.inject(DashboardService) as jasmine.SpyObj<DashboardService>;
|
|
21
|
+
store.setGridConfig({ rows: 8, columns: 16 });
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
describe('setGridConfig', () => {
|
|
25
|
+
it('should update rows only', () => {
|
|
26
|
+
store.setGridConfig({ rows: 12 });
|
|
27
|
+
expect(store.rows()).toBe(12);
|
|
28
|
+
expect(store.columns()).toBe(16); // unchanged
|
|
29
|
+
expect(store.gutterSize()).toBe('0.5em'); // unchanged
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
it('should update columns only', () => {
|
|
33
|
+
store.setGridConfig({ columns: 20 });
|
|
34
|
+
expect(store.columns()).toBe(20);
|
|
35
|
+
expect(store.rows()).toBe(8); // unchanged
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
it('should update gutterSize only', () => {
|
|
39
|
+
store.setGridConfig({ gutterSize: '1em' });
|
|
40
|
+
expect(store.gutterSize()).toBe('1em');
|
|
41
|
+
expect(store.rows()).toBe(8); // unchanged
|
|
42
|
+
expect(store.columns()).toBe(16); // unchanged
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
it('should update multiple properties at once', () => {
|
|
46
|
+
store.setGridConfig({ rows: 10, columns: 24, gutterSize: '2rem' });
|
|
47
|
+
expect(store.rows()).toBe(10);
|
|
48
|
+
expect(store.columns()).toBe(24);
|
|
49
|
+
expect(store.gutterSize()).toBe('2rem');
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
it('should handle edge case values', () => {
|
|
53
|
+
store.setGridConfig({ rows: 1, columns: 1, gutterSize: '0px' });
|
|
54
|
+
expect(store.rows()).toBe(1);
|
|
55
|
+
expect(store.columns()).toBe(1);
|
|
56
|
+
expect(store.gutterSize()).toBe('0px');
|
|
57
|
+
});
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
describe('setGridCellDimensions', () => {
|
|
61
|
+
it('should update grid cell dimensions', () => {
|
|
62
|
+
store.setGridCellDimensions(100, 50);
|
|
63
|
+
expect(store.gridCellDimensions()).toEqual({ width: 100, height: 50 });
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
it('should handle zero dimensions', () => {
|
|
67
|
+
store.setGridCellDimensions(0, 0);
|
|
68
|
+
expect(store.gridCellDimensions()).toEqual({ width: 0, height: 0 });
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
it('should handle large dimensions', () => {
|
|
72
|
+
store.setGridCellDimensions(9999, 9999);
|
|
73
|
+
expect(store.gridCellDimensions()).toEqual({ width: 9999, height: 9999 });
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
it('should handle fractional dimensions', () => {
|
|
77
|
+
store.setGridCellDimensions(100.5, 75.25);
|
|
78
|
+
expect(store.gridCellDimensions()).toEqual({ width: 100.5, height: 75.25 });
|
|
79
|
+
});
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
describe('toggleEditMode', () => {
|
|
83
|
+
it('should toggle from false to true', () => {
|
|
84
|
+
expect(store.isEditMode()).toBe(false);
|
|
85
|
+
store.toggleEditMode();
|
|
86
|
+
expect(store.isEditMode()).toBe(true);
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
it('should toggle from true to false', () => {
|
|
90
|
+
store.setEditMode(true);
|
|
91
|
+
expect(store.isEditMode()).toBe(true);
|
|
92
|
+
store.toggleEditMode();
|
|
93
|
+
expect(store.isEditMode()).toBe(false);
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
it('should toggle multiple times', () => {
|
|
97
|
+
expect(store.isEditMode()).toBe(false);
|
|
98
|
+
store.toggleEditMode();
|
|
99
|
+
expect(store.isEditMode()).toBe(true);
|
|
100
|
+
store.toggleEditMode();
|
|
101
|
+
expect(store.isEditMode()).toBe(false);
|
|
102
|
+
store.toggleEditMode();
|
|
103
|
+
expect(store.isEditMode()).toBe(true);
|
|
104
|
+
});
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
describe('setEditMode', () => {
|
|
108
|
+
it('should set edit mode to true', () => {
|
|
109
|
+
store.setEditMode(true);
|
|
110
|
+
expect(store.isEditMode()).toBe(true);
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
it('should set edit mode to false', () => {
|
|
114
|
+
store.setEditMode(false);
|
|
115
|
+
expect(store.isEditMode()).toBe(false);
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
it('should be idempotent', () => {
|
|
119
|
+
store.setEditMode(true);
|
|
120
|
+
store.setEditMode(true);
|
|
121
|
+
expect(store.isEditMode()).toBe(true);
|
|
122
|
+
|
|
123
|
+
store.setEditMode(false);
|
|
124
|
+
store.setEditMode(false);
|
|
125
|
+
expect(store.isEditMode()).toBe(false);
|
|
126
|
+
});
|
|
127
|
+
});
|
|
128
|
+
});
|
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
import { TestBed } from '@angular/core/testing';
|
|
2
|
+
import { DashboardService } from '../../services/dashboard.service';
|
|
3
|
+
import { DashboardStore } from '../dashboard-store';
|
|
4
|
+
import { CellIdUtils, WidgetIdUtils, CellData, WidgetFactory } from '../../models';
|
|
5
|
+
import { GridQueryInternalUtils } from '../features/utils/grid-query-internal.utils';
|
|
6
|
+
|
|
7
|
+
describe('DashboardStore - Grid Query Methods', () => {
|
|
8
|
+
let store: InstanceType<typeof DashboardStore>;
|
|
9
|
+
let mockWidgetFactory: WidgetFactory;
|
|
10
|
+
let mockDashboardService: jasmine.SpyObj<DashboardService>;
|
|
11
|
+
|
|
12
|
+
beforeEach(() => {
|
|
13
|
+
const dashboardServiceSpy = jasmine.createSpyObj('DashboardService', ['getFactory']);
|
|
14
|
+
|
|
15
|
+
TestBed.configureTestingModule({
|
|
16
|
+
providers: [
|
|
17
|
+
DashboardStore,
|
|
18
|
+
{ provide: DashboardService, useValue: dashboardServiceSpy }
|
|
19
|
+
]
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
store = TestBed.inject(DashboardStore);
|
|
23
|
+
mockDashboardService = TestBed.inject(DashboardService) as jasmine.SpyObj<DashboardService>;
|
|
24
|
+
store.setGridConfig({ rows: 10, columns: 10 });
|
|
25
|
+
|
|
26
|
+
mockWidgetFactory = {
|
|
27
|
+
widgetTypeid: 'test-widget',
|
|
28
|
+
createComponent: jasmine.createSpy()
|
|
29
|
+
} as any;
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
describe('isCellOccupied', () => {
|
|
33
|
+
it('should return false for empty grid', () => {
|
|
34
|
+
expect(GridQueryInternalUtils.isCellOccupied(store.cells(), 5, 5)).toBe(false);
|
|
35
|
+
expect(GridQueryInternalUtils.isCellOccupied(store.cells(), 1, 1)).toBe(false);
|
|
36
|
+
expect(GridQueryInternalUtils.isCellOccupied(store.cells(), 10, 10)).toBe(false);
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
it('should return true for occupied single cell', () => {
|
|
40
|
+
const cell: CellData = {
|
|
41
|
+
widgetId: WidgetIdUtils.generate(),
|
|
42
|
+
cellId: CellIdUtils.create(5, 5),
|
|
43
|
+
row: 5,
|
|
44
|
+
col: 5,
|
|
45
|
+
rowSpan: 1,
|
|
46
|
+
colSpan: 1,
|
|
47
|
+
widgetFactory: mockWidgetFactory,
|
|
48
|
+
widgetState: {},
|
|
49
|
+
};
|
|
50
|
+
store.addWidget(cell);
|
|
51
|
+
|
|
52
|
+
expect(GridQueryInternalUtils.isCellOccupied(store.cells(), 5, 5)).toBe(true);
|
|
53
|
+
expect(GridQueryInternalUtils.isCellOccupied(store.cells(), 4, 5)).toBe(false);
|
|
54
|
+
expect(GridQueryInternalUtils.isCellOccupied(store.cells(), 5, 4)).toBe(false);
|
|
55
|
+
expect(GridQueryInternalUtils.isCellOccupied(store.cells(), 6, 5)).toBe(false);
|
|
56
|
+
expect(GridQueryInternalUtils.isCellOccupied(store.cells(), 5, 6)).toBe(false);
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
it('should return true for cells within multi-cell widget', () => {
|
|
60
|
+
const cell: CellData = {
|
|
61
|
+
widgetId: WidgetIdUtils.generate(),
|
|
62
|
+
cellId: CellIdUtils.create(3, 4),
|
|
63
|
+
row: 3,
|
|
64
|
+
col: 4,
|
|
65
|
+
rowSpan: 3,
|
|
66
|
+
colSpan: 2,
|
|
67
|
+
widgetFactory: mockWidgetFactory,
|
|
68
|
+
widgetState: {},
|
|
69
|
+
};
|
|
70
|
+
store.addWidget(cell);
|
|
71
|
+
|
|
72
|
+
// Check all cells within the widget (3,4) to (5,5)
|
|
73
|
+
expect(GridQueryInternalUtils.isCellOccupied(store.cells(), 3, 4)).toBe(true);
|
|
74
|
+
expect(GridQueryInternalUtils.isCellOccupied(store.cells(), 3, 5)).toBe(true);
|
|
75
|
+
expect(GridQueryInternalUtils.isCellOccupied(store.cells(), 4, 4)).toBe(true);
|
|
76
|
+
expect(GridQueryInternalUtils.isCellOccupied(store.cells(), 4, 5)).toBe(true);
|
|
77
|
+
expect(GridQueryInternalUtils.isCellOccupied(store.cells(), 5, 4)).toBe(true);
|
|
78
|
+
expect(GridQueryInternalUtils.isCellOccupied(store.cells(), 5, 5)).toBe(true);
|
|
79
|
+
|
|
80
|
+
// Check boundary cells
|
|
81
|
+
expect(GridQueryInternalUtils.isCellOccupied(store.cells(), 2, 4)).toBe(false);
|
|
82
|
+
expect(GridQueryInternalUtils.isCellOccupied(store.cells(), 3, 3)).toBe(false);
|
|
83
|
+
expect(GridQueryInternalUtils.isCellOccupied(store.cells(), 6, 4)).toBe(false);
|
|
84
|
+
expect(GridQueryInternalUtils.isCellOccupied(store.cells(), 3, 6)).toBe(false);
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
it('should exclude specified widget from occupation check', () => {
|
|
88
|
+
const cellId = CellIdUtils.create(5, 5);
|
|
89
|
+
const widgetId = WidgetIdUtils.generate();
|
|
90
|
+
const cell: CellData = {
|
|
91
|
+
widgetId,
|
|
92
|
+
cellId,
|
|
93
|
+
row: 5,
|
|
94
|
+
col: 5,
|
|
95
|
+
rowSpan: 2,
|
|
96
|
+
colSpan: 2,
|
|
97
|
+
widgetFactory: mockWidgetFactory,
|
|
98
|
+
widgetState: {},
|
|
99
|
+
};
|
|
100
|
+
store.addWidget(cell);
|
|
101
|
+
|
|
102
|
+
// Without exclusion
|
|
103
|
+
expect(GridQueryInternalUtils.isCellOccupied(store.cells(), 5, 5)).toBe(true);
|
|
104
|
+
expect(GridQueryInternalUtils.isCellOccupied(store.cells(), 6, 6)).toBe(true);
|
|
105
|
+
|
|
106
|
+
// With exclusion (now using widgetId instead of cellId)
|
|
107
|
+
expect(GridQueryInternalUtils.isCellOccupied(store.cells(), 5, 5, widgetId)).toBe(false);
|
|
108
|
+
expect(GridQueryInternalUtils.isCellOccupied(store.cells(), 6, 6, widgetId)).toBe(false);
|
|
109
|
+
});
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
describe('isOutOfBounds', () => {
|
|
113
|
+
it('should return false for valid single cell placement', () => {
|
|
114
|
+
expect(GridQueryInternalUtils.isOutOfBounds(1, 1, 1, 1, 10, 10)).toBe(false);
|
|
115
|
+
expect(GridQueryInternalUtils.isOutOfBounds(5, 5, 1, 1, 10, 10)).toBe(false);
|
|
116
|
+
expect(GridQueryInternalUtils.isOutOfBounds(10, 10, 1, 1, 10, 10)).toBe(false);
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
it('should return false for valid multi-cell placement', () => {
|
|
120
|
+
expect(GridQueryInternalUtils.isOutOfBounds(1, 1, 3, 3, 10, 10)).toBe(false);
|
|
121
|
+
expect(GridQueryInternalUtils.isOutOfBounds(8, 8, 3, 3, 10, 10)).toBe(false);
|
|
122
|
+
expect(GridQueryInternalUtils.isOutOfBounds(1, 8, 3, 3, 10, 10)).toBe(false);
|
|
123
|
+
expect(GridQueryInternalUtils.isOutOfBounds(8, 1, 3, 3, 10, 10)).toBe(false);
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
it('should return true for row out of bounds', () => {
|
|
127
|
+
expect(GridQueryInternalUtils.isOutOfBounds(11, 5, 1, 1, 10, 10)).toBe(true);
|
|
128
|
+
expect(GridQueryInternalUtils.isOutOfBounds(9, 5, 3, 1, 10, 10)).toBe(true); // Spans to row 11
|
|
129
|
+
expect(GridQueryInternalUtils.isOutOfBounds(10, 5, 2, 1, 10, 10)).toBe(true); // Spans to row 11
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
it('should return true for column out of bounds', () => {
|
|
133
|
+
expect(GridQueryInternalUtils.isOutOfBounds(5, 11, 1, 1, 10, 10)).toBe(true);
|
|
134
|
+
expect(GridQueryInternalUtils.isOutOfBounds(5, 9, 1, 3, 10, 10)).toBe(true); // Spans to col 11
|
|
135
|
+
expect(GridQueryInternalUtils.isOutOfBounds(5, 10, 1, 2, 10, 10)).toBe(true); // Spans to col 11
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
it('should return true for both row and column out of bounds', () => {
|
|
139
|
+
expect(GridQueryInternalUtils.isOutOfBounds(11, 11, 1, 1, 10, 10)).toBe(true);
|
|
140
|
+
expect(GridQueryInternalUtils.isOutOfBounds(9, 9, 3, 3, 10, 10)).toBe(true); // Spans to (11,11)
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
it('should handle edge cases at exact boundaries', () => {
|
|
144
|
+
expect(GridQueryInternalUtils.isOutOfBounds(10, 10, 1, 1, 10, 10)).toBe(false); // Exactly at boundary
|
|
145
|
+
expect(GridQueryInternalUtils.isOutOfBounds(8, 8, 3, 3, 10, 10)).toBe(false); // Spans exactly to boundary
|
|
146
|
+
expect(GridQueryInternalUtils.isOutOfBounds(9, 9, 2, 2, 10, 10)).toBe(false); // Spans exactly to boundary
|
|
147
|
+
});
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
describe('getCellAt', () => {
|
|
151
|
+
it('should return null for empty grid', () => {
|
|
152
|
+
expect(GridQueryInternalUtils.getCellAt(store.cells(), 5, 5)).toBeNull();
|
|
153
|
+
expect(GridQueryInternalUtils.getCellAt(store.cells(), 1, 1)).toBeNull();
|
|
154
|
+
expect(GridQueryInternalUtils.getCellAt(store.cells(), 10, 10)).toBeNull();
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
it('should return cell at exact position', () => {
|
|
158
|
+
const cell: CellData = {
|
|
159
|
+
widgetId: WidgetIdUtils.generate(),
|
|
160
|
+
cellId: CellIdUtils.create(3, 7),
|
|
161
|
+
row: 3,
|
|
162
|
+
col: 7,
|
|
163
|
+
rowSpan: 1,
|
|
164
|
+
colSpan: 1,
|
|
165
|
+
widgetFactory: mockWidgetFactory,
|
|
166
|
+
widgetState: {},
|
|
167
|
+
};
|
|
168
|
+
store.addWidget(cell);
|
|
169
|
+
|
|
170
|
+
expect(GridQueryInternalUtils.getCellAt(store.cells(), 3, 7)).toBe(cell);
|
|
171
|
+
expect(GridQueryInternalUtils.getCellAt(store.cells(), 3, 6)).toBeNull();
|
|
172
|
+
expect(GridQueryInternalUtils.getCellAt(store.cells(), 4, 7)).toBeNull();
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
it('should return null for cells within multi-cell widget but not at origin', () => {
|
|
176
|
+
const cell: CellData = {
|
|
177
|
+
widgetId: WidgetIdUtils.generate(),
|
|
178
|
+
cellId: CellIdUtils.create(5, 5),
|
|
179
|
+
row: 5,
|
|
180
|
+
col: 5,
|
|
181
|
+
rowSpan: 3,
|
|
182
|
+
colSpan: 3,
|
|
183
|
+
widgetFactory: mockWidgetFactory,
|
|
184
|
+
widgetState: {},
|
|
185
|
+
};
|
|
186
|
+
store.addWidget(cell);
|
|
187
|
+
|
|
188
|
+
// Only origin position should return the cell
|
|
189
|
+
expect(GridQueryInternalUtils.getCellAt(store.cells(), 5, 5)).toBe(cell);
|
|
190
|
+
|
|
191
|
+
// Other positions within the widget should return null
|
|
192
|
+
expect(GridQueryInternalUtils.getCellAt(store.cells(), 5, 6)).toBeNull();
|
|
193
|
+
expect(GridQueryInternalUtils.getCellAt(store.cells(), 6, 5)).toBeNull();
|
|
194
|
+
expect(GridQueryInternalUtils.getCellAt(store.cells(), 7, 7)).toBeNull();
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
it('should handle multiple widgets correctly', () => {
|
|
198
|
+
const cell1: CellData = {
|
|
199
|
+
widgetId: WidgetIdUtils.generate(),
|
|
200
|
+
cellId: CellIdUtils.create(2, 2),
|
|
201
|
+
row: 2,
|
|
202
|
+
col: 2,
|
|
203
|
+
rowSpan: 1,
|
|
204
|
+
colSpan: 1,
|
|
205
|
+
widgetFactory: mockWidgetFactory,
|
|
206
|
+
widgetState: {},
|
|
207
|
+
};
|
|
208
|
+
|
|
209
|
+
const cell2: CellData = {
|
|
210
|
+
widgetId: WidgetIdUtils.generate(),
|
|
211
|
+
cellId: CellIdUtils.create(8, 8),
|
|
212
|
+
row: 8,
|
|
213
|
+
col: 8,
|
|
214
|
+
rowSpan: 2,
|
|
215
|
+
colSpan: 2,
|
|
216
|
+
widgetFactory: mockWidgetFactory,
|
|
217
|
+
widgetState: {},
|
|
218
|
+
};
|
|
219
|
+
|
|
220
|
+
store.addWidget(cell1);
|
|
221
|
+
store.addWidget(cell2);
|
|
222
|
+
|
|
223
|
+
expect(GridQueryInternalUtils.getCellAt(store.cells(), 2, 2)).toBe(cell1);
|
|
224
|
+
expect(GridQueryInternalUtils.getCellAt(store.cells(), 8, 8)).toBe(cell2);
|
|
225
|
+
expect(GridQueryInternalUtils.getCellAt(store.cells(), 5, 5)).toBeNull();
|
|
226
|
+
expect(GridQueryInternalUtils.getCellAt(store.cells(), 8, 9)).toBeNull(); // Within cell2 but not at origin
|
|
227
|
+
});
|
|
228
|
+
});
|
|
229
|
+
});
|