@dragonworks/ngx-dashboard 21.2.1 → 22.0.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.
|
@@ -23,7 +23,7 @@ import { isPlatformBrowser } from '@angular/common';
|
|
|
23
23
|
|
|
24
24
|
// Auto-generated by scripts/generate-versions.js
|
|
25
25
|
// Do not edit manually
|
|
26
|
-
const NGX_DASHBOARD_VERSION = '
|
|
26
|
+
const NGX_DASHBOARD_VERSION = '22.0.0';
|
|
27
27
|
|
|
28
28
|
/**
|
|
29
29
|
* Maximum number of columns supported by the grid.
|
|
@@ -232,8 +232,10 @@ class UnknownWidgetComponent {
|
|
|
232
232
|
};
|
|
233
233
|
state = signal({
|
|
234
234
|
originalWidgetTypeid: 'unknown',
|
|
235
|
-
},
|
|
236
|
-
|
|
235
|
+
}, /* @ts-ignore */
|
|
236
|
+
...(ngDevMode ? [{ debugName: "state" }] : /* istanbul ignore next */ []));
|
|
237
|
+
tooltipText = computed(() => `${this.state().originalWidgetTypeid}`, /* @ts-ignore */
|
|
238
|
+
...(ngDevMode ? [{ debugName: "tooltipText" }] : /* istanbul ignore next */ []));
|
|
237
239
|
dashboardSetState(state) {
|
|
238
240
|
if (state && typeof state === 'object' && 'originalWidgetTypeid' in state) {
|
|
239
241
|
this.state.set(state);
|
|
@@ -242,14 +244,14 @@ class UnknownWidgetComponent {
|
|
|
242
244
|
dashboardGetState() {
|
|
243
245
|
return this.state();
|
|
244
246
|
}
|
|
245
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
246
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "
|
|
247
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: UnknownWidgetComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
248
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.0.4", type: UnknownWidgetComponent, isStandalone: true, selector: "lib-unknown-widget", ngImport: i0, template: `
|
|
247
249
|
<div class="unknown-widget-container" [matTooltip]="tooltipText()">
|
|
248
250
|
<mat-icon class="unknown-widget-icon">error_outline</mat-icon>
|
|
249
251
|
</div>
|
|
250
252
|
`, isInline: true, styles: [".unknown-widget-container{display:flex;align-items:center;justify-content:center;width:100%;height:100%;background-color:var(--mat-sys-error);border-radius:8px;container-type:size}.unknown-widget-icon{color:var(--mat-sys-on-error);font-size:clamp(12px,75cqmin,68px);width:clamp(12px,75cqmin,68px);height:clamp(12px,75cqmin,68px)}\n"], dependencies: [{ kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i2$1.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
251
253
|
}
|
|
252
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
254
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: UnknownWidgetComponent, decorators: [{
|
|
253
255
|
type: Component,
|
|
254
256
|
args: [{ selector: 'lib-unknown-widget', imports: [MatIconModule, MatTooltipModule], template: `
|
|
255
257
|
<div class="unknown-widget-container" [matTooltip]="tooltipText()">
|
|
@@ -260,7 +262,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.10", ngImpo
|
|
|
260
262
|
|
|
261
263
|
// dashboard.service.ts
|
|
262
264
|
class DashboardService {
|
|
263
|
-
#widgetTypes = signal([],
|
|
265
|
+
#widgetTypes = signal([], /* @ts-ignore */
|
|
266
|
+
...(ngDevMode ? [{ debugName: "#widgetTypes" }] : /* istanbul ignore next */ []));
|
|
264
267
|
#widgetFactoryMap = new Map();
|
|
265
268
|
#sharedStateProviders = new Map();
|
|
266
269
|
#pendingSharedStates = new Map();
|
|
@@ -362,10 +365,10 @@ class DashboardService {
|
|
|
362
365
|
}
|
|
363
366
|
}
|
|
364
367
|
}
|
|
365
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
366
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "
|
|
368
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: DashboardService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
369
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: DashboardService, providedIn: 'root' });
|
|
367
370
|
}
|
|
368
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
371
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: DashboardService, decorators: [{
|
|
369
372
|
type: Injectable,
|
|
370
373
|
args: [{
|
|
371
374
|
providedIn: 'root',
|
|
@@ -1143,8 +1146,8 @@ class CellSettingsDialogComponent {
|
|
|
1143
1146
|
};
|
|
1144
1147
|
this.dialogRef.close(newData);
|
|
1145
1148
|
}
|
|
1146
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
1147
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "
|
|
1149
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: CellSettingsDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1150
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.0.4", type: CellSettingsDialogComponent, isStandalone: true, selector: "lib-cell-settings-dialog", ngImport: i0, template: `
|
|
1148
1151
|
<h2 mat-dialog-title i18n="@@ngx.dashboard.cell.settings.title">
|
|
1149
1152
|
Cell Display Settings
|
|
1150
1153
|
</h2>
|
|
@@ -1210,7 +1213,7 @@ class CellSettingsDialogComponent {
|
|
|
1210
1213
|
</mat-dialog-actions>
|
|
1211
1214
|
`, isInline: true, styles: ["mat-dialog-content{display:block;overflow-y:auto;overflow-x:hidden;padding-top:.5rem}.cell-info{margin:0 0 1.5rem;padding-bottom:1rem}.radio-group{width:100%}mat-radio-group{display:block}mat-radio-button{width:100%;display:block;margin-bottom:1rem}mat-radio-button:last-child{margin-bottom:0}.radio-option{margin-left:.75rem;padding:.25rem 0}.option-title{display:block;margin-bottom:.25rem}.option-description{display:block}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: MatDialogModule }, { kind: "directive", type: i2$2.MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { kind: "directive", type: i2$2.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]", inputs: ["align"] }, { kind: "directive", type: i2$2.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i4.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatRadioModule }, { kind: "directive", type: i4$1.MatRadioGroup, selector: "mat-radio-group", inputs: ["color", "name", "labelPosition", "value", "selected", "disabled", "required", "disabledInteractive"], outputs: ["change"], exportAs: ["matRadioGroup"] }, { kind: "component", type: i4$1.MatRadioButton, selector: "mat-radio-button", inputs: ["id", "name", "aria-label", "aria-labelledby", "aria-describedby", "disableRipple", "tabIndex", "checked", "value", "labelPosition", "disabled", "required", "color", "disabledInteractive"], outputs: ["change"], exportAs: ["matRadioButton"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
1212
1215
|
}
|
|
1213
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
1216
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: CellSettingsDialogComponent, decorators: [{
|
|
1214
1217
|
type: Component,
|
|
1215
1218
|
args: [{ selector: 'lib-cell-settings-dialog', changeDetection: ChangeDetectionStrategy.OnPush, imports: [
|
|
1216
1219
|
FormsModule,
|
|
@@ -1301,10 +1304,10 @@ class DefaultCellSettingsDialogProvider extends CellSettingsDialogProvider {
|
|
|
1301
1304
|
const result = await firstValueFrom(dialogRef.afterClosed());
|
|
1302
1305
|
return result;
|
|
1303
1306
|
}
|
|
1304
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
1305
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "
|
|
1307
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: DefaultCellSettingsDialogProvider, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
|
|
1308
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: DefaultCellSettingsDialogProvider, providedIn: 'root' });
|
|
1306
1309
|
}
|
|
1307
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
1310
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: DefaultCellSettingsDialogProvider, decorators: [{
|
|
1308
1311
|
type: Injectable,
|
|
1309
1312
|
args: [{
|
|
1310
1313
|
providedIn: 'root',
|
|
@@ -1328,7 +1331,8 @@ const CELL_SETTINGS_DIALOG_PROVIDER = new InjectionToken('CellSettingsDialogProv
|
|
|
1328
1331
|
});
|
|
1329
1332
|
|
|
1330
1333
|
class CellContextMenuService {
|
|
1331
|
-
#activeMenu = signal(null,
|
|
1334
|
+
#activeMenu = signal(null, /* @ts-ignore */
|
|
1335
|
+
...(ngDevMode ? [{ debugName: "#activeMenu" }] : /* istanbul ignore next */ []));
|
|
1332
1336
|
activeMenu = this.#activeMenu.asReadonly();
|
|
1333
1337
|
show(x, y, items) {
|
|
1334
1338
|
this.#activeMenu.set({ x, y, items });
|
|
@@ -1336,26 +1340,37 @@ class CellContextMenuService {
|
|
|
1336
1340
|
hide() {
|
|
1337
1341
|
this.#activeMenu.set(null);
|
|
1338
1342
|
}
|
|
1339
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
1340
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "
|
|
1343
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: CellContextMenuService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
1344
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: CellContextMenuService });
|
|
1341
1345
|
}
|
|
1342
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
1346
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: CellContextMenuService, decorators: [{
|
|
1343
1347
|
type: Injectable
|
|
1344
1348
|
}] });
|
|
1345
1349
|
|
|
1346
1350
|
// cell.component.ts
|
|
1347
1351
|
class CellComponent {
|
|
1348
|
-
widgetId = input.required(
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1352
|
+
widgetId = input.required(/* @ts-ignore */
|
|
1353
|
+
...(ngDevMode ? [{ debugName: "widgetId" }] : /* istanbul ignore next */ [])); // Unique widget instance identifier
|
|
1354
|
+
cellId = input.required(/* @ts-ignore */
|
|
1355
|
+
...(ngDevMode ? [{ debugName: "cellId" }] : /* istanbul ignore next */ [])); // Current grid position
|
|
1356
|
+
widgetFactory = input(undefined, /* @ts-ignore */
|
|
1357
|
+
...(ngDevMode ? [{ debugName: "widgetFactory" }] : /* istanbul ignore next */ []));
|
|
1358
|
+
widgetState = input(undefined, /* @ts-ignore */
|
|
1359
|
+
...(ngDevMode ? [{ debugName: "widgetState" }] : /* istanbul ignore next */ []));
|
|
1360
|
+
isEditMode = input(false, /* @ts-ignore */
|
|
1361
|
+
...(ngDevMode ? [{ debugName: "isEditMode" }] : /* istanbul ignore next */ []));
|
|
1362
|
+
flat = input(undefined, /* @ts-ignore */
|
|
1363
|
+
...(ngDevMode ? [{ debugName: "flat" }] : /* istanbul ignore next */ []));
|
|
1364
|
+
row = model.required(/* @ts-ignore */
|
|
1365
|
+
...(ngDevMode ? [{ debugName: "row" }] : /* istanbul ignore next */ []));
|
|
1366
|
+
column = model.required(/* @ts-ignore */
|
|
1367
|
+
...(ngDevMode ? [{ debugName: "column" }] : /* istanbul ignore next */ []));
|
|
1368
|
+
rowSpan = input(1, /* @ts-ignore */
|
|
1369
|
+
...(ngDevMode ? [{ debugName: "rowSpan" }] : /* istanbul ignore next */ []));
|
|
1370
|
+
colSpan = input(1, /* @ts-ignore */
|
|
1371
|
+
...(ngDevMode ? [{ debugName: "colSpan" }] : /* istanbul ignore next */ []));
|
|
1372
|
+
draggable = input(false, /* @ts-ignore */
|
|
1373
|
+
...(ngDevMode ? [{ debugName: "draggable" }] : /* istanbul ignore next */ []));
|
|
1359
1374
|
dragStart = output();
|
|
1360
1375
|
dragEnd = output();
|
|
1361
1376
|
edit = output();
|
|
@@ -1376,20 +1391,27 @@ class CellComponent {
|
|
|
1376
1391
|
// Document event listeners cleanup function
|
|
1377
1392
|
// Performance: Only created when actively resizing, not for every cell
|
|
1378
1393
|
#documentListeners;
|
|
1379
|
-
isDragging = signal(false,
|
|
1380
|
-
|
|
1381
|
-
|
|
1394
|
+
isDragging = signal(false, /* @ts-ignore */
|
|
1395
|
+
...(ngDevMode ? [{ debugName: "isDragging" }] : /* istanbul ignore next */ []));
|
|
1396
|
+
gridRowStyle = computed(() => `${this.row()} / span ${this.rowSpan()}`, /* @ts-ignore */
|
|
1397
|
+
...(ngDevMode ? [{ debugName: "gridRowStyle" }] : /* istanbul ignore next */ []));
|
|
1398
|
+
gridColumnStyle = computed(() => `${this.column()} / span ${this.colSpan()}`, /* @ts-ignore */
|
|
1399
|
+
...(ngDevMode ? [{ debugName: "gridColumnStyle" }] : /* istanbul ignore next */ []));
|
|
1382
1400
|
isResizing = computed(() => {
|
|
1383
1401
|
const resizeData = this.#store.resizeData();
|
|
1384
1402
|
return resizeData
|
|
1385
1403
|
? CellIdUtils.equals(resizeData.cellId, this.cellId())
|
|
1386
1404
|
: false;
|
|
1387
|
-
},
|
|
1388
|
-
|
|
1405
|
+
}, /* @ts-ignore */
|
|
1406
|
+
...(ngDevMode ? [{ debugName: "isResizing" }] : /* istanbul ignore next */ []));
|
|
1407
|
+
isDragActive = computed(() => !!this.#store.dragData(), /* @ts-ignore */
|
|
1408
|
+
...(ngDevMode ? [{ debugName: "isDragActive" }] : /* istanbul ignore next */ []));
|
|
1389
1409
|
resizeData = this.#store.resizeData;
|
|
1390
1410
|
gridCellDimensions = this.#store.gridCellDimensions;
|
|
1391
|
-
resizeDirection = signal(null,
|
|
1392
|
-
|
|
1411
|
+
resizeDirection = signal(null, /* @ts-ignore */
|
|
1412
|
+
...(ngDevMode ? [{ debugName: "resizeDirection" }] : /* istanbul ignore next */ []));
|
|
1413
|
+
resizeStartPos = signal({ x: 0, y: 0 }, /* @ts-ignore */
|
|
1414
|
+
...(ngDevMode ? [{ debugName: "resizeStartPos" }] : /* istanbul ignore next */ []));
|
|
1393
1415
|
constructor() {
|
|
1394
1416
|
// widget creation - triggers when factory or state changes
|
|
1395
1417
|
effect(() => {
|
|
@@ -1624,10 +1646,10 @@ class CellComponent {
|
|
|
1624
1646
|
// Fall back to stored state if widget doesn't implement dashboardGetState
|
|
1625
1647
|
return this.widgetState();
|
|
1626
1648
|
}
|
|
1627
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
1628
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "
|
|
1649
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: CellComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1650
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.4", type: CellComponent, isStandalone: true, selector: "lib-cell", inputs: { widgetId: { classPropertyName: "widgetId", publicName: "widgetId", isSignal: true, isRequired: true, transformFunction: null }, cellId: { classPropertyName: "cellId", publicName: "cellId", isSignal: true, isRequired: true, transformFunction: null }, widgetFactory: { classPropertyName: "widgetFactory", publicName: "widgetFactory", isSignal: true, isRequired: false, transformFunction: null }, widgetState: { classPropertyName: "widgetState", publicName: "widgetState", isSignal: true, isRequired: false, transformFunction: null }, isEditMode: { classPropertyName: "isEditMode", publicName: "isEditMode", isSignal: true, isRequired: false, transformFunction: null }, flat: { classPropertyName: "flat", publicName: "flat", isSignal: true, isRequired: false, transformFunction: null }, row: { classPropertyName: "row", publicName: "row", isSignal: true, isRequired: true, transformFunction: null }, column: { classPropertyName: "column", publicName: "column", isSignal: true, isRequired: true, transformFunction: null }, rowSpan: { classPropertyName: "rowSpan", publicName: "rowSpan", isSignal: true, isRequired: false, transformFunction: null }, colSpan: { classPropertyName: "colSpan", publicName: "colSpan", isSignal: true, isRequired: false, transformFunction: null }, draggable: { classPropertyName: "draggable", publicName: "draggable", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { row: "rowChange", column: "columnChange", dragStart: "dragStart", dragEnd: "dragEnd", edit: "edit", delete: "delete", settings: "settings", resizeStart: "resizeStart", resizeMove: "resizeMove", resizeEnd: "resizeEnd" }, host: { properties: { "style.grid-row": "gridRowStyle()", "style.grid-column": "gridColumnStyle()", "class.is-dragging": "isDragging()", "class.drag-active": "isDragActive()", "class.flat": "flat() === true" } }, viewQueries: [{ propertyName: "container", first: true, predicate: ["container"], descendants: true, read: ViewContainerRef, isSignal: true }], ngImport: i0, template: "<!-- cell.component.html -->\n<div\n class=\"cell\"\n [class.is-resizing]=\"isResizing()\"\n [class.flat]=\"flat() === true\"\n [draggable]=\"draggable()\"\n (dragstart)=\"onDragStart($event)\"\n (dragend)=\"onDragEnd()\"\n (contextmenu)=\"onContextMenu($event)\"\n>\n <div class=\"content-area\">\n <ng-template #container></ng-template>\n </div>\n @if (isEditMode() && !isDragging()) {\n <!-- Right resize handle -->\n <div\n class=\"resize-handle resize-handle--right\"\n (mousedown)=\"onResizeStart($event, 'horizontal')\"\n >\n <div class=\"resize-handle-line\"></div>\n </div>\n <!-- Bottom resize handle -->\n <div\n class=\"resize-handle resize-handle--bottom\"\n (mousedown)=\"onResizeStart($event, 'vertical')\"\n >\n <div class=\"resize-handle-line\"></div>\n </div>\n }\n</div>\n\n@if (isResizing()) {\n<div class=\"resize-preview\" i18n=\"@@ngx.dashboard.cell.resize.dimensions\">\n {{ resizeData()?.previewColSpan ?? colSpan() }} \u00D7\n {{ resizeData()?.previewRowSpan ?? rowSpan() }}\n</div>\n}\n", styles: [":host{display:block;width:100%;height:100%;position:relative;z-index:1;container-type:inline-size}:host(.drag-active):not(.is-dragging){pointer-events:none}:host(.is-dragging){z-index:100;opacity:.5;pointer-events:none}:host(.is-dragging) .content-area{pointer-events:none}:host(:hover) .resize-handle{opacity:1}.cell{width:100%;height:100%;border-radius:4px;box-shadow:0 2px 6px #0000001a;padding:0;box-sizing:border-box;overflow:hidden;position:relative;container-type:inline-size}.cell:hover{box-shadow:0 4px 10px #00000026;transform:translateY(-2px)}.cell.flat{box-shadow:none;border:none}.cell.flat:hover{box-shadow:none;transform:none;border-color:#bdbdbd}.cell.resizing{-webkit-user-select:none;user-select:none}.content-area{width:100%;height:100%;overflow:auto;pointer-events:auto;position:relative;z-index:1}.content-area:hover{transform:initial}:host(:not(.is-dragging)) .cell.flat .content-area{pointer-events:auto}:host(:not(.is-dragging)) .cell.flat .content-area:hover{transform:initial}.resize-handle{position:absolute;z-index:20}.resize-handle--right{cursor:col-resize;width:16px;height:100%;right:-8px;top:0;display:flex;align-items:center;justify-content:center;opacity:0}.resize-handle--right:hover{opacity:1}.resize-handle--right:hover .resize-handle-line{background-color:var(--mat-sys-primary-container)}.resize-handle--bottom{cursor:row-resize;width:100%;height:16px;bottom:-8px;left:0;display:flex;align-items:center;justify-content:center;opacity:0}.resize-handle--bottom:hover{opacity:1}.resize-handle--bottom:hover .resize-handle-line{background-color:var(--mat-sys-primary-container)}.resize-handle-line{background-color:#0000001a}.resize-handle--right .resize-handle-line{width:8px;height:40px;border-radius:2px}.resize-handle--bottom .resize-handle-line{width:40px;height:8px;border-radius:2px}.resize-preview{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);background-color:var(--mat-sys-primary);color:var(--mat-sys-on-primary);padding:4px 12px;border-radius:4px;font-size:14px;font-weight:500;pointer-events:none;z-index:30}.cell.is-resizing{opacity:.6}.cell.is-resizing .resize-handle{background-color:#2196f380}:root .cursor-col-resize{cursor:col-resize!important}:root .cursor-row-resize{cursor:row-resize!important}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
1629
1651
|
}
|
|
1630
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
1652
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: CellComponent, decorators: [{
|
|
1631
1653
|
type: Component,
|
|
1632
1654
|
args: [{ selector: 'lib-cell', standalone: true, imports: [], changeDetection: ChangeDetectionStrategy.OnPush, host: {
|
|
1633
1655
|
'[style.grid-row]': 'gridRowStyle()',
|
|
@@ -1653,15 +1675,23 @@ class DashboardViewerComponent {
|
|
|
1653
1675
|
#store = inject(DashboardStore);
|
|
1654
1676
|
#renderer = inject(Renderer2);
|
|
1655
1677
|
#destroyRef = inject(DestroyRef);
|
|
1656
|
-
cellComponents = viewChildren(CellComponent,
|
|
1657
|
-
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
|
|
1678
|
+
cellComponents = viewChildren(CellComponent, /* @ts-ignore */
|
|
1679
|
+
...(ngDevMode ? [{ debugName: "cellComponents" }] : /* istanbul ignore next */ []));
|
|
1680
|
+
gridElement = viewChild('gridElement', /* @ts-ignore */
|
|
1681
|
+
...(ngDevMode ? [{ debugName: "gridElement" }] : /* istanbul ignore next */ []));
|
|
1682
|
+
rows = input.required(/* @ts-ignore */
|
|
1683
|
+
...(ngDevMode ? [{ debugName: "rows" }] : /* istanbul ignore next */ []));
|
|
1684
|
+
columns = input.required(/* @ts-ignore */
|
|
1685
|
+
...(ngDevMode ? [{ debugName: "columns" }] : /* istanbul ignore next */ []));
|
|
1686
|
+
gutterSize = input('1em', /* @ts-ignore */
|
|
1687
|
+
...(ngDevMode ? [{ debugName: "gutterSize" }] : /* istanbul ignore next */ []));
|
|
1688
|
+
gutters = computed(() => this.columns() + 1, /* @ts-ignore */
|
|
1689
|
+
...(ngDevMode ? [{ debugName: "gutters" }] : /* istanbul ignore next */ []));
|
|
1662
1690
|
// Selection feature
|
|
1663
|
-
enableSelection = input(false,
|
|
1664
|
-
|
|
1691
|
+
enableSelection = input(false, /* @ts-ignore */
|
|
1692
|
+
...(ngDevMode ? [{ debugName: "enableSelection" }] : /* istanbul ignore next */ []));
|
|
1693
|
+
selectionModifier = input(null, /* @ts-ignore */
|
|
1694
|
+
...(ngDevMode ? [{ debugName: "selectionModifier" }] : /* istanbul ignore next */ []));
|
|
1665
1695
|
/**
|
|
1666
1696
|
* Minimum pointer movement (in CSS pixels) between pointerdown and
|
|
1667
1697
|
* pointerup required to emit `selectionComplete`. Below the threshold,
|
|
@@ -1670,16 +1700,21 @@ class DashboardViewerComponent {
|
|
|
1670
1700
|
* Default 4 — matches OS-native click-vs-drag thresholds. Set to 0 to
|
|
1671
1701
|
* preserve the legacy behavior where every pointerup emits.
|
|
1672
1702
|
*/
|
|
1673
|
-
dragThreshold = input(4,
|
|
1703
|
+
dragThreshold = input(4, /* @ts-ignore */
|
|
1704
|
+
...(ngDevMode ? [{ debugName: "dragThreshold" }] : /* istanbul ignore next */ []));
|
|
1674
1705
|
selectionComplete = output();
|
|
1675
1706
|
// store signals - read-only
|
|
1676
1707
|
cells = this.#store.cells;
|
|
1677
1708
|
// Selection state
|
|
1678
|
-
isSelecting = signal(false,
|
|
1679
|
-
|
|
1680
|
-
|
|
1709
|
+
isSelecting = signal(false, /* @ts-ignore */
|
|
1710
|
+
...(ngDevMode ? [{ debugName: "isSelecting" }] : /* istanbul ignore next */ []));
|
|
1711
|
+
selectionStart = signal(null, /* @ts-ignore */
|
|
1712
|
+
...(ngDevMode ? [{ debugName: "selectionStart" }] : /* istanbul ignore next */ []));
|
|
1713
|
+
selectionCurrent = signal(null, /* @ts-ignore */
|
|
1714
|
+
...(ngDevMode ? [{ debugName: "selectionCurrent" }] : /* istanbul ignore next */ []));
|
|
1681
1715
|
// Modifier-key gating state for selectionModifier
|
|
1682
|
-
#modifierHeld = signal(false,
|
|
1716
|
+
#modifierHeld = signal(false, /* @ts-ignore */
|
|
1717
|
+
...(ngDevMode ? [{ debugName: "#modifierHeld" }] : /* istanbul ignore next */ []));
|
|
1683
1718
|
/**
|
|
1684
1719
|
* Whether the selection overlay is currently interactive (intercepts
|
|
1685
1720
|
* pointer events). Always false when `enableSelection` is false.
|
|
@@ -1694,7 +1729,8 @@ class DashboardViewerComponent {
|
|
|
1694
1729
|
if (this.selectionModifier() === null)
|
|
1695
1730
|
return true;
|
|
1696
1731
|
return this.#modifierHeld() || this.isSelecting();
|
|
1697
|
-
},
|
|
1732
|
+
}, /* @ts-ignore */
|
|
1733
|
+
...(ngDevMode ? [{ debugName: "armed" }] : /* istanbul ignore next */ []));
|
|
1698
1734
|
// Computed selection bounds (normalized)
|
|
1699
1735
|
selectionBounds = computed(() => {
|
|
1700
1736
|
const start = this.selectionStart();
|
|
@@ -1707,15 +1743,19 @@ class DashboardViewerComponent {
|
|
|
1707
1743
|
startCol: Math.min(start.col, current.col),
|
|
1708
1744
|
endCol: Math.max(start.col, current.col),
|
|
1709
1745
|
};
|
|
1710
|
-
},
|
|
1746
|
+
}, /* @ts-ignore */
|
|
1747
|
+
...(ngDevMode ? [{ debugName: "selectionBounds" }] : /* istanbul ignore next */ []));
|
|
1711
1748
|
// Generate array for template iteration
|
|
1712
|
-
rowNumbers = computed(() => Array.from({ length: this.rows() }, (_, i) => i + 1),
|
|
1713
|
-
|
|
1749
|
+
rowNumbers = computed(() => Array.from({ length: this.rows() }, (_, i) => i + 1), /* @ts-ignore */
|
|
1750
|
+
...(ngDevMode ? [{ debugName: "rowNumbers" }] : /* istanbul ignore next */ []));
|
|
1751
|
+
colNumbers = computed(() => Array.from({ length: this.columns() }, (_, i) => i + 1), /* @ts-ignore */
|
|
1752
|
+
...(ngDevMode ? [{ debugName: "colNumbers" }] : /* istanbul ignore next */ []));
|
|
1714
1753
|
// Document-level pointer listeners (cleanup needed)
|
|
1715
1754
|
#pointerMoveListener;
|
|
1716
1755
|
#pointerUpListener;
|
|
1717
1756
|
// Pointer position at the start of a drag, for dragThreshold checks
|
|
1718
|
-
#pointerDownPos = signal(null,
|
|
1757
|
+
#pointerDownPos = signal(null, /* @ts-ignore */
|
|
1758
|
+
...(ngDevMode ? [{ debugName: "#pointerDownPos" }] : /* istanbul ignore next */ []));
|
|
1719
1759
|
constructor() {
|
|
1720
1760
|
// Sync grid configuration with store when inputs change
|
|
1721
1761
|
effect(() => {
|
|
@@ -1728,9 +1768,7 @@ class DashboardViewerComponent {
|
|
|
1728
1768
|
// Clear selection when selection mode is disabled
|
|
1729
1769
|
effect(() => {
|
|
1730
1770
|
if (!this.enableSelection()) {
|
|
1731
|
-
this.
|
|
1732
|
-
this.selectionCurrent.set(null);
|
|
1733
|
-
this.isSelecting.set(false);
|
|
1771
|
+
this.clearSelection();
|
|
1734
1772
|
}
|
|
1735
1773
|
});
|
|
1736
1774
|
// Modifier-key tracking. Only registers document/window listeners when a
|
|
@@ -1864,6 +1902,17 @@ class DashboardViewerComponent {
|
|
|
1864
1902
|
// Don't clear selection - let the parent control when to clear.
|
|
1865
1903
|
// Selection remains visible until enableSelection becomes false.
|
|
1866
1904
|
}
|
|
1905
|
+
/**
|
|
1906
|
+
* Drop the visible selection rectangle. After `selectionComplete` emits,
|
|
1907
|
+
* the viewer leaves `selectionStart`/`selectionCurrent` set so consumers
|
|
1908
|
+
* can render a confirm UX with the rectangle still visible. Call this
|
|
1909
|
+
* once that UX is done. No-op if no selection is active.
|
|
1910
|
+
*/
|
|
1911
|
+
clearSelection() {
|
|
1912
|
+
this.selectionStart.set(null);
|
|
1913
|
+
this.selectionCurrent.set(null);
|
|
1914
|
+
this.isSelecting.set(false);
|
|
1915
|
+
}
|
|
1867
1916
|
/**
|
|
1868
1917
|
* Clean up document-level event listeners
|
|
1869
1918
|
*/
|
|
@@ -1877,17 +1926,17 @@ class DashboardViewerComponent {
|
|
|
1877
1926
|
this.#pointerUpListener = undefined;
|
|
1878
1927
|
}
|
|
1879
1928
|
}
|
|
1880
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
1881
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "
|
|
1929
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: DashboardViewerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1930
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.4", type: DashboardViewerComponent, isStandalone: true, selector: "ngx-dashboard-viewer", inputs: { rows: { classPropertyName: "rows", publicName: "rows", isSignal: true, isRequired: true, transformFunction: null }, columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: true, transformFunction: null }, gutterSize: { classPropertyName: "gutterSize", publicName: "gutterSize", isSignal: true, isRequired: false, transformFunction: null }, enableSelection: { classPropertyName: "enableSelection", publicName: "enableSelection", isSignal: true, isRequired: false, transformFunction: null }, selectionModifier: { classPropertyName: "selectionModifier", publicName: "selectionModifier", isSignal: true, isRequired: false, transformFunction: null }, dragThreshold: { classPropertyName: "dragThreshold", publicName: "dragThreshold", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selectionComplete: "selectionComplete" }, host: { properties: { "style.--rows": "rows()", "style.--columns": "columns()", "style.--gutter-size": "gutterSize()", "style.--gutters": "gutters()" } }, viewQueries: [{ propertyName: "cellComponents", predicate: CellComponent, descendants: true, isSignal: true }, { propertyName: "gridElement", first: true, predicate: ["gridElement"], descendants: true, isSignal: true }], ngImport: i0, template: "<!-- Dashboard viewer - read-only grid -->\n<div class=\"grid top-grid\" #gridElement>\n @for (cell of cells(); track cell.widgetId) {\n <lib-cell\n class=\"grid-cell\"\n [widgetId]=\"cell.widgetId\"\n [cellId]=\"cell.cellId\"\n [isEditMode]=\"false\"\n [draggable]=\"false\"\n [row]=\"cell.row\"\n [column]=\"cell.col\"\n [rowSpan]=\"cell.rowSpan\"\n [colSpan]=\"cell.colSpan\"\n [flat]=\"cell.flat\"\n [widgetFactory]=\"cell.widgetFactory\"\n [widgetState]=\"cell.widgetState\"\n >\n </lib-cell>\n }\n</div>\n\n<!-- Selection overlay grid - mirror of main grid for cell selection -->\n@if (enableSelection()) {\n <div class=\"selection-overlay-grid\" [class.armed]=\"armed()\">\n @for (row of rowNumbers(); track row) {\n @for (col of colNumbers(); track col) {\n <div\n class=\"selection-ghost-cell\"\n [class.selected]=\"isCellSelected(row, col)\"\n [class.selecting]=\"isSelecting()\"\n [style.grid-row]=\"row\"\n [style.grid-column]=\"col\"\n [attr.data-row]=\"row\"\n [attr.data-col]=\"col\"\n (pointerdown)=\"onGhostCellPointerDown($event, row, col)\"\n ></div>\n }\n }\n </div>\n}\n", styles: ["@charset \"UTF-8\";:host{--cell-size: calc( 100cqi / var(--columns) - var(--gutter-size) * var(--gutters) / var(--columns) );--tile-size: calc(var(--cell-size) + var(--gutter-size));--tile-offset: calc( var(--gutter-size) + var(--cell-size) + var(--gutter-size) / 2 );display:block;container-type:inline-size;box-sizing:border-box;aspect-ratio:var(--columns)/var(--rows);width:100%;height:auto;position:relative;background-color:var(--mat-sys-surface-container)}.grid{display:grid;gap:var(--gutter-size);padding:var(--gutter-size);width:100%;height:100%;box-sizing:border-box;grid-template-columns:repeat(var(--columns),var(--cell-size));grid-template-rows:repeat(var(--rows),var(--cell-size))}.grid-cell{pointer-events:none}.grid-cell:not(.flat){pointer-events:auto;cursor:default}.grid-cell:not(.flat) .content-area{pointer-events:none}.top-grid{z-index:2;pointer-events:none}.selection-overlay-grid{position:absolute;top:0;left:0;width:100%;height:100%;display:grid;gap:var(--gutter-size);padding:var(--gutter-size);grid-template-columns:repeat(var(--columns),var(--cell-size));grid-template-rows:repeat(var(--rows),var(--cell-size));z-index:5;pointer-events:none;-webkit-user-select:none;user-select:none}.selection-overlay-grid.armed{pointer-events:auto}.selection-ghost-cell{transition:background-color .1s ease,border-radius .1s ease;border-radius:2px}.selection-ghost-cell.selected{background-color:color-mix(in srgb,var(--mat-sys-primary) 25%,transparent);border-radius:4px}.selection-overlay-grid.armed .selection-ghost-cell{cursor:crosshair}.selection-overlay-grid.armed .selection-ghost-cell:hover:not(.selecting){background-color:color-mix(in srgb,var(--mat-sys-primary) 8%,transparent)}.selection-overlay-grid.armed .selection-ghost-cell.selecting{cursor:crosshair}\n"], dependencies: [{ kind: "component", type: CellComponent, selector: "lib-cell", inputs: ["widgetId", "cellId", "widgetFactory", "widgetState", "isEditMode", "flat", "row", "column", "rowSpan", "colSpan", "draggable"], outputs: ["rowChange", "columnChange", "dragStart", "dragEnd", "edit", "delete", "settings", "resizeStart", "resizeMove", "resizeEnd"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
1882
1931
|
}
|
|
1883
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
1932
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: DashboardViewerComponent, decorators: [{
|
|
1884
1933
|
type: Component,
|
|
1885
1934
|
args: [{ selector: 'ngx-dashboard-viewer', standalone: true, imports: [CellComponent], changeDetection: ChangeDetectionStrategy.OnPush, host: {
|
|
1886
1935
|
'[style.--rows]': 'rows()',
|
|
1887
1936
|
'[style.--columns]': 'columns()',
|
|
1888
1937
|
'[style.--gutter-size]': 'gutterSize()',
|
|
1889
1938
|
'[style.--gutters]': 'gutters()',
|
|
1890
|
-
}, template: "<!-- Dashboard viewer - read-only grid -->\n<div class=\"grid top-grid\" #gridElement>\n @for (cell of cells(); track cell.widgetId) {\n <lib-cell\n class=\"grid-cell\"\n [widgetId]=\"cell.widgetId\"\n [cellId]=\"cell.cellId\"\n [isEditMode]=\"false\"\n [draggable]=\"false\"\n [row]=\"cell.row\"\n [column]=\"cell.col\"\n [rowSpan]=\"cell.rowSpan\"\n [colSpan]=\"cell.colSpan\"\n [flat]=\"cell.flat\"\n [widgetFactory]=\"cell.widgetFactory\"\n [widgetState]=\"cell.widgetState\"\n >\n </lib-cell>\n }\n</div>\n\n<!-- Selection overlay grid - mirror of main grid for cell selection -->\n@if (enableSelection()) {\n <div class=\"selection-overlay-grid\" [class.armed]=\"armed()\">\n @for (row of rowNumbers(); track row) {\n @for (col of colNumbers(); track col) {\n <div\n class=\"selection-ghost-cell\"\n [class.selected]=\"isCellSelected(row, col)\"\n [class.selecting]=\"isSelecting()\"\n [style.grid-row]=\"row\"\n [style.grid-column]=\"col\"\n [attr.data-row]=\"row\"\n [attr.data-col]=\"col\"\n (pointerdown)=\"onGhostCellPointerDown($event, row, col)\"\n ></div>\n }\n }\n </div>\n}\n", styles: ["@charset \"UTF-8\";:host{--cell-size: calc( 100cqi / var(--columns) - var(--gutter-size) * var(--gutters) / var(--columns) );--tile-size: calc(var(--cell-size) + var(--gutter-size));--tile-offset: calc( var(--gutter-size) + var(--cell-size) + var(--gutter-size) / 2 );display:block;container-type:inline-size;box-sizing:border-box;aspect-ratio:var(--columns)/var(--rows);width:100%;height:auto;position:relative;background-color:var(--mat-sys-surface-container)}.grid{display:grid;gap:var(--gutter-size);padding:var(--gutter-size);width:100%;height:100%;box-sizing:border-box;grid-template-columns:repeat(var(--columns),var(--cell-size));grid-template-rows:repeat(var(--rows),var(--cell-size))}.grid-cell{pointer-events:none}.grid-cell:not(.flat){pointer-events:auto;cursor:default}.grid-cell:not(.flat) .content-area{pointer-events:none}.top-grid{z-index:2;pointer-events:none}.selection-overlay-grid{position:absolute;top:0;left:0;width:100%;height:100%;display:grid;gap:var(--gutter-size);padding:var(--gutter-size);grid-template-columns:repeat(var(--columns),var(--cell-size));grid-template-rows:repeat(var(--rows),var(--cell-size));z-index:5;pointer-events:none;-webkit-user-select:none;user-select:none}.selection-overlay-grid.armed{pointer-events:auto}.selection-ghost-cell{transition:background-color .1s ease,border-radius .1s ease;border-radius:2px}.selection-ghost-cell.selected{background-color:var(--mat-sys-primary)
|
|
1939
|
+
}, template: "<!-- Dashboard viewer - read-only grid -->\n<div class=\"grid top-grid\" #gridElement>\n @for (cell of cells(); track cell.widgetId) {\n <lib-cell\n class=\"grid-cell\"\n [widgetId]=\"cell.widgetId\"\n [cellId]=\"cell.cellId\"\n [isEditMode]=\"false\"\n [draggable]=\"false\"\n [row]=\"cell.row\"\n [column]=\"cell.col\"\n [rowSpan]=\"cell.rowSpan\"\n [colSpan]=\"cell.colSpan\"\n [flat]=\"cell.flat\"\n [widgetFactory]=\"cell.widgetFactory\"\n [widgetState]=\"cell.widgetState\"\n >\n </lib-cell>\n }\n</div>\n\n<!-- Selection overlay grid - mirror of main grid for cell selection -->\n@if (enableSelection()) {\n <div class=\"selection-overlay-grid\" [class.armed]=\"armed()\">\n @for (row of rowNumbers(); track row) {\n @for (col of colNumbers(); track col) {\n <div\n class=\"selection-ghost-cell\"\n [class.selected]=\"isCellSelected(row, col)\"\n [class.selecting]=\"isSelecting()\"\n [style.grid-row]=\"row\"\n [style.grid-column]=\"col\"\n [attr.data-row]=\"row\"\n [attr.data-col]=\"col\"\n (pointerdown)=\"onGhostCellPointerDown($event, row, col)\"\n ></div>\n }\n }\n </div>\n}\n", styles: ["@charset \"UTF-8\";:host{--cell-size: calc( 100cqi / var(--columns) - var(--gutter-size) * var(--gutters) / var(--columns) );--tile-size: calc(var(--cell-size) + var(--gutter-size));--tile-offset: calc( var(--gutter-size) + var(--cell-size) + var(--gutter-size) / 2 );display:block;container-type:inline-size;box-sizing:border-box;aspect-ratio:var(--columns)/var(--rows);width:100%;height:auto;position:relative;background-color:var(--mat-sys-surface-container)}.grid{display:grid;gap:var(--gutter-size);padding:var(--gutter-size);width:100%;height:100%;box-sizing:border-box;grid-template-columns:repeat(var(--columns),var(--cell-size));grid-template-rows:repeat(var(--rows),var(--cell-size))}.grid-cell{pointer-events:none}.grid-cell:not(.flat){pointer-events:auto;cursor:default}.grid-cell:not(.flat) .content-area{pointer-events:none}.top-grid{z-index:2;pointer-events:none}.selection-overlay-grid{position:absolute;top:0;left:0;width:100%;height:100%;display:grid;gap:var(--gutter-size);padding:var(--gutter-size);grid-template-columns:repeat(var(--columns),var(--cell-size));grid-template-rows:repeat(var(--rows),var(--cell-size));z-index:5;pointer-events:none;-webkit-user-select:none;user-select:none}.selection-overlay-grid.armed{pointer-events:auto}.selection-ghost-cell{transition:background-color .1s ease,border-radius .1s ease;border-radius:2px}.selection-ghost-cell.selected{background-color:color-mix(in srgb,var(--mat-sys-primary) 25%,transparent);border-radius:4px}.selection-overlay-grid.armed .selection-ghost-cell{cursor:crosshair}.selection-overlay-grid.armed .selection-ghost-cell:hover:not(.selecting){background-color:color-mix(in srgb,var(--mat-sys-primary) 8%,transparent)}.selection-overlay-grid.armed .selection-ghost-cell.selecting{cursor:crosshair}\n"] }]
|
|
1891
1940
|
}], ctorParameters: () => [], propDecorators: { cellComponents: [{ type: i0.ViewChildren, args: [i0.forwardRef(() => CellComponent), { isSignal: true }] }], gridElement: [{ type: i0.ViewChild, args: ['gridElement', { isSignal: true }] }], rows: [{ type: i0.Input, args: [{ isSignal: true, alias: "rows", required: true }] }], columns: [{ type: i0.Input, args: [{ isSignal: true, alias: "columns", required: true }] }], gutterSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "gutterSize", required: false }] }], enableSelection: [{ type: i0.Input, args: [{ isSignal: true, alias: "enableSelection", required: false }] }], selectionModifier: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectionModifier", required: false }] }], dragThreshold: [{ type: i0.Input, args: [{ isSignal: true, alias: "dragThreshold", required: false }] }], selectionComplete: [{ type: i0.Output, args: ["selectionComplete"] }] } });
|
|
1892
1941
|
|
|
1893
1942
|
class CellContextMenuComponent {
|
|
@@ -1898,11 +1947,13 @@ class CellContextMenuComponent {
|
|
|
1898
1947
|
menuPosition = computed(() => {
|
|
1899
1948
|
const menu = this.menuService.activeMenu();
|
|
1900
1949
|
return menu ? { left: `${menu.x}px`, top: `${menu.y}px` } : { left: '0px', top: '0px' };
|
|
1901
|
-
},
|
|
1950
|
+
}, /* @ts-ignore */
|
|
1951
|
+
...(ngDevMode ? [{ debugName: "menuPosition" }] : /* istanbul ignore next */ []));
|
|
1902
1952
|
menuItems = computed(() => {
|
|
1903
1953
|
const menu = this.menuService.activeMenu();
|
|
1904
1954
|
return menu?.items || [];
|
|
1905
|
-
},
|
|
1955
|
+
}, /* @ts-ignore */
|
|
1956
|
+
...(ngDevMode ? [{ debugName: "menuItems" }] : /* istanbul ignore next */ []));
|
|
1906
1957
|
constructor() {
|
|
1907
1958
|
// Material Menu has a backdrop that blocks events from reaching other elements.
|
|
1908
1959
|
// When any right-click occurs while menu is open, we need to:
|
|
@@ -1963,8 +2014,8 @@ class CellContextMenuComponent {
|
|
|
1963
2014
|
this.menuService.hide();
|
|
1964
2015
|
}
|
|
1965
2016
|
}
|
|
1966
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
1967
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "
|
|
2017
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: CellContextMenuComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2018
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.4", type: CellContextMenuComponent, isStandalone: true, selector: "lib-cell-context-menu", viewQueries: [{ propertyName: "menuTrigger", first: true, predicate: ["menuTrigger"], descendants: true, read: MatMenuTrigger, isSignal: true }], ngImport: i0, template: `
|
|
1968
2019
|
<!-- Hidden trigger for menu positioned at exact mouse coordinates
|
|
1969
2020
|
|
|
1970
2021
|
IMPORTANT: Angular Material applies its own positioning logic to menus,
|
|
@@ -2018,7 +2069,7 @@ class CellContextMenuComponent {
|
|
|
2018
2069
|
</mat-menu>
|
|
2019
2070
|
`, isInline: true, styles: [":host{display:contents}\n"], dependencies: [{ kind: "ngmodule", type: MatMenuModule }, { kind: "component", type: i1$1.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: i1$1.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i1$1.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatDividerModule }, { kind: "component", type: i3.MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i4.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
2020
2071
|
}
|
|
2021
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
2072
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: CellContextMenuComponent, decorators: [{
|
|
2022
2073
|
type: Component,
|
|
2023
2074
|
args: [{ selector: 'lib-cell-context-menu', standalone: true, imports: [MatMenuModule, MatIconModule, MatDividerModule, MatButtonModule], changeDetection: ChangeDetectionStrategy.OnPush, template: `
|
|
2024
2075
|
<!-- Hidden trigger for menu positioned at exact mouse coordinates
|
|
@@ -2109,10 +2160,10 @@ class DefaultEmptyCellContextProvider extends EmptyCellContextProvider {
|
|
|
2109
2160
|
handleEmptyCellContext() {
|
|
2110
2161
|
// Default behavior: do nothing
|
|
2111
2162
|
}
|
|
2112
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
2113
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "
|
|
2163
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: DefaultEmptyCellContextProvider, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
|
|
2164
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: DefaultEmptyCellContextProvider, providedIn: 'root' });
|
|
2114
2165
|
}
|
|
2115
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
2166
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: DefaultEmptyCellContextProvider, decorators: [{
|
|
2116
2167
|
type: Injectable,
|
|
2117
2168
|
args: [{
|
|
2118
2169
|
providedIn: 'root',
|
|
@@ -2147,8 +2198,10 @@ const EMPTY_CELL_CONTEXT_PROVIDER = new InjectionToken('EmptyCellContextProvider
|
|
|
2147
2198
|
* of the context menu that appears when right-clicking on empty dashboard cells.
|
|
2148
2199
|
*/
|
|
2149
2200
|
class EmptyCellContextMenuService {
|
|
2150
|
-
#activeMenu = signal(null,
|
|
2151
|
-
|
|
2201
|
+
#activeMenu = signal(null, /* @ts-ignore */
|
|
2202
|
+
...(ngDevMode ? [{ debugName: "#activeMenu" }] : /* istanbul ignore next */ []));
|
|
2203
|
+
#lastSelectedWidgetTypeId = signal(null, /* @ts-ignore */
|
|
2204
|
+
...(ngDevMode ? [{ debugName: "#lastSelectedWidgetTypeId" }] : /* istanbul ignore next */ []));
|
|
2152
2205
|
activeMenu = this.#activeMenu.asReadonly();
|
|
2153
2206
|
lastSelectedWidgetTypeId = this.#lastSelectedWidgetTypeId.asReadonly();
|
|
2154
2207
|
/**
|
|
@@ -2176,10 +2229,10 @@ class EmptyCellContextMenuService {
|
|
|
2176
2229
|
setLastSelection(widgetTypeId) {
|
|
2177
2230
|
this.#lastSelectedWidgetTypeId.set(widgetTypeId);
|
|
2178
2231
|
}
|
|
2179
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
2180
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "
|
|
2232
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: EmptyCellContextMenuService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
2233
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: EmptyCellContextMenuService, providedIn: 'root' });
|
|
2181
2234
|
}
|
|
2182
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
2235
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: EmptyCellContextMenuService, decorators: [{
|
|
2183
2236
|
type: Injectable,
|
|
2184
2237
|
args: [{
|
|
2185
2238
|
providedIn: 'root',
|
|
@@ -2294,37 +2347,47 @@ class WidgetListContextMenuProvider extends EmptyCellContextProvider {
|
|
|
2294
2347
|
'Ensure you are using a compatible version of the dashboard component.');
|
|
2295
2348
|
}
|
|
2296
2349
|
}
|
|
2297
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
2298
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "
|
|
2350
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: WidgetListContextMenuProvider, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
|
|
2351
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: WidgetListContextMenuProvider });
|
|
2299
2352
|
}
|
|
2300
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
2353
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: WidgetListContextMenuProvider, decorators: [{
|
|
2301
2354
|
type: Injectable
|
|
2302
2355
|
}] });
|
|
2303
2356
|
|
|
2304
2357
|
// drop-zone.component.ts
|
|
2305
2358
|
class DropZoneComponent {
|
|
2306
2359
|
// Required inputs
|
|
2307
|
-
row = input.required(
|
|
2308
|
-
|
|
2309
|
-
|
|
2360
|
+
row = input.required(/* @ts-ignore */
|
|
2361
|
+
...(ngDevMode ? [{ debugName: "row" }] : /* istanbul ignore next */ []));
|
|
2362
|
+
col = input.required(/* @ts-ignore */
|
|
2363
|
+
...(ngDevMode ? [{ debugName: "col" }] : /* istanbul ignore next */ []));
|
|
2364
|
+
index = input.required(/* @ts-ignore */
|
|
2365
|
+
...(ngDevMode ? [{ debugName: "index" }] : /* istanbul ignore next */ []));
|
|
2310
2366
|
// Optional inputs with defaults
|
|
2311
|
-
highlight = input(false,
|
|
2312
|
-
|
|
2313
|
-
|
|
2314
|
-
|
|
2367
|
+
highlight = input(false, /* @ts-ignore */
|
|
2368
|
+
...(ngDevMode ? [{ debugName: "highlight" }] : /* istanbul ignore next */ []));
|
|
2369
|
+
highlightInvalid = input(false, /* @ts-ignore */
|
|
2370
|
+
...(ngDevMode ? [{ debugName: "highlightInvalid" }] : /* istanbul ignore next */ []));
|
|
2371
|
+
highlightResize = input(false, /* @ts-ignore */
|
|
2372
|
+
...(ngDevMode ? [{ debugName: "highlightResize" }] : /* istanbul ignore next */ []));
|
|
2373
|
+
editMode = input(false, /* @ts-ignore */
|
|
2374
|
+
...(ngDevMode ? [{ debugName: "editMode" }] : /* istanbul ignore next */ []));
|
|
2315
2375
|
// Outputs
|
|
2316
2376
|
dragEnter = output();
|
|
2317
2377
|
dragExit = output();
|
|
2318
2378
|
dragOver = output();
|
|
2319
2379
|
dragDrop = output();
|
|
2320
2380
|
// Computed properties
|
|
2321
|
-
dropZoneId = computed(() => `drop-zone-${this.row()}-${this.col()}`,
|
|
2381
|
+
dropZoneId = computed(() => `drop-zone-${this.row()}-${this.col()}`, /* @ts-ignore */
|
|
2382
|
+
...(ngDevMode ? [{ debugName: "dropZoneId" }] : /* istanbul ignore next */ []));
|
|
2322
2383
|
dropData = computed(() => ({
|
|
2323
2384
|
row: this.row(),
|
|
2324
2385
|
col: this.col(),
|
|
2325
|
-
}),
|
|
2386
|
+
}), /* @ts-ignore */
|
|
2387
|
+
...(ngDevMode ? [{ debugName: "dropData" }] : /* istanbul ignore next */ []));
|
|
2326
2388
|
// Abstract drag state from store
|
|
2327
|
-
dragData = computed(() => this.#store.dragData(),
|
|
2389
|
+
dragData = computed(() => this.#store.dragData(), /* @ts-ignore */
|
|
2390
|
+
...(ngDevMode ? [{ debugName: "dragData" }] : /* istanbul ignore next */ []));
|
|
2328
2391
|
// Computed drop effect based on drag data and validity
|
|
2329
2392
|
dropEffect = computed(() => {
|
|
2330
2393
|
const data = this.dragData();
|
|
@@ -2332,7 +2395,8 @@ class DropZoneComponent {
|
|
|
2332
2395
|
return 'none';
|
|
2333
2396
|
}
|
|
2334
2397
|
return data.kind === 'cell' ? 'move' : 'copy';
|
|
2335
|
-
},
|
|
2398
|
+
}, /* @ts-ignore */
|
|
2399
|
+
...(ngDevMode ? [{ debugName: "dropEffect" }] : /* istanbul ignore next */ []));
|
|
2336
2400
|
#store = inject(DashboardStore);
|
|
2337
2401
|
#elementRef = inject(ElementRef);
|
|
2338
2402
|
#dashboardService = inject(DashboardService);
|
|
@@ -2410,10 +2474,10 @@ class DropZoneComponent {
|
|
|
2410
2474
|
});
|
|
2411
2475
|
}
|
|
2412
2476
|
}
|
|
2413
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
2414
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "
|
|
2477
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: DropZoneComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2478
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.4", type: DropZoneComponent, isStandalone: true, selector: "lib-drop-zone", inputs: { row: { classPropertyName: "row", publicName: "row", isSignal: true, isRequired: true, transformFunction: null }, col: { classPropertyName: "col", publicName: "col", isSignal: true, isRequired: true, transformFunction: null }, index: { classPropertyName: "index", publicName: "index", isSignal: true, isRequired: true, transformFunction: null }, highlight: { classPropertyName: "highlight", publicName: "highlight", isSignal: true, isRequired: false, transformFunction: null }, highlightInvalid: { classPropertyName: "highlightInvalid", publicName: "highlightInvalid", isSignal: true, isRequired: false, transformFunction: null }, highlightResize: { classPropertyName: "highlightResize", publicName: "highlightResize", isSignal: true, isRequired: false, transformFunction: null }, editMode: { classPropertyName: "editMode", publicName: "editMode", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { dragEnter: "dragEnter", dragExit: "dragExit", dragOver: "dragOver", dragDrop: "dragDrop" }, ngImport: i0, template: "<!-- drop-zone.component.html -->\n<div\n class=\"drop-zone\"\n [class.drop-zone--highlight]=\"highlight() && !highlightInvalid()\"\n [class.drop-zone--invalid]=\"highlightInvalid()\"\n [class.drop-zone--resize]=\"highlightResize()\"\n [style.grid-row]=\"row()\"\n [style.grid-column]=\"col()\"\n (dragenter)=\"onDragEnter($event)\"\n (dragover)=\"onDragOver($event)\"\n (dragleave)=\"onDragLeave($event)\"\n (drop)=\"onDrop($event)\"\n (contextmenu)=\"onContextMenu($event)\"\n>\n @if (editMode()) {\n <div class=\"edit-mode-cell-number\">\n {{ index() }}<br />\n {{ row() }},{{ col() }}\n </div>\n }\n</div>\n", styles: [".drop-zone{width:100%;height:100%;z-index:0;align-self:stretch;justify-self:stretch;display:block;box-sizing:border-box}.drop-zone--active,.drop-zone--highlight{background-color:#80808080}.drop-zone--invalid{background-color:light-dark(color-mix(in srgb,var(--mat-sys-error) 40%,white),color-mix(in srgb,var(--mat-sys-error) 80%,black))}.drop-zone--resize{background-color:#2196f34d;outline:1px solid rgba(33,150,243,.6)}.edit-mode-cell-number{font-size:10px;line-height:1.1;color:#64646499;pointer-events:none;-webkit-user-select:none;user-select:none;z-index:-1;display:flex;flex-direction:column;align-items:center;justify-content:center;text-align:center;width:100%;height:100%}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
2415
2479
|
}
|
|
2416
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
2480
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: DropZoneComponent, decorators: [{
|
|
2417
2481
|
type: Component,
|
|
2418
2482
|
args: [{ selector: 'lib-drop-zone', standalone: true, imports: [], changeDetection: ChangeDetectionStrategy.OnPush, template: "<!-- drop-zone.component.html -->\n<div\n class=\"drop-zone\"\n [class.drop-zone--highlight]=\"highlight() && !highlightInvalid()\"\n [class.drop-zone--invalid]=\"highlightInvalid()\"\n [class.drop-zone--resize]=\"highlightResize()\"\n [style.grid-row]=\"row()\"\n [style.grid-column]=\"col()\"\n (dragenter)=\"onDragEnter($event)\"\n (dragover)=\"onDragOver($event)\"\n (dragleave)=\"onDragLeave($event)\"\n (drop)=\"onDrop($event)\"\n (contextmenu)=\"onContextMenu($event)\"\n>\n @if (editMode()) {\n <div class=\"edit-mode-cell-number\">\n {{ index() }}<br />\n {{ row() }},{{ col() }}\n </div>\n }\n</div>\n", styles: [".drop-zone{width:100%;height:100%;z-index:0;align-self:stretch;justify-self:stretch;display:block;box-sizing:border-box}.drop-zone--active,.drop-zone--highlight{background-color:#80808080}.drop-zone--invalid{background-color:light-dark(color-mix(in srgb,var(--mat-sys-error) 40%,white),color-mix(in srgb,var(--mat-sys-error) 80%,black))}.drop-zone--resize{background-color:#2196f34d;outline:1px solid rgba(33,150,243,.6)}.edit-mode-cell-number{font-size:10px;line-height:1.1;color:#64646499;pointer-events:none;-webkit-user-select:none;user-select:none;z-index:-1;display:flex;flex-direction:column;align-items:center;justify-content:center;text-align:center;width:100%;height:100%}\n"] }]
|
|
2419
2483
|
}], propDecorators: { row: [{ type: i0.Input, args: [{ isSignal: true, alias: "row", required: true }] }], col: [{ type: i0.Input, args: [{ isSignal: true, alias: "col", required: true }] }], index: [{ type: i0.Input, args: [{ isSignal: true, alias: "index", required: true }] }], highlight: [{ type: i0.Input, args: [{ isSignal: true, alias: "highlight", required: false }] }], highlightInvalid: [{ type: i0.Input, args: [{ isSignal: true, alias: "highlightInvalid", required: false }] }], highlightResize: [{ type: i0.Input, args: [{ isSignal: true, alias: "highlightResize", required: false }] }], editMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "editMode", required: false }] }], dragEnter: [{ type: i0.Output, args: ["dragEnter"] }], dragExit: [{ type: i0.Output, args: ["dragExit"] }], dragOver: [{ type: i0.Output, args: ["dragOver"] }], dragDrop: [{ type: i0.Output, args: ["dragDrop"] }] } });
|
|
@@ -2438,11 +2502,13 @@ class EmptyCellContextMenuComponent {
|
|
|
2438
2502
|
return menu
|
|
2439
2503
|
? { left: `${menu.x}px`, top: `${menu.y}px` }
|
|
2440
2504
|
: { left: '0px', top: '0px' };
|
|
2441
|
-
},
|
|
2505
|
+
}, /* @ts-ignore */
|
|
2506
|
+
...(ngDevMode ? [{ debugName: "menuPosition" }] : /* istanbul ignore next */ []));
|
|
2442
2507
|
menuItems = computed(() => {
|
|
2443
2508
|
const menu = this.menuService.activeMenu();
|
|
2444
2509
|
return menu?.items || [];
|
|
2445
|
-
},
|
|
2510
|
+
}, /* @ts-ignore */
|
|
2511
|
+
...(ngDevMode ? [{ debugName: "menuItems" }] : /* istanbul ignore next */ []));
|
|
2446
2512
|
constructor() {
|
|
2447
2513
|
// Material Menu has a backdrop that blocks events from reaching other elements.
|
|
2448
2514
|
// When any right-click occurs while menu is open, we need to:
|
|
@@ -2514,8 +2580,8 @@ class EmptyCellContextMenuComponent {
|
|
|
2514
2580
|
sanitizeSvg(svg) {
|
|
2515
2581
|
return this.#sanitizer.bypassSecurityTrustHtml(svg);
|
|
2516
2582
|
}
|
|
2517
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
2518
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "
|
|
2583
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: EmptyCellContextMenuComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2584
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.4", type: EmptyCellContextMenuComponent, isStandalone: true, selector: "lib-empty-cell-context-menu", viewQueries: [{ propertyName: "menuTrigger", first: true, predicate: ["menuTrigger"], descendants: true, read: MatMenuTrigger, isSignal: true }], ngImport: i0, template: `
|
|
2519
2585
|
<!-- Hidden trigger for menu positioned at exact mouse coordinates
|
|
2520
2586
|
|
|
2521
2587
|
IMPORTANT: Angular Material applies its own positioning logic to menus,
|
|
@@ -2575,7 +2641,7 @@ class EmptyCellContextMenuComponent {
|
|
|
2575
2641
|
</mat-menu>
|
|
2576
2642
|
`, isInline: true, styles: [":host{display:contents}.empty-cell-widget-menu{max-height:400px;overflow-y:auto}.widget-icon{width:24px;height:24px;display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;vertical-align:middle}.widget-icon :deep(svg){width:20px;height:20px;fill:currentColor}\n"], dependencies: [{ kind: "ngmodule", type: MatMenuModule }, { kind: "component", type: i1$1.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: i1$1.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i1$1.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatDividerModule }, { kind: "component", type: i3.MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i4.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
2577
2643
|
}
|
|
2578
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
2644
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: EmptyCellContextMenuComponent, decorators: [{
|
|
2579
2645
|
type: Component,
|
|
2580
2646
|
args: [{ selector: 'lib-empty-cell-context-menu', standalone: true, imports: [
|
|
2581
2647
|
MatMenuModule,
|
|
@@ -2646,15 +2712,21 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.10", ngImpo
|
|
|
2646
2712
|
// dashboard-editor.component.ts
|
|
2647
2713
|
class DashboardEditorComponent {
|
|
2648
2714
|
bottomGridRef = viewChild.required('bottomGrid');
|
|
2649
|
-
dropZones = viewChildren(DropZoneComponent,
|
|
2650
|
-
|
|
2715
|
+
dropZones = viewChildren(DropZoneComponent, /* @ts-ignore */
|
|
2716
|
+
...(ngDevMode ? [{ debugName: "dropZones" }] : /* istanbul ignore next */ []));
|
|
2717
|
+
cellComponents = viewChildren(CellComponent, /* @ts-ignore */
|
|
2718
|
+
...(ngDevMode ? [{ debugName: "cellComponents" }] : /* istanbul ignore next */ []));
|
|
2651
2719
|
#store = inject(DashboardStore);
|
|
2652
2720
|
#destroyRef = inject(DestroyRef);
|
|
2653
2721
|
#resizeObserver;
|
|
2654
|
-
rows = input.required(
|
|
2655
|
-
|
|
2656
|
-
|
|
2657
|
-
|
|
2722
|
+
rows = input.required(/* @ts-ignore */
|
|
2723
|
+
...(ngDevMode ? [{ debugName: "rows" }] : /* istanbul ignore next */ []));
|
|
2724
|
+
columns = input.required(/* @ts-ignore */
|
|
2725
|
+
...(ngDevMode ? [{ debugName: "columns" }] : /* istanbul ignore next */ []));
|
|
2726
|
+
gutterSize = input('1em', /* @ts-ignore */
|
|
2727
|
+
...(ngDevMode ? [{ debugName: "gutterSize" }] : /* istanbul ignore next */ []));
|
|
2728
|
+
gutters = computed(() => this.columns() + 1, /* @ts-ignore */
|
|
2729
|
+
...(ngDevMode ? [{ debugName: "gutters" }] : /* istanbul ignore next */ []));
|
|
2658
2730
|
// store signals
|
|
2659
2731
|
cells = this.#store.cells;
|
|
2660
2732
|
highlightedZones = this.#store.highlightedZones;
|
|
@@ -2676,7 +2748,8 @@ class DashboardEditorComponent {
|
|
|
2676
2748
|
}
|
|
2677
2749
|
}
|
|
2678
2750
|
return positions;
|
|
2679
|
-
},
|
|
2751
|
+
}, /* @ts-ignore */
|
|
2752
|
+
...(ngDevMode ? [{ debugName: "dropzonePositions" }] : /* istanbul ignore next */ []));
|
|
2680
2753
|
// Helper method for template
|
|
2681
2754
|
createCellId(row, col) {
|
|
2682
2755
|
return CellIdUtils.create(row, col);
|
|
@@ -2748,12 +2821,12 @@ class DashboardEditorComponent {
|
|
|
2748
2821
|
this.#store.handleDrop(event.data, event.target);
|
|
2749
2822
|
// Note: Store handles all validation and error handling internally
|
|
2750
2823
|
}
|
|
2751
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
2752
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "
|
|
2824
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: DashboardEditorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2825
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.4", type: DashboardEditorComponent, isStandalone: true, selector: "ngx-dashboard-editor", inputs: { rows: { classPropertyName: "rows", publicName: "rows", isSignal: true, isRequired: true, transformFunction: null }, columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: true, transformFunction: null }, gutterSize: { classPropertyName: "gutterSize", publicName: "gutterSize", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "style.--rows": "rows()", "style.--columns": "columns()", "style.--gutter-size": "gutterSize()", "style.--gutters": "gutters()", "class.is-edit-mode": "true" } }, providers: [
|
|
2753
2826
|
CellContextMenuService,
|
|
2754
2827
|
], viewQueries: [{ propertyName: "bottomGridRef", first: true, predicate: ["bottomGrid"], descendants: true, isSignal: true }, { propertyName: "dropZones", predicate: DropZoneComponent, descendants: true, isSignal: true }, { propertyName: "cellComponents", predicate: CellComponent, descendants: true, isSignal: true }], ngImport: i0, template: "<!-- dashboard-editor.component.html -->\n<div class=\"grid-container\">\n <!-- Bottom grid with drop zones -->\n <div class=\"grid\" id=\"bottom-grid\" #bottomGrid>\n @for (position of dropzonePositions(); track position.id) {\n <lib-drop-zone\n class=\"drop-zone\"\n [row]=\"position.row\"\n [col]=\"position.col\"\n [index]=\"position.index\"\n [highlight]=\"highlightMap().has(createCellId(position.row, position.col))\"\n [highlightInvalid]=\"\n invalidHighlightMap().has(createCellId(position.row, position.col))\n \"\n [highlightResize]=\"\n resizePreviewMap().has(createCellId(position.row, position.col))\n \"\n [editMode]=\"true\"\n (dragEnter)=\"onDragEnter($event)\"\n (dragExit)=\"onDragExit()\"\n (dragOver)=\"onDragOver($event)\"\n (dragDrop)=\"onDragDrop($event)\"\n ></lib-drop-zone>\n }\n </div>\n\n <!-- Top grid with interactive cells -->\n <div class=\"grid\" id=\"top-grid\">\n @for (cell of cells(); track cell.widgetId) {\n <lib-cell\n class=\"grid-cell\"\n [widgetId]=\"cell.widgetId\"\n [cellId]=\"cell.cellId\"\n [isEditMode]=\"true\"\n [draggable]=\"true\"\n [row]=\"cell.row\"\n [column]=\"cell.col\"\n [rowSpan]=\"cell.rowSpan\"\n [colSpan]=\"cell.colSpan\"\n [flat]=\"cell.flat\"\n [widgetFactory]=\"cell.widgetFactory\"\n [widgetState]=\"cell.widgetState\"\n (dragStart)=\"onCellDragStart($event)\"\n (dragEnd)=\"dragEnd()\"\n (delete)=\"onCellDelete($event)\"\n (settings)=\"onCellSettings($event)\"\n (resizeStart)=\"onCellResizeStart($event)\"\n (resizeMove)=\"onCellResizeMove($event)\"\n (resizeEnd)=\"onCellResizeEnd($event)\"\n >\n </lib-cell>\n }\n </div>\n</div>\n\n<!-- Context menus -->\n<lib-cell-context-menu></lib-cell-context-menu>\n<lib-empty-cell-context-menu></lib-empty-cell-context-menu>\n", styles: ["@charset \"UTF-8\";:host{--cell-size: calc( 100cqi / var(--columns) - var(--gutter-size) * var(--gutters) / var(--columns) );--tile-size: calc(var(--cell-size) + var(--gutter-size));--tile-offset: calc( var(--gutter-size) + var(--cell-size) + var(--gutter-size) / 2 );display:block;container-type:inline-size;box-sizing:border-box;aspect-ratio:var(--columns)/var(--rows);width:100%;height:auto}:host .grid{background-image:linear-gradient(to right,rgba(100,100,100,.12) 1px,transparent 1px),linear-gradient(to bottom,rgba(100,100,100,.12) 1px,transparent 1px),linear-gradient(to bottom,rgba(100,100,100,.12) 1px,transparent 1px);background-size:var(--tile-size) var(--tile-size),var(--tile-size) var(--tile-size),100% 1px;background-position:var(--tile-offset) var(--tile-offset),var(--tile-offset) var(--tile-offset),bottom;background-repeat:repeat,repeat,no-repeat}.grid-container{position:relative;width:100%;height:100%}.grid{display:grid;gap:var(--gutter-size);padding:var(--gutter-size);position:absolute;inset:0;width:100%;height:100%;box-sizing:border-box;align-items:stretch;justify-items:stretch;grid-template-columns:repeat(var(--columns),var(--cell-size));grid-template-rows:repeat(var(--rows),var(--cell-size))}#bottom-grid{z-index:1}#top-grid{z-index:2;pointer-events:none}.grid-cell{pointer-events:auto}.grid-cell.is-dragging{pointer-events:none;opacity:.5}\n"], dependencies: [{ kind: "component", type: CellComponent, selector: "lib-cell", inputs: ["widgetId", "cellId", "widgetFactory", "widgetState", "isEditMode", "flat", "row", "column", "rowSpan", "colSpan", "draggable"], outputs: ["rowChange", "columnChange", "dragStart", "dragEnd", "edit", "delete", "settings", "resizeStart", "resizeMove", "resizeEnd"] }, { kind: "component", type: DropZoneComponent, selector: "lib-drop-zone", inputs: ["row", "col", "index", "highlight", "highlightInvalid", "highlightResize", "editMode"], outputs: ["dragEnter", "dragExit", "dragOver", "dragDrop"] }, { kind: "component", type: CellContextMenuComponent, selector: "lib-cell-context-menu" }, { kind: "component", type: EmptyCellContextMenuComponent, selector: "lib-empty-cell-context-menu" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
2755
2828
|
}
|
|
2756
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
2829
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: DashboardEditorComponent, decorators: [{
|
|
2757
2830
|
type: Component,
|
|
2758
2831
|
args: [{ selector: 'ngx-dashboard-editor', standalone: true, imports: [
|
|
2759
2832
|
CellComponent,
|
|
@@ -2780,7 +2853,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.10", ngImpo
|
|
|
2780
2853
|
*/
|
|
2781
2854
|
class DashboardBridgeService {
|
|
2782
2855
|
// Map of registered dashboard instances with their reactive dimensions
|
|
2783
|
-
dashboards = signal(new Map(),
|
|
2856
|
+
dashboards = signal(new Map(), /* @ts-ignore */
|
|
2857
|
+
...(ngDevMode ? [{ debugName: "dashboards" }] : /* istanbul ignore next */ []));
|
|
2784
2858
|
/**
|
|
2785
2859
|
* Register a dashboard store instance using its dashboard ID
|
|
2786
2860
|
*/
|
|
@@ -2831,7 +2905,8 @@ class DashboardBridgeService {
|
|
|
2831
2905
|
}
|
|
2832
2906
|
// Return dimensions from first available dashboard with fallback for undefined
|
|
2833
2907
|
return dashboardEntries[0].dimensions() || { width: 100, height: 100 };
|
|
2834
|
-
},
|
|
2908
|
+
}, /* @ts-ignore */
|
|
2909
|
+
...(ngDevMode ? [{ debugName: "availableDimensions" }] : /* istanbul ignore next */ []));
|
|
2835
2910
|
/**
|
|
2836
2911
|
* Start drag operation on the first available dashboard
|
|
2837
2912
|
* (Widget lists need some dashboard to coordinate with during drag)
|
|
@@ -2854,15 +2929,18 @@ class DashboardBridgeService {
|
|
|
2854
2929
|
/**
|
|
2855
2930
|
* Get all registered dashboard IDs
|
|
2856
2931
|
*/
|
|
2857
|
-
registeredDashboards = computed(() => Array.from(this.dashboards().keys()),
|
|
2932
|
+
registeredDashboards = computed(() => Array.from(this.dashboards().keys()), /* @ts-ignore */
|
|
2933
|
+
...(ngDevMode ? [{ debugName: "registeredDashboards" }] : /* istanbul ignore next */ []));
|
|
2858
2934
|
/**
|
|
2859
2935
|
* Get the number of registered dashboards
|
|
2860
2936
|
*/
|
|
2861
|
-
dashboardCount = computed(() => this.dashboards().size,
|
|
2937
|
+
dashboardCount = computed(() => this.dashboards().size, /* @ts-ignore */
|
|
2938
|
+
...(ngDevMode ? [{ debugName: "dashboardCount" }] : /* istanbul ignore next */ []));
|
|
2862
2939
|
/**
|
|
2863
2940
|
* Check if any dashboards are registered
|
|
2864
2941
|
*/
|
|
2865
|
-
hasDashboards = computed(() => this.dashboards().size > 0,
|
|
2942
|
+
hasDashboards = computed(() => this.dashboards().size > 0, /* @ts-ignore */
|
|
2943
|
+
...(ngDevMode ? [{ debugName: "hasDashboards" }] : /* istanbul ignore next */ []));
|
|
2866
2944
|
/**
|
|
2867
2945
|
* Update registration for a dashboard store when its ID becomes available
|
|
2868
2946
|
*/
|
|
@@ -2897,10 +2975,10 @@ class DashboardBridgeService {
|
|
|
2897
2975
|
getAllDashboards() {
|
|
2898
2976
|
return this.dashboards();
|
|
2899
2977
|
}
|
|
2900
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
2901
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "
|
|
2978
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: DashboardBridgeService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
2979
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: DashboardBridgeService, providedIn: 'root' });
|
|
2902
2980
|
}
|
|
2903
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
2981
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: DashboardBridgeService, decorators: [{
|
|
2904
2982
|
type: Injectable,
|
|
2905
2983
|
args: [{ providedIn: 'root' }]
|
|
2906
2984
|
}] });
|
|
@@ -2915,8 +2993,10 @@ class DashboardViewportService {
|
|
|
2915
2993
|
platformId = inject(PLATFORM_ID);
|
|
2916
2994
|
destroyRef = inject(DestroyRef);
|
|
2917
2995
|
store = inject(DashboardStore);
|
|
2918
|
-
viewportSize = signal({ width: 0, height: 0 },
|
|
2919
|
-
|
|
2996
|
+
viewportSize = signal({ width: 0, height: 0 }, /* @ts-ignore */
|
|
2997
|
+
...(ngDevMode ? [{ debugName: "viewportSize" }] : /* istanbul ignore next */ []));
|
|
2998
|
+
reservedSpace = signal(DEFAULT_RESERVED_SPACE, /* @ts-ignore */
|
|
2999
|
+
...(ngDevMode ? [{ debugName: "reservedSpace" }] : /* istanbul ignore next */ []));
|
|
2920
3000
|
resizeObserver = null;
|
|
2921
3001
|
constructor() {
|
|
2922
3002
|
if (isPlatformBrowser(this.platformId)) {
|
|
@@ -2974,7 +3054,8 @@ class DashboardViewportService {
|
|
|
2974
3054
|
width: Math.max(0, viewport.width - reserved.left - reserved.right),
|
|
2975
3055
|
height: Math.max(0, viewport.height - reserved.top - reserved.bottom)
|
|
2976
3056
|
};
|
|
2977
|
-
},
|
|
3057
|
+
}, /* @ts-ignore */
|
|
3058
|
+
...(ngDevMode ? [{ debugName: "availableSpace" }] : /* istanbul ignore next */ []));
|
|
2978
3059
|
/**
|
|
2979
3060
|
* Calculate dashboard constraints for this dashboard instance
|
|
2980
3061
|
*/
|
|
@@ -3015,11 +3096,12 @@ class DashboardViewportService {
|
|
|
3015
3096
|
maxHeight: Math.max(0, maxHeight),
|
|
3016
3097
|
constrainedBy
|
|
3017
3098
|
};
|
|
3018
|
-
},
|
|
3019
|
-
|
|
3020
|
-
static
|
|
3099
|
+
}, /* @ts-ignore */
|
|
3100
|
+
...(ngDevMode ? [{ debugName: "constraints" }] : /* istanbul ignore next */ []));
|
|
3101
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: DashboardViewportService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
3102
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: DashboardViewportService });
|
|
3021
3103
|
}
|
|
3022
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
3104
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: DashboardViewportService, decorators: [{
|
|
3023
3105
|
type: Injectable
|
|
3024
3106
|
}], ctorParameters: () => [] });
|
|
3025
3107
|
|
|
@@ -3037,19 +3119,27 @@ class DashboardComponent {
|
|
|
3037
3119
|
store = this.#store;
|
|
3038
3120
|
viewport = this.#viewport;
|
|
3039
3121
|
// Component inputs
|
|
3040
|
-
dashboardData = input.required(
|
|
3041
|
-
|
|
3042
|
-
|
|
3043
|
-
|
|
3044
|
-
|
|
3045
|
-
|
|
3122
|
+
dashboardData = input.required(/* @ts-ignore */
|
|
3123
|
+
...(ngDevMode ? [{ debugName: "dashboardData" }] : /* istanbul ignore next */ []));
|
|
3124
|
+
editMode = input(false, /* @ts-ignore */
|
|
3125
|
+
...(ngDevMode ? [{ debugName: "editMode" }] : /* istanbul ignore next */ []));
|
|
3126
|
+
reservedSpace = input(/* @ts-ignore */
|
|
3127
|
+
...(ngDevMode ? [undefined, { debugName: "reservedSpace" }] : /* istanbul ignore next */ []));
|
|
3128
|
+
enableSelection = input(false, /* @ts-ignore */
|
|
3129
|
+
...(ngDevMode ? [{ debugName: "enableSelection" }] : /* istanbul ignore next */ []));
|
|
3130
|
+
selectionModifier = input(null, /* @ts-ignore */
|
|
3131
|
+
...(ngDevMode ? [{ debugName: "selectionModifier" }] : /* istanbul ignore next */ []));
|
|
3132
|
+
dragThreshold = input(4, /* @ts-ignore */
|
|
3133
|
+
...(ngDevMode ? [{ debugName: "dragThreshold" }] : /* istanbul ignore next */ []));
|
|
3046
3134
|
// Component outputs
|
|
3047
3135
|
selectionComplete = output();
|
|
3048
3136
|
// Store signals - shared by both child components
|
|
3049
3137
|
cells = this.#store.cells;
|
|
3050
3138
|
// ViewChild references for export/import functionality
|
|
3051
|
-
dashboardEditor = viewChild(DashboardEditorComponent,
|
|
3052
|
-
|
|
3139
|
+
dashboardEditor = viewChild(DashboardEditorComponent, /* @ts-ignore */
|
|
3140
|
+
...(ngDevMode ? [{ debugName: "dashboardEditor" }] : /* istanbul ignore next */ []));
|
|
3141
|
+
dashboardViewer = viewChild(DashboardViewerComponent, /* @ts-ignore */
|
|
3142
|
+
...(ngDevMode ? [{ debugName: "dashboardViewer" }] : /* istanbul ignore next */ []));
|
|
3053
3143
|
// Track if we're in the middle of preserving states
|
|
3054
3144
|
#isPreservingStates = false;
|
|
3055
3145
|
// Track if component has been initialized
|
|
@@ -3143,6 +3233,13 @@ class DashboardComponent {
|
|
|
3143
3233
|
clearDashboard() {
|
|
3144
3234
|
this.#store.clearDashboard();
|
|
3145
3235
|
}
|
|
3236
|
+
/**
|
|
3237
|
+
* Forwards to the active viewer. No-op in edit mode.
|
|
3238
|
+
* See `DashboardViewerComponent.clearSelection()`.
|
|
3239
|
+
*/
|
|
3240
|
+
clearSelection() {
|
|
3241
|
+
this.dashboardViewer()?.clearSelection();
|
|
3242
|
+
}
|
|
3146
3243
|
/**
|
|
3147
3244
|
* Preserve widget states before switching modes by collecting live states
|
|
3148
3245
|
* from the currently active component and updating the store.
|
|
@@ -3179,10 +3276,10 @@ class DashboardComponent {
|
|
|
3179
3276
|
this.#isPreservingStates = false;
|
|
3180
3277
|
}
|
|
3181
3278
|
}
|
|
3182
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
3183
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "
|
|
3279
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: DashboardComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
3280
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.4", type: DashboardComponent, isStandalone: true, selector: "ngx-dashboard", inputs: { dashboardData: { classPropertyName: "dashboardData", publicName: "dashboardData", isSignal: true, isRequired: true, transformFunction: null }, editMode: { classPropertyName: "editMode", publicName: "editMode", isSignal: true, isRequired: false, transformFunction: null }, reservedSpace: { classPropertyName: "reservedSpace", publicName: "reservedSpace", isSignal: true, isRequired: false, transformFunction: null }, enableSelection: { classPropertyName: "enableSelection", publicName: "enableSelection", isSignal: true, isRequired: false, transformFunction: null }, selectionModifier: { classPropertyName: "selectionModifier", publicName: "selectionModifier", isSignal: true, isRequired: false, transformFunction: null }, dragThreshold: { classPropertyName: "dragThreshold", publicName: "dragThreshold", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selectionComplete: "selectionComplete" }, host: { properties: { "style.--rows": "store.rows()", "style.--columns": "store.columns()", "style.--gutter-size": "store.gutterSize()", "style.--gutters": "store.columns() + 1", "class.is-edit-mode": "editMode()", "style.max-width.px": "viewport.constraints().maxWidth", "style.max-height.px": "viewport.constraints().maxHeight" } }, providers: [DashboardStore, DashboardViewportService], viewQueries: [{ propertyName: "dashboardEditor", first: true, predicate: DashboardEditorComponent, descendants: true, isSignal: true }, { propertyName: "dashboardViewer", first: true, predicate: DashboardViewerComponent, descendants: true, isSignal: true }], usesOnChanges: true, ngImport: i0, template: "<!-- dashboard.component.html -->\n<div class=\"grid-container\">\n @if (editMode()) {\n <!-- Full editor with drag & drop capabilities -->\n <ngx-dashboard-editor\n [rows]=\"store.rows()\"\n [columns]=\"store.columns()\"\n [gutterSize]=\"store.gutterSize()\"\n ></ngx-dashboard-editor>\n } @else {\n <!-- Read-only viewer -->\n <ngx-dashboard-viewer\n [rows]=\"store.rows()\"\n [columns]=\"store.columns()\"\n [gutterSize]=\"store.gutterSize()\"\n [enableSelection]=\"enableSelection()\"\n [selectionModifier]=\"selectionModifier()\"\n [dragThreshold]=\"dragThreshold()\"\n (selectionComplete)=\"selectionComplete.emit($event)\"\n ></ngx-dashboard-viewer>\n }\n</div>\n", styles: [":host{display:block;container-type:inline-size;box-sizing:border-box;aspect-ratio:var(--columns)/var(--rows);width:100%;height:auto}.grid-container{position:relative;width:100%;height:100%}\n"], dependencies: [{ kind: "component", type: DashboardViewerComponent, selector: "ngx-dashboard-viewer", inputs: ["rows", "columns", "gutterSize", "enableSelection", "selectionModifier", "dragThreshold"], outputs: ["selectionComplete"] }, { kind: "component", type: DashboardEditorComponent, selector: "ngx-dashboard-editor", inputs: ["rows", "columns", "gutterSize"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
3184
3281
|
}
|
|
3185
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
3282
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: DashboardComponent, decorators: [{
|
|
3186
3283
|
type: Component,
|
|
3187
3284
|
args: [{ selector: 'ngx-dashboard', standalone: true, imports: [DashboardViewerComponent, DashboardEditorComponent], providers: [DashboardStore, DashboardViewportService], changeDetection: ChangeDetectionStrategy.OnPush, host: {
|
|
3188
3285
|
'[style.--rows]': 'store.rows()',
|
|
@@ -3202,14 +3299,17 @@ class WidgetListComponent {
|
|
|
3202
3299
|
#renderer = inject(Renderer2);
|
|
3203
3300
|
#bridge = inject(DashboardBridgeService);
|
|
3204
3301
|
// Input to track collapsed state for tooltip display
|
|
3205
|
-
collapsed = input(false,
|
|
3206
|
-
|
|
3302
|
+
collapsed = input(false, /* @ts-ignore */
|
|
3303
|
+
...(ngDevMode ? [{ debugName: "collapsed" }] : /* istanbul ignore next */ []));
|
|
3304
|
+
activeWidget = signal(null, /* @ts-ignore */
|
|
3305
|
+
...(ngDevMode ? [{ debugName: "activeWidget" }] : /* istanbul ignore next */ []));
|
|
3207
3306
|
// Get grid cell dimensions from bridge service (uses first available dashboard)
|
|
3208
3307
|
gridCellDimensions = this.#bridge.availableDimensions;
|
|
3209
3308
|
widgets = computed(() => this.#service.widgetTypes().map((w) => ({
|
|
3210
3309
|
...w.metadata,
|
|
3211
3310
|
safeSvgIcon: this.#sanitizer.bypassSecurityTrustHtml(w.metadata.svgIcon),
|
|
3212
|
-
})),
|
|
3311
|
+
})), /* @ts-ignore */
|
|
3312
|
+
...(ngDevMode ? [{ debugName: "widgets" }] : /* istanbul ignore next */ []));
|
|
3213
3313
|
onDragStart(event, widget) {
|
|
3214
3314
|
if (!event.dataTransfer)
|
|
3215
3315
|
return;
|
|
@@ -3261,10 +3361,10 @@ class WidgetListComponent {
|
|
|
3261
3361
|
// Using $localize for the template pattern
|
|
3262
3362
|
return $localize `:@@ngx.dashboard.widget.list.item.ariaLabel:${widget.name} widget: ${widget.description}`;
|
|
3263
3363
|
}
|
|
3264
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
3265
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "
|
|
3364
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: WidgetListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
3365
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.4", type: WidgetListComponent, isStandalone: true, selector: "ngx-dashboard-widget-list", inputs: { collapsed: { classPropertyName: "collapsed", publicName: "collapsed", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<!-- widget-list.component.html -->\n<div\n class=\"widget-list\"\n role=\"list\"\n i18n-aria-label=\"@@ngx.dashboard.widget.list.available\"\n aria-label=\"Available widgets\"\n>\n @for (widget of widgets(); track widget.widgetTypeid) {\n <div\n class=\"widget-list-item\"\n [class.active]=\"activeWidget() === widget.widgetTypeid\"\n draggable=\"true\"\n (dragstart)=\"onDragStart($event, widget)\"\n (dragend)=\"onDragEnd()\"\n role=\"listitem\"\n [attr.aria-grabbed]=\"activeWidget() === widget.widgetTypeid\"\n [attr.aria-label]=\"getWidgetAriaLabel(widget)\"\n [matTooltip]=\"widget.description\"\n [matTooltipDisabled]=\"!collapsed()\"\n matTooltipPosition=\"right\"\n tabindex=\"0\"\n >\n <div class=\"icon\" [innerHTML]=\"widget.safeSvgIcon\" aria-hidden=\"true\"></div>\n <div class=\"content\">\n <strong>{{ widget.name }}</strong>\n <small>{{ widget.description }}</small>\n </div>\n </div>\n }\n</div>\n", styles: [":host{background-color:var(--mat-sys-surface-container, #f5f5f5);container-type:inline-size}.widget-list{display:flex;flex-direction:column;gap:var(--mat-sys-spacing-2, 8px)}@container (max-width: 200px){.widget-list{gap:var(--mat-sys-spacing-1, 4px)}}@container (min-width: 400px){.widget-list{gap:var(--mat-sys-spacing-3, 12px)}}.widget-list-item{display:flex;align-items:start;gap:var(--mat-sys-spacing-3, 12px);background-color:var(--mat-sys-surface, #ffffff);border:1px solid var(--mat-sys-outline-variant, #c7c7c7);padding:var(--mat-sys-spacing-3, 12px);border-radius:var(--mat-sys-corner-small, 4px);cursor:grab;transition:background-color var(--mat-sys-motion-duration-medium2, .3s) var(--mat-sys-motion-easing-standard, ease-in-out),border-color var(--mat-sys-motion-duration-medium2, .3s) var(--mat-sys-motion-easing-standard, ease-in-out),box-shadow var(--mat-sys-motion-duration-medium2, .3s) var(--mat-sys-motion-easing-standard, ease-in-out);box-shadow:var(--mat-sys-elevation-level1, 0 1px 2px rgba(0, 0, 0, .05))}@container (max-width: 200px){.widget-list-item{padding:var(--mat-sys-spacing-2, 8px);gap:var(--mat-sys-spacing-2, 8px)}}@container (min-width: 400px){.widget-list-item{padding:var(--mat-sys-spacing-4, 16px);gap:var(--mat-sys-spacing-4, 16px)}}.widget-list-item .icon{width:clamp(20px,4vw,28px);height:clamp(20px,4vw,28px);flex-shrink:0;color:var(--mat-sys-on-surface-variant, #5f5f5f);transition:color var(--mat-sys-motion-duration-short2, .15s) var(--mat-sys-motion-easing-standard, ease-in-out)}.widget-list-item .icon ::ng-deep svg{width:100%;height:100%;display:block}.widget-list-item .content{display:flex;flex-direction:column;line-height:1.2;color:var(--mat-sys-on-surface, #1c1c1c);flex:1;min-width:0}.widget-list-item .content strong{color:var(--mat-sys-on-surface, #1c1c1c);font-weight:500;font-size:clamp(.875rem,2.5vw,1rem);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.widget-list-item .content small{color:var(--mat-sys-on-surface-variant, #5f5f5f);font-size:clamp(.75rem,2vw,.875rem);margin-top:var(--mat-sys-spacing-1, 4px);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.widget-list-item:hover{background-color:var(--mat-sys-surface-container-low, #f0f0f0);box-shadow:var(--mat-sys-elevation-level2, 0 2px 4px rgba(0, 0, 0, .1))}.widget-list-item:hover .icon{color:var(--mat-sys-on-surface, #1c1c1c)}.widget-list-item:active{cursor:grabbing;background-color:var(--mat-sys-surface-container, #f5f5f5)}.widget-list-item.active{background-color:var(--mat-sys-primary-container, #e6f2ff);border-color:var(--mat-sys-primary, #1976d2);color:var(--mat-sys-on-primary-container, #004a99)}.widget-list-item.active .content strong{color:var(--mat-sys-on-primary-container, #004a99)}.widget-list-item.active .content small{color:var(--mat-sys-on-primary-container, #004a99);opacity:.8}.widget-list-item.active .icon{color:var(--mat-sys-on-primary-container, #004a99)}.drag-ghost{position:absolute;top:0;left:0;z-index:9999;margin:0;pointer-events:none;display:flex;align-items:center;justify-content:center;box-sizing:border-box;background-color:var(--mat-sys-surface, #ffffff);border:1px solid var(--mat-sys-outline-variant, #c7c7c7);border-radius:var(--mat-sys-corner-small, 4px);box-shadow:var(--mat-sys-elevation-level3, 0 4px 6px rgba(0, 0, 0, .15));opacity:.8}.drag-ghost .icon{display:flex;align-items:center;justify-content:center;color:var(--mat-sys-on-surface-variant, #5f5f5f);opacity:.6}.drag-ghost .icon ::ng-deep svg{display:block}\n"], dependencies: [{ kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i2$1.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
3266
3366
|
}
|
|
3267
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
3367
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: WidgetListComponent, decorators: [{
|
|
3268
3368
|
type: Component,
|
|
3269
3369
|
args: [{ selector: 'ngx-dashboard-widget-list', standalone: true, imports: [MatTooltipModule], changeDetection: ChangeDetectionStrategy.OnPush, template: "<!-- widget-list.component.html -->\n<div\n class=\"widget-list\"\n role=\"list\"\n i18n-aria-label=\"@@ngx.dashboard.widget.list.available\"\n aria-label=\"Available widgets\"\n>\n @for (widget of widgets(); track widget.widgetTypeid) {\n <div\n class=\"widget-list-item\"\n [class.active]=\"activeWidget() === widget.widgetTypeid\"\n draggable=\"true\"\n (dragstart)=\"onDragStart($event, widget)\"\n (dragend)=\"onDragEnd()\"\n role=\"listitem\"\n [attr.aria-grabbed]=\"activeWidget() === widget.widgetTypeid\"\n [attr.aria-label]=\"getWidgetAriaLabel(widget)\"\n [matTooltip]=\"widget.description\"\n [matTooltipDisabled]=\"!collapsed()\"\n matTooltipPosition=\"right\"\n tabindex=\"0\"\n >\n <div class=\"icon\" [innerHTML]=\"widget.safeSvgIcon\" aria-hidden=\"true\"></div>\n <div class=\"content\">\n <strong>{{ widget.name }}</strong>\n <small>{{ widget.description }}</small>\n </div>\n </div>\n }\n</div>\n", styles: [":host{background-color:var(--mat-sys-surface-container, #f5f5f5);container-type:inline-size}.widget-list{display:flex;flex-direction:column;gap:var(--mat-sys-spacing-2, 8px)}@container (max-width: 200px){.widget-list{gap:var(--mat-sys-spacing-1, 4px)}}@container (min-width: 400px){.widget-list{gap:var(--mat-sys-spacing-3, 12px)}}.widget-list-item{display:flex;align-items:start;gap:var(--mat-sys-spacing-3, 12px);background-color:var(--mat-sys-surface, #ffffff);border:1px solid var(--mat-sys-outline-variant, #c7c7c7);padding:var(--mat-sys-spacing-3, 12px);border-radius:var(--mat-sys-corner-small, 4px);cursor:grab;transition:background-color var(--mat-sys-motion-duration-medium2, .3s) var(--mat-sys-motion-easing-standard, ease-in-out),border-color var(--mat-sys-motion-duration-medium2, .3s) var(--mat-sys-motion-easing-standard, ease-in-out),box-shadow var(--mat-sys-motion-duration-medium2, .3s) var(--mat-sys-motion-easing-standard, ease-in-out);box-shadow:var(--mat-sys-elevation-level1, 0 1px 2px rgba(0, 0, 0, .05))}@container (max-width: 200px){.widget-list-item{padding:var(--mat-sys-spacing-2, 8px);gap:var(--mat-sys-spacing-2, 8px)}}@container (min-width: 400px){.widget-list-item{padding:var(--mat-sys-spacing-4, 16px);gap:var(--mat-sys-spacing-4, 16px)}}.widget-list-item .icon{width:clamp(20px,4vw,28px);height:clamp(20px,4vw,28px);flex-shrink:0;color:var(--mat-sys-on-surface-variant, #5f5f5f);transition:color var(--mat-sys-motion-duration-short2, .15s) var(--mat-sys-motion-easing-standard, ease-in-out)}.widget-list-item .icon ::ng-deep svg{width:100%;height:100%;display:block}.widget-list-item .content{display:flex;flex-direction:column;line-height:1.2;color:var(--mat-sys-on-surface, #1c1c1c);flex:1;min-width:0}.widget-list-item .content strong{color:var(--mat-sys-on-surface, #1c1c1c);font-weight:500;font-size:clamp(.875rem,2.5vw,1rem);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.widget-list-item .content small{color:var(--mat-sys-on-surface-variant, #5f5f5f);font-size:clamp(.75rem,2vw,.875rem);margin-top:var(--mat-sys-spacing-1, 4px);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.widget-list-item:hover{background-color:var(--mat-sys-surface-container-low, #f0f0f0);box-shadow:var(--mat-sys-elevation-level2, 0 2px 4px rgba(0, 0, 0, .1))}.widget-list-item:hover .icon{color:var(--mat-sys-on-surface, #1c1c1c)}.widget-list-item:active{cursor:grabbing;background-color:var(--mat-sys-surface-container, #f5f5f5)}.widget-list-item.active{background-color:var(--mat-sys-primary-container, #e6f2ff);border-color:var(--mat-sys-primary, #1976d2);color:var(--mat-sys-on-primary-container, #004a99)}.widget-list-item.active .content strong{color:var(--mat-sys-on-primary-container, #004a99)}.widget-list-item.active .content small{color:var(--mat-sys-on-primary-container, #004a99);opacity:.8}.widget-list-item.active .icon{color:var(--mat-sys-on-primary-container, #004a99)}.drag-ghost{position:absolute;top:0;left:0;z-index:9999;margin:0;pointer-events:none;display:flex;align-items:center;justify-content:center;box-sizing:border-box;background-color:var(--mat-sys-surface, #ffffff);border:1px solid var(--mat-sys-outline-variant, #c7c7c7);border-radius:var(--mat-sys-corner-small, 4px);box-shadow:var(--mat-sys-elevation-level3, 0 4px 6px rgba(0, 0, 0, .15));opacity:.8}.drag-ghost .icon{display:flex;align-items:center;justify-content:center;color:var(--mat-sys-on-surface-variant, #5f5f5f);opacity:.6}.drag-ghost .icon ::ng-deep svg{display:block}\n"] }]
|
|
3270
3370
|
}], propDecorators: { collapsed: [{ type: i0.Input, args: [{ isSignal: true, alias: "collapsed", required: false }] }] } });
|