UNPKG

@c8y/ngx-components

Version:

Angular modules for Cumulocity IoT applications

1 lines • 66.3 kB
{"version":3,"file":"c8y-ngx-components-dashboard-details-advanced-tab-dashboard-details-advanced-tab.component-L0Ns8oOr.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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"}