@c8y/ngx-components 1023.75.1 → 1023.76.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-branding-plain-branding-editor.mjs +1 -1
- package/fesm2022/c8y-ngx-components-branding-plain-branding-editor.mjs.map +1 -1
- package/fesm2022/{c8y-ngx-components-dashboard-details-advanced-tab-dashboard-details-advanced-tab.component-Cek3_qZQ.mjs → c8y-ngx-components-dashboard-details-advanced-tab-dashboard-details-advanced-tab.component-DVEnCRzW.mjs} +2 -2
- package/fesm2022/c8y-ngx-components-dashboard-details-advanced-tab-dashboard-details-advanced-tab.component-DVEnCRzW.mjs.map +1 -0
- package/fesm2022/c8y-ngx-components-dashboard-details-advanced-tab.mjs +2 -2
- package/fesm2022/c8y-ngx-components-global-context.mjs +40 -18
- package/fesm2022/c8y-ngx-components-global-context.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-widgets-definitions-alarms-alarm-list.mjs +1 -1
- package/fesm2022/c8y-ngx-components-widgets-definitions-alarms-alarm-list.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-widgets-definitions-alarms-all-critical-alarms.mjs +4 -5
- package/fesm2022/c8y-ngx-components-widgets-definitions-alarms-all-critical-alarms.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-widgets-definitions-alarms-recent-alarms.mjs +4 -5
- package/fesm2022/c8y-ngx-components-widgets-definitions-alarms-recent-alarms.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-widgets-definitions-asset-notes.mjs +1 -1
- package/fesm2022/c8y-ngx-components-widgets-definitions-asset-notes.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-widgets-definitions-asset-table.mjs +1 -1
- package/fesm2022/c8y-ngx-components-widgets-definitions-asset-table.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-widgets-definitions-datapoints-graph.mjs +1 -1
- package/fesm2022/c8y-ngx-components-widgets-definitions-datapoints-graph.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-widgets-definitions-datapoints-table.mjs +1 -1
- package/fesm2022/c8y-ngx-components-widgets-definitions-datapoints-table.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-widgets-definitions-device-control-message.mjs +1 -1
- package/fesm2022/c8y-ngx-components-widgets-definitions-device-control-message.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-widgets-definitions-html-widget.mjs +1 -1
- package/fesm2022/c8y-ngx-components-widgets-definitions-html-widget.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-widgets-definitions-image.mjs +1 -1
- package/fesm2022/c8y-ngx-components-widgets-definitions-image.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-widgets-definitions-info-gauge.mjs +1 -1
- package/fesm2022/c8y-ngx-components-widgets-definitions-info-gauge.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-widgets-definitions-kpi.mjs +1 -1
- package/fesm2022/c8y-ngx-components-widgets-definitions-kpi.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-widgets-definitions-linear-gauge.mjs +1 -1
- package/fesm2022/c8y-ngx-components-widgets-definitions-linear-gauge.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-widgets-definitions-map.mjs +1 -1
- package/fesm2022/c8y-ngx-components-widgets-definitions-map.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-widgets-definitions-markdown.mjs +1 -1
- package/fesm2022/c8y-ngx-components-widgets-definitions-markdown.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-widgets-definitions-radial-gauge.mjs +1 -1
- package/fesm2022/c8y-ngx-components-widgets-definitions-radial-gauge.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-widgets-definitions-silo.mjs +1 -1
- package/fesm2022/c8y-ngx-components-widgets-definitions-silo.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-widgets-definitions-three-d-rotation.mjs +1 -1
- package/fesm2022/c8y-ngx-components-widgets-definitions-three-d-rotation.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-widgets-implementations-alarms.mjs +66 -59
- package/fesm2022/c8y-ngx-components-widgets-implementations-alarms.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-widgets-implementations-info-gauge.mjs +1 -1
- package/fesm2022/c8y-ngx-components-widgets-implementations-info-gauge.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components.mjs +132 -144
- package/fesm2022/c8y-ngx-components.mjs.map +1 -1
- package/global-context/index.d.ts +87 -1
- package/global-context/index.d.ts.map +1 -1
- package/index.d.ts +10 -4
- package/index.d.ts.map +1 -1
- package/locales/de.po +3 -0
- package/locales/es.po +3 -0
- package/locales/fr.po +3 -0
- package/locales/ja_JP.po +3 -0
- package/locales/ko.po +3 -0
- package/locales/locales.pot +3 -0
- package/locales/nl.po +3 -0
- package/locales/pl.po +3 -0
- package/locales/pt_BR.po +3 -0
- package/locales/zh_CN.po +3 -0
- package/locales/zh_TW.po +3 -0
- package/package.json +1 -1
- package/widgets/definitions/alarms/all-critical-alarms/index.d.ts +1 -2
- package/widgets/definitions/alarms/all-critical-alarms/index.d.ts.map +1 -1
- package/widgets/definitions/alarms/recent-alarms/index.d.ts +1 -2
- package/widgets/definitions/alarms/recent-alarms/index.d.ts.map +1 -1
- package/widgets/implementations/alarms/index.d.ts +6 -1
- package/widgets/implementations/alarms/index.d.ts.map +1 -1
- package/fesm2022/c8y-ngx-components-dashboard-details-advanced-tab-dashboard-details-advanced-tab.component-Cek3_qZQ.mjs.map +0 -1
|
@@ -25,7 +25,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImpo
|
|
|
25
25
|
}] });
|
|
26
26
|
|
|
27
27
|
function getBrandingOptionsJsonSchema() {
|
|
28
|
-
return import('c8y-schema-loader?interfaceName=BrandingOptionsJson!@c8y/ngx-components/branding/shared/data')
|
|
28
|
+
return import('c8y-schema-loader?interfaceName=BrandingOptionsJson&type=branding!@c8y/ngx-components/branding/shared/data')
|
|
29
29
|
.then(m => m.default || m)
|
|
30
30
|
.then(s => {
|
|
31
31
|
return s.schema;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"c8y-ngx-components-branding-plain-branding-editor.mjs","sources":["../../branding/plain-branding-editor/plain-branding-editor-tab.factory.ts","../../branding/plain-branding-editor/plain-branding-editor.module.ts","../../branding/plain-branding-editor/c8y-ngx-components-branding-plain-branding-editor.ts"],"sourcesContent":["import { Injectable } from '@angular/core';\nimport { gettext } from '@c8y/ngx-components/gettext';\nimport { Tab } from '@c8y/ngx-components';\nimport { BrandingTabFactory } from '@c8y/ngx-components/branding/shared';\n\nexport const advancedTabLabel = gettext('Advanced branding');\n\n@Injectable({ providedIn: 'root' })\nexport class PlainBrandingEditorTabFactory extends BrandingTabFactory {\n protected getTabsForVersion(name: string): Tab[] {\n return [\n {\n path: this.getPathForBranding(name, 'advanced'),\n label: advancedTabLabel,\n icon: 'c8y-css',\n priority: 200\n }\n ];\n }\n}\n","import { NgModule } from '@angular/core';\nimport { hookTab } from '@c8y/ngx-components';\nimport {\n BRANDING_EDIT_CHILD_ROUTES,\n SharedBrandingModule\n} from '@c8y/ngx-components/branding/shared';\nimport {\n advancedTabLabel,\n PlainBrandingEditorTabFactory\n} from './plain-branding-editor-tab.factory';\n\nexport function getBrandingOptionsJsonSchema(): Promise<any> {\n return import(\n 'c8y-schema-loader?interfaceName=BrandingOptionsJson!@c8y/ngx-components/branding/shared/data'\n )\n .then(m => m.default || m)\n .then(s => {\n return s.schema;\n });\n}\n\nBRANDING_EDIT_CHILD_ROUTES.push({\n path: 'advanced',\n loadComponent: () =>\n import('@c8y/ngx-components/branding/plain-branding-editor/lazy').then(\n m => m.AdvancedEditBrandingComponent\n ),\n data: {\n tabName: advancedTabLabel\n },\n resolve: {\n editorSchema: getBrandingOptionsJsonSchema\n }\n});\n\n@NgModule({\n imports: [SharedBrandingModule],\n providers: [hookTab(PlainBrandingEditorTabFactory)]\n})\nexport class PlainBrandingEditorModule {}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;;;;;AAKO,MAAM,gBAAgB,GAAG,OAAO,CAAC,mBAAmB,CAAC;AAGtD,MAAO,6BAA8B,SAAQ,kBAAkB,CAAA;AACzD,IAAA,iBAAiB,CAAC,IAAY,EAAA;QACtC,OAAO;AACL,YAAA;gBACE,IAAI,EAAE,IAAI,CAAC,kBAAkB,CAAC,IAAI,EAAE,UAAU,CAAC;AAC/C,gBAAA,KAAK,EAAE,gBAAgB;AACvB,gBAAA,IAAI,EAAE,SAAS;AACf,gBAAA,QAAQ,EAAE;AACX;SACF;IACH;+GAVW,6BAA6B,EAAA,IAAA,EAAA,IAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA,CAAA;AAA7B,IAAA,SAAA,IAAA,CAAA,KAAA,GAAA,EAAA,CAAA,qBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,6BAA6B,cADhB,MAAM,EAAA,CAAA,CAAA;;4FACnB,6BAA6B,EAAA,UAAA,EAAA,CAAA;kBADzC,UAAU;mBAAC,EAAE,UAAU,EAAE,MAAM,EAAE;;;SCIlB,4BAA4B,GAAA;IAC1C,OAAO,OACL,
|
|
1
|
+
{"version":3,"file":"c8y-ngx-components-branding-plain-branding-editor.mjs","sources":["../../branding/plain-branding-editor/plain-branding-editor-tab.factory.ts","../../branding/plain-branding-editor/plain-branding-editor.module.ts","../../branding/plain-branding-editor/c8y-ngx-components-branding-plain-branding-editor.ts"],"sourcesContent":["import { Injectable } from '@angular/core';\nimport { gettext } from '@c8y/ngx-components/gettext';\nimport { Tab } from '@c8y/ngx-components';\nimport { BrandingTabFactory } from '@c8y/ngx-components/branding/shared';\n\nexport const advancedTabLabel = gettext('Advanced branding');\n\n@Injectable({ providedIn: 'root' })\nexport class PlainBrandingEditorTabFactory extends BrandingTabFactory {\n protected getTabsForVersion(name: string): Tab[] {\n return [\n {\n path: this.getPathForBranding(name, 'advanced'),\n label: advancedTabLabel,\n icon: 'c8y-css',\n priority: 200\n }\n ];\n }\n}\n","import { NgModule } from '@angular/core';\nimport { hookTab } from '@c8y/ngx-components';\nimport {\n BRANDING_EDIT_CHILD_ROUTES,\n SharedBrandingModule\n} from '@c8y/ngx-components/branding/shared';\nimport {\n advancedTabLabel,\n PlainBrandingEditorTabFactory\n} from './plain-branding-editor-tab.factory';\n\nexport function getBrandingOptionsJsonSchema(): Promise<any> {\n return import(\n 'c8y-schema-loader?interfaceName=BrandingOptionsJson&type=branding!@c8y/ngx-components/branding/shared/data'\n )\n .then(m => m.default || m)\n .then(s => {\n return s.schema;\n });\n}\n\nBRANDING_EDIT_CHILD_ROUTES.push({\n path: 'advanced',\n loadComponent: () =>\n import('@c8y/ngx-components/branding/plain-branding-editor/lazy').then(\n m => m.AdvancedEditBrandingComponent\n ),\n data: {\n tabName: advancedTabLabel\n },\n resolve: {\n editorSchema: getBrandingOptionsJsonSchema\n }\n});\n\n@NgModule({\n imports: [SharedBrandingModule],\n providers: [hookTab(PlainBrandingEditorTabFactory)]\n})\nexport class PlainBrandingEditorModule {}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;;;;;AAKO,MAAM,gBAAgB,GAAG,OAAO,CAAC,mBAAmB,CAAC;AAGtD,MAAO,6BAA8B,SAAQ,kBAAkB,CAAA;AACzD,IAAA,iBAAiB,CAAC,IAAY,EAAA;QACtC,OAAO;AACL,YAAA;gBACE,IAAI,EAAE,IAAI,CAAC,kBAAkB,CAAC,IAAI,EAAE,UAAU,CAAC;AAC/C,gBAAA,KAAK,EAAE,gBAAgB;AACvB,gBAAA,IAAI,EAAE,SAAS;AACf,gBAAA,QAAQ,EAAE;AACX;SACF;IACH;+GAVW,6BAA6B,EAAA,IAAA,EAAA,IAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA,CAAA;AAA7B,IAAA,SAAA,IAAA,CAAA,KAAA,GAAA,EAAA,CAAA,qBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,6BAA6B,cADhB,MAAM,EAAA,CAAA,CAAA;;4FACnB,6BAA6B,EAAA,UAAA,EAAA,CAAA;kBADzC,UAAU;mBAAC,EAAE,UAAU,EAAE,MAAM,EAAE;;;SCIlB,4BAA4B,GAAA;IAC1C,OAAO,OACL,4GAA4G;SAE3G,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,IAAI,CAAC;SACxB,IAAI,CAAC,CAAC,IAAG;QACR,OAAO,CAAC,CAAC,MAAM;AACjB,IAAA,CAAC,CAAC;AACN;AAEA,0BAA0B,CAAC,IAAI,CAAC;AAC9B,IAAA,IAAI,EAAE,UAAU;AAChB,IAAA,aAAa,EAAE,MACb,OAAO,yDAAyD,CAAC,CAAC,IAAI,CACpE,CAAC,IAAI,CAAC,CAAC,6BAA6B,CACrC;AACH,IAAA,IAAI,EAAE;AACJ,QAAA,OAAO,EAAE;AACV,KAAA;AACD,IAAA,OAAO,EAAE;AACP,QAAA,YAAY,EAAE;AACf;AACF,CAAA,CAAC;MAMW,yBAAyB,CAAA;+GAAzB,yBAAyB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,QAAA,EAAA,CAAA,CAAA;AAAzB,IAAA,SAAA,IAAA,CAAA,IAAA,GAAA,EAAA,CAAA,mBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,yBAAyB,YAH1B,oBAAoB,CAAA,EAAA,CAAA,CAAA;gHAGnB,yBAAyB,EAAA,SAAA,EAFzB,CAAC,OAAO,CAAC,6BAA6B,CAAC,CAAC,YADzC,oBAAoB,CAAA,EAAA,CAAA,CAAA;;4FAGnB,yBAAyB,EAAA,UAAA,EAAA,CAAA;kBAJrC,QAAQ;AAAC,YAAA,IAAA,EAAA,CAAA;oBACR,OAAO,EAAE,CAAC,oBAAoB,CAAC;AAC/B,oBAAA,SAAS,EAAE,CAAC,OAAO,CAAC,6BAA6B,CAAC;AACnD,iBAAA;;;ACtCD;;AAEG;;;;"}
|
|
@@ -120,7 +120,7 @@ class JsonValidationService {
|
|
|
120
120
|
const validWidgetSchemas = widgetSchemasResults
|
|
121
121
|
.filter((result) => result.status === 'fulfilled' && result.value !== null)
|
|
122
122
|
.map(result => result.value);
|
|
123
|
-
const { schema: dashboardSchemaOriginal } = await import('c8y-schema-loader?interfaceName=ContextDashboard!@c8y/ngx-components/context-dashboard');
|
|
123
|
+
const { schema: dashboardSchemaOriginal } = await import('c8y-schema-loader?interfaceName=ContextDashboard&type=dashboarding!@c8y/ngx-components/context-dashboard');
|
|
124
124
|
const dashboardSchema = JSON.parse(JSON.stringify(dashboardSchemaOriginal));
|
|
125
125
|
// Modify Widget definition with proper schema structure
|
|
126
126
|
if (validWidgetSchemas.length > 0) {
|
|
@@ -587,4 +587,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImpo
|
|
|
587
587
|
}] });
|
|
588
588
|
|
|
589
589
|
export { DashboardDetailsAdvancedTabComponent };
|
|
590
|
-
//# sourceMappingURL=c8y-ngx-components-dashboard-details-advanced-tab-dashboard-details-advanced-tab.component-
|
|
590
|
+
//# sourceMappingURL=c8y-ngx-components-dashboard-details-advanced-tab-dashboard-details-advanced-tab.component-DVEnCRzW.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"c8y-ngx-components-dashboard-details-advanced-tab-dashboard-details-advanced-tab.component-DVEnCRzW.mjs","sources":["../../dashboard-details-advanced-tab/dashboard-json-editor/json-validation.service.ts","../../dashboard-details-advanced-tab/assign-widget-assets/assign-widget-asset-modal.component.ts","../../dashboard-details-advanced-tab/assign-widget-assets/assign-widget-asset-modal.component.html","../../dashboard-details-advanced-tab/dashboard-json-editor/import-export-widgets.service.ts","../../dashboard-details-advanced-tab/dashboard-json-editor/dashboard-json-editor.component.ts","../../dashboard-details-advanced-tab/dashboard-json-editor/dashboard-json-editor.component.html","../../dashboard-details-advanced-tab/dashboard-details-advanced-tab.component.ts"],"sourcesContent":["import { Injectable } from '@angular/core';\nimport { ContextDashboard } from '@c8y/ngx-components/context-dashboard';\nimport { DynamicComponentService } from '@c8y/ngx-components';\nimport Ajv from 'ajv';\nimport addFormats from 'ajv-formats';\nimport { JSONSchema7 } from 'json-schema';\n\nexport type JSONValidationError = {\n message: string;\n path: string;\n};\n\n@Injectable()\nexport class JsonValidationService {\n ajv: Ajv;\n private OMIT_ERRORS = ['must NOT be valid', 'must match exactly one schema in oneOf'];\n\n constructor(private dynamicComponentService: DynamicComponentService) {\n this.ajv = new Ajv({ verbose: true, allErrors: true });\n addFormats(this.ajv as any);\n }\n\n async validateDashboard(dashboardJson: string, schemas?: any[]): Promise<JSONValidationError[]> {\n try {\n // Parse JSON string to object\n const dashboard: ContextDashboard = JSON.parse(dashboardJson);\n\n // Get or use provided schemas\n const validationSchemas = schemas || (await this.getJsonSchemas(dashboard));\n\n // Create a new Ajv instance\n const validator = new Ajv({\n verbose: true,\n allErrors: true\n });\n\n addFormats(validator as any);\n\n // Add all component schemas individually\n validationSchemas.forEach(({ uri, schema }) => {\n validator.addSchema(schema, uri);\n });\n\n const errorsMap = new Map<string, JSONValidationError>();\n\n // Validate main dashboard structure first (without children)\n const mainSchema = validationSchemas.find(\n s => s.uri === 'context-dashboard.c8y-schema-loader'\n )?.schema;\n\n if (!mainSchema) {\n throw new Error('Dashboard schema not found');\n }\n\n // Create a copy without children for main validation\n const dashboardWithoutChildren = { ...dashboard };\n delete dashboardWithoutChildren.children;\n\n const mainValidate = validator.compile(mainSchema);\n mainValidate(dashboardWithoutChildren);\n\n // Now validate each widget with its specific schema\n if (dashboard.children) {\n Object.entries(dashboard.children).forEach(([widgetId, widget]) => {\n const componentId = widget.componentId;\n // Find the correct schema for this widget type\n const widgetSchema = validationSchemas.find(s => s.uri === componentId)?.schema;\n\n if (widgetSchema) {\n // Validate this widget's config against its specific schema\n const validateWidgetConfig = validator.compile(widgetSchema);\n const isValid = validateWidgetConfig(widget.config);\n\n if (!isValid && validateWidgetConfig.errors) {\n validateWidgetConfig.errors.forEach(error => {\n const message = error.message || 'Unknown error';\n const basePath = `/children/${widgetId}/config`;\n const relativePath = error.instancePath;\n const fullPath = basePath + relativePath;\n\n if (!this.OMIT_ERRORS.includes(message)) {\n errorsMap.set(`${message}::${fullPath}`, {\n message,\n path: fullPath\n });\n }\n });\n }\n }\n });\n }\n\n // Process any errors from main validation\n if (mainValidate.errors) {\n mainValidate.errors.forEach(error => {\n const message = error.message || 'Unknown error';\n const path = error.instancePath;\n\n // Skip children validation errors as we handled them separately\n if (!path.includes('/children/') && !this.OMIT_ERRORS.includes(message)) {\n errorsMap.set(`${message}::${path}`, { message, path });\n }\n });\n }\n\n return Array.from(errorsMap.values());\n } catch (error) {\n if (error instanceof SyntaxError) {\n return [{ message: 'Invalid JSON syntax', path: '' }];\n }\n throw error;\n }\n }\n\n /**\n * Returns JSON schema for dashboard and all its children.\n * Children are referenced by their componentId. Dashboard schema is enriched with references to children schemas.\n * @param dashboard Context dashboard object.\n */\n async getJsonSchemas(dashboard: ContextDashboard) {\n try {\n const dashboardChildrenIds = [\n ...new Set(Object.entries(dashboard.children || {}).map(([_, value]) => value.componentId))\n ];\n\n const widgetSchemasPromises = dashboardChildrenIds.map(id => this.getSchemaForWidget(id));\n const widgetSchemasResults = await Promise.allSettled(widgetSchemasPromises);\n\n // Filter out failed or null schemas\n const validWidgetSchemas = widgetSchemasResults\n .filter(\n (result): result is PromiseFulfilledResult<{ id: string; schema: any }> =>\n result.status === 'fulfilled' && result.value !== null\n )\n .map(result => result.value);\n\n const { schema: dashboardSchemaOriginal }: { schema: JSONSchema7 } = await import(\n 'c8y-schema-loader?interfaceName=ContextDashboard&type=dashboarding!@c8y/ngx-components/context-dashboard'\n );\n const dashboardSchema = JSON.parse(JSON.stringify(dashboardSchemaOriginal));\n\n // Modify Widget definition with proper schema structure\n if (validWidgetSchemas.length > 0) {\n // Remove any existing allOf or oneOf conditions that might interfere\n if (dashboardSchema.definitions.Widget.allOf) {\n delete dashboardSchema.definitions.Widget.allOf;\n }\n\n // Set up the oneOf condition\n dashboardSchema.definitions.Widget.oneOf = this.getWidgetSchemasReferences(\n validWidgetSchemas.map(({ id }) => id)\n );\n }\n\n return [\n {\n uri: 'context-dashboard.c8y-schema-loader',\n fileMatch: ['*'],\n schema: dashboardSchema\n },\n ...validWidgetSchemas.map(({ id, schema }) => ({\n uri: id,\n schema: schema\n }))\n ];\n } catch (error) {\n console.error('Error processing dashboard schemas:', error);\n throw error;\n }\n }\n\n private async getSchemaForWidget(id: string) {\n try {\n const def = await this.dynamicComponentService.getById(id);\n if (def?.data?.schema && typeof def.data.schema === 'function') {\n const { schema }: { schema: JSONSchema7 } = await def.data.schema();\n return { id, schema };\n }\n return null;\n } catch (error) {\n console.warn(`Failed to fetch schema for widget ${id}:`, error);\n return null;\n }\n }\n\n private getWidgetSchemasReferences(widgetIds: string[]) {\n // provide references to all children schemas\n const schemasPart = widgetIds.map(id => {\n return {\n properties: {\n componentId: { const: id },\n config: { $ref: `${id}#` } // Ensure proper URI reference format\n },\n required: ['componentId'] // Only require componentId\n };\n });\n\n // provide default schema for object if component has no schema definition\n const defaultPart = {\n not: {\n properties: {\n componentId: {\n enum: widgetIds\n }\n }\n },\n properties: {\n config: {\n type: 'object',\n additionalProperties: true\n }\n }\n };\n\n return [...schemasPart, defaultPart];\n }\n}\n","import { Component, inject, Input, OnInit } from '@angular/core';\nimport { gettext } from '@c8y/ngx-components/gettext';\nimport { CoreModule } from '@c8y/ngx-components';\nimport { BsModalRef } from 'ngx-bootstrap/modal';\nimport { IManagedObject } from '@c8y/client';\nimport {\n AssetSelectionChangeEvent,\n AssetSelectorModule\n} from '@c8y/ngx-components/assets-navigator';\nimport { WidgetAssetToAlign } from '../advanced-tab.model';\nimport { BsDropdownModule } from 'ngx-bootstrap/dropdown';\nimport { TooltipModule } from 'ngx-bootstrap/tooltip';\n\n@Component({\n selector: 'c8y-assign-widget-asset-modal',\n templateUrl: './assign-widget-asset-modal.component.html',\n standalone: true,\n imports: [CoreModule, AssetSelectorModule, BsDropdownModule, TooltipModule]\n})\nexport class AssignWidgetAssetModalComponent implements OnInit {\n @Input() assetsToAlign: WidgetAssetToAlign[];\n @Input() contextAsset: IManagedObject;\n @Input() notSupportedWidgets: string[] = [];\n\n modalTitle = gettext(`\n For each asset in the widgets, we suggest a source based on the original configuration. \n You can accept it, choose another asset, or configure it later. If you don’t choose any option,\n the widget will not be imported.\n `);\n assetIdInfo = gettext('id: {{ assetId }}');\n acceptSuggestedLabel = gettext('Accept suggested asset');\n noSuggestedAssetLabel = gettext('No suggestion available');\n updatedWidgetAssets: (WidgetAssetToAlign & { selectedAsset?: IManagedObject | null })[] = [];\n hasSuggestedAssets: boolean;\n userClickedAcceptAllSuggested = false;\n assetSelectedLabel = gettext('Asset selected');\n assetNotSelectedLabel = gettext('Asset not selected');\n result: Promise<WidgetAssetToAlign[]> = new Promise((resolve, reject) => {\n this._close = resolve;\n this._cancel = reject;\n });\n private _close: (value: WidgetAssetToAlign[]) => void;\n private _cancel: (reason?: any) => void;\n private bsModalRef = inject(BsModalRef);\n\n ngOnInit() {\n this.updatedWidgetAssets = this.assetsToAlign.map(asset => ({\n ...asset\n }));\n this.hasSuggestedAssets = this.updatedWidgetAssets.some(\n asset => !!asset.deviceRef.value.suggestedDevice\n );\n }\n\n apply(): void {\n const alignedAssets: WidgetAssetToAlign[] = this.updatedWidgetAssets.map(asset => {\n return {\n widgetId: asset.widgetId,\n title: asset.title,\n deviceRef: {\n path: asset.deviceRef.path,\n value:\n asset.selectedAsset == null\n ? asset.selectedAsset\n : { ...asset.selectedAsset, suggestedDevice: null }\n }\n };\n });\n this._close(alignedAssets);\n this.bsModalRef.hide();\n }\n\n acceptAllSuggested() {\n this.userClickedAcceptAllSuggested = true;\n this.updatedWidgetAssets.forEach(asset => {\n if (asset.deviceRef.value.suggestedDevice) {\n asset.selectedAsset = asset.deviceRef.value.suggestedDevice;\n }\n });\n }\n\n cancel() {\n this.bsModalRef.hide();\n this._cancel();\n }\n\n selectionChange(\n $event: AssetSelectionChangeEvent,\n widgetAsset: WidgetAssetToAlign & { selectedAsset?: IManagedObject | null }\n ) {\n widgetAsset.selectedAsset = $event.change.item;\n }\n}\n","<div class=\"viewport-modal has-asset-selector\">\n <div class=\"modal-header dialog-header\">\n <i [c8yIcon]=\"'th-large'\"></i>\n <div\n class=\"modal-title\"\n id=\"modal-title\"\n translate\n >\n Select and confirm widget assets mapping\n </div>\n </div>\n <div\n class=\"inner-scroll\"\n id=\"modal-body\"\n >\n <div class=\"p-16\">\n <p class=\"text-center text-balance\">\n {{ modalTitle | translate }}\n </p>\n </div>\n @if (notSupportedWidgets.length) {\n <div class=\"d-flex fit-w j-c-center p-16 p-t-0\">\n <div class=\"alert alert-warning\">\n {{ 'Widgets not supported for asset mapping: {{ notSupportedWidgets }}' | translate: {\n notSupportedWidgets: notSupportedWidgets.join(', ') } }}\n </div>\n </div>\n }\n @if (!assetsToAlign.length) {\n <div class=\"p-16 d-flex j-c-center\">\n <c8y-ui-empty-state\n class=\"\"\n [icon]=\"'empty-box'\"\n [title]=\"'No assets to assign' | translate\"\n ></c8y-ui-empty-state>\n </div>\n }\n @if (assetsToAlign.length) {\n <div>\n <c8y-list-group class=\"separator-top no-border-last\">\n <c8y-li class=\"sticky-top bg-level-1 hidden-sm hidden-xs\">\n <c8y-li-icon></c8y-li-icon>\n <div class=\"d-flex\">\n <div class=\"col-md-2\">\n <!-- title -->\n <p\n class=\"text-truncate text-medium\"\n translate\n >\n Widget\n </p>\n </div>\n <div class=\"col-md-10\">\n <div class=\"row\">\n <div class=\"col-md-4 p-r-0\">\n <p\n class=\"text-medium\"\n translate\n >\n Original source\n </p>\n </div>\n <div class=\"col-md-1 text-center\">\n <button\n class=\"btn btn-default btn-sm\"\n [attr.aria-label]=\"'Accept all suggested' | translate\"\n [tooltip]=\"'Accept all suggested' | translate\"\n placement=\"right\"\n (click)=\"acceptAllSuggested()\"\n [disabled]=\"!hasSuggestedAssets\"\n >\n <i [c8yIcon]=\"'check'\"></i>\n </button>\n </div>\n <div class=\"col-md-7 p-l-8\">\n <p\n class=\"text-medium\"\n translate\n >\n Selected source\n </p>\n </div>\n </div>\n </div>\n </div>\n </c8y-li>\n @for (widgetAsset of updatedWidgetAssets; track widgetAsset; let i = $index) {\n <c8y-li class=\"c8y-list__item--overflow-visible\">\n <c8y-li-icon\n class=\"p-r-0 p-t-16\"\n icon=\"th-large\"\n ></c8y-li-icon>\n <div class=\"d-flex-md\">\n <div class=\"col-md-2\">\n <!-- title -->\n <p\n class=\"text-truncate text-medium boxed-label p-l-0\"\n title=\"{{ widgetAsset.title }}\"\n >\n {{ widgetAsset.title }}\n </p>\n </div>\n <div class=\"col-md-10\">\n <div class=\"row\">\n <div class=\"col-md-4 p-l-md-0 p-r-0\">\n <!-- origin device -->\n <p class=\"visible-sm visible-xs text-label-small\">\n {{ 'Original source' | translate }}\n </p>\n <div class=\"d-flex gap-4 boxed-label\">\n <ng-container\n *ngTemplateOutlet=\"\n assetIcon;\n context: { $implicit: widgetAsset.deviceRef.value }\n \"\n ></ng-container>\n <span class=\"text-truncate\">\n <span\n class=\"text-truncate\"\n title=\"{{ widgetAsset.deviceRef.value.name }}\"\n >\n {{ widgetAsset.deviceRef.value.name }}\n </span>\n <small class=\"text-muted\">\n {{\n assetIdInfo | translate: { assetId: widgetAsset.deviceRef.value.id }\n }}\n </small>\n </span>\n </div>\n </div>\n <div\n class=\"col-md-1 col-xs-1 p-l-xs-0 p-l-sm-0 p-r-sm-0 p-r-xs-0 text-center p-t-16\"\n >\n <i\n class=\"icon-20\"\n [c8yIcon]=\"\n widgetAsset.selectedAsset !== undefined ? 'ok' : 'inactive-state'\n \"\n [title]=\"\n widgetAsset.selectedAsset !== undefined\n ? (assetSelectedLabel | translate)\n : (assetNotSelectedLabel | translate)\n \"\n [ngClass]=\"{\n 'text-success': widgetAsset.selectedAsset !== undefined,\n 'text-muted': widgetAsset.selectedAsset === undefined\n }\"\n ></i>\n @if (\n widgetAsset.selectedAsset === undefined && userClickedAcceptAllSuggested\n ) {\n <span\n class=\"c8y-icon-badge\"\n [tooltip]=\"\n 'No suggestion available- widget will not be imported' | translate\n \"\n placement=\"right\"\n >\n <i\n class=\"status major stroked-icon\"\n c8yIcon=\"warning\"\n ></i>\n </span>\n }\n </div>\n <div class=\"col-md-4 col-xs-11 p-l-md-0\">\n <!-- Suggested/Selected source -->\n <p class=\"visible-sm visible-xs text-label-small m-t-16 m-b-8\">\n {{ 'Selected source' | translate }}\n </p>\n @if (\n widgetAsset.deviceRef.value.suggestedDevice && !widgetAsset.selectedAsset\n ) {\n <div\n class=\"d-flex gap-4 text-muted boxed-label\"\n [attr.data-label]=\"'Suggested' | translate\"\n >\n <ng-container\n *ngTemplateOutlet=\"\n assetIcon;\n context: { $implicit: widgetAsset.deviceRef.value.suggestedDevice }\n \"\n ></ng-container>\n <span class=\"text-truncate\">\n <span\n class=\"text-truncate\"\n title=\"{{ widgetAsset.deviceRef.value.suggestedDevice?.name }}\"\n >\n {{ widgetAsset.deviceRef.value.suggestedDevice?.name }}\n </span>\n <small class=\"text-muted\">\n {{\n assetIdInfo\n | translate\n : { assetId: widgetAsset.deviceRef.value.suggestedDevice?.id }\n }}\n </small>\n </span>\n </div>\n }\n @if (widgetAsset.selectedAsset) {\n <div class=\"d-flex gap-4 boxed-label\">\n <!-- selectedAsset icon -->\n <ng-container\n *ngTemplateOutlet=\"\n assetIcon;\n context: { $implicit: widgetAsset.selectedAsset }\n \"\n ></ng-container>\n <!-- selectedAsset Name and ID -->\n <span class=\"text-truncate\">\n <span\n class=\"text-truncate\"\n title=\"{{ widgetAsset.selectedAsset?.name }}\"\n >\n {{ widgetAsset.selectedAsset?.name }}\n </span>\n <small class=\"text-muted\">\n {{\n assetIdInfo | translate: { assetId: widgetAsset.selectedAsset.id }\n }}\n </small>\n </span>\n </div>\n }\n @if (\n !widgetAsset.deviceRef.value.suggestedDevice && !widgetAsset.selectedAsset\n ) {\n <div class=\"text-muted boxed-label\">\n <em>{{ 'No suggestion available' | translate }}</em>\n </div>\n }\n </div>\n <div class=\"col-md-3 p-0 flex-grow\">\n <div class=\"d-flex a-i-center j-c-end-md gap-8 boxed-label p-l-md-0 p-r-0\">\n <div class=\"input-group max-width-fit\">\n <div class=\"input-group-btn\">\n <button\n class=\"btn btn-default\"\n [attr.aria-label]=\"\n (widgetAsset.deviceRef.value.suggestedDevice\n ? acceptSuggestedLabel\n : noSuggestedAssetLabel\n ) | translate\n \"\n [tooltip]=\"\n (widgetAsset.deviceRef.value.suggestedDevice\n ? acceptSuggestedLabel\n : noSuggestedAssetLabel\n ) | translate\n \"\n placement=\"top\"\n container=\"body\"\n [ngClass]=\"{\n active:\n widgetAsset.selectedAsset &&\n widgetAsset.selectedAsset ===\n widgetAsset.deviceRef.value.suggestedDevice\n }\"\n [disabled]=\"!widgetAsset.deviceRef.value.suggestedDevice\"\n (click)=\"\n widgetAsset.selectedAsset =\n widgetAsset.deviceRef.value.suggestedDevice\n \"\n >\n <i [c8yIcon]=\"'check'\"></i>\n </button>\n </div>\n <div\n class=\"dropdown input-group-btn\"\n container=\"body\"\n dropdown\n [insideClick]=\"true\"\n #dropdown=\"bs-dropdown\"\n >\n <button\n class=\"btn btn-default dropdown-toggle c8y-dropdown\"\n [attr.aria-label]=\"'Select asset' | translate\"\n tooltip=\"{{ 'Select asset' | translate }}\"\n placement=\"top\"\n container=\"body\"\n type=\"button\"\n dropdownToggle\n [ngClass]=\"{\n active:\n widgetAsset.selectedAsset &&\n widgetAsset.selectedAsset !==\n widgetAsset.deviceRef.value.suggestedDevice\n }\"\n >\n <i [c8yIcon]=\"'card-exchange'\"></i>\n </button>\n <div\n class=\"dropdown-menu dropdown-menu-right--md\"\n style=\"width: 300px\"\n *dropdownMenu\n >\n @if (dropdown.isOpen) {\n <c8y-asset-selector-miller\n (onSelected)=\"\n selectionChange($event, widgetAsset); dropdown.hide()\n \"\n [asset]=\"contextAsset\"\n [config]=\"{\n groupsSelectable: true,\n showChildDevices: true,\n showFilter: true,\n showSelected: false,\n columnHeaders: true,\n singleColumn: true,\n preventInitialSelect: true\n }\"\n ></c8y-asset-selector-miller>\n }\n </div>\n </div>\n <div class=\"input-group-btn\">\n <button\n class=\"btn btn-default\"\n [attr.aria-label]=\"'Configure later' | translate\"\n tooltip=\"{{ 'Configure later' | translate }}\"\n placement=\"top\"\n container=\"body\"\n [ngClass]=\"{ active: widgetAsset.selectedAsset === null }\"\n (click)=\"widgetAsset.selectedAsset = null\"\n >\n <i [c8yIcon]=\"'link-off'\"></i>\n </button>\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n </c8y-li>\n }\n </c8y-list-group>\n </div>\n }\n </div>\n <div class=\"modal-footer\">\n <button\n class=\"btn btn-default\"\n [title]=\"'Cancel' | translate\"\n type=\"button\"\n (click)=\"cancel()\"\n >\n {{ 'Cancel' | translate }}\n </button>\n <button\n class=\"btn btn-primary\"\n [title]=\"'Apply' | translate\"\n type=\"button\"\n (click)=\"apply()\"\n >\n {{ 'Apply' | translate }}\n </button>\n </div>\n</div>\n\n<ng-template\n #assetIcon\n let-device\n>\n @if (device.c8y_IsDevice) {\n <i\n class=\"l-h-inherit\"\n [c8yIcon]=\"'data-transfer'\"\n ></i>\n }\n @if (device.c8y_IsDeviceGroup && !device.c8y_IsAsset) {\n <i\n class=\"l-h-inherit\"\n [c8yIcon]=\"'c8y-group'\"\n ></i>\n }\n @if (device.c8y_IsAsset) {\n <i\n class=\"l-h-inherit\"\n [c8yIcon]=\"device.icon?.name || 'c8y-group'\"\n ></i>\n }\n</ng-template>\n","import { inject, Injectable, Injector, runInInjectionContext } from '@angular/core';\nimport { ContextDashboard, DashboardDetailService } from '@c8y/ngx-components/context-dashboard';\nimport { gettext } from '@c8y/ngx-components/gettext';\nimport { cloneDeep } from 'lodash-es';\nimport { saveAs } from 'file-saver';\nimport {\n AlertService,\n DroppedFile,\n DynamicComponentService,\n Widget,\n WidgetDataType\n} from '@c8y/ngx-components';\nimport { IManagedObject } from '@c8y/client';\nimport { BsModalService } from 'ngx-bootstrap/modal';\nimport { AssignWidgetAssetModalComponent } from '../assign-widget-assets/assign-widget-asset-modal.component';\nimport { WidgetAssetToAlign } from '../advanced-tab.model';\n\n@Injectable()\nexport class ImportExportWidgetsService {\n private dynamicComponentService = inject(DynamicComponentService);\n private injector = inject(Injector);\n private alertService = inject(AlertService);\n private dashboardDetailService = inject(DashboardDetailService);\n private modal = inject(BsModalService);\n\n /**\n * Export the dashboard to a JSON file. If the widget has an export method, it will be called to export\n * the widget's configuration.\n * @param dashboard Context dashboard to be exported\n */\n async export(dashboard: ContextDashboard) {\n const copiedDashboard: ContextDashboard = cloneDeep(dashboard);\n\n for (const [id, child] of Object.entries(copiedDashboard.children || {})) {\n try {\n const definition = await this.dynamicComponentService.getById(child.componentId);\n\n if (definition && typeof definition.data.export === 'function') {\n const widgetData: WidgetDataType = definition.data;\n const pluginInjector = definition.injector || this.injector;\n await runInInjectionContext(pluginInjector, async () => {\n const exportedConfig = await widgetData.export(\n child.config,\n this.dashboardDetailService.details,\n { pluginInjector, injector: this.injector }\n );\n copiedDashboard.children[id].config = exportedConfig;\n });\n }\n } catch (error) {\n this.alertService.addServerFailure(error);\n }\n }\n const dateStr = new Date().toISOString().replace(/[:.]/g, '-');\n const filename = `dashboard_${dateStr}.json`;\n const blob = new Blob([JSON.stringify(copiedDashboard)], { type: 'application/json' });\n saveAs(blob, filename);\n this.alertService.success(gettext('Dashboard exported.'));\n }\n\n /**\n * Import the dashboard from a JSON file. If the widget has an import method, it will be called to import\n * widget's configuration.\n * @param file JSON file with context dashboard configuration\n */\n async import(file: DroppedFile[]) {\n if (!file || file.length === 0) {\n return;\n }\n const dashboard: ContextDashboard = await file[0].readAsJson();\n const notSupportedWidgets: string[] = [];\n\n for (const [id, child] of Object.entries(dashboard.children)) {\n try {\n const definition = await this.dynamicComponentService.getById(child.componentId);\n\n if (definition && typeof definition.data.import === 'function') {\n const widgetData: WidgetDataType = definition.data;\n const pluginInjector = definition.injector || this.injector;\n await runInInjectionContext(pluginInjector, async () => {\n const importedConfig = await widgetData.import(\n child.config,\n this.dashboardDetailService.details,\n { pluginInjector, injector: this.injector }\n );\n dashboard.children[id].config = importedConfig;\n });\n } else {\n notSupportedWidgets.push(child.title);\n }\n } catch (error) {\n console.error(`Error importing widget with id ${id}:`, error);\n }\n }\n if (Object.entries(dashboard.children).length) {\n dashboard.children = await this.assignWidgetAssets(dashboard.children, notSupportedWidgets);\n if (!dashboard.children) {\n return;\n }\n }\n\n return JSON.stringify(dashboard, null, 2);\n }\n\n private async assignWidgetAssets(\n widgets: {\n [id: string]: Widget;\n },\n notSupportedWidgets: string[]\n ): Promise<{ [id: string]: Widget }> {\n const assetsToAlign = this.findWidgetsWithSuggestedDevice(widgets);\n const contextAsset = this.dashboardDetailService.details.context;\n\n try {\n const modalRef = this.modal.show(AssignWidgetAssetModalComponent, {\n class: 'modal-lg',\n ariaDescribedby: 'modal-body',\n ariaLabelledBy: 'modal-title',\n ignoreBackdropClick: true,\n keyboard: false,\n initialState: { assetsToAlign, contextAsset, notSupportedWidgets }\n }).content;\n const result = await modalRef.result;\n\n return this.updateWidgets(widgets, result);\n } catch (_) {\n // cancel clicked\n return null;\n }\n }\n\n private findWidgetsWithSuggestedDevice(widgets: Record<string, Widget>): WidgetAssetToAlign[] {\n const results: WidgetAssetToAlign[] = [];\n\n const searchObject = (obj: any, path: string[] = []): void => {\n if (!obj || typeof obj !== 'object') return;\n\n for (const [key, value] of Object.entries(obj)) {\n const currentPath = [...path, key];\n\n if (key === 'suggestedDevice') {\n // Find the nearest device/__target reference\n let deviceRef: (IManagedObject & { suggestedDevice: IManagedObject }) | null = null;\n let devicePath: string[] = [];\n\n // Search for __target or device in parent objects\n let currentObj = obj;\n const currentSearchPath = [...path];\n while (currentObj && !deviceRef) {\n if (currentObj.__target) {\n deviceRef = currentObj.__target;\n devicePath = [...currentSearchPath, '__target'];\n break;\n }\n if (currentObj.device) {\n deviceRef = currentObj.device;\n devicePath = [...currentSearchPath, 'device'];\n break;\n }\n // Move up one level\n currentSearchPath.pop();\n currentObj = this.getObjectByPath(widgets, currentSearchPath);\n }\n\n if (deviceRef) {\n const widgetId = path[0]; // First element in path should be widget ID\n results.push({\n widgetId,\n title: widgets[widgetId].title,\n deviceRef: { path: devicePath, value: deviceRef }\n });\n }\n } else if (typeof value === 'object') {\n searchObject(value, currentPath);\n }\n }\n };\n\n searchObject(widgets);\n return results;\n }\n\n private getObjectByPath(obj: any, path: string[]): any {\n return path.reduce((curr, key) => curr && curr[key], obj);\n }\n\n private updateWidgets(\n originalWidgets: Record<string, Widget>,\n processedReferences: Array<{\n widgetId: string;\n deviceRef: { path: string[]; value: IManagedObject };\n }>\n ): Record<string, Widget> {\n const result = JSON.parse(JSON.stringify(originalWidgets));\n\n // remove widgets that were no aligned\n processedReferences.forEach(ref => {\n if (ref.deviceRef.value === undefined) {\n delete result[ref.widgetId];\n return;\n }\n\n // apply selected assets to widgets\n const obj = this.getObjectByPath(result, ref.deviceRef.path.slice(0, -1));\n const lastKey = ref.deviceRef.path[ref.deviceRef.path.length - 1];\n if (obj && lastKey) {\n obj[lastKey] = ref.deviceRef.value;\n delete obj[lastKey]?.suggestedDevice;\n }\n });\n\n return result;\n }\n}\n","import { ContextDashboard, DashboardDetailService } from '@c8y/ngx-components/context-dashboard';\nimport { Component, inject, OnInit, signal, ViewChild } from '@angular/core';\nimport { PopoverModule } from 'ngx-bootstrap/popover';\nimport { gettext } from '@c8y/ngx-components/gettext';\nimport {\n CommonModule,\n CoreModule,\n DroppedFile,\n FormsModule,\n ThemeOptions\n} from '@c8y/ngx-components';\nimport { EditorComponent } from '@c8y/ngx-components/editor';\nimport { JSONValidationError, JsonValidationService } from './json-validation.service';\nimport { debounceTime, Subject, takeUntil } from 'rxjs';\nimport { ReactiveFormsModule } from '@angular/forms';\nimport { ImportExportWidgetsService } from './import-export-widgets.service';\n\n@Component({\n selector: 'c8y-dashboard-json-editor',\n templateUrl: 'dashboard-json-editor.component.html',\n standalone: true,\n imports: [\n CommonModule,\n FormsModule,\n ReactiveFormsModule,\n CoreModule,\n PopoverModule,\n EditorComponent\n ],\n providers: [JsonValidationService, ImportExportWidgetsService]\n})\nexport class DashboardJsonEditorComponent implements OnInit {\n infoText = gettext(\n \"Import / Export allows copying dashboard configurations between assets using JSON files. You can export a dashboard's setup and import it to another asset.\\n\\nNote: Basic knowledge of dashboard JSON structure is required.\"\n );\n @ViewChild(EditorComponent) editorComponent!: EditorComponent;\n dashboard: ContextDashboard;\n\n valueString = '';\n errors = signal<JSONValidationError[]>([]);\n editorDirty: boolean;\n editorTheme: ThemeOptions;\n isExporting = false;\n isImporting = false;\n editorOptions: EditorComponent['editorOptions'] = {\n hover: {\n above: false\n }\n };\n\n private dashboardDetailService = inject(DashboardDetailService);\n private jsonValidationService = inject(JsonValidationService);\n private importExportWidgetsService = inject(ImportExportWidgetsService);\n\n private valueChange = new Subject<void>();\n private destroy$ = new Subject<void>();\n private currentSchemas: any[] | null = null;\n\n ngOnInit() {\n this.dashboard = this.dashboardDetailService.details.dashboard;\n this.editorTheme = this.getEditorTheme();\n\n this.valueString = JSON.stringify(this.dashboard, null, 2);\n this.valueChange.pipe(debounceTime(500), takeUntil(this.destroy$)).subscribe(() => {\n this.applyChanges();\n this.validate();\n });\n }\n\n ngOnDestroy() {\n this.destroy$.next();\n this.destroy$.complete();\n }\n\n dashboardJSONChange(value: string) {\n this.valueString = value;\n this.valueChange.next();\n }\n\n async assignSchema() {\n this.currentSchemas = await this.jsonValidationService.getJsonSchemas(this.dashboard);\n this.editorComponent.monaco.languages.json.jsonDefaults.setDiagnosticsOptions({\n validate: true,\n schemas: this.currentSchemas,\n enableSchemaRequest: false,\n allowComments: false\n });\n this.validate();\n }\n\n async validate() {\n this.editorDirty = this.valueString !== JSON.stringify(this.dashboard, null, 2);\n try {\n const validationResult = await this.jsonValidationService.validateDashboard(\n this.valueString,\n this.currentSchemas\n );\n this.errors.set(validationResult);\n } catch (error) {\n console.error('Validation error:', error);\n this.errors.set([\n {\n message: 'An error occurred during validation',\n path: ''\n }\n ]);\n }\n }\n\n applyChanges() {\n try {\n const newDashboard = JSON.parse(this.valueString);\n this.dashboardDetailService.details.dashboard = newDashboard;\n this.dashboardDetailService.generalSettingsForm.patchValue(newDashboard);\n this.dashboardDetailService.appearanceSettingsForm.patchValue(newDashboard);\n this.dashboardDetailService.widgetsForm.patchValue(newDashboard);\n this.dashboardDetailService.previewChangedFn({\n classes: newDashboard.classes,\n widgetClasses: newDashboard.widgetClasses\n });\n this.dashboardDetailService.dashboardDetailsForm.markAsDirty();\n this.dashboardDetailService.saveButtonDisabled = false;\n } catch (error) {\n // disable save button if JSON is invalid and don't apply value to form\n this.dashboardDetailService.saveButtonDisabled = true;\n }\n }\n\n async export() {\n this.isExporting = true;\n try {\n await this.importExportWidgetsService.export(this.dashboard);\n } finally {\n this.isExporting = false;\n }\n }\n\n async import(file: DroppedFile[]) {\n this.isImporting = true;\n try {\n if (file && file.length !== 0) {\n const importedValue = await this.importExportWidgetsService.import(file);\n if (importedValue) {\n this.valueString = importedValue;\n this.valueChange.next();\n }\n }\n } finally {\n this.isImporting = false;\n }\n }\n\n private getEditorTheme(): ThemeOptions | null {\n const dashboardClasses =\n this.dashboardDetailService.appearanceSettingsForm.get('classes').value;\n\n if (dashboardClasses['dashboard-theme-dark']) {\n return 'dark';\n } else if (dashboardClasses['dashboard-theme-white']) {\n return 'light';\n }\n return null;\n }\n}\n","<div class=\"card-block\">\n<div\n class=\"d-flex d-col\"\n [ngStyle]=\"{ height: '410px' }\"\n>\n <ng-container *ngIf=\"!isExporting && !isImporting; else loading\">\n <div class=\"d-flex gap-16 flex-grow min-height-0\">\n <div class=\"d-col col-md-8 col-xs-6\">\n <label class=\"d-flex a-i-center\">{{ 'Dashboard configuration' | translate }} \n <button \n type=\"button\"\n [attr.aria-label]=\"'Help' | translate\"\n class=\"btn-help \" \n placement=\"right\"\n triggers=\"focus\"\n containerClass=\"text-pre-wrap\"\n [popover]=\"infoText | translate\"\n ></button>\n </label>\n <c8y-editor\n class=\"flex-grow min-height-0\"\n [ngModel]=\"valueString\"\n (ngModelChange)=\"dashboardJSONChange($event)\"\n (editorInit)=\"assignSchema()\"\n [theme]=\"editorTheme\"\n monacoEditorMarkerValidator\n [editorOptions]=\"editorOptions\"\n ></c8y-editor>\n </div>\n <div class=\"col-md-4 d-col col-xs-6\">\n <label translate>Validation</label>\n <div\n class=\"c8y-messages has-error m-b-24 inner-scroll flex-grow\"\n *ngIf=\"errors().length > 0\"\n >\n <div\n class=\"form-control-feedback-message\"\n *ngFor=\"let error of errors()\"\n >\n <span\n class=\"error-path\"\n *ngIf=\"error.path\"\n >\n {{ error.path }}:\n </span>\n <span class=\"error-message\">{{ error.message }}</span>\n </div>\n </div>\n <div\n class=\"c8y-messages has-success m-b-24\"\n *ngIf=\"errors().length === 0\"\n >\n <div\n class=\"form-control-feedback-message\"\n >\n <span class=\"error-message\">{{ 'No errors found' | translate }}</span>\n </div>\n </div>\n <div class=\"d-flex gap-16 a-i-center flex-no-shrink min-height-0 m-t-auto\">\n <c8y-drop-area\n class=\"drop-area-sm min-width-0\"\n [icon]=\"'upload'\"\n *ngIf=\"!isExporting\"\n [accept]=\"'.json'\"\n [maxAllowedFiles]=\"1\"\n [message]=\"'Import JSON' | translate\"\n (dropped)=\"import($event)\"\n [loading]=\"isImporting\"\n ></c8y-drop-area>\n <button\n class=\"btn btn-primary\"\n (click)=\"export()\"\n [disabled]=\"isExporting || isImporting\"\n [ngClass]=\"{\n 'btn-pending': isExporting\n }\"\n >\n {{'Export JSON' | translate}}\n </button>\n </div>\n </div>\n </div>\n </ng-container>\n\n</div>\n\n<ng-template #loading>\n <c8y-loading></c8y-loading>\n</ng-template>\n","import { Component } from '@angular/core';\nimport { DashboardJsonEditorComponent } from './dashboard-json-editor/dashboard-json-editor.component';\n\n@Component({\n selector: 'app-dashboard-details-advanced-tab',\n template: `<c8y-dashboard-json-editor></c8y-dashboard-json-editor>`,\n standalone: true,\n imports: [DashboardJsonEditorComponent]\n})\nexport class DashboardDetailsAdvancedTabComponent {}\n"],"names":["i3","i4"],"mappings":"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"}
|
|
@@ -64,7 +64,7 @@ class DashboardDetailsAdvancedTabModule {
|
|
|
64
64
|
hookRoute([
|
|
65
65
|
{
|
|
66
66
|
path: TAB_ID,
|
|
67
|
-
loadComponent: () => import('./c8y-ngx-components-dashboard-details-advanced-tab-dashboard-details-advanced-tab.component-
|
|
67
|
+
loadComponent: () => import('./c8y-ngx-components-dashboard-details-advanced-tab-dashboard-details-advanced-tab.component-DVEnCRzW.mjs').then(m => m.DashboardDetailsAdvancedTabComponent),
|
|
68
68
|
outlet: DASHBOARD_DETAILS_OUTLET,
|
|
69
69
|
context: ViewContext.Dashboard,
|
|
70
70
|
canActivate: [AdvancedTabRouteGuard]
|
|
@@ -86,7 +86,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImpo
|
|
|
86
86
|
hookRoute([
|
|
87
87
|
{
|
|
88
88
|
path: TAB_ID,
|
|
89
|
-
loadComponent: () => import('./c8y-ngx-components-dashboard-details-advanced-tab-dashboard-details-advanced-tab.component-
|
|
89
|
+
loadComponent: () => import('./c8y-ngx-components-dashboard-details-advanced-tab-dashboard-details-advanced-tab.component-DVEnCRzW.mjs').then(m => m.DashboardDetailsAdvancedTabComponent),
|
|
90
90
|
outlet: DASHBOARD_DETAILS_OUTLET,
|
|
91
91
|
context: ViewContext.Dashboard,
|
|
92
92
|
canActivate: [AdvancedTabRouteGuard]
|
|
@@ -11202,15 +11202,18 @@ class ConfigModeControls {
|
|
|
11202
11202
|
const mode = cfg.displayMode ?? GLOBAL_CONTEXT_DISPLAY_MODE.DASHBOARD;
|
|
11203
11203
|
const context = mode === GLOBAL_CONTEXT_DISPLAY_MODE.DASHBOARD
|
|
11204
11204
|
? this.getGlobalContextState(mode)
|
|
11205
|
-
:
|
|
11206
|
-
|
|
11207
|
-
|
|
11208
|
-
|
|
11209
|
-
|
|
11210
|
-
|
|
11211
|
-
|
|
11212
|
-
|
|
11213
|
-
|
|
11205
|
+
: this.buildNonDashboardContext(cfg);
|
|
11206
|
+
this.emit(context);
|
|
11207
|
+
}
|
|
11208
|
+
buildNonDashboardContext(cfg) {
|
|
11209
|
+
const isLive = cfg.refreshOption !== REFRESH_OPTION.HISTORY && !!cfg.dateTimeContext;
|
|
11210
|
+
return {
|
|
11211
|
+
...cfg,
|
|
11212
|
+
isGlobalContextReady: true,
|
|
11213
|
+
dateTimeContext: isLive
|
|
11214
|
+
? DateTimeContextUtil.normalizeForLive(cfg.dateTimeContext)
|
|
11215
|
+
: cfg.dateTimeContext
|
|
11216
|
+
};
|
|
11214
11217
|
}
|
|
11215
11218
|
emitForDisplayMode(mode) {
|
|
11216
11219
|
if (mode === GLOBAL_CONTEXT_DISPLAY_MODE.DASHBOARD) {
|
|
@@ -11221,9 +11224,12 @@ class ConfigModeControls {
|
|
|
11221
11224
|
this.emit({ ...(snapshot ?? this.config()), displayMode: mode, isGlobalContextReady: true });
|
|
11222
11225
|
}
|
|
11223
11226
|
}
|
|
11227
|
+
/** Emits configChange if the diff contains changes beyond transient flags. */
|
|
11224
11228
|
emit(context) {
|
|
11225
11229
|
const diff = this.globalContextUtils.getChangedFields(this.lastEmittedContext(), context);
|
|
11226
|
-
|
|
11230
|
+
const substantiveDiff = { ...diff };
|
|
11231
|
+
delete substantiveDiff.isGlobalContextReady;
|
|
11232
|
+
if (Object.keys(substantiveDiff).length === 0)
|
|
11227
11233
|
return;
|
|
11228
11234
|
this.lastEmittedContext.set(context);
|
|
11229
11235
|
this.configChange.emit({ context, diff });
|
|
@@ -11403,22 +11409,27 @@ class ContextControlsComponent {
|
|
|
11403
11409
|
this.syncConfigToForm();
|
|
11404
11410
|
this.subscribeToFormChanges();
|
|
11405
11411
|
}
|
|
11412
|
+
ngOnInit() {
|
|
11413
|
+
this.emitInitialNonDashboardState();
|
|
11414
|
+
}
|
|
11406
11415
|
onAutoRefresh() {
|
|
11407
11416
|
if (this.emitRefresh()) {
|
|
11408
11417
|
this.onRefresh();
|
|
11409
11418
|
}
|
|
11410
11419
|
}
|
|
11411
11420
|
onRefresh() {
|
|
11412
|
-
const
|
|
11413
|
-
if (!dateTimeContext) {
|
|
11421
|
+
const cfg = this.config();
|
|
11422
|
+
if (!cfg.dateTimeContext) {
|
|
11414
11423
|
this.refresh.emit();
|
|
11415
11424
|
return;
|
|
11416
11425
|
}
|
|
11417
|
-
|
|
11418
|
-
|
|
11419
|
-
|
|
11426
|
+
// Normalize dates to "now" and emit as a config change.
|
|
11427
|
+
// If dates haven't changed (same second), fall back to a plain refresh.
|
|
11428
|
+
const normalized = {
|
|
11429
|
+
...cfg,
|
|
11430
|
+
dateTimeContext: DateTimeContextUtil.normalizeForLive(cfg.dateTimeContext)
|
|
11420
11431
|
};
|
|
11421
|
-
if (!this.emitIfChanged(
|
|
11432
|
+
if (!this.emitIfChanged(normalized)) {
|
|
11422
11433
|
this.refresh.emit();
|
|
11423
11434
|
}
|
|
11424
11435
|
}
|
|
@@ -11435,9 +11446,20 @@ class ContextControlsComponent {
|
|
|
11435
11446
|
effect(() => {
|
|
11436
11447
|
const cfg = this.config();
|
|
11437
11448
|
this.form.patchValue(cfg, { emitEvent: false });
|
|
11438
|
-
this.lastEmittedState.set(this.form.value);
|
|
11439
11449
|
});
|
|
11440
11450
|
}
|
|
11451
|
+
/** On first render for non-dashboard mode, normalize stale live dates and emit. */
|
|
11452
|
+
emitInitialNonDashboardState() {
|
|
11453
|
+
if (this.displayMode() === GLOBAL_CONTEXT_DISPLAY_MODE.DASHBOARD)
|
|
11454
|
+
return;
|
|
11455
|
+
const cfg = this.config();
|
|
11456
|
+
const isLive = cfg.refreshOption !== REFRESH_OPTION.HISTORY && !!cfg.dateTimeContext;
|
|
11457
|
+
const normalized = isLive
|
|
11458
|
+
? { ...cfg, dateTimeContext: DateTimeContextUtil.normalizeForLive(cfg.dateTimeContext) }
|
|
11459
|
+
: cfg;
|
|
11460
|
+
this.form.patchValue(normalized, { emitEvent: false });
|
|
11461
|
+
this.emitIfChanged(normalized);
|
|
11462
|
+
}
|
|
11441
11463
|
subscribeToFormChanges() {
|
|
11442
11464
|
this.form.valueChanges.pipe(takeUntilDestroyed()).subscribe(value => {
|
|
11443
11465
|
const context = this.clearInvalidAggregation(value);
|
|
@@ -12029,5 +12051,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImpo
|
|
|
12029
12051
|
* Generated bundle index. Do not edit.
|
|
12030
12052
|
*/
|
|
12031
12053
|
|
|
12032
|
-
export { AGGREGATIONS, AGGREGATION_ICONS, AGGREGATION_ICON_TYPE, AGGREGATION_LABELS, AGGREGATION_LIMITS, AGGREGATION_TEXTS, AGGREGATION_VALUES, AGGREGATION_VALUES_ARR, AggregationDisplayComponent, AggregationPickerComponent, AggregationPickerService, AggregationValidationService, AutoRefreshControlComponent, CONTEXT_FEATURE, CONTROL_PRESETS, ConfigContextSelectorComponent, ConfigModeControls, ConfigModeControls as ConfigModeControlsComponent, ConfigurationCollapseComponent, ConfigurationControlsComponent, ContextControlsComponent$1 as ContextControlsComponent, DEFAULT_WIDGET_TEMPLATE, DateContextQueryParamNames, DateTimeContextPickerComponent, DateTimeContextPickerService, GLOBAL_CONTEXT_DASHBOARD_PATHS, GLOBAL_CONTEXT_DEFAULTS, GLOBAL_CONTEXT_DISPLAY_MODE, GLOBAL_CONTEXT_EVENTS, GLOBAL_CONTEXT_SOURCE, GlobalContextComponent, GlobalContextConfigComponent, GlobalContextConnectorComponent, GlobalContextEventService, GlobalContextFormService, GlobalContextInlineComponent, GlobalContextLinkControlsComponent, GlobalContextModule, GlobalContextNavigationService, GlobalContextQueryService, GlobalContextService, GlobalContextUtilsService, GlobalContextValidationService, GlobalContextWidgetConfigComponent, GlobalContextWidgetWrapperComponent, HistoryModeConfigurationControlsComponent, INTERVALS, INTERVAL_TITLES, IntervalPickerComponent, LINK_BTNS_CONFIG, LinkButtonsComponent, LiveModeConfigurationControlsComponent, LocalControlsComponent, PRESET_NAME, PreviewControlsComponent, REFRESH_OPTION, ROUTE_PATHS, RealtimeControlComponent, TIME_DURATION, TIME_INTERVAL, TIME_SPAN_MS, TIMING, TimeRangeDisplayComponent, UI_PRIORITIES, WIDGET_DISPLAY_MODE, WIDGET_FEATURE_MAP, WidgetConfigMigrationService, WidgetControlService, applyModeConstraints, buildAggregationExtensions, buildBaselineControls, buildWidgetControlsFromPresets, controlsToSettings, createAutoRefreshHandlers, createResult, defineWidgetControls, getSupportedModes, guards, isAggregationLinked, isAggregationUnlinked, isAutoRefreshDisabled, isAutoRefreshEnabled, isConfig, isDashboard, isDateTimeContextLinked, isDateTimeContextUnlinked, isHistory, isLive, isViewAndConfig, mergePartialControls, resolveWidgetControlsInput, setAutoRefreshControlsVisibility, setAutoRefreshLinks, updateBothSettings };
|
|
12054
|
+
export { AGGREGATIONS, AGGREGATION_ICONS, AGGREGATION_ICON_TYPE, AGGREGATION_LABELS, AGGREGATION_LIMITS, AGGREGATION_TEXTS, AGGREGATION_VALUES, AGGREGATION_VALUES_ARR, AggregationDisplayComponent, AggregationPickerComponent, AggregationPickerService, AggregationValidationService, AutoRefreshControlComponent, CONTEXT_FEATURE, CONTROL_PRESETS, ConfigContextSelectorComponent, ConfigModeControls, ConfigModeControls as ConfigModeControlsComponent, ConfigurationCollapseComponent, ConfigurationControlsComponent, ContextControlsComponent$1 as ContextControlsComponent, DEFAULT_WIDGET_TEMPLATE, DateContextQueryParamNames, DateTimeContextPickerComponent, DateTimeContextPickerService, DateTimeContextUtil, GLOBAL_CONTEXT_DASHBOARD_PATHS, GLOBAL_CONTEXT_DEFAULTS, GLOBAL_CONTEXT_DISPLAY_MODE, GLOBAL_CONTEXT_EVENTS, GLOBAL_CONTEXT_SOURCE, GlobalContextComponent, GlobalContextConfigComponent, GlobalContextConnectorComponent, GlobalContextEventService, GlobalContextFormService, GlobalContextInlineComponent, GlobalContextLinkControlsComponent, GlobalContextModule, GlobalContextNavigationService, GlobalContextQueryService, GlobalContextService, GlobalContextUtilsService, GlobalContextValidationService, GlobalContextWidgetConfigComponent, GlobalContextWidgetWrapperComponent, HistoryModeConfigurationControlsComponent, INTERVALS, INTERVAL_TITLES, IntervalPickerComponent, LINK_BTNS_CONFIG, LinkButtonsComponent, LiveModeConfigurationControlsComponent, LocalControlsComponent, PRESET_NAME, PreviewControlsComponent, REFRESH_OPTION, ROUTE_PATHS, RealtimeControlComponent, TIME_DURATION, TIME_INTERVAL, TIME_SPAN_MS, TIMING, TimeRangeDisplayComponent, UI_PRIORITIES, WIDGET_DISPLAY_MODE, WIDGET_FEATURE_MAP, WidgetConfigMigrationService, WidgetControlService, applyModeConstraints, buildAggregationExtensions, buildBaselineControls, buildWidgetControlsFromPresets, controlsToSettings, createAutoRefreshHandlers, createResult, defineWidgetControls, getSupportedModes, guards, isAggregationLinked, isAggregationUnlinked, isAutoRefreshDisabled, isAutoRefreshEnabled, isConfig, isDashboard, isDateTimeContextLinked, isDateTimeContextUnlinked, isHistory, isLive, isViewAndConfig, mergePartialControls, resolveWidgetControlsInput, setAutoRefreshControlsVisibility, setAutoRefreshLinks, updateBothSettings };
|
|
12033
12055
|
//# sourceMappingURL=c8y-ngx-components-global-context.mjs.map
|