@c8y/ngx-components 1024.20.1 → 1024.21.3
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-ai-agent-chat.mjs +527 -12
- package/fesm2022/c8y-ngx-components-ai-agent-chat.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-ai-ai-chat.mjs +31 -9
- package/fesm2022/c8y-ngx-components-ai-ai-chat.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-ai.mjs +503 -62
- package/fesm2022/c8y-ngx-components-ai.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-alarm-event-selector.mjs +2 -2
- package/fesm2022/c8y-ngx-components-alarm-event-selector.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-alarms.mjs +3 -3
- package/fesm2022/c8y-ngx-components-alarms.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-application-access-list.mjs +1 -1
- package/fesm2022/c8y-ngx-components-application-access-list.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-application-select.mjs +1 -1
- package/fesm2022/c8y-ngx-components-application-select.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-asset-properties.mjs +3 -2
- package/fesm2022/c8y-ngx-components-asset-properties.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-auth-configuration.mjs +1 -1
- package/fesm2022/c8y-ngx-components-auth-configuration.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-bookmarks.mjs +1 -1
- package/fesm2022/c8y-ngx-components-bookmarks.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-branding-shared-lazy.mjs +1 -1
- package/fesm2022/c8y-ngx-components-branding-shared-lazy.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-cockpit-config.mjs +5 -5
- package/fesm2022/c8y-ngx-components-cockpit-config.mjs.map +1 -1
- package/fesm2022/{c8y-ngx-components-context-dashboard-dashboard-version-history.component-Jyjkv4JT.mjs → c8y-ngx-components-context-dashboard-dashboard-version-history.component-CP1afwVe.mjs} +2 -2
- package/fesm2022/{c8y-ngx-components-context-dashboard-dashboard-version-history.component-Jyjkv4JT.mjs.map → c8y-ngx-components-context-dashboard-dashboard-version-history.component-CP1afwVe.mjs.map} +1 -1
- package/fesm2022/c8y-ngx-components-context-dashboard.mjs +81 -20
- package/fesm2022/c8y-ngx-components-context-dashboard.mjs.map +1 -1
- package/fesm2022/{c8y-ngx-components-dashboard-details-advanced-tab-dashboard-details-advanced-tab.component-UEUYsXBv.mjs → c8y-ngx-components-dashboard-details-advanced-tab-dashboard-details-advanced-tab.component-CRvgIgri.mjs} +2 -2
- package/fesm2022/{c8y-ngx-components-dashboard-details-advanced-tab-dashboard-details-advanced-tab.component-UEUYsXBv.mjs.map → c8y-ngx-components-dashboard-details-advanced-tab-dashboard-details-advanced-tab.component-CRvgIgri.mjs.map} +1 -1
- package/fesm2022/c8y-ngx-components-dashboard-details-advanced-tab.mjs +2 -2
- package/fesm2022/c8y-ngx-components-dashboard-manager.mjs +1 -1
- package/fesm2022/c8y-ngx-components-dashboard-manager.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-datapoint-explorer-view.mjs +3 -3
- package/fesm2022/c8y-ngx-components-datapoint-explorer-view.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-datapoint-selector.mjs +2 -2
- package/fesm2022/c8y-ngx-components-datapoint-selector.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-device-profile.mjs +2 -2
- package/fesm2022/c8y-ngx-components-device-profile.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-diagnostics.mjs +1 -1
- package/fesm2022/c8y-ngx-components-diagnostics.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-echart.mjs +146 -126
- package/fesm2022/c8y-ngx-components-echart.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-ecosystem-application-plugins.mjs +2 -2
- package/fesm2022/c8y-ngx-components-ecosystem-application-plugins.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-ecosystem-shared.mjs +1 -1
- package/fesm2022/c8y-ngx-components-ecosystem-shared.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-ecosystem.mjs +4 -4
- package/fesm2022/c8y-ngx-components-ecosystem.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-events-events-timeline.mjs +1 -1
- package/fesm2022/c8y-ngx-components-events-events-timeline.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-events.mjs +2 -2
- package/fesm2022/c8y-ngx-components-events.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-icon-selector.mjs +4 -4
- package/fesm2022/c8y-ngx-components-icon-selector.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-operations-bulk-operation-list-item.mjs +1 -1
- package/fesm2022/c8y-ngx-components-operations-bulk-operation-list-item.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-operations-operations-list.mjs +1 -1
- package/fesm2022/c8y-ngx-components-operations-operations-list.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-operations-operations-timeline.mjs +1 -1
- package/fesm2022/c8y-ngx-components-operations-operations-timeline.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-operations-stepper-bulk-type-configuration.mjs +1 -1
- package/fesm2022/c8y-ngx-components-operations-stepper-bulk-type-configuration.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-operations-stepper-bulk-type-device-profile.mjs +2 -2
- package/fesm2022/c8y-ngx-components-operations-stepper-bulk-type-device-profile.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-operations-stepper-bulk-type-firmware.mjs +2 -2
- package/fesm2022/c8y-ngx-components-operations-stepper-bulk-type-firmware.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-operations-stepper-bulk-type-software.mjs +2 -2
- package/fesm2022/c8y-ngx-components-operations-stepper-bulk-type-software.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-protocol-lpwan.mjs +5 -5
- package/fesm2022/c8y-ngx-components-protocol-lpwan.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-protocol-opcua.mjs +1 -1
- package/fesm2022/c8y-ngx-components-protocol-opcua.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-register-device.mjs +3 -3
- package/fesm2022/c8y-ngx-components-register-device.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-remote-access-configurations.mjs +1 -1
- package/fesm2022/c8y-ngx-components-remote-access-configurations.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-replace-device-replace-device-wizard.mjs +1 -1
- package/fesm2022/c8y-ngx-components-replace-device-replace-device-wizard.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-report-dashboard.mjs +1 -1
- package/fesm2022/c8y-ngx-components-report-dashboard.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-repository-configuration.mjs +4 -4
- package/fesm2022/c8y-ngx-components-repository-configuration.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-repository-firmware.mjs +4 -4
- package/fesm2022/c8y-ngx-components-repository-firmware.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-repository-shared.mjs +2 -2
- package/fesm2022/c8y-ngx-components-repository-shared.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-repository-software.mjs +3 -3
- package/fesm2022/c8y-ngx-components-repository-software.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-static-assets-modal.mjs +1 -1
- package/fesm2022/c8y-ngx-components-static-assets-modal.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-tracking.mjs +1 -1
- package/fesm2022/c8y-ngx-components-tracking.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-trusted-certificates.mjs +1 -1
- package/fesm2022/c8y-ngx-components-trusted-certificates.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-widgets-definitions-html-widget.mjs +17 -1
- package/fesm2022/c8y-ngx-components-widgets-definitions-html-widget.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-widgets-definitions-scada.mjs +21 -1
- package/fesm2022/c8y-ngx-components-widgets-definitions-scada.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-widgets-implementations-asset-table.mjs +60 -31
- package/fesm2022/c8y-ngx-components-widgets-implementations-asset-table.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-widgets-implementations-datapoints-graph.mjs +2 -2
- package/fesm2022/c8y-ngx-components-widgets-implementations-datapoints-graph.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-widgets-implementations-datapoints-list.mjs +2 -2
- package/fesm2022/c8y-ngx-components-widgets-implementations-datapoints-list.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-widgets-implementations-datapoints-table.mjs +1 -1
- package/fesm2022/c8y-ngx-components-widgets-implementations-datapoints-table.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-widgets-implementations-image.mjs +1 -1
- package/fesm2022/c8y-ngx-components-widgets-implementations-image.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-widgets-implementations-quick-links.mjs +1 -1
- package/fesm2022/c8y-ngx-components-widgets-implementations-quick-links.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-widgets-implementations-scada.mjs +1 -1
- package/fesm2022/c8y-ngx-components-widgets-implementations-scada.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components.mjs +500 -38
- package/fesm2022/c8y-ngx-components.mjs.map +1 -1
- package/locales/de.po +72 -0
- package/locales/es.po +72 -0
- package/locales/fr.po +72 -0
- package/locales/ja_JP.po +72 -0
- package/locales/ko.po +72 -0
- package/locales/locales.pot +72 -3
- package/locales/nl.po +72 -0
- package/locales/pl.po +73 -1
- package/locales/pt_BR.po +74 -2
- package/locales/zh_CN.po +72 -0
- package/locales/zh_TW.po +72 -0
- package/package.json +1 -1
- package/types/c8y-ngx-components-ai-agent-chat.d.ts +201 -3
- package/types/c8y-ngx-components-ai-agent-chat.d.ts.map +1 -1
- package/types/c8y-ngx-components-ai-ai-chat.d.ts +14 -4
- package/types/c8y-ngx-components-ai-ai-chat.d.ts.map +1 -1
- package/types/c8y-ngx-components-ai.d.ts +157 -2
- package/types/c8y-ngx-components-ai.d.ts.map +1 -1
- package/types/c8y-ngx-components-asset-properties.d.ts.map +1 -1
- package/types/c8y-ngx-components-context-dashboard.d.ts +37 -3
- package/types/c8y-ngx-components-context-dashboard.d.ts.map +1 -1
- package/types/c8y-ngx-components-echart.d.ts +6 -0
- package/types/c8y-ngx-components-echart.d.ts.map +1 -1
- package/types/c8y-ngx-components-widgets-implementations-asset-table.d.ts +5 -0
- package/types/c8y-ngx-components-widgets-implementations-asset-table.d.ts.map +1 -1
- package/types/c8y-ngx-components.d.ts +310 -12
- package/types/c8y-ngx-components.d.ts.map +1 -1
|
@@ -173,7 +173,7 @@ class DiagnosticsComponent {
|
|
|
173
173
|
this.diagnosticService.cancelOperation(operation);
|
|
174
174
|
}
|
|
175
175
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: DiagnosticsComponent, deps: [{ token: i1$1.ActivatedRoute }, { token: DiagnosticsService }, { token: i2.OperationRealtimeService }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
176
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.19", type: DiagnosticsComponent, isStandalone: true, selector: "c8y-diagnostics", ngImport: i0, template: "<c8y-action-bar-item [placement]=\"'right'\">\n <button\n class=\"btn btn-link\"\n type=\"button\"\n title=\"{{ 'Request diagnostic file' | translate }}\"\n (click)=\"onDiagnosticRequest()\"\n >\n <i c8yIcon=\"stethoscope\"></i>\n <span translate>Request diagnostic file</span>\n </button>\n</c8y-action-bar-item>\n\n<div\n class=\"page-sticky-header hidden-xs c8y-list__item c8y-list--timeline\"\n *ngIf=\"operationCount > 0\"\n>\n <div class=\"d-flex\">\n <div class=\"c8y-list--timeline__item__date a-s-center\">\n <label>{{ 'Date' | translate }}</label>\n </div>\n <div class=\"c8y-list__item__block flex-grow\">\n <div class=\"c8y-list__item__icon\">\n <i class=\"p-l-24\"></i>\n </div>\n <div class=\"c8y-list__item__body\">\n <div class=\"content-flex-40\">\n <div class=\"col-4\">{{ 'Event' | translate }}</div>\n <div class=\"col-5 m-l-8\">{{ 'File' | translate }}</div>\n </div>\n </div>\n </div>\n </div>\n</div>\n\n<c8y-list-group>\n <ng-template\n c8yFor\n let-operation\n [c8yForOf]=\"operations$\"\n [c8yForPipe]=\"operationsPipe\"\n [c8yForRealtime]=\"operationRealtime\"\n [c8yForRealtimeOptions]=\"realtimeOptions\"\n (c8yForCount)=\"operationCount = $event\"\n >\n <c8y-li-timeline>\n {{ operation.creationTime | c8yDate }}\n <c8y-li>\n <c8y-li-icon>\n <i\n [c8yIcon]=\"statusIcons[operation.status]\"\n [ngClass]=\"statusClasses[operation.status]\"\n [tooltip]=\"operation.status?.toString() | translate\"\n ></i>\n </c8y-li-icon>\n <c8y-li-body class=\"content-flex-40\">\n <div class=\"col-4\">\n <p class=\"text-truncate-wrap\" title=\"{{ operation.description | translate }}\">\n {{ operation.description | translate }}\n </p>\n </div>\n <div class=\"col-5\" *ngIf=\"operation.c8y_DiagnosticReport?.file\">\n <div class=\"text-truncate-wrap m-t-xs-8\">\n <span class=\"text-label-small visible-xs\" translate>File</span>\n <span title=\"{{ operation.c8y_DiagnosticReport.file }}\">\n <c8y-file-download\n url=\"{{ operation.c8y_DiagnosticReport.file }}\"\n ></c8y-file-download>\n </span>\n </div>\n </div>\n </c8y-li-body>\n <c8y-li-action\n (click)=\"onCancel(operation)\"\n *ngIf=\"operation.status === 'PENDING'\"\n icon=\"times\"\n label=\"{{ 'Cancel' | translate }}\"\n ></c8y-li-action>\n <c8y-li-action\n (click)=\"onDelete(operation)\"\n *ngIf=\"operation.status === 'SUCCESSFUL'\"\n icon=\"delete\"\n label=\"{{ 'Delete' | translate }}\"\n ></c8y-li-action>\n </c8y-li>\n </c8y-li-timeline>\n </ng-template>\n</c8y-list-group>\n\n<!-- EMPTY STATE -->\n\n<c8y-ui-empty-state\n *ngIf=\"operationCount === 0\"\n [icon]=\"'stethoscope'\"\n [title]=\"'No diagnostic files available.' | translate\"\n></c8y-ui-empty-state>\n", dependencies: [{ kind: "component", type: ActionBarItemComponent, selector: "c8y-action-bar-item", inputs: ["placement", "priority", "itemClass", "injector", "groupId", "inGroupPriority"] }, { kind: "directive", type: IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "directive", type: C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: ListGroupComponent, selector: "c8y-list-group" }, { kind: "directive", type: ForOfDirective, selector: "[c8yFor]", inputs: ["c8yForOf", "c8yForLoadMore", "c8yForPipe", "c8yForNotFound", "c8yForMaxIterations", "c8yForLoadingTemplate", "c8yForLoadNextLabel", "c8yForLoadingLabel", "c8yForRealtime", "c8yForRealtimeOptions", "c8yForComparator", "c8yForEnableVirtualScroll", "c8yForVirtualScrollElementSize", "c8yForVirtualScrollStrategy", "c8yForVirtualScrollContainerHeight"], outputs: ["c8yForCount", "c8yForChange", "c8yForLoadMoreComponent"] }, { kind: "component", type: ListItemTimelineComponent, selector: "c8y-list-item-timeline, c8y-li-timeline" }, { kind: "component", type: ListItemComponent, selector: "c8y-list-item, c8y-li", inputs: ["active", "highlighted", "emptyActions", "dense", "collapsed", "selectable"], outputs: ["collapsedChange"] }, { kind: "component", type: ListItemIconComponent, selector: "c8y-list-item-icon, c8y-li-icon", inputs: ["icon", "status"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: TooltipDirective, selector: "[tooltip], [tooltipHtml]", inputs: ["adaptivePosition", "tooltip", "placement", "triggers", "container", "containerClass", "boundariesElement", "isOpen", "isDisabled", "delay", "tooltipHtml", "tooltipPlacement", "tooltipIsOpen", "tooltipEnable", "tooltipAppendToBody", "tooltipAnimation", "tooltipClass", "tooltipContext", "tooltipPopupDelay", "tooltipFadeDuration", "tooltipTrigger"], outputs: ["tooltipChange", "onShown", "onHidden", "tooltipStateChanged"], exportAs: ["bs-tooltip"] }, { kind: "component", type: ListItemBodyComponent, selector: "c8y-list-item-body, c8y-li-body", inputs: ["body"] }, { kind: "component", type: FileDownloadComponent, selector: "c8y-file-download", inputs: ["url"] }, { kind: "component", type: ListItemActionComponent, selector: "c8y-list-item-action, c8y-li-action", inputs: ["label", "icon", "disabled"], outputs: ["click"] }, { kind: "component", type: EmptyStateComponent, selector: "c8y-ui-empty-state", inputs: ["icon", "title", "subtitle", "horizontal"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }, { kind: "pipe", type: DatePipe, name: "c8yDate" }], changeDetection: i0.ChangeDetectionStrategy.Eager }); }
|
|
176
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.19", type: DiagnosticsComponent, isStandalone: true, selector: "c8y-diagnostics", ngImport: i0, template: "<c8y-action-bar-item [placement]=\"'right'\">\n <button\n class=\"btn btn-link\"\n type=\"button\"\n title=\"{{ 'Request diagnostic file' | translate }}\"\n (click)=\"onDiagnosticRequest()\"\n >\n <i c8yIcon=\"stethoscope\"></i>\n <span translate>Request diagnostic file</span>\n </button>\n</c8y-action-bar-item>\n\n<div\n class=\"page-sticky-header hidden-xs c8y-list__item c8y-list--timeline\"\n *ngIf=\"operationCount > 0\"\n>\n <div class=\"d-flex\">\n <div class=\"c8y-list--timeline__item__date a-s-center\">\n <label>{{ 'Date' | translate }}</label>\n </div>\n <div class=\"c8y-list__item__block flex-grow\">\n <div class=\"c8y-list__item__icon\">\n <i class=\"p-l-24\"></i>\n </div>\n <div class=\"c8y-list__item__body\">\n <div class=\"content-flex-40\">\n <div class=\"col-4\">{{ 'Event' | translate }}</div>\n <div class=\"col-5 m-l-8\">{{ 'File' | translate }}</div>\n </div>\n </div>\n </div>\n </div>\n</div>\n\n<c8y-list-group>\n <ng-template\n c8yFor\n let-operation\n [c8yForOf]=\"operations$\"\n [c8yForPipe]=\"operationsPipe\"\n [c8yForRealtime]=\"operationRealtime\"\n [c8yForRealtimeOptions]=\"realtimeOptions\"\n (c8yForCount)=\"operationCount = $event\"\n >\n <c8y-li-timeline>\n {{ operation.creationTime | c8yDate }}\n <c8y-li>\n <c8y-li-icon>\n <i\n [c8yIcon]=\"statusIcons[operation.status]\"\n [ngClass]=\"statusClasses[operation.status]\"\n [tooltip]=\"operation.status?.toString() | translate\"\n ></i>\n </c8y-li-icon>\n <c8y-li-body class=\"content-flex-40\">\n <div class=\"col-4\">\n <p class=\"text-truncate-wrap\" title=\"{{ operation.description | translate }}\">\n {{ operation.description | translate }}\n </p>\n </div>\n <div class=\"col-5\" *ngIf=\"operation.c8y_DiagnosticReport?.file\">\n <div class=\"text-truncate-wrap m-t-xs-8\">\n <span class=\"text-label-small visible-xs\" translate>File</span>\n <span title=\"{{ operation.c8y_DiagnosticReport.file }}\">\n <c8y-file-download\n url=\"{{ operation.c8y_DiagnosticReport.file }}\"\n ></c8y-file-download>\n </span>\n </div>\n </div>\n </c8y-li-body>\n <c8y-li-action\n (click)=\"onCancel(operation)\"\n *ngIf=\"operation.status === 'PENDING'\"\n icon=\"times\"\n label=\"{{ 'Cancel' | translate }}\"\n ></c8y-li-action>\n <c8y-li-action\n (click)=\"onDelete(operation)\"\n *ngIf=\"operation.status === 'SUCCESSFUL'\"\n icon=\"delete\"\n label=\"{{ 'Delete' | translate }}\"\n ></c8y-li-action>\n </c8y-li>\n </c8y-li-timeline>\n </ng-template>\n</c8y-list-group>\n\n<!-- EMPTY STATE -->\n\n<c8y-ui-empty-state\n *ngIf=\"operationCount === 0\"\n [icon]=\"'stethoscope'\"\n [title]=\"'No diagnostic files available.' | translate\"\n></c8y-ui-empty-state>\n", dependencies: [{ kind: "component", type: ActionBarItemComponent, selector: "c8y-action-bar-item", inputs: ["placement", "priority", "itemClass", "injector", "groupId", "inGroupPriority"] }, { kind: "directive", type: IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "directive", type: C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: ListGroupComponent, selector: "c8y-list-group" }, { kind: "directive", type: ForOfDirective, selector: "[c8yFor]", inputs: ["c8yForOf", "c8yForLoadMore", "c8yForPipe", "c8yForNotFound", "c8yForMaxIterations", "c8yForLoadingTemplate", "c8yForLoadNextLabel", "c8yForLoadingLabel", "c8yForRealtime", "c8yForRealtimeOptions", "c8yForComparator", "c8yForEnableVirtualScroll", "c8yForVirtualScrollElementSize", "c8yForVirtualScrollStrategy", "c8yForVirtualScrollContainerHeight"], outputs: ["c8yForCount", "c8yForChange", "c8yForLoadMoreComponent"] }, { kind: "component", type: ListItemTimelineComponent, selector: "c8y-list-item-timeline, c8y-li-timeline" }, { kind: "component", type: ListItemComponent, selector: "c8y-list-item, c8y-li", inputs: ["active", "highlighted", "emptyActions", "dense", "collapsed", "selectable", "selectOnClick"], outputs: ["collapsedChange"] }, { kind: "component", type: ListItemIconComponent, selector: "c8y-list-item-icon, c8y-li-icon", inputs: ["icon", "status"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: TooltipDirective, selector: "[tooltip], [tooltipHtml]", inputs: ["adaptivePosition", "tooltip", "placement", "triggers", "container", "containerClass", "boundariesElement", "isOpen", "isDisabled", "delay", "tooltipHtml", "tooltipPlacement", "tooltipIsOpen", "tooltipEnable", "tooltipAppendToBody", "tooltipAnimation", "tooltipClass", "tooltipContext", "tooltipPopupDelay", "tooltipFadeDuration", "tooltipTrigger"], outputs: ["tooltipChange", "onShown", "onHidden", "tooltipStateChanged"], exportAs: ["bs-tooltip"] }, { kind: "component", type: ListItemBodyComponent, selector: "c8y-list-item-body, c8y-li-body", inputs: ["body"] }, { kind: "component", type: FileDownloadComponent, selector: "c8y-file-download", inputs: ["url"] }, { kind: "component", type: ListItemActionComponent, selector: "c8y-list-item-action, c8y-li-action", inputs: ["label", "icon", "disabled"], outputs: ["click"] }, { kind: "component", type: EmptyStateComponent, selector: "c8y-ui-empty-state", inputs: ["icon", "title", "subtitle", "horizontal"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }, { kind: "pipe", type: DatePipe, name: "c8yDate" }], changeDetection: i0.ChangeDetectionStrategy.Eager }); }
|
|
177
177
|
}
|
|
178
178
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: DiagnosticsComponent, decorators: [{
|
|
179
179
|
type: Component,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"c8y-ngx-components-diagnostics.mjs","sources":["../../diagnostics/diagnostics.service.ts","../../diagnostics/diagnostics-tab.guard.ts","../../diagnostics/diagnostics.component.ts","../../diagnostics/diagnostics.component.html","../../diagnostics/diagnostics.module.ts","../../diagnostics/c8y-ngx-components-diagnostics.ts"],"sourcesContent":["import { Observable } from 'rxjs';\nimport { Injectable } from '@angular/core';\nimport {\n IManagedObject,\n IResultList,\n InventoryBinaryService,\n IOperation,\n OperationService,\n OperationStatus\n} from '@c8y/client';\nimport { gettext } from '@c8y/ngx-components/gettext';\nimport { AlertService, ModalService } from '@c8y/ngx-components';\nimport { assign } from 'lodash-es';\nimport { switchMap } from 'rxjs/operators';\n\n@Injectable()\nexport class DiagnosticsService {\n readonly fragment = 'c8y_DiagnosticReport';\n constructor(\n private operationService: OperationService,\n private inventoryBinary: InventoryBinaryService,\n private modalService: ModalService,\n private alertService: AlertService\n ) {}\n\n isSupportedDevice(device): boolean {\n const supportedOperations = (device && device.c8y_SupportedOperations) || [];\n return supportedOperations.includes(this.fragment);\n }\n\n getOperations$(device$: Observable<IManagedObject>): Observable<IResultList<IOperation>> {\n return device$.pipe(\n switchMap(device =>\n this.operationService.list({\n deviceId: device.id,\n fragmentType: this.fragment,\n dateFrom: new Date(0).toISOString(),\n dateTo: new Date(Date.now()).toISOString(),\n revert: true,\n pageSize: 10,\n withTotalPages: true\n })\n )\n );\n }\n\n async createOperation(deviceId: string) {\n const operation = {\n deviceId,\n description: gettext('Diagnostic file request'),\n [this.fragment]: {}\n };\n try {\n await this.operationService.create(operation);\n this.alertService.success(gettext('Diagnostic file request sent.'));\n } catch (error) {\n this.alertService.addServerFailure(error);\n }\n }\n\n async deleteOperation(operation: IOperation) {\n try {\n const result = await this.modalService.confirm(\n gettext('Delete diagnostic file'),\n gettext('You are about to delete this diagnostic file. Do you want to proceed?'),\n 'danger',\n {\n ok: gettext('Delete'),\n cancel: gettext('Cancel')\n }\n );\n\n if (result) {\n this.deleteDiagnosticsBinary(operation);\n }\n } catch (error) {\n // Do nothing\n }\n }\n\n async cancelOperation(operation: IOperation) {\n try {\n const operationAfterUpdate = (\n await this.operationService.update({\n id: operation.id,\n status: OperationStatus.FAILED,\n failureReason: gettext('Operation cancelled by user.')\n })\n ).data;\n assign(operation, operationAfterUpdate);\n this.alertService.success(gettext('Diagnostic file request cancelled.'));\n } catch (ex) {\n this.alertService.addServerFailure(ex);\n }\n }\n\n private getOperation(op: IOperation) {\n if (!op) {\n return null;\n }\n return op && op[this.fragment];\n }\n\n private async deleteDiagnosticsBinary(op: IOperation) {\n const operation = this.getOperation(op);\n if (operation && operation.file) {\n const { file } = operation;\n try {\n const binaryId = this.inventoryBinary.getIdFromUrl(file);\n const result = await this.inventoryBinary.delete(binaryId);\n if (result) {\n this.deleteDiagnosticsFragment(op);\n }\n } catch (err) {\n if (err.res.status === 404) {\n // In case the file is already deleted via other means we want to delete the fragment\n this.deleteDiagnosticsFragment(op);\n } else {\n const msg = gettext('Could not delete the diagnostic file.');\n this.alertService.danger(msg);\n }\n }\n }\n }\n\n private async deleteDiagnosticsFragment(op: IOperation) {\n const deleteOp = {\n id: op.id,\n status: op.status,\n [this.fragment]: null\n };\n try {\n const operationAfterUpdate = (await this.operationService.update(deleteOp)).data;\n assign(op, operationAfterUpdate);\n this.alertService.success(gettext('Diagnostic file deleted.'));\n } catch (error) {\n this.alertService.addServerFailure(error);\n }\n }\n}\n","import { DiagnosticsService } from './diagnostics.service';\nimport { Injectable } from '@angular/core';\nimport { ActivatedRouteSnapshot } from '@angular/router';\n\n@Injectable()\nexport class DiagnosticsTabGuard {\n constructor(private diagnosticsService: DiagnosticsService) {}\n\n canActivate(route: ActivatedRouteSnapshot) {\n const device = route.data.contextData || route.parent.data.contextData;\n return this.diagnosticsService.isSupportedDevice(device);\n }\n}\n","import { DiagnosticsService } from './diagnostics.service';\nimport { ActivatedRoute } from '@angular/router';\nimport { Component, ChangeDetectionStrategy } from '@angular/core';\nimport { BehaviorSubject, pipe } from 'rxjs';\nimport { map } from 'rxjs/operators';\nimport {\n ForOfRealtimeOptions,\n operationStatusClasses,\n operationStatusIcons,\n OperationRealtimeService,\n ForOfFilterPipe,\n ActionBarItemComponent,\n IconDirective,\n C8yTranslateDirective,\n ListGroupComponent,\n ForOfDirective,\n ListItemTimelineComponent,\n ListItemComponent,\n ListItemIconComponent,\n ListItemBodyComponent,\n ListItemActionComponent,\n EmptyStateComponent,\n C8yTranslatePipe,\n DatePipe\n} from '@c8y/ngx-components';\nimport { IManagedObject, IOperation } from '@c8y/client';\nimport { NgIf, NgClass } from '@angular/common';\nimport { TooltipDirective } from 'ngx-bootstrap/tooltip';\nimport { FileDownloadComponent } from '@c8y/ngx-components/repository/shared';\n@Component({\n templateUrl: './diagnostics.component.html',\n selector: 'c8y-diagnostics',\n imports: [\n ActionBarItemComponent,\n IconDirective,\n C8yTranslateDirective,\n NgIf,\n ListGroupComponent,\n ForOfDirective,\n ListItemTimelineComponent,\n ListItemComponent,\n ListItemIconComponent,\n NgClass,\n TooltipDirective,\n ListItemBodyComponent,\n FileDownloadComponent,\n ListItemActionComponent,\n EmptyStateComponent,\n C8yTranslatePipe,\n DatePipe\n ],\n changeDetection: ChangeDetectionStrategy.Eager\n})\nexport class DiagnosticsComponent {\n statusIcons = operationStatusIcons;\n statusClasses = operationStatusClasses;\n deviceId: string = this.route.snapshot.parent.data.contextData.id;\n device$ = new BehaviorSubject<IManagedObject>(this.route.snapshot.parent.data.contextData);\n operations$ = this.diagnosticService.getOperations$(this.device$);\n operationsPipe: ForOfFilterPipe<IOperation> = pipe(\n map(ops => ops.filter(op => op[this.diagnosticService.fragment]))\n );\n realtimeOptions: ForOfRealtimeOptions = {\n entityOrId: this.deviceId,\n removeOnUpdate: true,\n insertOnUpdate: true\n } as ForOfRealtimeOptions;\n operationCount: number;\n\n constructor(\n private route: ActivatedRoute,\n private diagnosticService: DiagnosticsService,\n public operationRealtime: OperationRealtimeService\n ) {}\n\n onDiagnosticRequest() {\n this.diagnosticService.createOperation(this.deviceId);\n }\n\n onDelete(operation: IOperation) {\n this.diagnosticService.deleteOperation(operation);\n }\n\n onCancel(operation: IOperation) {\n this.diagnosticService.cancelOperation(operation);\n }\n}\n","<c8y-action-bar-item [placement]=\"'right'\">\n <button\n class=\"btn btn-link\"\n type=\"button\"\n title=\"{{ 'Request diagnostic file' | translate }}\"\n (click)=\"onDiagnosticRequest()\"\n >\n <i c8yIcon=\"stethoscope\"></i>\n <span translate>Request diagnostic file</span>\n </button>\n</c8y-action-bar-item>\n\n<div\n class=\"page-sticky-header hidden-xs c8y-list__item c8y-list--timeline\"\n *ngIf=\"operationCount > 0\"\n>\n <div class=\"d-flex\">\n <div class=\"c8y-list--timeline__item__date a-s-center\">\n <label>{{ 'Date' | translate }}</label>\n </div>\n <div class=\"c8y-list__item__block flex-grow\">\n <div class=\"c8y-list__item__icon\">\n <i class=\"p-l-24\"></i>\n </div>\n <div class=\"c8y-list__item__body\">\n <div class=\"content-flex-40\">\n <div class=\"col-4\">{{ 'Event' | translate }}</div>\n <div class=\"col-5 m-l-8\">{{ 'File' | translate }}</div>\n </div>\n </div>\n </div>\n </div>\n</div>\n\n<c8y-list-group>\n <ng-template\n c8yFor\n let-operation\n [c8yForOf]=\"operations$\"\n [c8yForPipe]=\"operationsPipe\"\n [c8yForRealtime]=\"operationRealtime\"\n [c8yForRealtimeOptions]=\"realtimeOptions\"\n (c8yForCount)=\"operationCount = $event\"\n >\n <c8y-li-timeline>\n {{ operation.creationTime | c8yDate }}\n <c8y-li>\n <c8y-li-icon>\n <i\n [c8yIcon]=\"statusIcons[operation.status]\"\n [ngClass]=\"statusClasses[operation.status]\"\n [tooltip]=\"operation.status?.toString() | translate\"\n ></i>\n </c8y-li-icon>\n <c8y-li-body class=\"content-flex-40\">\n <div class=\"col-4\">\n <p class=\"text-truncate-wrap\" title=\"{{ operation.description | translate }}\">\n {{ operation.description | translate }}\n </p>\n </div>\n <div class=\"col-5\" *ngIf=\"operation.c8y_DiagnosticReport?.file\">\n <div class=\"text-truncate-wrap m-t-xs-8\">\n <span class=\"text-label-small visible-xs\" translate>File</span>\n <span title=\"{{ operation.c8y_DiagnosticReport.file }}\">\n <c8y-file-download\n url=\"{{ operation.c8y_DiagnosticReport.file }}\"\n ></c8y-file-download>\n </span>\n </div>\n </div>\n </c8y-li-body>\n <c8y-li-action\n (click)=\"onCancel(operation)\"\n *ngIf=\"operation.status === 'PENDING'\"\n icon=\"times\"\n label=\"{{ 'Cancel' | translate }}\"\n ></c8y-li-action>\n <c8y-li-action\n (click)=\"onDelete(operation)\"\n *ngIf=\"operation.status === 'SUCCESSFUL'\"\n icon=\"delete\"\n label=\"{{ 'Delete' | translate }}\"\n ></c8y-li-action>\n </c8y-li>\n </c8y-li-timeline>\n </ng-template>\n</c8y-list-group>\n\n<!-- EMPTY STATE -->\n\n<c8y-ui-empty-state\n *ngIf=\"operationCount === 0\"\n [icon]=\"'stethoscope'\"\n [title]=\"'No diagnostic files available.' | translate\"\n></c8y-ui-empty-state>\n","import { DiagnosticsTabGuard } from './diagnostics-tab.guard';\nimport { gettext } from '@c8y/ngx-components/gettext';\nimport { ListGroupModule, CoreModule, hookRoute, ViewContext } from '@c8y/ngx-components';\nimport { RouterModule } from '@angular/router';\nimport { DiagnosticsService } from './diagnostics.service';\nimport { DiagnosticsComponent } from './diagnostics.component';\nimport { NgModule } from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { TooltipModule } from 'ngx-bootstrap/tooltip';\nimport { BsDropdownModule, BsDropdownConfig } from 'ngx-bootstrap/dropdown';\nimport { SharedRepositoryModule } from '@c8y/ngx-components/repository/shared';\n\n@NgModule({\n imports: [\n CoreModule,\n RouterModule,\n CommonModule,\n ListGroupModule,\n SharedRepositoryModule,\n BsDropdownModule,\n TooltipModule,\n DiagnosticsComponent\n ],\n exports: [DiagnosticsComponent],\n providers: [\n DiagnosticsService,\n BsDropdownConfig,\n DiagnosticsTabGuard,\n hookRoute({\n context: ViewContext.Device,\n path: 'diagnostics',\n component: DiagnosticsComponent,\n label: gettext('Diagnostics'),\n icon: 'stethoscope',\n canActivate: [DiagnosticsTabGuard],\n priority: 200\n })\n ]\n})\nexport class DiagnosticsModule {}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":["i1.DiagnosticsService","i1","i2.DiagnosticsService","i3"],"mappings":";;;;;;;;;;;;;;;;;MAgBa,kBAAkB,CAAA;AAE7B,IAAA,WAAA,CACU,gBAAkC,EAClC,eAAuC,EACvC,YAA0B,EAC1B,YAA0B,EAAA;QAH1B,IAAA,CAAA,gBAAgB,GAAhB,gBAAgB;QAChB,IAAA,CAAA,eAAe,GAAf,eAAe;QACf,IAAA,CAAA,YAAY,GAAZ,YAAY;QACZ,IAAA,CAAA,YAAY,GAAZ,YAAY;QALb,IAAA,CAAA,QAAQ,GAAG,sBAAsB;IAMvC;AAEH,IAAA,iBAAiB,CAAC,MAAM,EAAA;QACtB,MAAM,mBAAmB,GAAG,CAAC,MAAM,IAAI,MAAM,CAAC,uBAAuB,KAAK,EAAE;QAC5E,OAAO,mBAAmB,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC;IACpD;AAEA,IAAA,cAAc,CAAC,OAAmC,EAAA;AAChD,QAAA,OAAO,OAAO,CAAC,IAAI,CACjB,SAAS,CAAC,MAAM,IACd,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC;YACzB,QAAQ,EAAE,MAAM,CAAC,EAAE;YACnB,YAAY,EAAE,IAAI,CAAC,QAAQ;YAC3B,QAAQ,EAAE,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE;YACnC,MAAM,EAAE,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,WAAW,EAAE;AAC1C,YAAA,MAAM,EAAE,IAAI;AACZ,YAAA,QAAQ,EAAE,EAAE;AACZ,YAAA,cAAc,EAAE;SACjB,CAAC,CACH,CACF;IACH;IAEA,MAAM,eAAe,CAAC,QAAgB,EAAA;AACpC,QAAA,MAAM,SAAS,GAAG;YAChB,QAAQ;AACR,YAAA,WAAW,EAAE,OAAO,CAAC,yBAAyB,CAAC;AAC/C,YAAA,CAAC,IAAI,CAAC,QAAQ,GAAG;SAClB;AACD,QAAA,IAAI;YACF,MAAM,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,SAAS,CAAC;YAC7C,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,OAAO,CAAC,+BAA+B,CAAC,CAAC;QACrE;QAAE,OAAO,KAAK,EAAE;AACd,YAAA,IAAI,CAAC,YAAY,CAAC,gBAAgB,CAAC,KAAK,CAAC;QAC3C;IACF;IAEA,MAAM,eAAe,CAAC,SAAqB,EAAA;AACzC,QAAA,IAAI;YACF,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,OAAO,CAC5C,OAAO,CAAC,wBAAwB,CAAC,EACjC,OAAO,CAAC,uEAAuE,CAAC,EAChF,QAAQ,EACR;AACE,gBAAA,EAAE,EAAE,OAAO,CAAC,QAAQ,CAAC;AACrB,gBAAA,MAAM,EAAE,OAAO,CAAC,QAAQ;AACzB,aAAA,CACF;YAED,IAAI,MAAM,EAAE;AACV,gBAAA,IAAI,CAAC,uBAAuB,CAAC,SAAS,CAAC;YACzC;QACF;QAAE,OAAO,KAAK,EAAE;;QAEhB;IACF;IAEA,MAAM,eAAe,CAAC,SAAqB,EAAA;AACzC,QAAA,IAAI;YACF,MAAM,oBAAoB,GAAG,CAC3B,MAAM,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC;gBACjC,EAAE,EAAE,SAAS,CAAC,EAAE;gBAChB,MAAM,EAAE,eAAe,CAAC,MAAM;AAC9B,gBAAA,aAAa,EAAE,OAAO,CAAC,8BAA8B;aACtD,CAAC,EACF,IAAI;AACN,YAAA,MAAM,CAAC,SAAS,EAAE,oBAAoB,CAAC;YACvC,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,OAAO,CAAC,oCAAoC,CAAC,CAAC;QAC1E;QAAE,OAAO,EAAE,EAAE;AACX,YAAA,IAAI,CAAC,YAAY,CAAC,gBAAgB,CAAC,EAAE,CAAC;QACxC;IACF;AAEQ,IAAA,YAAY,CAAC,EAAc,EAAA;QACjC,IAAI,CAAC,EAAE,EAAE;AACP,YAAA,OAAO,IAAI;QACb;QACA,OAAO,EAAE,IAAI,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC;IAChC;IAEQ,MAAM,uBAAuB,CAAC,EAAc,EAAA;QAClD,MAAM,SAAS,GAAG,IAAI,CAAC,YAAY,CAAC,EAAE,CAAC;AACvC,QAAA,IAAI,SAAS,IAAI,SAAS,CAAC,IAAI,EAAE;AAC/B,YAAA,MAAM,EAAE,IAAI,EAAE,GAAG,SAAS;AAC1B,YAAA,IAAI;gBACF,MAAM,QAAQ,GAAG,IAAI,CAAC,eAAe,CAAC,YAAY,CAAC,IAAI,CAAC;gBACxD,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,QAAQ,CAAC;gBAC1D,IAAI,MAAM,EAAE;AACV,oBAAA,IAAI,CAAC,yBAAyB,CAAC,EAAE,CAAC;gBACpC;YACF;YAAE,OAAO,GAAG,EAAE;gBACZ,IAAI,GAAG,CAAC,GAAG,CAAC,MAAM,KAAK,GAAG,EAAE;;AAE1B,oBAAA,IAAI,CAAC,yBAAyB,CAAC,EAAE,CAAC;gBACpC;qBAAO;AACL,oBAAA,MAAM,GAAG,GAAG,OAAO,CAAC,uCAAuC,CAAC;AAC5D,oBAAA,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,GAAG,CAAC;gBAC/B;YACF;QACF;IACF;IAEQ,MAAM,yBAAyB,CAAC,EAAc,EAAA;AACpD,QAAA,MAAM,QAAQ,GAAG;YACf,EAAE,EAAE,EAAE,CAAC,EAAE;YACT,MAAM,EAAE,EAAE,CAAC,MAAM;AACjB,YAAA,CAAC,IAAI,CAAC,QAAQ,GAAG;SAClB;AACD,QAAA,IAAI;AACF,YAAA,MAAM,oBAAoB,GAAG,CAAC,MAAM,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,IAAI;AAChF,YAAA,MAAM,CAAC,EAAE,EAAE,oBAAoB,CAAC;YAChC,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,OAAO,CAAC,0BAA0B,CAAC,CAAC;QAChE;QAAE,OAAO,KAAK,EAAE;AACd,YAAA,IAAI,CAAC,YAAY,CAAC,gBAAgB,CAAC,KAAK,CAAC;QAC3C;IACF;+GA1HW,kBAAkB,EAAA,IAAA,EAAA,CAAA,EAAA,KAAA,EAAA,EAAA,CAAA,gBAAA,EAAA,EAAA,EAAA,KAAA,EAAA,EAAA,CAAA,sBAAA,EAAA,EAAA,EAAA,KAAA,EAAA,EAAA,CAAA,YAAA,EAAA,EAAA,EAAA,KAAA,EAAA,EAAA,CAAA,YAAA,EAAA,CAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA,CAAA;mHAAlB,kBAAkB,EAAA,CAAA,CAAA;;4FAAlB,kBAAkB,EAAA,UAAA,EAAA,CAAA;kBAD9B;;;MCVY,mBAAmB,CAAA;AAC9B,IAAA,WAAA,CAAoB,kBAAsC,EAAA;QAAtC,IAAA,CAAA,kBAAkB,GAAlB,kBAAkB;IAAuB;AAE7D,IAAA,WAAW,CAAC,KAA6B,EAAA;AACvC,QAAA,MAAM,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC,WAAW,IAAI,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,WAAW;QACtE,OAAO,IAAI,CAAC,kBAAkB,CAAC,iBAAiB,CAAC,MAAM,CAAC;IAC1D;+GANW,mBAAmB,EAAA,IAAA,EAAA,CAAA,EAAA,KAAA,EAAAA,kBAAA,EAAA,CAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA,CAAA;mHAAnB,mBAAmB,EAAA,CAAA,CAAA;;4FAAnB,mBAAmB,EAAA,UAAA,EAAA,CAAA;kBAD/B;;;MCiDY,oBAAoB,CAAA;AAgB/B,IAAA,WAAA,CACU,KAAqB,EACrB,iBAAqC,EACtC,iBAA2C,EAAA;QAF1C,IAAA,CAAA,KAAK,GAAL,KAAK;QACL,IAAA,CAAA,iBAAiB,GAAjB,iBAAiB;QAClB,IAAA,CAAA,iBAAiB,GAAjB,iBAAiB;QAlB1B,IAAA,CAAA,WAAW,GAAG,oBAAoB;QAClC,IAAA,CAAA,aAAa,GAAG,sBAAsB;AACtC,QAAA,IAAA,CAAA,QAAQ,GAAW,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE;AACjE,QAAA,IAAA,CAAA,OAAO,GAAG,IAAI,eAAe,CAAiB,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC;QAC1F,IAAA,CAAA,WAAW,GAAG,IAAI,CAAC,iBAAiB,CAAC,cAAc,CAAC,IAAI,CAAC,OAAO,CAAC;AACjE,QAAA,IAAA,CAAA,cAAc,GAAgC,IAAI,CAChD,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,IAAI,CAAC,iBAAiB,CAAC,QAAQ,CAAC,CAAC,CAAC,CAClE;AACD,QAAA,IAAA,CAAA,eAAe,GAAyB;YACtC,UAAU,EAAE,IAAI,CAAC,QAAQ;AACzB,YAAA,cAAc,EAAE,IAAI;AACpB,YAAA,cAAc,EAAE;SACO;IAOtB;IAEH,mBAAmB,GAAA;QACjB,IAAI,CAAC,iBAAiB,CAAC,eAAe,CAAC,IAAI,CAAC,QAAQ,CAAC;IACvD;AAEA,IAAA,QAAQ,CAAC,SAAqB,EAAA;AAC5B,QAAA,IAAI,CAAC,iBAAiB,CAAC,eAAe,CAAC,SAAS,CAAC;IACnD;AAEA,IAAA,QAAQ,CAAC,SAAqB,EAAA;AAC5B,QAAA,IAAI,CAAC,iBAAiB,CAAC,eAAe,CAAC,SAAS,CAAC;IACnD;+GAhCW,oBAAoB,EAAA,IAAA,EAAA,CAAA,EAAA,KAAA,EAAAC,IAAA,CAAA,cAAA,EAAA,EAAA,EAAA,KAAA,EAAAC,kBAAA,EAAA,EAAA,EAAA,KAAA,EAAAC,EAAA,CAAA,wBAAA,EAAA,CAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA,CAAA;AAApB,IAAA,SAAA,IAAA,CAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,IAAA,EAAA,oBAAoB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,iBAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,ECrDjC,ylGA+FA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,ED9DI,sBAAsB,0JACtB,aAAa,EAAA,QAAA,EAAA,WAAA,EAAA,MAAA,EAAA,CAAA,SAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EACb,qBAAqB,EAAA,QAAA,EAAA,6BAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EACrB,IAAI,EAAA,QAAA,EAAA,QAAA,EAAA,MAAA,EAAA,CAAA,MAAA,EAAA,UAAA,EAAA,UAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EACJ,kBAAkB,EAAA,QAAA,EAAA,gBAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAClB,cAAc,keACd,yBAAyB,EAAA,QAAA,EAAA,yCAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EACzB,iBAAiB,EAAA,QAAA,EAAA,uBAAA,EAAA,MAAA,EAAA,CAAA,QAAA,EAAA,aAAA,EAAA,cAAA,EAAA,OAAA,EAAA,WAAA,EAAA,YAAA,CAAA,EAAA,OAAA,EAAA,CAAA,iBAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EACjB,qBAAqB,EAAA,QAAA,EAAA,iCAAA,EAAA,MAAA,EAAA,CAAA,MAAA,EAAA,QAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EACrB,OAAO,EAAA,QAAA,EAAA,WAAA,EAAA,MAAA,EAAA,CAAA,OAAA,EAAA,SAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EACP,gBAAgB,ghBAChB,qBAAqB,EAAA,QAAA,EAAA,iCAAA,EAAA,MAAA,EAAA,CAAA,MAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EACrB,qBAAqB,EAAA,QAAA,EAAA,mBAAA,EAAA,MAAA,EAAA,CAAA,KAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EACrB,uBAAuB,EAAA,QAAA,EAAA,qCAAA,EAAA,MAAA,EAAA,CAAA,OAAA,EAAA,MAAA,EAAA,UAAA,CAAA,EAAA,OAAA,EAAA,CAAA,OAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EACvB,mBAAmB,EAAA,QAAA,EAAA,oBAAA,EAAA,MAAA,EAAA,CAAA,MAAA,EAAA,OAAA,EAAA,UAAA,EAAA,YAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,MAAA,EAAA,IAAA,EACnB,gBAAgB,6CAChB,QAAQ,EAAA,IAAA,EAAA,SAAA,EAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,KAAA,EAAA,CAAA,CAAA;;4FAIC,oBAAoB,EAAA,UAAA,EAAA,CAAA;kBAxBhC,SAAS;AAEE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,iBAAiB,EAAA,OAAA,EAClB;wBACP,sBAAsB;wBACtB,aAAa;wBACb,qBAAqB;wBACrB,IAAI;wBACJ,kBAAkB;wBAClB,cAAc;wBACd,yBAAyB;wBACzB,iBAAiB;wBACjB,qBAAqB;wBACrB,OAAO;wBACP,gBAAgB;wBAChB,qBAAqB;wBACrB,qBAAqB;wBACrB,uBAAuB;wBACvB,mBAAmB;wBACnB,gBAAgB;wBAChB;qBACD,EAAA,eAAA,EACgB,uBAAuB,CAAC,KAAK,EAAA,QAAA,EAAA,ylGAAA,EAAA;;;MEZnC,iBAAiB,CAAA;+GAAjB,iBAAiB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,QAAA,EAAA,CAAA,CAAA;AAAjB,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,iBAAiB,YAzB1B,UAAU;YACV,YAAY;YACZ,YAAY;YACZ,eAAe;YACf,sBAAsB;YACtB,gBAAgB;YAChB,aAAa;AACb,YAAA,oBAAoB,aAEZ,oBAAoB,CAAA,EAAA,CAAA,CAAA;AAgBnB,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,iBAAiB,EAAA,SAAA,EAfjB;YACT,kBAAkB;YAClB,gBAAgB;YAChB,mBAAmB;AACnB,YAAA,SAAS,CAAC;gBACR,OAAO,EAAE,WAAW,CAAC,MAAM;AAC3B,gBAAA,IAAI,EAAE,aAAa;AACnB,gBAAA,SAAS,EAAE,oBAAoB;AAC/B,gBAAA,KAAK,EAAE,OAAO,CAAC,aAAa,CAAC;AAC7B,gBAAA,IAAI,EAAE,aAAa;gBACnB,WAAW,EAAE,CAAC,mBAAmB,CAAC;AAClC,gBAAA,QAAQ,EAAE;aACX;AACF,SAAA,EAAA,OAAA,EAAA,CAvBC,UAAU;YACV,YAAY;YACZ,YAAY;YACZ,eAAe;YACf,sBAAsB;YACtB,gBAAgB;YAChB,aAAa;YACb,oBAAoB,CAAA,EAAA,CAAA,CAAA;;4FAkBX,iBAAiB,EAAA,UAAA,EAAA,CAAA;kBA3B7B,QAAQ;AAAC,YAAA,IAAA,EAAA,CAAA;AACR,oBAAA,OAAO,EAAE;wBACP,UAAU;wBACV,YAAY;wBACZ,YAAY;wBACZ,eAAe;wBACf,sBAAsB;wBACtB,gBAAgB;wBAChB,aAAa;wBACb;AACD,qBAAA;oBACD,OAAO,EAAE,CAAC,oBAAoB,CAAC;AAC/B,oBAAA,SAAS,EAAE;wBACT,kBAAkB;wBAClB,gBAAgB;wBAChB,mBAAmB;AACnB,wBAAA,SAAS,CAAC;4BACR,OAAO,EAAE,WAAW,CAAC,MAAM;AAC3B,4BAAA,IAAI,EAAE,aAAa;AACnB,4BAAA,SAAS,EAAE,oBAAoB;AAC/B,4BAAA,KAAK,EAAE,OAAO,CAAC,aAAa,CAAC;AAC7B,4BAAA,IAAI,EAAE,aAAa;4BACnB,WAAW,EAAE,CAAC,mBAAmB,CAAC;AAClC,4BAAA,QAAQ,EAAE;yBACX;AACF;AACF,iBAAA;;;ACtCD;;AAEG;;;;"}
|
|
1
|
+
{"version":3,"file":"c8y-ngx-components-diagnostics.mjs","sources":["../../diagnostics/diagnostics.service.ts","../../diagnostics/diagnostics-tab.guard.ts","../../diagnostics/diagnostics.component.ts","../../diagnostics/diagnostics.component.html","../../diagnostics/diagnostics.module.ts","../../diagnostics/c8y-ngx-components-diagnostics.ts"],"sourcesContent":["import { Observable } from 'rxjs';\nimport { Injectable } from '@angular/core';\nimport {\n IManagedObject,\n IResultList,\n InventoryBinaryService,\n IOperation,\n OperationService,\n OperationStatus\n} from '@c8y/client';\nimport { gettext } from '@c8y/ngx-components/gettext';\nimport { AlertService, ModalService } from '@c8y/ngx-components';\nimport { assign } from 'lodash-es';\nimport { switchMap } from 'rxjs/operators';\n\n@Injectable()\nexport class DiagnosticsService {\n readonly fragment = 'c8y_DiagnosticReport';\n constructor(\n private operationService: OperationService,\n private inventoryBinary: InventoryBinaryService,\n private modalService: ModalService,\n private alertService: AlertService\n ) {}\n\n isSupportedDevice(device): boolean {\n const supportedOperations = (device && device.c8y_SupportedOperations) || [];\n return supportedOperations.includes(this.fragment);\n }\n\n getOperations$(device$: Observable<IManagedObject>): Observable<IResultList<IOperation>> {\n return device$.pipe(\n switchMap(device =>\n this.operationService.list({\n deviceId: device.id,\n fragmentType: this.fragment,\n dateFrom: new Date(0).toISOString(),\n dateTo: new Date(Date.now()).toISOString(),\n revert: true,\n pageSize: 10,\n withTotalPages: true\n })\n )\n );\n }\n\n async createOperation(deviceId: string) {\n const operation = {\n deviceId,\n description: gettext('Diagnostic file request'),\n [this.fragment]: {}\n };\n try {\n await this.operationService.create(operation);\n this.alertService.success(gettext('Diagnostic file request sent.'));\n } catch (error) {\n this.alertService.addServerFailure(error);\n }\n }\n\n async deleteOperation(operation: IOperation) {\n try {\n const result = await this.modalService.confirm(\n gettext('Delete diagnostic file'),\n gettext('You are about to delete this diagnostic file. Do you want to proceed?'),\n 'danger',\n {\n ok: gettext('Delete'),\n cancel: gettext('Cancel')\n }\n );\n\n if (result) {\n this.deleteDiagnosticsBinary(operation);\n }\n } catch (error) {\n // Do nothing\n }\n }\n\n async cancelOperation(operation: IOperation) {\n try {\n const operationAfterUpdate = (\n await this.operationService.update({\n id: operation.id,\n status: OperationStatus.FAILED,\n failureReason: gettext('Operation cancelled by user.')\n })\n ).data;\n assign(operation, operationAfterUpdate);\n this.alertService.success(gettext('Diagnostic file request cancelled.'));\n } catch (ex) {\n this.alertService.addServerFailure(ex);\n }\n }\n\n private getOperation(op: IOperation) {\n if (!op) {\n return null;\n }\n return op && op[this.fragment];\n }\n\n private async deleteDiagnosticsBinary(op: IOperation) {\n const operation = this.getOperation(op);\n if (operation && operation.file) {\n const { file } = operation;\n try {\n const binaryId = this.inventoryBinary.getIdFromUrl(file);\n const result = await this.inventoryBinary.delete(binaryId);\n if (result) {\n this.deleteDiagnosticsFragment(op);\n }\n } catch (err) {\n if (err.res.status === 404) {\n // In case the file is already deleted via other means we want to delete the fragment\n this.deleteDiagnosticsFragment(op);\n } else {\n const msg = gettext('Could not delete the diagnostic file.');\n this.alertService.danger(msg);\n }\n }\n }\n }\n\n private async deleteDiagnosticsFragment(op: IOperation) {\n const deleteOp = {\n id: op.id,\n status: op.status,\n [this.fragment]: null\n };\n try {\n const operationAfterUpdate = (await this.operationService.update(deleteOp)).data;\n assign(op, operationAfterUpdate);\n this.alertService.success(gettext('Diagnostic file deleted.'));\n } catch (error) {\n this.alertService.addServerFailure(error);\n }\n }\n}\n","import { DiagnosticsService } from './diagnostics.service';\nimport { Injectable } from '@angular/core';\nimport { ActivatedRouteSnapshot } from '@angular/router';\n\n@Injectable()\nexport class DiagnosticsTabGuard {\n constructor(private diagnosticsService: DiagnosticsService) {}\n\n canActivate(route: ActivatedRouteSnapshot) {\n const device = route.data.contextData || route.parent.data.contextData;\n return this.diagnosticsService.isSupportedDevice(device);\n }\n}\n","import { DiagnosticsService } from './diagnostics.service';\nimport { ActivatedRoute } from '@angular/router';\nimport { Component, ChangeDetectionStrategy } from '@angular/core';\nimport { BehaviorSubject, pipe } from 'rxjs';\nimport { map } from 'rxjs/operators';\nimport {\n ForOfRealtimeOptions,\n operationStatusClasses,\n operationStatusIcons,\n OperationRealtimeService,\n ForOfFilterPipe,\n ActionBarItemComponent,\n IconDirective,\n C8yTranslateDirective,\n ListGroupComponent,\n ForOfDirective,\n ListItemTimelineComponent,\n ListItemComponent,\n ListItemIconComponent,\n ListItemBodyComponent,\n ListItemActionComponent,\n EmptyStateComponent,\n C8yTranslatePipe,\n DatePipe\n} from '@c8y/ngx-components';\nimport { IManagedObject, IOperation } from '@c8y/client';\nimport { NgIf, NgClass } from '@angular/common';\nimport { TooltipDirective } from 'ngx-bootstrap/tooltip';\nimport { FileDownloadComponent } from '@c8y/ngx-components/repository/shared';\n@Component({\n templateUrl: './diagnostics.component.html',\n selector: 'c8y-diagnostics',\n imports: [\n ActionBarItemComponent,\n IconDirective,\n C8yTranslateDirective,\n NgIf,\n ListGroupComponent,\n ForOfDirective,\n ListItemTimelineComponent,\n ListItemComponent,\n ListItemIconComponent,\n NgClass,\n TooltipDirective,\n ListItemBodyComponent,\n FileDownloadComponent,\n ListItemActionComponent,\n EmptyStateComponent,\n C8yTranslatePipe,\n DatePipe\n ],\n changeDetection: ChangeDetectionStrategy.Eager\n})\nexport class DiagnosticsComponent {\n statusIcons = operationStatusIcons;\n statusClasses = operationStatusClasses;\n deviceId: string = this.route.snapshot.parent.data.contextData.id;\n device$ = new BehaviorSubject<IManagedObject>(this.route.snapshot.parent.data.contextData);\n operations$ = this.diagnosticService.getOperations$(this.device$);\n operationsPipe: ForOfFilterPipe<IOperation> = pipe(\n map(ops => ops.filter(op => op[this.diagnosticService.fragment]))\n );\n realtimeOptions: ForOfRealtimeOptions = {\n entityOrId: this.deviceId,\n removeOnUpdate: true,\n insertOnUpdate: true\n } as ForOfRealtimeOptions;\n operationCount: number;\n\n constructor(\n private route: ActivatedRoute,\n private diagnosticService: DiagnosticsService,\n public operationRealtime: OperationRealtimeService\n ) {}\n\n onDiagnosticRequest() {\n this.diagnosticService.createOperation(this.deviceId);\n }\n\n onDelete(operation: IOperation) {\n this.diagnosticService.deleteOperation(operation);\n }\n\n onCancel(operation: IOperation) {\n this.diagnosticService.cancelOperation(operation);\n }\n}\n","<c8y-action-bar-item [placement]=\"'right'\">\n <button\n class=\"btn btn-link\"\n type=\"button\"\n title=\"{{ 'Request diagnostic file' | translate }}\"\n (click)=\"onDiagnosticRequest()\"\n >\n <i c8yIcon=\"stethoscope\"></i>\n <span translate>Request diagnostic file</span>\n </button>\n</c8y-action-bar-item>\n\n<div\n class=\"page-sticky-header hidden-xs c8y-list__item c8y-list--timeline\"\n *ngIf=\"operationCount > 0\"\n>\n <div class=\"d-flex\">\n <div class=\"c8y-list--timeline__item__date a-s-center\">\n <label>{{ 'Date' | translate }}</label>\n </div>\n <div class=\"c8y-list__item__block flex-grow\">\n <div class=\"c8y-list__item__icon\">\n <i class=\"p-l-24\"></i>\n </div>\n <div class=\"c8y-list__item__body\">\n <div class=\"content-flex-40\">\n <div class=\"col-4\">{{ 'Event' | translate }}</div>\n <div class=\"col-5 m-l-8\">{{ 'File' | translate }}</div>\n </div>\n </div>\n </div>\n </div>\n</div>\n\n<c8y-list-group>\n <ng-template\n c8yFor\n let-operation\n [c8yForOf]=\"operations$\"\n [c8yForPipe]=\"operationsPipe\"\n [c8yForRealtime]=\"operationRealtime\"\n [c8yForRealtimeOptions]=\"realtimeOptions\"\n (c8yForCount)=\"operationCount = $event\"\n >\n <c8y-li-timeline>\n {{ operation.creationTime | c8yDate }}\n <c8y-li>\n <c8y-li-icon>\n <i\n [c8yIcon]=\"statusIcons[operation.status]\"\n [ngClass]=\"statusClasses[operation.status]\"\n [tooltip]=\"operation.status?.toString() | translate\"\n ></i>\n </c8y-li-icon>\n <c8y-li-body class=\"content-flex-40\">\n <div class=\"col-4\">\n <p class=\"text-truncate-wrap\" title=\"{{ operation.description | translate }}\">\n {{ operation.description | translate }}\n </p>\n </div>\n <div class=\"col-5\" *ngIf=\"operation.c8y_DiagnosticReport?.file\">\n <div class=\"text-truncate-wrap m-t-xs-8\">\n <span class=\"text-label-small visible-xs\" translate>File</span>\n <span title=\"{{ operation.c8y_DiagnosticReport.file }}\">\n <c8y-file-download\n url=\"{{ operation.c8y_DiagnosticReport.file }}\"\n ></c8y-file-download>\n </span>\n </div>\n </div>\n </c8y-li-body>\n <c8y-li-action\n (click)=\"onCancel(operation)\"\n *ngIf=\"operation.status === 'PENDING'\"\n icon=\"times\"\n label=\"{{ 'Cancel' | translate }}\"\n ></c8y-li-action>\n <c8y-li-action\n (click)=\"onDelete(operation)\"\n *ngIf=\"operation.status === 'SUCCESSFUL'\"\n icon=\"delete\"\n label=\"{{ 'Delete' | translate }}\"\n ></c8y-li-action>\n </c8y-li>\n </c8y-li-timeline>\n </ng-template>\n</c8y-list-group>\n\n<!-- EMPTY STATE -->\n\n<c8y-ui-empty-state\n *ngIf=\"operationCount === 0\"\n [icon]=\"'stethoscope'\"\n [title]=\"'No diagnostic files available.' | translate\"\n></c8y-ui-empty-state>\n","import { DiagnosticsTabGuard } from './diagnostics-tab.guard';\nimport { gettext } from '@c8y/ngx-components/gettext';\nimport { ListGroupModule, CoreModule, hookRoute, ViewContext } from '@c8y/ngx-components';\nimport { RouterModule } from '@angular/router';\nimport { DiagnosticsService } from './diagnostics.service';\nimport { DiagnosticsComponent } from './diagnostics.component';\nimport { NgModule } from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { TooltipModule } from 'ngx-bootstrap/tooltip';\nimport { BsDropdownModule, BsDropdownConfig } from 'ngx-bootstrap/dropdown';\nimport { SharedRepositoryModule } from '@c8y/ngx-components/repository/shared';\n\n@NgModule({\n imports: [\n CoreModule,\n RouterModule,\n CommonModule,\n ListGroupModule,\n SharedRepositoryModule,\n BsDropdownModule,\n TooltipModule,\n DiagnosticsComponent\n ],\n exports: [DiagnosticsComponent],\n providers: [\n DiagnosticsService,\n BsDropdownConfig,\n DiagnosticsTabGuard,\n hookRoute({\n context: ViewContext.Device,\n path: 'diagnostics',\n component: DiagnosticsComponent,\n label: gettext('Diagnostics'),\n icon: 'stethoscope',\n canActivate: [DiagnosticsTabGuard],\n priority: 200\n })\n ]\n})\nexport class DiagnosticsModule {}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":["i1.DiagnosticsService","i1","i2.DiagnosticsService","i3"],"mappings":"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"}
|
|
@@ -755,7 +755,7 @@ class EchartsOptionsService {
|
|
|
755
755
|
/** True while the chart shows only alarms/events (carrier path); gates the resize-driven row reflow. */
|
|
756
756
|
this.isAlarmEventOnlyChart = false;
|
|
757
757
|
}
|
|
758
|
-
getChartOptions(datapointsWithValues, timeRange, showSplitLines, events, alarms, displayOptions, selectedTimeRange, aggregatedDatapoint, sliderZoomUsed = false) {
|
|
758
|
+
getChartOptions(datapointsWithValues, timeRange, showSplitLines, events, alarms, displayOptions, selectedTimeRange, aggregatedDatapoint, sliderZoomUsed = false, aggregationIntervalMs) {
|
|
759
759
|
displayOptions = {
|
|
760
760
|
numberOfDecimalPlaces: CHART_DISPLAY_OPTION_DEFAULTS.numberOfDecimalPlaces,
|
|
761
761
|
...displayOptions
|
|
@@ -786,6 +786,12 @@ class EchartsOptionsService {
|
|
|
786
786
|
if (displayOptions.showOnlyAlarmsOrEvents) {
|
|
787
787
|
return this.getAlarmEventOnlyChartOptions(alarms, events, timeRange, displayOptions);
|
|
788
788
|
}
|
|
789
|
+
const aggregatedTimestamps = Object.keys(aggregatedDatapoint?.values || {}).map(date => new Date(date).valueOf());
|
|
790
|
+
const xAxisMin = aggregatedTimestamps.length > 0
|
|
791
|
+
? Math.min(aggregatedTimestamps.reduce((min, ts) => Math.min(min, ts)), new Date(timeRange.dateFrom).valueOf())
|
|
792
|
+
: new Date(timeRange.dateFrom).valueOf() - intervalInMs;
|
|
793
|
+
const xAxisMax = new Date(timeRange.dateTo).valueOf();
|
|
794
|
+
const paddedAggregatedDatapoint = this.padAggregatedValuesToAxisExtent(aggregatedDatapoint, xAxisMin, xAxisMax, aggregationIntervalMs);
|
|
789
795
|
return {
|
|
790
796
|
grid: {
|
|
791
797
|
containLabel: true, // axis labels are taken into account to calculate graph grid
|
|
@@ -873,12 +879,8 @@ class EchartsOptionsService {
|
|
|
873
879
|
show: false
|
|
874
880
|
},
|
|
875
881
|
xAxis: {
|
|
876
|
-
min:
|
|
877
|
-
|
|
878
|
-
.map(date => new Date(date).valueOf())
|
|
879
|
-
.sort((a, b) => a - b)[0], new Date(timeRange.dateFrom).valueOf())
|
|
880
|
-
: new Date(timeRange.dateFrom).valueOf() - intervalInMs,
|
|
881
|
-
max: new Date(timeRange.dateTo).valueOf(),
|
|
882
|
+
min: xAxisMin,
|
|
883
|
+
max: xAxisMax,
|
|
882
884
|
type: 'time',
|
|
883
885
|
animation: false,
|
|
884
886
|
axisPointer: {
|
|
@@ -934,7 +936,7 @@ class EchartsOptionsService {
|
|
|
934
936
|
},
|
|
935
937
|
yAxis,
|
|
936
938
|
series: [
|
|
937
|
-
this.getAggregatedSeries(
|
|
939
|
+
this.getAggregatedSeries(paddedAggregatedDatapoint || null, displayOptions),
|
|
938
940
|
...this.getChartSeries(expandedDatapoints, events, alarms, displayOptions)
|
|
939
941
|
]
|
|
940
942
|
};
|
|
@@ -1746,83 +1748,46 @@ class EchartsOptionsService {
|
|
|
1746
1748
|
}
|
|
1747
1749
|
];
|
|
1748
1750
|
}
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
|
|
1768
|
-
|
|
1769
|
-
|
|
1770
|
-
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
-
|
|
1789
|
-
{
|
|
1790
|
-
coord: coordCreationTime,
|
|
1791
|
-
name: item.type,
|
|
1792
|
-
itemType: item.type,
|
|
1793
|
-
itemStyle: {
|
|
1794
|
-
color: item['color']
|
|
1795
|
-
},
|
|
1796
|
-
symbol: 'circle',
|
|
1797
|
-
symbolSize: 24
|
|
1798
|
-
},
|
|
1799
|
-
{
|
|
1800
|
-
coord: coordCreationTime,
|
|
1801
|
-
name: item.type,
|
|
1802
|
-
itemType: item.type,
|
|
1803
|
-
itemStyle: { color: 'white' },
|
|
1804
|
-
symbol: ICONS_MAP[item.severity],
|
|
1805
|
-
symbolSize: 16
|
|
1806
|
-
},
|
|
1807
|
-
{
|
|
1808
|
-
coord: coordLastUpdatedTime,
|
|
1809
|
-
name: item.type,
|
|
1810
|
-
itemType: item.type,
|
|
1811
|
-
itemStyle: {
|
|
1812
|
-
color: item['color']
|
|
1813
|
-
},
|
|
1814
|
-
symbol: 'circle',
|
|
1815
|
-
symbolSize: 24
|
|
1816
|
-
},
|
|
1817
|
-
{
|
|
1818
|
-
coord: coordLastUpdatedTime,
|
|
1819
|
-
name: item.type,
|
|
1820
|
-
itemType: item.type,
|
|
1821
|
-
itemStyle: { color: 'white' },
|
|
1822
|
-
symbol: ICONS_MAP[item.severity],
|
|
1823
|
-
symbolSize: 16
|
|
1824
|
-
}
|
|
1825
|
-
];
|
|
1751
|
+
const creationMarks = [
|
|
1752
|
+
{
|
|
1753
|
+
coord: coordCreationTime,
|
|
1754
|
+
name: item.type,
|
|
1755
|
+
itemType: item.type,
|
|
1756
|
+
itemStyle: { color: item['color'] },
|
|
1757
|
+
symbol: 'circle',
|
|
1758
|
+
symbolSize: 24
|
|
1759
|
+
},
|
|
1760
|
+
{
|
|
1761
|
+
coord: coordCreationTime,
|
|
1762
|
+
name: item.type,
|
|
1763
|
+
itemType: item.type,
|
|
1764
|
+
itemStyle: { color: 'white' },
|
|
1765
|
+
symbol: ICONS_MAP[item.severity],
|
|
1766
|
+
symbolSize: 16
|
|
1767
|
+
}
|
|
1768
|
+
];
|
|
1769
|
+
if (!item['lastUpdated']) {
|
|
1770
|
+
return creationMarks;
|
|
1771
|
+
}
|
|
1772
|
+
return [
|
|
1773
|
+
...creationMarks,
|
|
1774
|
+
{
|
|
1775
|
+
coord: coordLastUpdatedTime,
|
|
1776
|
+
name: item.type,
|
|
1777
|
+
itemType: item.type,
|
|
1778
|
+
itemStyle: { color: item['color'] },
|
|
1779
|
+
symbol: 'circle',
|
|
1780
|
+
symbolSize: 24
|
|
1781
|
+
},
|
|
1782
|
+
{
|
|
1783
|
+
coord: coordLastUpdatedTime,
|
|
1784
|
+
name: item.type,
|
|
1785
|
+
itemType: item.type,
|
|
1786
|
+
itemStyle: { color: 'white' },
|
|
1787
|
+
symbol: isCleared ? ICONS_MAP.CLEARED : ICONS_MAP[item.severity],
|
|
1788
|
+
symbolSize: 16
|
|
1789
|
+
}
|
|
1790
|
+
];
|
|
1826
1791
|
}
|
|
1827
1792
|
/**
|
|
1828
1793
|
* This method creates a markLine on the chart which represents the line between every alarm or event on the chart.
|
|
@@ -1844,7 +1809,7 @@ class EchartsOptionsService {
|
|
|
1844
1809
|
}
|
|
1845
1810
|
]);
|
|
1846
1811
|
}
|
|
1847
|
-
if (item.creationTime === item['lastUpdated']) {
|
|
1812
|
+
if (!item['lastUpdated'] || item.creationTime === item['lastUpdated']) {
|
|
1848
1813
|
return acc.concat([
|
|
1849
1814
|
{
|
|
1850
1815
|
xAxis: item.creationTime,
|
|
@@ -1872,6 +1837,40 @@ class EchartsOptionsService {
|
|
|
1872
1837
|
}
|
|
1873
1838
|
}, []);
|
|
1874
1839
|
}
|
|
1840
|
+
/**
|
|
1841
|
+
* The slider's data shadow spreads the shadow series over its own data extent instead of
|
|
1842
|
+
* the axis extent (echarts SliderZoomView limitation. Without alignment, a series covering only part of
|
|
1843
|
+
* the time range is stretched across the whole slider. Padding the aggregated series with
|
|
1844
|
+
* empty boundary values makes its extent match the axis, so ranges without data render as
|
|
1845
|
+
* empty in the slider preview, mirroring the chart.
|
|
1846
|
+
*/
|
|
1847
|
+
padAggregatedValuesToAxisExtent(aggregatedDatapoint, axisMin, axisMax, aggregationIntervalMs) {
|
|
1848
|
+
const values = aggregatedDatapoint?.values || {};
|
|
1849
|
+
const entries = Object.entries(values).sort(([a], [b]) => new Date(a).valueOf() - new Date(b).valueOf());
|
|
1850
|
+
// series with a single value or none are dropped by getSingleSeries — nothing to align
|
|
1851
|
+
if (entries.length <= 1) {
|
|
1852
|
+
return aggregatedDatapoint || null;
|
|
1853
|
+
}
|
|
1854
|
+
const dataMin = new Date(entries[0][0]).valueOf();
|
|
1855
|
+
const [lastDate, lastValue] = entries[entries.length - 1];
|
|
1856
|
+
const dataMax = new Date(lastDate).valueOf();
|
|
1857
|
+
const emptyValue = [{ min: null, max: null }];
|
|
1858
|
+
const lastBucketEnd = dataMax + (aggregationIntervalMs ?? 0);
|
|
1859
|
+
const trailingValues = axisMax <= lastBucketEnd
|
|
1860
|
+
? { [new Date(axisMax).toISOString()]: lastValue }
|
|
1861
|
+
: {
|
|
1862
|
+
...(lastBucketEnd > dataMax && { [new Date(lastBucketEnd).toISOString()]: lastValue }),
|
|
1863
|
+
[new Date(axisMax).toISOString()]: emptyValue
|
|
1864
|
+
};
|
|
1865
|
+
return {
|
|
1866
|
+
...aggregatedDatapoint,
|
|
1867
|
+
values: {
|
|
1868
|
+
...(axisMin < dataMin && { [new Date(axisMin).toISOString()]: emptyValue }),
|
|
1869
|
+
...values,
|
|
1870
|
+
...(axisMax > dataMax && trailingValues)
|
|
1871
|
+
}
|
|
1872
|
+
};
|
|
1873
|
+
}
|
|
1875
1874
|
/**
|
|
1876
1875
|
* Builds the display name of a datapoint. Passing the whole datapoint lets `translateDatapointLabel`
|
|
1877
1876
|
* apply its `fragment → series` fallback, so an unlabeled datapoint still gets an informative
|
|
@@ -2300,10 +2299,11 @@ class ChartRealtimeService {
|
|
|
2300
2299
|
if (!alarmOrEvent)
|
|
2301
2300
|
return;
|
|
2302
2301
|
const matchingConfig = activeAlarmsOrEvents.find(aOrE => aOrE.filters.type === alarmOrEvent.type && aOrE.__target?.id === alarmOrEvent.source?.id);
|
|
2303
|
-
if (matchingConfig) {
|
|
2304
|
-
|
|
2305
|
-
alarmOrEvent['selectedDatapoint'] = matchingConfig.selectedDatapoint;
|
|
2302
|
+
if (!matchingConfig) {
|
|
2303
|
+
return;
|
|
2306
2304
|
}
|
|
2305
|
+
alarmOrEvent['color'] = matchingConfig.color;
|
|
2306
|
+
alarmOrEvent['selectedDatapoint'] = matchingConfig.selectedDatapoint;
|
|
2307
2307
|
if ('severity' in alarmOrEvent) {
|
|
2308
2308
|
// Alarm
|
|
2309
2309
|
const existingIdx = this.currentAlarms.findIndex(a => a.id === alarmOrEvent.id);
|
|
@@ -2867,6 +2867,11 @@ class ChartsComponent {
|
|
|
2867
2867
|
[aggregationType.HOURLY]: '60m',
|
|
2868
2868
|
[aggregationType.DAILY]: '1d'
|
|
2869
2869
|
};
|
|
2870
|
+
this.AGGREGATION_TYPE_MS = {
|
|
2871
|
+
[aggregationType.MINUTELY]: 60_000,
|
|
2872
|
+
[aggregationType.HOURLY]: 3_600_000,
|
|
2873
|
+
[aggregationType.DAILY]: 86_400_000
|
|
2874
|
+
};
|
|
2870
2875
|
this.configChangedSubject = new BehaviorSubject(null);
|
|
2871
2876
|
/**
|
|
2872
2877
|
* Deep copy of the config the last reload ran with; content-identical rebuilds are skipped.
|
|
@@ -3707,7 +3712,7 @@ class ChartsComponent {
|
|
|
3707
3712
|
sliderPositionMode,
|
|
3708
3713
|
collapsedDpIds: this.lastCollapsedDpIds,
|
|
3709
3714
|
...this.displayOptions
|
|
3710
|
-
}, undefined, aggregatedDatapoint);
|
|
3715
|
+
}, undefined, aggregatedDatapoint, false, aggregatedDatapoint?.['aggregationIntervalMs']);
|
|
3711
3716
|
}
|
|
3712
3717
|
else {
|
|
3713
3718
|
const cachedTimeRange = this.widgetTimeContextDateRangeService.initialTimeRange();
|
|
@@ -3744,7 +3749,7 @@ class ChartsComponent {
|
|
|
3744
3749
|
...this.displayOptions
|
|
3745
3750
|
},
|
|
3746
3751
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
3747
|
-
timeRange, aggregatedDatapoint, true);
|
|
3752
|
+
timeRange, aggregatedDatapoint, true, aggregatedDatapoint?.['aggregationIntervalMs']);
|
|
3748
3753
|
}
|
|
3749
3754
|
}
|
|
3750
3755
|
/**
|
|
@@ -3899,50 +3904,23 @@ class ChartsComponent {
|
|
|
3899
3904
|
aggregatedDatapoint = aggregatedDatapoint
|
|
3900
3905
|
? aggregatedDatapoint
|
|
3901
3906
|
: this.config?.datapoints?.filter(dp => dp.__active)[0];
|
|
3907
|
+
const { params: aggregationParams, intervalMs: aggregationIntervalMs } = this.resolveSliderAggregation(aggregatedDatapoint, customTimeRange ?? timeRange);
|
|
3902
3908
|
const request = defer(() => this.measurementService.listSeries({
|
|
3903
3909
|
...(customTimeRange ? customTimeRange : timeRange),
|
|
3904
3910
|
source: aggregatedDatapoint.__target?.id || '',
|
|
3905
3911
|
series: [`${aggregatedDatapoint.fragment}.${aggregatedDatapoint.series}`],
|
|
3906
|
-
|
|
3907
|
-
// Falls back to raw data when the zoom level is fine enough that aggregation
|
|
3908
|
-
// would add no value (calculateAutoAggregationInterval returns null).
|
|
3909
|
-
// Non-migrated tenants don't support aggregationFunction/aggregationInterval,
|
|
3910
|
-
// so we map the computed interval to the nearest standard aggregationType.
|
|
3911
|
-
...(this.config.autoAggregation &&
|
|
3912
|
-
(() => {
|
|
3913
|
-
const interval = this.chartHelpersService.calculateAutoAggregationInterval((customTimeRange ?? timeRange).dateFrom, (customTimeRange ?? timeRange).dateTo, this.config.autoAggregation.datapoints);
|
|
3914
|
-
if (!interval)
|
|
3915
|
-
return {};
|
|
3916
|
-
if (this.config.showAdvancedChartOptions) {
|
|
3917
|
-
return {
|
|
3918
|
-
aggregationFunction: aggregatedDatapoint.renderType || 'avg',
|
|
3919
|
-
aggregationInterval: interval
|
|
3920
|
-
};
|
|
3921
|
-
}
|
|
3922
|
-
const aggType = this.chartHelpersService.mapIntervalToAggregationType(interval);
|
|
3923
|
-
return aggType ? { aggregationType: aggType } : {};
|
|
3924
|
-
})()),
|
|
3925
|
-
// Standard aggregation (only when auto aggregation is not active)
|
|
3926
|
-
...(!this.config.autoAggregation &&
|
|
3927
|
-
(this.config.aggregation || customTimeRange) &&
|
|
3928
|
-
(!this.config.showAdvancedChartOptions || aggregatedDatapoint.renderType === 'area') && {
|
|
3929
|
-
aggregationType: customTimeRange
|
|
3930
|
-
? this.getAggregationTypeForTimeRange()
|
|
3931
|
-
: this.config.aggregation
|
|
3932
|
-
}),
|
|
3933
|
-
...(!this.config.autoAggregation &&
|
|
3934
|
-
(this.config.aggregation || customTimeRange) &&
|
|
3935
|
-
this.config.showAdvancedChartOptions &&
|
|
3936
|
-
aggregatedDatapoint.renderType !== 'area' && {
|
|
3937
|
-
aggregationFunction: aggregatedDatapoint.renderType || 'avg',
|
|
3938
|
-
aggregationInterval: this.AGGREGATION_INTERVAL_MAP[(customTimeRange ? this.getAggregationTypeForTimeRange() : this.config.aggregation)]
|
|
3939
|
-
})
|
|
3912
|
+
...aggregationParams
|
|
3940
3913
|
})).pipe(map(res => {
|
|
3941
3914
|
const values = res.data.values || {};
|
|
3942
3915
|
if (res.data.truncated && this.config.dateFrom) {
|
|
3943
3916
|
values[new Date(this.config.dateFrom).toISOString()] = [{ min: null, max: null }];
|
|
3944
3917
|
}
|
|
3945
|
-
return {
|
|
3918
|
+
return {
|
|
3919
|
+
...aggregatedDatapoint,
|
|
3920
|
+
values,
|
|
3921
|
+
truncated: res.data.truncated,
|
|
3922
|
+
aggregationIntervalMs
|
|
3923
|
+
};
|
|
3946
3924
|
}));
|
|
3947
3925
|
return request.pipe(tap((dpsWithValues) => {
|
|
3948
3926
|
if (dpsWithValues['truncated']) {
|
|
@@ -3968,6 +3946,48 @@ class ChartsComponent {
|
|
|
3968
3946
|
return aggregationType.HOURLY;
|
|
3969
3947
|
}
|
|
3970
3948
|
}
|
|
3949
|
+
/**
|
|
3950
|
+
* Resolves the aggregation query params for the slider's series request and the bucket size (ms)
|
|
3951
|
+
*/
|
|
3952
|
+
resolveSliderAggregation(dp, range) {
|
|
3953
|
+
if (this.config.autoAggregation) {
|
|
3954
|
+
const interval = this.chartHelpersService.calculateAutoAggregationInterval(range.dateFrom, range.dateTo, this.config.autoAggregation.datapoints);
|
|
3955
|
+
// raw data — no aggregation, no fixed bucket
|
|
3956
|
+
if (!interval) {
|
|
3957
|
+
return { params: {}, intervalMs: undefined };
|
|
3958
|
+
}
|
|
3959
|
+
if (this.config.showAdvancedChartOptions) {
|
|
3960
|
+
return {
|
|
3961
|
+
params: { aggregationFunction: dp.renderType || 'avg', aggregationInterval: interval },
|
|
3962
|
+
intervalMs: this.intervalStringToMs(interval)
|
|
3963
|
+
};
|
|
3964
|
+
}
|
|
3965
|
+
const aggType = this.chartHelpersService.mapIntervalToAggregationType(interval);
|
|
3966
|
+
return aggType
|
|
3967
|
+
? { params: { aggregationType: aggType }, intervalMs: this.AGGREGATION_TYPE_MS[aggType] }
|
|
3968
|
+
: { params: {}, intervalMs: undefined };
|
|
3969
|
+
}
|
|
3970
|
+
const aggType = this.getAggregationTypeForTimeRange();
|
|
3971
|
+
const intervalMs = this.AGGREGATION_TYPE_MS[aggType];
|
|
3972
|
+
if (this.config.showAdvancedChartOptions && dp.renderType !== 'area') {
|
|
3973
|
+
return {
|
|
3974
|
+
params: {
|
|
3975
|
+
aggregationFunction: dp.renderType || 'avg',
|
|
3976
|
+
aggregationInterval: this.AGGREGATION_INTERVAL_MAP[aggType]
|
|
3977
|
+
},
|
|
3978
|
+
intervalMs
|
|
3979
|
+
};
|
|
3980
|
+
}
|
|
3981
|
+
return { params: { aggregationType: aggType }, intervalMs };
|
|
3982
|
+
}
|
|
3983
|
+
intervalStringToMs(interval) {
|
|
3984
|
+
const match = /^(\d+)(s|m|h|d)$/.exec(interval);
|
|
3985
|
+
if (!match) {
|
|
3986
|
+
return undefined;
|
|
3987
|
+
}
|
|
3988
|
+
const unitMs = { s: 1_000, m: 60_000, h: 3_600_000, d: 86_400_000 };
|
|
3989
|
+
return Number(match[1]) * unitMs[match[2]];
|
|
3990
|
+
}
|
|
3971
3991
|
getSliderPositionMode() {
|
|
3972
3992
|
if ((this.chartViewContext === CHART_VIEW_CONTEXT.DATAPOINT_EXPLORER ||
|
|
3973
3993
|
this.chartViewContext === CHART_VIEW_CONTEXT.WIDGET_CONFIG) &&
|