@c8y/ngx-components 1024.5.1 → 1024.9.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.
- package/fesm2022/{c8y-ngx-components-asset-property-grid.component-DhfJagxU.mjs → c8y-ngx-components-asset-property-grid.component-Ddva2QJW.mjs} +35 -19
- package/fesm2022/c8y-ngx-components-asset-property-grid.component-Ddva2QJW.mjs.map +1 -0
- package/fesm2022/c8y-ngx-components-context-dashboard.mjs +28 -14
- package/fesm2022/c8y-ngx-components-context-dashboard.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-datapoints-export-selector.mjs +2 -2
- package/fesm2022/c8y-ngx-components-datapoints-export-selector.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-icon-selector.mjs +1538 -59
- package/fesm2022/c8y-ngx-components-icon-selector.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-platform-configuration.mjs +2 -2
- package/fesm2022/c8y-ngx-components-platform-configuration.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-remote-access-data.mjs +9 -2
- package/fesm2022/c8y-ngx-components-remote-access-data.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-remote-access-terminal-viewer.mjs +6 -1
- package/fesm2022/c8y-ngx-components-remote-access-terminal-viewer.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-reports.mjs +3 -5
- package/fesm2022/c8y-ngx-components-reports.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-repository-configuration.mjs +94 -49
- package/fesm2022/c8y-ngx-components-repository-configuration.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components.mjs +1 -1
- package/locales/de.po +266 -3
- package/locales/es.po +266 -3
- package/locales/fr.po +266 -3
- package/locales/ja_JP.po +265 -3
- package/locales/ko.po +266 -3
- package/locales/locales.pot +294 -7
- package/locales/nl.po +266 -3
- package/locales/pl.po +266 -3
- package/locales/pt_BR.po +266 -3
- package/locales/zh_CN.po +266 -3
- package/locales/zh_TW.po +266 -3
- package/package.json +1 -1
- package/types/c8y-ngx-components-context-dashboard.d.ts +7 -3
- package/types/c8y-ngx-components-context-dashboard.d.ts.map +1 -1
- package/types/c8y-ngx-components-icon-selector.d.ts +286 -32
- package/types/c8y-ngx-components-icon-selector.d.ts.map +1 -1
- package/types/c8y-ngx-components-platform-configuration.d.ts +2 -2
- package/types/c8y-ngx-components-remote-access-data.d.ts +8 -1
- package/types/c8y-ngx-components-remote-access-data.d.ts.map +1 -1
- package/types/c8y-ngx-components-remote-access-terminal-viewer.d.ts.map +1 -1
- package/types/c8y-ngx-components-reports.d.ts.map +1 -1
- package/types/c8y-ngx-components-repository-configuration.d.ts +20 -10
- package/types/c8y-ngx-components-repository-configuration.d.ts.map +1 -1
- package/fesm2022/c8y-ngx-components-asset-property-grid.component-DhfJagxU.mjs.map +0 -1
|
@@ -157,6 +157,12 @@ class AssetPropertyGridComponent {
|
|
|
157
157
|
hover: true
|
|
158
158
|
};
|
|
159
159
|
this.onAddCustomColumn = new EventEmitter();
|
|
160
|
+
/**
|
|
161
|
+
* Maps a selectable node path to its column header, derived while building the
|
|
162
|
+
* tree. Lets a selected column be resolved locally, without a redundant fetch
|
|
163
|
+
* for a definition whose header the list response already provides.
|
|
164
|
+
*/
|
|
165
|
+
this.headersByPath = new Map();
|
|
160
166
|
}
|
|
161
167
|
async onDataSourceModifier(dataSourceModifier) {
|
|
162
168
|
const { columns, pagination, parentRow } = dataSourceModifier;
|
|
@@ -174,6 +180,7 @@ class AssetPropertyGridComponent {
|
|
|
174
180
|
};
|
|
175
181
|
});
|
|
176
182
|
const treeNodes = data.map(d => this.toTreeNode(d));
|
|
183
|
+
this.cacheHeaders(treeNodes);
|
|
177
184
|
return {
|
|
178
185
|
res,
|
|
179
186
|
data: treeNodes,
|
|
@@ -182,34 +189,43 @@ class AssetPropertyGridComponent {
|
|
|
182
189
|
size: paging?.totalElements
|
|
183
190
|
};
|
|
184
191
|
}
|
|
185
|
-
|
|
192
|
+
selectItem(identifiers) {
|
|
186
193
|
if (this.bottomDrawerRef) {
|
|
187
194
|
this.bottomDrawerRef.close();
|
|
188
195
|
}
|
|
189
196
|
this.addColumn(identifiers[0]);
|
|
190
197
|
}
|
|
191
|
-
|
|
192
|
-
const
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
const header = childSchema?.title || childKey || def.jsonSchema?.title;
|
|
197
|
-
this.onAddCustomColumn.emit({
|
|
198
|
-
name: camelCase(path),
|
|
199
|
-
header,
|
|
200
|
-
path,
|
|
201
|
-
type: 'property',
|
|
202
|
-
custom: true,
|
|
203
|
-
visible: true
|
|
204
|
-
});
|
|
205
|
-
}
|
|
206
|
-
catch (err) {
|
|
207
|
-
this.alertService.addServerFailure(err);
|
|
198
|
+
addColumn(path) {
|
|
199
|
+
const header = this.headersByPath.get(path);
|
|
200
|
+
if (!header) {
|
|
201
|
+
this.alertService.danger(gettext('Unable to add the column because the property definition could not be found.'));
|
|
202
|
+
return;
|
|
208
203
|
}
|
|
204
|
+
this.onAddCustomColumn.emit({
|
|
205
|
+
name: camelCase(path),
|
|
206
|
+
header,
|
|
207
|
+
path,
|
|
208
|
+
type: 'property',
|
|
209
|
+
custom: true,
|
|
210
|
+
visible: true
|
|
211
|
+
});
|
|
209
212
|
}
|
|
210
213
|
close() {
|
|
211
214
|
this.bottomDrawerRef?.close();
|
|
212
215
|
}
|
|
216
|
+
/**
|
|
217
|
+
* Records the header (node title) for every node path in the given tree,
|
|
218
|
+
* recursing into children. Merges with previously loaded pages so selections
|
|
219
|
+
* stay resolvable after "Load more".
|
|
220
|
+
*/
|
|
221
|
+
cacheHeaders(nodes) {
|
|
222
|
+
for (const node of nodes) {
|
|
223
|
+
this.headersByPath.set(node.id, node.title);
|
|
224
|
+
if (node.children?.length) {
|
|
225
|
+
this.cacheHeaders(node.children);
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
}
|
|
213
229
|
buildChildGridData(parentRow) {
|
|
214
230
|
const children = parentRow.children ?? [];
|
|
215
231
|
const currentPage = parentRow.pagination?.currentPage ?? 1;
|
|
@@ -282,4 +298,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImpo
|
|
|
282
298
|
}] } });
|
|
283
299
|
|
|
284
300
|
export { AssetPropertyGridComponent };
|
|
285
|
-
//# sourceMappingURL=c8y-ngx-components-asset-property-grid.component-
|
|
301
|
+
//# sourceMappingURL=c8y-ngx-components-asset-property-grid.component-Ddva2QJW.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"c8y-ngx-components-asset-property-grid.component-Ddva2QJW.mjs","sources":["../../core/data-grid/configure-custom-column/columns/identifier.cell-renderer.component.ts","../../core/data-grid/configure-custom-column/columns/identifier.data-grid-column.ts","../../core/data-grid/configure-custom-column/columns/tags.cell-renderer.components.ts","../../core/data-grid/configure-custom-column/columns/tags.data-grid-column.ts","../../core/data-grid/configure-custom-column/columns/title.cell-renderer.component.ts","../../core/data-grid/configure-custom-column/columns/title.data-grid-column.ts","../../core/data-grid/configure-custom-column/asset-property-grid.component.ts","../../core/data-grid/configure-custom-column/asset-property-grid.component.html"],"sourcesContent":["import { Component } from '@angular/core';\nimport { CellRendererContext } from '../../column/cell-renderer';\n\n@Component({\n template: ` {{ context.item.id }} `,\n selector: 'c8y-identifier-cell-renderer',\n standalone: true\n})\nexport class IdentifierCellRendererComponent {\n constructor(public context: CellRendererContext) {}\n}\n","import { getBasicInputArrayFormFieldConfig } from '../../../dynamic-forms';\nimport { gettext } from '@c8y/ngx-components/gettext';\nimport { BaseColumn } from '../../column/base.column';\nimport { ColumnConfig } from '../../data-grid.model';\nimport { IdentifierCellRendererComponent } from './identifier.cell-renderer.component';\n\nexport class IdentifierGridColumn extends BaseColumn {\n constructor(initialColumnConfig?: ColumnConfig) {\n super(initialColumnConfig);\n\n this.name = 'key';\n this.header = gettext('Key');\n this.cellRendererComponent = IdentifierCellRendererComponent;\n\n this.filterable = true;\n this.filteringConfig = {\n fields: getBasicInputArrayFormFieldConfig({\n key: 'identifiers',\n label: gettext('Show items with identifier'),\n addText: gettext('Add next`identifier`'),\n placeholder: 'c8y_Position'\n }),\n getFilter(_model) {\n return _model;\n }\n };\n\n this.sortable = false;\n }\n}\n","import { Component } from '@angular/core';\nimport { CellRendererContext } from '../../column/cell-renderer';\n\n@Component({\n template: ` {{ context.item.tags }} `,\n selector: 'c8y-tags-cell-renderer',\n standalone: true\n})\nexport class TagsCellRendererComponent {\n constructor(public context: CellRendererContext) {}\n}\n","import { getBasicInputArrayFormFieldConfig } from '../../../dynamic-forms';\nimport { gettext } from '@c8y/ngx-components/gettext';\nimport { BaseColumn } from '../../column/base.column';\nimport { ColumnConfig } from '../../data-grid.model';\nimport { TagsCellRendererComponent } from './tags.cell-renderer.components';\n\nexport class TagsGridColumn extends BaseColumn {\n constructor(initialColumnConfig?: ColumnConfig) {\n super(initialColumnConfig);\n\n this.name = 'tags';\n this.header = gettext('Tags');\n this.cellRendererComponent = TagsCellRendererComponent;\n\n this.filterable = true;\n this.filteringConfig = {\n fields: getBasicInputArrayFormFieldConfig({\n key: 'tags',\n label: gettext('Show items with tags'),\n addText: gettext('Add next`tag`'),\n placeholder: 'tag1'\n }),\n getFilter(_model) {\n return _model;\n }\n };\n\n this.sortable = false;\n }\n}\n","import { Component } from '@angular/core';\nimport { CellRendererContext } from '../..';\n\n@Component({\n template: ` {{ context.item.title }} `,\n selector: 'c8y-title-cell-renderer',\n standalone: true\n})\nexport class TitleCellRendererComponent {\n constructor(public context: CellRendererContext) {}\n}\n","import { getBasicInputArrayFormFieldConfig } from '../../../dynamic-forms';\nimport { gettext } from '@c8y/ngx-components/gettext';\nimport { BaseColumn } from '../../column/base.column';\nimport { ColumnConfig } from '../../data-grid.model';\nimport { TitleCellRendererComponent } from './title.cell-renderer.component';\n\nexport class TitleGridColumn extends BaseColumn {\n constructor(initialColumnConfig?: ColumnConfig) {\n super(initialColumnConfig);\n\n this.name = 'title';\n this.header = gettext('Title');\n this.cellRendererComponent = TitleCellRendererComponent;\n\n this.filterable = true;\n this.filteringConfig = {\n fields: getBasicInputArrayFormFieldConfig({\n key: 'titles',\n label: gettext('Show items with title'),\n addText: gettext('Add next`title`'),\n placeholder: 'location'\n }),\n getFilter(_model) {\n return _model;\n }\n };\n\n this.sortable = false;\n }\n}\n","import { Component, EventEmitter, Output } from '@angular/core';\nimport { gettext } from '@c8y/ngx-components/gettext';\nimport { camelCase } from 'lodash-es';\nimport { alertOnError, AlertService } from '../../alert';\nimport {\n AssetPropertyDefinition,\n SchemaNode,\n TreeNode\n} from '../../asset-property/asset-property.model';\nimport { AssetPropertyService } from '../../asset-property/asset-property.service';\nimport { BottomDrawerRef } from '../../bottom-drawer';\nimport { C8yTranslatePipe } from '../../i18n/c8y-translate.pipe';\nimport { DataGridComponent } from '../data-grid.component';\nimport {\n Column,\n CustomColumnConfig,\n DataSourceModifier,\n DisplayOptions,\n Pagination,\n ServerSideDataCallback,\n ServerSideDataResult\n} from '../data-grid.model';\nimport { IdentifierCellRendererComponent } from './columns/identifier.cell-renderer.component';\nimport { IdentifierGridColumn } from './columns/identifier.data-grid-column';\nimport { TagsCellRendererComponent } from './columns/tags.cell-renderer.components';\nimport { TagsGridColumn } from './columns/tags.data-grid-column';\nimport { TitleCellRendererComponent } from './columns/title.cell-renderer.component';\nimport { TitleGridColumn } from './columns/title.data-grid-column';\n\nconst CHILD_PAGE_SIZE = 5;\nconst ROOT_PAGE_SIZE = 25;\n\n@Component({\n selector: 'c8y-asset-property-grid',\n host: { class: 'd-contents' },\n standalone: true,\n imports: [\n C8yTranslatePipe,\n DataGridComponent,\n IdentifierCellRendererComponent,\n TitleCellRendererComponent,\n TagsCellRendererComponent\n ],\n templateUrl: './asset-property-grid.component.html'\n})\nexport class AssetPropertyGridComponent {\n columns: readonly Column[] = [\n new TitleGridColumn(),\n new IdentifierGridColumn(),\n new TagsGridColumn(),\n {\n name: 'description',\n header: gettext('Description'),\n path: 'description',\n filterable: false,\n sortable: false\n },\n {\n name: 'dataType',\n header: gettext('Data Type'),\n path: 'type',\n filterable: false,\n sortable: false\n }\n ];\n\n pagination: Pagination = { pageSize: ROOT_PAGE_SIZE, currentPage: 1 };\n childNodePagination: Pagination = { pageSize: CHILD_PAGE_SIZE, currentPage: 1 };\n serverSideDataCallback: ServerSideDataCallback = this.onDataSourceModifier.bind(this);\n loadError: string | null = null;\n\n headerActionControls = [];\n\n displayOptions: DisplayOptions = {\n bordered: false,\n striped: true,\n filter: true,\n gridHeader: true,\n hover: true\n };\n\n @Output() onAddCustomColumn = new EventEmitter<CustomColumnConfig>();\n\n /**\n * Maps a selectable node path to its column header, derived while building the\n * tree. Lets a selected column be resolved locally, without a redundant fetch\n * for a definition whose header the list response already provides.\n */\n private readonly headersByPath = new Map<string, string>();\n\n constructor(\n private service: AssetPropertyService,\n private bottomDrawerRef: BottomDrawerRef<AssetPropertyGridComponent>,\n private alertService: AlertService\n ) {}\n\n async onDataSourceModifier(\n dataSourceModifier: DataSourceModifier\n ): Promise<ServerSideDataResult> {\n const { columns, pagination, parentRow } = dataSourceModifier;\n\n if (parentRow) {\n return this.buildChildGridData(parentRow);\n }\n\n const {\n res,\n data = [],\n paging\n } = await alertOnError(this.service.list(this.buildFilter(columns, pagination))).catch(() => {\n this.loadError = gettext('Unable to load asset properties. Please try again later.');\n return {\n res: null,\n data: [],\n paging: null,\n filteredSize: 0,\n size: 0\n };\n });\n\n const treeNodes = data.map(d => this.toTreeNode(d));\n this.cacheHeaders(treeNodes);\n\n return {\n res,\n data: treeNodes,\n paging,\n filteredSize: paging?.totalElements,\n size: paging?.totalElements\n };\n }\n\n selectItem(identifiers: string[]): void {\n if (this.bottomDrawerRef) {\n this.bottomDrawerRef.close();\n }\n this.addColumn(identifiers[0]);\n }\n\n addColumn(path: string): void {\n const header = this.headersByPath.get(path);\n\n if (!header) {\n this.alertService.danger(\n gettext('Unable to add the column because the property definition could not be found.')\n );\n return;\n }\n\n this.onAddCustomColumn.emit({\n name: camelCase(path),\n header,\n path,\n type: 'property',\n custom: true,\n visible: true\n });\n }\n\n close(): void {\n this.bottomDrawerRef?.close();\n }\n\n /**\n * Records the header (node title) for every node path in the given tree,\n * recursing into children. Merges with previously loaded pages so selections\n * stay resolvable after \"Load more\".\n */\n private cacheHeaders(nodes: TreeNode[]): void {\n for (const node of nodes) {\n this.headersByPath.set(node.id, node.title);\n if (node.children?.length) {\n this.cacheHeaders(node.children);\n }\n }\n }\n\n private buildChildGridData(parentRow) {\n const children = parentRow.children ?? [];\n const currentPage = parentRow.pagination?.currentPage ?? 1;\n\n const start = (currentPage - 1) * CHILD_PAGE_SIZE;\n const data = children.slice(start, start + CHILD_PAGE_SIZE);\n const totalPages = Math.ceil(children.length / CHILD_PAGE_SIZE);\n\n return {\n data,\n filteredSize: children.length,\n size: children.length,\n paging: {\n currentPage,\n pageSize: CHILD_PAGE_SIZE,\n totalPages,\n totalElements: children.length,\n nextPage: currentPage < totalPages ? currentPage + 1 : null,\n prevPage: currentPage > 1 ? currentPage - 1 : null\n },\n parentRow\n } as ServerSideDataResult;\n }\n\n private buildFilter(columns: Column[], pagination: Pagination) {\n const predicates = columns\n .filter(column => column.filterable && column.externalFilterQuery)\n .reduce((acc, column) => ({ ...acc, ...column.externalFilterQuery }), {});\n\n return { currentPage: pagination.currentPage, pageSize: pagination.pageSize, ...predicates };\n }\n\n private toTreeNode({ identifier, jsonSchema = {}, tags }: AssetPropertyDefinition): TreeNode {\n const { title, description, type, properties } = jsonSchema;\n\n return {\n id: identifier,\n title: title ?? identifier,\n description,\n type,\n tags,\n children: this.mapSchema(properties, identifier),\n hasChildren: !!properties\n };\n }\n\n private mapSchema(props: Record<string, SchemaNode> | undefined, base = ''): TreeNode[] {\n if (!props) return [];\n\n return Object.entries(props).map(([key, schema]) => {\n const id = base ? `${base}.${key}` : key;\n const children = this.mapSchema(schema.properties, id);\n return {\n id,\n title: schema.title ?? key,\n description: schema.description,\n type: schema.type,\n children,\n hasChildren: children.length > 0\n };\n });\n }\n}\n","<div class=\"card-block flex-no-shrink separator-bottom col-xs-12 large-padding p-t-24 p-b-24\">\n <div\n class=\"h4 text-center text-medium\"\n id=\"drawerTitle\"\n translate\n >\n Add custom column\n </div>\n</div>\n<c8y-data-grid\n class=\"min-height-0 flex-grow d-col\"\n [title]=\"'Asset properties' | translate\"\n [loadMoreItemsLabel]=\"'Load more asset properties' | translate\"\n [loadingItemsLabel]=\"'Loading asset properties…' | translate\"\n [displayOptions]=\"displayOptions\"\n [headerActionControls]=\"headerActionControls\"\n [columns]=\"columns\"\n [treeGrid]=\"true\"\n [childNodePagination]=\"childNodePagination\"\n parentNodeLabelProperty=\"title\"\n [pagination]=\"pagination\"\n [serverSideDataCallback]=\"serverSideDataCallback\"\n [selectable]=\"true\"\n [singleSelection]=\"true\"\n (itemsSelect)=\"selectItem($event)\"\n></c8y-data-grid>\n<div class=\"card-footer p-24 separator text-center\">\n <button\n class=\"btn btn-default\"\n type=\"button\"\n (click)=\"close()\"\n >\n {{ ' Cancel' | translate }}\n </button>\n</div>\n"],"names":["i1.CellRendererContext","i1.AssetPropertyService","i2.BottomDrawerRef","i3.AlertService"],"mappings":"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"}
|
|
@@ -453,18 +453,23 @@ class ContextDashboardService {
|
|
|
453
453
|
this.dashboardTabs$ = this.getTabs$(mo, types, route?.parent?.data, options);
|
|
454
454
|
return this.dashboardTabs$;
|
|
455
455
|
}
|
|
456
|
-
getDashboard(name, defaultWidgets) {
|
|
456
|
+
getDashboard(name, defaultWidgets, context) {
|
|
457
457
|
const children = this.mapWidgets(defaultWidgets);
|
|
458
|
+
const defaultDashboard = this.getDefaultDashboard({
|
|
459
|
+
name,
|
|
460
|
+
children,
|
|
461
|
+
translateWidgetTitle: true,
|
|
462
|
+
widgetClasses: { 'dashboard-theme-light': true, 'panel-title-regular': true }
|
|
463
|
+
});
|
|
458
464
|
return this.getDashboard$(name, [ContextDashboardType.Named]).pipe(throwIfEmpty(), catchError(() => {
|
|
459
|
-
|
|
460
|
-
this.
|
|
461
|
-
|
|
462
|
-
return
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
}));
|
|
465
|
+
const canCreate$ = context?.id
|
|
466
|
+
? from(this.permissions.canEdit(this.INVENTORY_ROLES, context))
|
|
467
|
+
: of(this.hasPermissionsToCopyDashboard());
|
|
468
|
+
return canCreate$.pipe(tap(hasPermission => {
|
|
469
|
+
if (!hasPermission) {
|
|
470
|
+
this.alert.warning(gettext('You are viewing a read-only dashboard because you don’t have the necessary permissions to modify it.'));
|
|
471
|
+
}
|
|
472
|
+
}), map(() => defaultDashboard));
|
|
468
473
|
}));
|
|
469
474
|
}
|
|
470
475
|
updateNavigatorItem(mo) {
|
|
@@ -521,12 +526,19 @@ class ContextDashboardService {
|
|
|
521
526
|
}
|
|
522
527
|
/**
|
|
523
528
|
* Checks if user is able to edit dashboard according to his roles and dashboard ownership.
|
|
529
|
+
* When the dashboard managed object has no ID (e.g. a default in-memory dashboard), the check
|
|
530
|
+
* falls back to the provided `fallbackContext` managed object (e.g. the device or group), which
|
|
531
|
+
* allows group-level inventory roles to be evaluated correctly via the request-based check.
|
|
524
532
|
*
|
|
525
533
|
* @param mo - Dashboard managed object.
|
|
534
|
+
* @param fallbackContext - Optional context (device or group) used for permission checks when `mo` has no ID.
|
|
526
535
|
* @returns True if user is able to edit dashboard, false if he cannot.
|
|
527
536
|
*/
|
|
528
|
-
async canEditDashboard(mo) {
|
|
529
|
-
|
|
537
|
+
async canEditDashboard(mo, fallbackContext) {
|
|
538
|
+
if (!isEmpty(mo.id) || !fallbackContext?.id) {
|
|
539
|
+
return await this.permissions.canEdit(this.INVENTORY_ROLES, mo);
|
|
540
|
+
}
|
|
541
|
+
return await this.permissions.canEdit(this.INVENTORY_ROLES, fallbackContext);
|
|
530
542
|
}
|
|
531
543
|
/**
|
|
532
544
|
* Checks if user has permissions to copy dashboard according to his roles.
|
|
@@ -3413,8 +3425,9 @@ class ContextDashboardComponent {
|
|
|
3413
3425
|
}
|
|
3414
3426
|
async onLoad(trackExperience) {
|
|
3415
3427
|
this.isNamedDashboard = this.contextDashboardService.isNamed(this.mo);
|
|
3428
|
+
const activeContext = this.context?.contextData || this.context;
|
|
3416
3429
|
this.hasPermissionToEditDashboard = this.dashboard
|
|
3417
|
-
? await this.contextDashboardService.canEditDashboard(this.mo)
|
|
3430
|
+
? await this.contextDashboardService.canEditDashboard(this.mo, activeContext)
|
|
3418
3431
|
: false;
|
|
3419
3432
|
this.canCopy =
|
|
3420
3433
|
this._canCopy &&
|
|
@@ -3516,8 +3529,9 @@ class ContextDashboardComponent {
|
|
|
3516
3529
|
}
|
|
3517
3530
|
}
|
|
3518
3531
|
loadNamedDashboard() {
|
|
3532
|
+
const activeContext = this.context?.contextData || this.context;
|
|
3519
3533
|
this.dataSub = this.contextDashboardService
|
|
3520
|
-
.getDashboard(this.name, this.defaultWidgets)
|
|
3534
|
+
.getDashboard(this.name, this.defaultWidgets, activeContext)
|
|
3521
3535
|
.subscribe(mo => {
|
|
3522
3536
|
this.context = this.context || {};
|
|
3523
3537
|
this.mo = mo;
|