@c8y/ngx-components 1024.16.19 → 1024.18.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/fesm2022/c8y-ngx-components-ai-agent-chat.mjs +14 -4
- package/fesm2022/c8y-ngx-components-ai-agent-chat.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-context-dashboard.mjs +1 -1
- package/fesm2022/c8y-ngx-components-context-dashboard.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-datapoint-explorer-view.mjs +1 -1
- package/fesm2022/c8y-ngx-components-datapoint-explorer-view.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-repository-configuration.mjs +77 -20
- package/fesm2022/c8y-ngx-components-repository-configuration.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-widgets-definitions-linear-gauge.mjs +4 -3
- package/fesm2022/c8y-ngx-components-widgets-definitions-linear-gauge.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-widgets-implementations-asset-notes.mjs +29 -7
- package/fesm2022/c8y-ngx-components-widgets-implementations-asset-notes.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-widgets-implementations-asset-table.mjs +24 -24
- package/fesm2022/c8y-ngx-components-widgets-implementations-asset-table.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 +159 -75
- package/fesm2022/c8y-ngx-components.mjs.map +1 -1
- package/locales/locales.pot +31 -17
- package/package.json +1 -1
- package/types/c8y-ngx-components-ai-agent-chat.d.ts +8 -1
- package/types/c8y-ngx-components-ai-agent-chat.d.ts.map +1 -1
- package/types/c8y-ngx-components-repository-configuration.d.ts +20 -4
- package/types/c8y-ngx-components-repository-configuration.d.ts.map +1 -1
- package/types/c8y-ngx-components-widgets-definitions-linear-gauge.d.ts.map +1 -1
- package/types/c8y-ngx-components-widgets-implementations-asset-notes.d.ts +7 -0
- package/types/c8y-ngx-components-widgets-implementations-asset-notes.d.ts.map +1 -1
- package/types/c8y-ngx-components.d.ts +80 -23
- package/types/c8y-ngx-components.d.ts.map +1 -1
|
@@ -6,7 +6,7 @@ import * as i3$1 from '@c8y/client';
|
|
|
6
6
|
import { OperationStatus, InventoryBinaryService } from '@c8y/client';
|
|
7
7
|
import { gettext } from '@c8y/ngx-components/gettext';
|
|
8
8
|
import * as i2 from '@c8y/ngx-components';
|
|
9
|
-
import { IconDirective, SelectComponent, C8yTranslatePipe, BottomDrawerRef, AlertService, ValidationPattern, isBinaryFile, C8yTranslateDirective, FormGroupComponent, TypeaheadComponent, ForOfDirective, ListItemComponent, HighlightComponent, FilePickerComponent, MessagesComponent, RequiredInputPlaceholderDirective, Permissions, DatePipe, FilterInputComponent, ActionBarItemComponent, TabsetAriaDirective,
|
|
9
|
+
import { IconDirective, SelectComponent, C8yTranslatePipe, BottomDrawerRef, AlertService, ValidationPattern, isBinaryFile, C8yTranslateDirective, FormGroupComponent, TypeaheadComponent, ForOfDirective, ListItemComponent, HighlightComponent, FilePickerComponent, MessagesComponent, RequiredInputPlaceholderDirective, TextareaAutoresizeDirective, Permissions, EmptyStateComponent, DatePipe, FilterInputComponent, ActionBarItemComponent, TabsetAriaDirective, ResizableGridComponent, hookRoute, ViewContext, DataGridService, BottomDrawerService, ModalService, BuiltInActionType, Status, TitleComponent, BreadcrumbComponent, BreadcrumbItemComponent, HelpComponent, DataGridComponent, EmptyStateContextDirective, GuideDocsComponent, GuideHrefDirective, NavigatorNode, hookNavigator, CoreModule, FormsModule as FormsModule$1 } from '@c8y/ngx-components';
|
|
10
10
|
import { EditorComponent, MonacoEditorMarkerValidatorDirective } from '@c8y/ngx-components/editor';
|
|
11
11
|
import * as i3 from '@c8y/ngx-components/repository/shared';
|
|
12
12
|
import { DeviceConfigurationOperation, RepositoryService, RepositoryType, mimeTypeToEditorLanguage, SharedRepositoryModule, RepositoryItemNameGridColumn, DescriptionGridColumn, FileGridColumn, DeviceTypeGridColumn, TypeGridColumn } from '@c8y/ngx-components/repository/shared';
|
|
@@ -18,8 +18,9 @@ import { has, uniqBy } from 'lodash-es';
|
|
|
18
18
|
import { saveAs } from 'file-saver';
|
|
19
19
|
import { map } from 'rxjs/operators';
|
|
20
20
|
import { pipe } from 'rxjs';
|
|
21
|
+
import { PopoverDirective } from 'ngx-bootstrap/popover';
|
|
21
22
|
import * as i1$3 from 'ngx-bootstrap/tabs';
|
|
22
|
-
import { TabsetComponent, TabDirective, TabsModule } from 'ngx-bootstrap/tabs';
|
|
23
|
+
import { TabsetComponent, TabDirective, TabHeadingDirective, TabsModule } from 'ngx-bootstrap/tabs';
|
|
23
24
|
import * as i1$2 from 'ngx-bootstrap/modal';
|
|
24
25
|
import { TranslateService } from '@ngx-translate/core';
|
|
25
26
|
|
|
@@ -212,7 +213,7 @@ class TextBasedConfigurationComponent {
|
|
|
212
213
|
})).data;
|
|
213
214
|
}
|
|
214
215
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: TextBasedConfigurationComponent, deps: [{ token: i1.ActivatedRoute }, { token: i2.AlertService }, { token: i3.RepositoryService }, { token: DeviceConfigurationService }, { token: i3$1.InventoryService }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
215
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.19", type: TextBasedConfigurationComponent, isStandalone: true, selector: "c8y-text-based-configuration", ngImport: i0, template: "<div\n class=\"d-flex d-col fit-h min-height-0\"\n [formGroup]=\"form\"\n>\n <fieldset class=\"card-block bg-level-1 fit-w\">\n <div class=\"content-flex-50 d-flex a-i-center\">\n <label\n class=\"m-r-8 flex-no-shrink\"\n for=\"textCfgEditorLanguage\"\n translate\n >\n Language\n </label>\n <c8y-select\n aria-label=\"{{ 'Editor language' | translate }}\"\n id=\"textCfgEditorLanguage\"\n [items]=\"editorLanguages\"\n formControlName=\"language\"\n ></c8y-select>\n <div class=\"m-l-auto d-flex\">\n @if (showTextBasedConfigReload) {\n <button\n class=\"btn btn-default btn-sm a-s-center m-t-8 m-b-8\"\n title=\"{{ 'Get configuration from device' | translate }}\"\n type=\"button\"\n (click)=\"reloadConfiguration()\"\n [disabled]=\"reloadingConfig() || savingConfig()\"\n >\n @if (reloadingConfig()) {\n <i\n class=\"m-r-4\"\n c8yIcon=\"refresh\"\n [ngClass]=\"{ 'icon-spin': reloadingConfig() }\"\n ></i>\n }\n @if (!reloadingConfig()) {\n <i\n class=\"m-r-4\"\n c8yIcon=\"
|
|
216
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.19", type: TextBasedConfigurationComponent, isStandalone: true, selector: "c8y-text-based-configuration", ngImport: i0, template: "<div\n class=\"d-flex d-col fit-h min-height-0\"\n [formGroup]=\"form\"\n>\n <fieldset class=\"card-block bg-level-1 fit-w\">\n <div class=\"content-flex-50 d-flex a-i-center\">\n <label\n class=\"m-r-8 flex-no-shrink\"\n for=\"textCfgEditorLanguage\"\n translate\n >\n Language\n </label>\n <c8y-select\n aria-label=\"{{ 'Editor language' | translate }}\"\n id=\"textCfgEditorLanguage\"\n [items]=\"editorLanguages\"\n formControlName=\"language\"\n ></c8y-select>\n <div class=\"m-l-auto d-flex\">\n @if (showTextBasedConfigReload) {\n <button\n class=\"btn btn-default btn-sm a-s-center m-t-8 m-b-8\"\n title=\"{{ 'Get configuration from device' | translate }}\"\n type=\"button\"\n (click)=\"reloadConfiguration()\"\n [disabled]=\"reloadingConfig() || savingConfig()\"\n >\n @if (reloadingConfig()) {\n <i\n class=\"m-r-4\"\n c8yIcon=\"refresh\"\n [ngClass]=\"{ 'icon-spin': reloadingConfig() }\"\n ></i>\n }\n @if (!reloadingConfig()) {\n <i\n class=\"m-r-4\"\n c8yIcon=\"arrow-down\"\n ></i>\n }\n\n {{ 'Get configuration from device' | translate }}\n </button>\n }\n </div>\n </div>\n </fieldset>\n <div class=\"p-relative flex-grow min-height-0\">\n <c8y-editor\n class=\"p-absolute top-0 left-0 fit-w fit-h\"\n formControlName=\"config\"\n [editorOptions]=\"editorOptions()\"\n ></c8y-editor>\n </div>\n @if (latestOperation() !== undefined) {\n <c8y-operation-details\n class=\"bg-level-2 p-0\"\n [operation]=\"latestOperation()\"\n ></c8y-operation-details>\n }\n @if (showTextBasedConfigSave) {\n <div class=\"card-footer flex-no-shrink fit-w separator\">\n <button\n class=\"btn btn-primary\"\n id=\"send-config-btn\"\n type=\"button\"\n (click)=\"updateConfiguration(configControl.value)\"\n [disabled]=\"reloadingConfig() || savingConfig() || !configControl.value\"\n [ngClass]=\"{ 'btn-pending': savingConfig() }\"\n >\n @if (!savingConfig()) {\n <span title=\"{{ 'Send' | translate }}\">\n {{ 'Send configuration to device' | translate }}\n </span>\n }\n @if (savingConfig()) {\n <span title=\"{{ 'Sending\u2026' | translate }}\">\n {{ 'Sending\u2026' | translate }}\n </span>\n }\n </button>\n </div>\n }\n</div>\n", dependencies: [{ kind: "directive", type: IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: EditorComponent, selector: "c8y-editor", inputs: ["editorOptions", "theme"], outputs: ["editorInit"] }, { kind: "component", type: OperationDetailsComponent, selector: "c8y-operation-details", inputs: ["operation"] }, { kind: "component", type: SelectComponent, selector: "c8y-select", inputs: ["placeholder", "items", "selected", "container", "multi", "canSelectWithSpace", "disabled", "autoClose", "insideClick", "required", "canDeselect", "name", "icon", "filterItems"], outputs: ["onSelect", "onDeselect", "onIconClick"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.Eager }); }
|
|
216
217
|
}
|
|
217
218
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: TextBasedConfigurationComponent, decorators: [{
|
|
218
219
|
type: Component,
|
|
@@ -224,7 +225,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImpo
|
|
|
224
225
|
OperationDetailsComponent,
|
|
225
226
|
C8yTranslatePipe,
|
|
226
227
|
SelectComponent
|
|
227
|
-
], changeDetection: ChangeDetectionStrategy.Eager, template: "<div\n class=\"d-flex d-col fit-h min-height-0\"\n [formGroup]=\"form\"\n>\n <fieldset class=\"card-block bg-level-1 fit-w\">\n <div class=\"content-flex-50 d-flex a-i-center\">\n <label\n class=\"m-r-8 flex-no-shrink\"\n for=\"textCfgEditorLanguage\"\n translate\n >\n Language\n </label>\n <c8y-select\n aria-label=\"{{ 'Editor language' | translate }}\"\n id=\"textCfgEditorLanguage\"\n [items]=\"editorLanguages\"\n formControlName=\"language\"\n ></c8y-select>\n <div class=\"m-l-auto d-flex\">\n @if (showTextBasedConfigReload) {\n <button\n class=\"btn btn-default btn-sm a-s-center m-t-8 m-b-8\"\n title=\"{{ 'Get configuration from device' | translate }}\"\n type=\"button\"\n (click)=\"reloadConfiguration()\"\n [disabled]=\"reloadingConfig() || savingConfig()\"\n >\n @if (reloadingConfig()) {\n <i\n class=\"m-r-4\"\n c8yIcon=\"refresh\"\n [ngClass]=\"{ 'icon-spin': reloadingConfig() }\"\n ></i>\n }\n @if (!reloadingConfig()) {\n <i\n class=\"m-r-4\"\n c8yIcon=\"
|
|
228
|
+
], changeDetection: ChangeDetectionStrategy.Eager, template: "<div\n class=\"d-flex d-col fit-h min-height-0\"\n [formGroup]=\"form\"\n>\n <fieldset class=\"card-block bg-level-1 fit-w\">\n <div class=\"content-flex-50 d-flex a-i-center\">\n <label\n class=\"m-r-8 flex-no-shrink\"\n for=\"textCfgEditorLanguage\"\n translate\n >\n Language\n </label>\n <c8y-select\n aria-label=\"{{ 'Editor language' | translate }}\"\n id=\"textCfgEditorLanguage\"\n [items]=\"editorLanguages\"\n formControlName=\"language\"\n ></c8y-select>\n <div class=\"m-l-auto d-flex\">\n @if (showTextBasedConfigReload) {\n <button\n class=\"btn btn-default btn-sm a-s-center m-t-8 m-b-8\"\n title=\"{{ 'Get configuration from device' | translate }}\"\n type=\"button\"\n (click)=\"reloadConfiguration()\"\n [disabled]=\"reloadingConfig() || savingConfig()\"\n >\n @if (reloadingConfig()) {\n <i\n class=\"m-r-4\"\n c8yIcon=\"refresh\"\n [ngClass]=\"{ 'icon-spin': reloadingConfig() }\"\n ></i>\n }\n @if (!reloadingConfig()) {\n <i\n class=\"m-r-4\"\n c8yIcon=\"arrow-down\"\n ></i>\n }\n\n {{ 'Get configuration from device' | translate }}\n </button>\n }\n </div>\n </div>\n </fieldset>\n <div class=\"p-relative flex-grow min-height-0\">\n <c8y-editor\n class=\"p-absolute top-0 left-0 fit-w fit-h\"\n formControlName=\"config\"\n [editorOptions]=\"editorOptions()\"\n ></c8y-editor>\n </div>\n @if (latestOperation() !== undefined) {\n <c8y-operation-details\n class=\"bg-level-2 p-0\"\n [operation]=\"latestOperation()\"\n ></c8y-operation-details>\n }\n @if (showTextBasedConfigSave) {\n <div class=\"card-footer flex-no-shrink fit-w separator\">\n <button\n class=\"btn btn-primary\"\n id=\"send-config-btn\"\n type=\"button\"\n (click)=\"updateConfiguration(configControl.value)\"\n [disabled]=\"reloadingConfig() || savingConfig() || !configControl.value\"\n [ngClass]=\"{ 'btn-pending': savingConfig() }\"\n >\n @if (!savingConfig()) {\n <span title=\"{{ 'Send' | translate }}\">\n {{ 'Send configuration to device' | translate }}\n </span>\n }\n @if (savingConfig()) {\n <span title=\"{{ 'Sending\u2026' | translate }}\">\n {{ 'Sending\u2026' | translate }}\n </span>\n }\n </button>\n </div>\n }\n</div>\n" }]
|
|
228
229
|
}], ctorParameters: () => [{ type: i1.ActivatedRoute }, { type: i2.AlertService }, { type: i3.RepositoryService }, { type: DeviceConfigurationService }, { type: i3$1.InventoryService }] });
|
|
229
230
|
|
|
230
231
|
class DeviceConfigurationGuard {
|
|
@@ -325,6 +326,12 @@ class ConfigurationDetailComponent {
|
|
|
325
326
|
this.cdr = inject(ChangeDetectorRef);
|
|
326
327
|
this.binary = { file: undefined, url: undefined };
|
|
327
328
|
this.mo = {};
|
|
329
|
+
/**
|
|
330
|
+
* Whether the drawer was opened from a device's Configuration tab rather than the
|
|
331
|
+
* Configuration Repository itself — controls whether titles/warnings spell out that
|
|
332
|
+
* the change lands in the shared repository, which isn't obvious from that context.
|
|
333
|
+
*/
|
|
334
|
+
this.isDeviceContext = false;
|
|
328
335
|
this.form = new FormGroup({
|
|
329
336
|
version: new FormControl('', [
|
|
330
337
|
Validators.required,
|
|
@@ -376,7 +383,14 @@ class ConfigurationDetailComponent {
|
|
|
376
383
|
: picked;
|
|
377
384
|
}, ...(ngDevMode ? [{ debugName: "editorLanguage" }] : /* istanbul ignore next */ []));
|
|
378
385
|
this.editorLanguages = [AUTO_LANGUAGE_OPTION, ...EDITOR_LANGUAGES];
|
|
379
|
-
this.
|
|
386
|
+
this.drawerTitle = computed(() => {
|
|
387
|
+
if (this.isDeviceContext) {
|
|
388
|
+
return this.mo?.id
|
|
389
|
+
? gettext('Edit configuration in repository')
|
|
390
|
+
: gettext('Save configuration to repository');
|
|
391
|
+
}
|
|
392
|
+
return this.mo?.id ? gettext('Edit configuration') : gettext('Add configuration');
|
|
393
|
+
}, ...(ngDevMode ? [{ debugName: "drawerTitle" }] : /* istanbul ignore next */ []));
|
|
380
394
|
this.form.controls.uploadChoice.valueChanges.pipe(takeUntilDestroyed()).subscribe(choice => {
|
|
381
395
|
const ctrl = this.form.controls.editorFilename;
|
|
382
396
|
if (choice === 'editInline') {
|
|
@@ -532,7 +546,7 @@ class ConfigurationDetailComponent {
|
|
|
532
546
|
}
|
|
533
547
|
}
|
|
534
548
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: ConfigurationDetailComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
535
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.19", type: ConfigurationDetailComponent, isStandalone: true, selector: "c8y-configuration-detail", inputs: { version: "version", description: "description", binary: "binary", deviceType: "deviceType", mo: "mo" }, host: { classAttribute: "d-contents" }, ngImport: i0, template: "<div class=\"card-header j-c-center separator flex-no-shrink p-24\">\n <i\n class=\"m-r-8\"\n [c8yIcon]=\"'cogs'\"\n aria-hidden=\"true\"\n ></i>\n <h4 id=\"drawerTitle\">\n @if (mo?.id) {\n {{ 'Update configuration' | translate }}\n } @else {\n {{ 'Add configuration' | translate }}\n }\n </h4>\n</div>\n\n<form\n class=\"d-contents\"\n [formGroup]=\"form\"\n (ngSubmit)=\"save()\"\n>\n <div\n class=\"card-body inner-scroll p-24\"\n [class.d-col]=\"form.value.uploadChoice === 'editInline'\"\n >\n <div class=\"row\">\n <c8y-form-group class=\"col-sm-3\">\n <label\n for=\"confVersion\"\n translate\n >\n Name\n </label>\n <input\n class=\"form-control\"\n id=\"confVersion\"\n placeholder=\"{{ 'e.g.' | translate }} hosts\"\n aria-required=\"true\"\n type=\"text\"\n autocomplete=\"off\"\n formControlName=\"version\"\n />\n </c8y-form-group>\n\n <c8y-form-group class=\"col-sm-3\">\n <label\n for=\"confDeviceType\"\n translate\n >\n Device type\n </label>\n <input\n class=\"form-control\"\n id=\"confDeviceType\"\n placeholder=\"{{ 'e.g.' | translate }} c8y_Linux\"\n type=\"text\"\n autocomplete=\"off\"\n formControlName=\"deviceType\"\n />\n </c8y-form-group>\n\n <c8y-form-group class=\"col-sm-3\">\n <label\n for=\"confDescription\"\n translate\n >\n Description\n </label>\n <input\n class=\"form-control\"\n id=\"confDescription\"\n placeholder=\"{{ 'e.g.' | translate }} Host configuration\"\n type=\"text\"\n autocomplete=\"off\"\n formControlName=\"description\"\n />\n </c8y-form-group>\n\n <c8y-form-group class=\"col-sm-3\">\n <label translate>Configuration type</label>\n <c8y-typeahead\n placeholder=\"{{ 'e.g.' | translate }} ssh\"\n name=\"confType\"\n data-cy=\"conf-detail--configuration-type\"\n [ngModel]=\"configurationTypeMO\"\n [ngModelOptions]=\"{ standalone: true }\"\n (ngModelChange)=\"configurationTypeMO = $event\"\n maxlength=\"254\"\n (onSearch)=\"setPipe($event)\"\n displayProperty=\"configurationType\"\n >\n @let patternStr = pattern();\n <c8y-li\n class=\"p-l-8 p-r-8 c8y-list__item--link\"\n *c8yFor=\"let config of configs; pipe: filterPipe; notFound: notFoundTemplate\"\n (click)=\"configurationTypeMO = config; setPipe('')\"\n [active]=\"configurationTypeMO === config\"\n >\n <c8y-highlight\n [text]=\"config.configurationType || '--'\"\n [pattern]=\"patternStr\"\n ></c8y-highlight>\n </c8y-li>\n <ng-template #notFoundTemplate>\n @if (patternStr.length > 0) {\n <c8y-li class=\"bg-level-2 p-8\">\n <span translate>No match found.</span>\n <button\n class=\"btn btn-primary btn-xs m-l-8\"\n title=\"{{ 'Add new`configuration type`' | translate }}\"\n type=\"button\"\n translate\n >\n Add new`configuration type`\n </button>\n </c8y-li>\n }\n </ng-template>\n </c8y-typeahead>\n </c8y-form-group>\n </div>\n\n <fieldset\n class=\"d-col\"\n [class.flex-grow]=\"form.value.uploadChoice === 'editInline'\"\n [class.min-height-0]=\"form.value.uploadChoice === 'editInline'\"\n >\n <legend\n class=\"legend form-block m-t-40\"\n translate\n >\n Configuration file\n </legend>\n\n @if (isExternalUrl()) {\n <p\n class=\"text-muted m-b-8\"\n translate\n >\n Content is sourced from a remote URL and cannot be edited inline.\n </p>\n <c8y-form-group>\n <label\n for=\"confFileUrl\"\n translate\n >\n File URL\n </label>\n <input\n class=\"form-control\"\n id=\"confFileUrl\"\n placeholder=\"https://...\"\n type=\"url\"\n autocomplete=\"off\"\n [ngModel]=\"binary.url\"\n [ngModelOptions]=\"{ standalone: true }\"\n (ngModelChange)=\"binary = { url: $event }; form.markAsDirty()\"\n />\n </c8y-form-group>\n } @else {\n <c8y-file-picker\n [maxAllowedFiles]=\"1\"\n [allowedUploadChoices]=\"['uploadBinary', 'uploadUrl', 'editInline']\"\n [uploadChoice]=\"form.controls.uploadChoice.value\"\n (uploadChoiceChange)=\"onUploadChoiceChange($event)\"\n [fileUrl]=\"binary.url\"\n (fileUrlChange)=\"onFileUrlChange($event)\"\n [fileBinary]=\"binary.file\"\n (fileBinaryChange)=\"onFileBinaryChange($event)\"\n (textFilePicked)=\"onTextFilePicked($event)\"\n [fileUrlPopover]=\"textForConfigurationUrlPopover\"\n >\n <ng-container c8yInlineEditor>\n <div class=\"row\">\n <c8y-form-group class=\"col-sm-9\">\n <label\n for=\"confEditorFilename\"\n translate\n >\n Filename\n </label>\n <input\n class=\"form-control\"\n id=\"confEditorFilename\"\n placeholder=\"config.json\"\n aria-required=\"true\"\n type=\"text\"\n autocomplete=\"off\"\n formControlName=\"editorFilename\"\n />\n </c8y-form-group>\n <c8y-form-group class=\"col-sm-3\">\n <label\n for=\"confEditorLanguage\"\n translate\n >\n Language\n </label>\n <c8y-select\n aria-label=\"{{ 'Editor language' | translate }}\"\n id=\"confEditorLanguage\"\n [items]=\"editorLanguages\"\n formControlName=\"editorLanguage\"\n ></c8y-select>\n </c8y-form-group>\n </div>\n <c8y-form-group class=\"d-col flex-grow min-height-0 m-b-0\">\n <label\n for=\"confEditorContent\"\n translate\n >\n Content\n </label>\n <c8y-editor\n class=\"flex-grow\"\n style=\"min-height: 95px\"\n id=\"confEditorContent\"\n formControlName=\"editorContent\"\n monacoEditorMarkerValidator\n [editorOptions]=\"{ language: editorLanguage() }\"\n ></c8y-editor>\n <c8y-messages></c8y-messages>\n </c8y-form-group>\n </ng-container>\n </c8y-file-picker>\n }\n </fieldset>\n </div>\n\n <div class=\"card-footer j-c-between separator flex-no-shrink p-24\">\n <button\n class=\"btn btn-default\"\n title=\"{{ 'Cancel' | translate }}\"\n type=\"button\"\n (click)=\"cancel()\"\n [disabled]=\"saving()\"\n >\n <span translate>Cancel</span>\n </button>\n <button\n class=\"btn btn-primary\"\n [class.btn-pending]=\"saving()\"\n [title]=\"submitButtonTitle() | translate\"\n type=\"submit\"\n [disabled]=\"isSaveDisabled\"\n >\n {{ submitButtonTitle() | translate }}\n </button>\n </div>\n</form>\n", dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.MaxLengthValidator, selector: "[maxlength][formControlName],[maxlength][formControl],[maxlength][ngModel]", inputs: ["maxlength"] }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "directive", type: C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "component", type: FormGroupComponent, selector: "c8y-form-group", inputs: ["hasError", "hasWarning", "hasSuccess", "novalidation", "status"] }, { kind: "component", type: TypeaheadComponent, selector: "c8y-typeahead", inputs: ["required", "maxlength", "disabled", "allowFreeEntries", "placeholder", "displayProperty", "icon", "name", "autoClose", "hideNew", "container", "selected", "title", "highlightFirstItem"], outputs: ["onSearch", "onIconClick"] }, { 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: ListItemComponent, selector: "c8y-list-item, c8y-li", inputs: ["active", "highlighted", "emptyActions", "dense", "collapsed", "selectable"], outputs: ["collapsedChange"] }, { kind: "component", type: HighlightComponent, selector: "c8y-highlight", inputs: ["pattern", "text", "elementClass", "shouldTrimPattern"] }, { kind: "component", type: FilePickerComponent, selector: "c8y-file-picker", inputs: ["maxAllowedFiles", "uploadChoice", "allowedUploadChoices", "fileUrl", "fileBinary", "config", "filePickerIndex", "fileUrlPopover", "editInlineConfirmTitle", "editInlineConfirmMessage"], outputs: ["onFilesPicked", "uploadChoiceChange", "fileBinaryChange", "fileUrlChange", "textFilePicked"] }, { kind: "component", type: EditorComponent, selector: "c8y-editor", inputs: ["editorOptions", "theme"], outputs: ["editorInit"] }, { kind: "directive", type: MonacoEditorMarkerValidatorDirective, selector: "c8y-editor [monacoEditorMarkerValidator]" }, { kind: "component", type: MessagesComponent, selector: "c8y-messages", inputs: ["show", "defaults", "helpMessage", "additionalMessages"] }, { kind: "directive", type: RequiredInputPlaceholderDirective, selector: "input[required], input[formControlName]" }, { kind: "component", type: SelectComponent, selector: "c8y-select", inputs: ["placeholder", "items", "selected", "container", "multi", "canSelectWithSpace", "disabled", "autoClose", "insideClick", "required", "canDeselect", "name", "icon", "filterItems"], outputs: ["onSelect", "onDeselect", "onIconClick"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
549
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.19", type: ConfigurationDetailComponent, isStandalone: true, selector: "c8y-configuration-detail", inputs: { version: "version", description: "description", binary: "binary", deviceType: "deviceType", mo: "mo", isDeviceContext: "isDeviceContext" }, host: { classAttribute: "d-contents" }, ngImport: i0, template: "<div class=\"card-header j-c-center separator flex-no-shrink p-24\">\n <i\n class=\"m-r-8\"\n [c8yIcon]=\"'gears'\"\n aria-hidden=\"true\"\n ></i>\n <h4 id=\"drawerTitle\">\n {{ drawerTitle() | translate }}\n </h4>\n</div>\n\n<form\n class=\"d-contents\"\n [formGroup]=\"form\"\n (ngSubmit)=\"save()\"\n>\n <div\n class=\"card-body inner-scroll p-24\"\n [class.d-col]=\"form.value.uploadChoice === 'editInline'\"\n >\n @if (isDeviceContext) {\n <div\n class=\"alert alert-warning fit-w max-width-100\"\n translate\n >\n Changes apply to the configuration repository and affect ongoing updates and future device\n deployments.\n </div>\n }\n <div class=\"row\">\n <c8y-form-group class=\"col-sm-3\">\n <label\n for=\"confVersion\"\n translate\n >\n Name\n </label>\n <input\n class=\"form-control\"\n id=\"confVersion\"\n placeholder=\"{{ 'e.g.' | translate }} hosts\"\n aria-required=\"true\"\n type=\"text\"\n autocomplete=\"off\"\n formControlName=\"version\"\n />\n </c8y-form-group>\n\n <c8y-form-group class=\"col-sm-3\">\n <label\n for=\"confDescription\"\n translate\n >\n Description\n </label>\n <textarea\n class=\"form-control no-resize\"\n id=\"confDescription\"\n placeholder=\"{{ 'e.g.' | translate }} Host configuration\"\n rows=\"1\"\n autocomplete=\"off\"\n formControlName=\"description\"\n c8y-textarea-autoresize\n ></textarea>\n </c8y-form-group>\n\n <c8y-form-group class=\"col-sm-3\">\n <label\n for=\"confDeviceType\"\n translate\n >\n Device type\n </label>\n <input\n class=\"form-control\"\n id=\"confDeviceType\"\n placeholder=\"{{ 'e.g.' | translate }} c8y_Linux\"\n type=\"text\"\n autocomplete=\"off\"\n formControlName=\"deviceType\"\n />\n </c8y-form-group>\n\n <c8y-form-group class=\"col-sm-3\">\n <label translate>Configuration type</label>\n <c8y-typeahead\n placeholder=\"{{ 'e.g.' | translate }} ssh\"\n name=\"confType\"\n data-cy=\"conf-detail--configuration-type\"\n [ngModel]=\"configurationTypeMO\"\n [ngModelOptions]=\"{ standalone: true }\"\n (ngModelChange)=\"configurationTypeMO = $event\"\n maxlength=\"254\"\n (onSearch)=\"setPipe($event)\"\n displayProperty=\"configurationType\"\n >\n @let patternStr = pattern();\n <c8y-li\n class=\"p-l-8 p-r-8 c8y-list__item--link\"\n *c8yFor=\"let config of configs; pipe: filterPipe; notFound: notFoundTemplate\"\n (click)=\"configurationTypeMO = config; setPipe('')\"\n [active]=\"configurationTypeMO === config\"\n >\n <c8y-highlight\n [text]=\"config.configurationType || '--'\"\n [pattern]=\"patternStr\"\n ></c8y-highlight>\n </c8y-li>\n <ng-template #notFoundTemplate>\n @if (patternStr.length > 0) {\n <c8y-li class=\"bg-level-2 p-8\">\n <span translate>No match found.</span>\n <button\n class=\"btn btn-primary btn-xs m-l-8\"\n title=\"{{ 'Add new`configuration type`' | translate }}\"\n type=\"button\"\n translate\n >\n Add new`configuration type`\n </button>\n </c8y-li>\n }\n </ng-template>\n </c8y-typeahead>\n </c8y-form-group>\n </div>\n\n <fieldset\n class=\"d-col\"\n [class.flex-grow]=\"form.value.uploadChoice === 'editInline'\"\n [class.min-height-0]=\"form.value.uploadChoice === 'editInline'\"\n >\n <legend\n class=\"legend form-block m-t-40\"\n translate\n >\n Configuration file\n </legend>\n\n @if (isExternalUrl()) {\n <p\n class=\"text-muted m-b-8\"\n translate\n >\n Content is sourced from a remote URL and cannot be edited inline.\n </p>\n <c8y-form-group>\n <label\n for=\"confFileUrl\"\n translate\n >\n File URL\n </label>\n <input\n class=\"form-control\"\n id=\"confFileUrl\"\n placeholder=\"https://...\"\n type=\"url\"\n autocomplete=\"off\"\n [ngModel]=\"binary.url\"\n [ngModelOptions]=\"{ standalone: true }\"\n (ngModelChange)=\"binary = { url: $event }; form.markAsDirty()\"\n />\n </c8y-form-group>\n } @else {\n <c8y-file-picker\n [maxAllowedFiles]=\"1\"\n [allowedUploadChoices]=\"['uploadBinary', 'uploadUrl', 'editInline']\"\n [uploadChoice]=\"form.controls.uploadChoice.value\"\n (uploadChoiceChange)=\"onUploadChoiceChange($event)\"\n [fileUrl]=\"binary.url\"\n (fileUrlChange)=\"onFileUrlChange($event)\"\n [fileBinary]=\"binary.file\"\n (fileBinaryChange)=\"onFileBinaryChange($event)\"\n (textFilePicked)=\"onTextFilePicked($event)\"\n [fileUrlPopover]=\"textForConfigurationUrlPopover\"\n >\n <ng-container c8yInlineEditor>\n <div class=\"row\">\n <c8y-form-group class=\"col-sm-9\">\n <label\n for=\"confEditorFilename\"\n translate\n >\n Filename\n </label>\n <input\n class=\"form-control\"\n id=\"confEditorFilename\"\n placeholder=\"config.json\"\n aria-required=\"true\"\n type=\"text\"\n autocomplete=\"off\"\n formControlName=\"editorFilename\"\n />\n </c8y-form-group>\n <c8y-form-group class=\"col-sm-3\">\n <label\n for=\"confEditorLanguage\"\n translate\n >\n Language\n </label>\n <c8y-select\n aria-label=\"{{ 'Editor language' | translate }}\"\n id=\"confEditorLanguage\"\n [items]=\"editorLanguages\"\n formControlName=\"editorLanguage\"\n ></c8y-select>\n </c8y-form-group>\n </div>\n <c8y-form-group class=\"d-col flex-grow min-height-0 m-b-0\">\n <label\n for=\"confEditorContent\"\n translate\n >\n Content\n </label>\n <c8y-editor\n class=\"flex-grow\"\n style=\"min-height: 95px\"\n id=\"confEditorContent\"\n formControlName=\"editorContent\"\n monacoEditorMarkerValidator\n [editorOptions]=\"{ language: editorLanguage() }\"\n ></c8y-editor>\n <c8y-messages></c8y-messages>\n </c8y-form-group>\n </ng-container>\n </c8y-file-picker>\n }\n </fieldset>\n </div>\n\n <div class=\"card-footer j-c-between separator flex-no-shrink p-24\">\n <button\n class=\"btn btn-default\"\n title=\"{{ 'Cancel' | translate }}\"\n type=\"button\"\n (click)=\"cancel()\"\n [disabled]=\"saving()\"\n >\n <span translate>Cancel</span>\n </button>\n <button\n class=\"btn btn-primary\"\n [class.btn-pending]=\"saving()\"\n [title]=\"drawerTitle() | translate\"\n type=\"submit\"\n [disabled]=\"isSaveDisabled\"\n >\n {{ 'Save' | translate }}\n </button>\n </div>\n</form>\n", dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.MaxLengthValidator, selector: "[maxlength][formControlName],[maxlength][formControl],[maxlength][ngModel]", inputs: ["maxlength"] }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "directive", type: C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "component", type: FormGroupComponent, selector: "c8y-form-group", inputs: ["hasError", "hasWarning", "hasSuccess", "novalidation", "status"] }, { kind: "component", type: TypeaheadComponent, selector: "c8y-typeahead", inputs: ["required", "maxlength", "disabled", "allowFreeEntries", "placeholder", "displayProperty", "icon", "name", "autoClose", "hideNew", "container", "selected", "title", "highlightFirstItem"], outputs: ["onSearch", "onIconClick"] }, { 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: ListItemComponent, selector: "c8y-list-item, c8y-li", inputs: ["active", "highlighted", "emptyActions", "dense", "collapsed", "selectable"], outputs: ["collapsedChange"] }, { kind: "component", type: HighlightComponent, selector: "c8y-highlight", inputs: ["pattern", "text", "elementClass", "shouldTrimPattern"] }, { kind: "component", type: FilePickerComponent, selector: "c8y-file-picker", inputs: ["maxAllowedFiles", "uploadChoice", "allowedUploadChoices", "fileUrl", "fileBinary", "config", "filePickerIndex", "fileUrlPopover", "editInlineConfirmTitle", "editInlineConfirmMessage"], outputs: ["onFilesPicked", "uploadChoiceChange", "fileBinaryChange", "fileUrlChange", "textFilePicked"] }, { kind: "component", type: EditorComponent, selector: "c8y-editor", inputs: ["editorOptions", "theme"], outputs: ["editorInit"] }, { kind: "directive", type: MonacoEditorMarkerValidatorDirective, selector: "c8y-editor [monacoEditorMarkerValidator]" }, { kind: "component", type: MessagesComponent, selector: "c8y-messages", inputs: ["show", "defaults", "helpMessage", "additionalMessages"] }, { kind: "directive", type: RequiredInputPlaceholderDirective, selector: "input[required], input[formControlName]" }, { kind: "component", type: SelectComponent, selector: "c8y-select", inputs: ["placeholder", "items", "selected", "container", "multi", "canSelectWithSpace", "disabled", "autoClose", "insideClick", "required", "canDeselect", "name", "icon", "filterItems"], outputs: ["onSelect", "onDeselect", "onIconClick"] }, { kind: "directive", type: TextareaAutoresizeDirective, selector: "[c8y-textarea-autoresize]" }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
536
550
|
}
|
|
537
551
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: ConfigurationDetailComponent, decorators: [{
|
|
538
552
|
type: Component,
|
|
@@ -553,8 +567,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImpo
|
|
|
553
567
|
MonacoEditorMarkerValidatorDirective,
|
|
554
568
|
MessagesComponent,
|
|
555
569
|
RequiredInputPlaceholderDirective,
|
|
556
|
-
SelectComponent
|
|
557
|
-
|
|
570
|
+
SelectComponent,
|
|
571
|
+
TextareaAutoresizeDirective
|
|
572
|
+
], template: "<div class=\"card-header j-c-center separator flex-no-shrink p-24\">\n <i\n class=\"m-r-8\"\n [c8yIcon]=\"'gears'\"\n aria-hidden=\"true\"\n ></i>\n <h4 id=\"drawerTitle\">\n {{ drawerTitle() | translate }}\n </h4>\n</div>\n\n<form\n class=\"d-contents\"\n [formGroup]=\"form\"\n (ngSubmit)=\"save()\"\n>\n <div\n class=\"card-body inner-scroll p-24\"\n [class.d-col]=\"form.value.uploadChoice === 'editInline'\"\n >\n @if (isDeviceContext) {\n <div\n class=\"alert alert-warning fit-w max-width-100\"\n translate\n >\n Changes apply to the configuration repository and affect ongoing updates and future device\n deployments.\n </div>\n }\n <div class=\"row\">\n <c8y-form-group class=\"col-sm-3\">\n <label\n for=\"confVersion\"\n translate\n >\n Name\n </label>\n <input\n class=\"form-control\"\n id=\"confVersion\"\n placeholder=\"{{ 'e.g.' | translate }} hosts\"\n aria-required=\"true\"\n type=\"text\"\n autocomplete=\"off\"\n formControlName=\"version\"\n />\n </c8y-form-group>\n\n <c8y-form-group class=\"col-sm-3\">\n <label\n for=\"confDescription\"\n translate\n >\n Description\n </label>\n <textarea\n class=\"form-control no-resize\"\n id=\"confDescription\"\n placeholder=\"{{ 'e.g.' | translate }} Host configuration\"\n rows=\"1\"\n autocomplete=\"off\"\n formControlName=\"description\"\n c8y-textarea-autoresize\n ></textarea>\n </c8y-form-group>\n\n <c8y-form-group class=\"col-sm-3\">\n <label\n for=\"confDeviceType\"\n translate\n >\n Device type\n </label>\n <input\n class=\"form-control\"\n id=\"confDeviceType\"\n placeholder=\"{{ 'e.g.' | translate }} c8y_Linux\"\n type=\"text\"\n autocomplete=\"off\"\n formControlName=\"deviceType\"\n />\n </c8y-form-group>\n\n <c8y-form-group class=\"col-sm-3\">\n <label translate>Configuration type</label>\n <c8y-typeahead\n placeholder=\"{{ 'e.g.' | translate }} ssh\"\n name=\"confType\"\n data-cy=\"conf-detail--configuration-type\"\n [ngModel]=\"configurationTypeMO\"\n [ngModelOptions]=\"{ standalone: true }\"\n (ngModelChange)=\"configurationTypeMO = $event\"\n maxlength=\"254\"\n (onSearch)=\"setPipe($event)\"\n displayProperty=\"configurationType\"\n >\n @let patternStr = pattern();\n <c8y-li\n class=\"p-l-8 p-r-8 c8y-list__item--link\"\n *c8yFor=\"let config of configs; pipe: filterPipe; notFound: notFoundTemplate\"\n (click)=\"configurationTypeMO = config; setPipe('')\"\n [active]=\"configurationTypeMO === config\"\n >\n <c8y-highlight\n [text]=\"config.configurationType || '--'\"\n [pattern]=\"patternStr\"\n ></c8y-highlight>\n </c8y-li>\n <ng-template #notFoundTemplate>\n @if (patternStr.length > 0) {\n <c8y-li class=\"bg-level-2 p-8\">\n <span translate>No match found.</span>\n <button\n class=\"btn btn-primary btn-xs m-l-8\"\n title=\"{{ 'Add new`configuration type`' | translate }}\"\n type=\"button\"\n translate\n >\n Add new`configuration type`\n </button>\n </c8y-li>\n }\n </ng-template>\n </c8y-typeahead>\n </c8y-form-group>\n </div>\n\n <fieldset\n class=\"d-col\"\n [class.flex-grow]=\"form.value.uploadChoice === 'editInline'\"\n [class.min-height-0]=\"form.value.uploadChoice === 'editInline'\"\n >\n <legend\n class=\"legend form-block m-t-40\"\n translate\n >\n Configuration file\n </legend>\n\n @if (isExternalUrl()) {\n <p\n class=\"text-muted m-b-8\"\n translate\n >\n Content is sourced from a remote URL and cannot be edited inline.\n </p>\n <c8y-form-group>\n <label\n for=\"confFileUrl\"\n translate\n >\n File URL\n </label>\n <input\n class=\"form-control\"\n id=\"confFileUrl\"\n placeholder=\"https://...\"\n type=\"url\"\n autocomplete=\"off\"\n [ngModel]=\"binary.url\"\n [ngModelOptions]=\"{ standalone: true }\"\n (ngModelChange)=\"binary = { url: $event }; form.markAsDirty()\"\n />\n </c8y-form-group>\n } @else {\n <c8y-file-picker\n [maxAllowedFiles]=\"1\"\n [allowedUploadChoices]=\"['uploadBinary', 'uploadUrl', 'editInline']\"\n [uploadChoice]=\"form.controls.uploadChoice.value\"\n (uploadChoiceChange)=\"onUploadChoiceChange($event)\"\n [fileUrl]=\"binary.url\"\n (fileUrlChange)=\"onFileUrlChange($event)\"\n [fileBinary]=\"binary.file\"\n (fileBinaryChange)=\"onFileBinaryChange($event)\"\n (textFilePicked)=\"onTextFilePicked($event)\"\n [fileUrlPopover]=\"textForConfigurationUrlPopover\"\n >\n <ng-container c8yInlineEditor>\n <div class=\"row\">\n <c8y-form-group class=\"col-sm-9\">\n <label\n for=\"confEditorFilename\"\n translate\n >\n Filename\n </label>\n <input\n class=\"form-control\"\n id=\"confEditorFilename\"\n placeholder=\"config.json\"\n aria-required=\"true\"\n type=\"text\"\n autocomplete=\"off\"\n formControlName=\"editorFilename\"\n />\n </c8y-form-group>\n <c8y-form-group class=\"col-sm-3\">\n <label\n for=\"confEditorLanguage\"\n translate\n >\n Language\n </label>\n <c8y-select\n aria-label=\"{{ 'Editor language' | translate }}\"\n id=\"confEditorLanguage\"\n [items]=\"editorLanguages\"\n formControlName=\"editorLanguage\"\n ></c8y-select>\n </c8y-form-group>\n </div>\n <c8y-form-group class=\"d-col flex-grow min-height-0 m-b-0\">\n <label\n for=\"confEditorContent\"\n translate\n >\n Content\n </label>\n <c8y-editor\n class=\"flex-grow\"\n style=\"min-height: 95px\"\n id=\"confEditorContent\"\n formControlName=\"editorContent\"\n monacoEditorMarkerValidator\n [editorOptions]=\"{ language: editorLanguage() }\"\n ></c8y-editor>\n <c8y-messages></c8y-messages>\n </c8y-form-group>\n </ng-container>\n </c8y-file-picker>\n }\n </fieldset>\n </div>\n\n <div class=\"card-footer j-c-between separator flex-no-shrink p-24\">\n <button\n class=\"btn btn-default\"\n title=\"{{ 'Cancel' | translate }}\"\n type=\"button\"\n (click)=\"cancel()\"\n [disabled]=\"saving()\"\n >\n <span translate>Cancel</span>\n </button>\n <button\n class=\"btn btn-primary\"\n [class.btn-pending]=\"saving()\"\n [title]=\"drawerTitle() | translate\"\n type=\"submit\"\n [disabled]=\"isSaveDisabled\"\n >\n {{ 'Save' | translate }}\n </button>\n </div>\n</form>\n" }]
|
|
558
573
|
}], ctorParameters: () => [], propDecorators: { version: [{
|
|
559
574
|
type: Input
|
|
560
575
|
}], description: [{
|
|
@@ -565,6 +580,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImpo
|
|
|
565
580
|
type: Input
|
|
566
581
|
}], mo: [{
|
|
567
582
|
type: Input
|
|
583
|
+
}], isDeviceContext: [{
|
|
584
|
+
type: Input
|
|
568
585
|
}] } });
|
|
569
586
|
|
|
570
587
|
class SourceCodePreviewComponent {
|
|
@@ -591,11 +608,11 @@ class SourceCodePreviewComponent {
|
|
|
591
608
|
};
|
|
592
609
|
}
|
|
593
610
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: SourceCodePreviewComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
594
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.19", type: SourceCodePreviewComponent, isStandalone: true, selector: "c8y-source-code-preview", inputs: { isDisabled: "isDisabled", text: "text", binaryType: "binaryType" }, usesOnChanges: true, ngImport: i0, template: "<c8y-editor\n class=\"flex-grow\"\n [ngModel]=\"text\"\n [editorOptions]=\"editorOptions\"\n (editorInit)=\"onEditorInit()\"\n></c8y-editor>\n", dependencies: [{ kind: "component", type: EditorComponent, selector: "c8y-editor", inputs: ["editorOptions", "theme"], outputs: ["editorInit"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
611
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.19", type: SourceCodePreviewComponent, isStandalone: true, selector: "c8y-source-code-preview", inputs: { isDisabled: "isDisabled", text: "text", binaryType: "binaryType" }, usesOnChanges: true, ngImport: i0, template: "<c8y-editor\n class=\"flex-grow min-height-0\"\n [ngModel]=\"text\"\n [editorOptions]=\"editorOptions\"\n (editorInit)=\"onEditorInit()\"\n></c8y-editor>\n", dependencies: [{ kind: "component", type: EditorComponent, selector: "c8y-editor", inputs: ["editorOptions", "theme"], outputs: ["editorInit"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
595
612
|
}
|
|
596
613
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: SourceCodePreviewComponent, decorators: [{
|
|
597
614
|
type: Component,
|
|
598
|
-
args: [{ selector: 'c8y-source-code-preview', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [EditorComponent, FormsModule], template: "<c8y-editor\n class=\"flex-grow\"\n [ngModel]=\"text\"\n [editorOptions]=\"editorOptions\"\n (editorInit)=\"onEditorInit()\"\n></c8y-editor>\n" }]
|
|
615
|
+
args: [{ selector: 'c8y-source-code-preview', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [EditorComponent, FormsModule], template: "<c8y-editor\n class=\"flex-grow min-height-0\"\n [ngModel]=\"text\"\n [editorOptions]=\"editorOptions\"\n (editorInit)=\"onEditorInit()\"\n></c8y-editor>\n" }]
|
|
599
616
|
}], propDecorators: { isDisabled: [{
|
|
600
617
|
type: Input
|
|
601
618
|
}], text: [{
|
|
@@ -624,6 +641,12 @@ class ConfigurationPreviewComponent {
|
|
|
624
641
|
this.editInRepository = new EventEmitter();
|
|
625
642
|
this.canCallAction = true;
|
|
626
643
|
this.deviceConfigurationOperation = DeviceConfigurationOperation;
|
|
644
|
+
/**
|
|
645
|
+
* Whether the previewed content is binary. Binary bytes are not rendered in the editor:
|
|
646
|
+
* they are unreadable as text and make the editor warn about invisible unicode characters,
|
|
647
|
+
* a warning the user cannot act on.
|
|
648
|
+
*/
|
|
649
|
+
this.isBinaryContent = signal(false, ...(ngDevMode ? [{ debugName: "isBinaryContent" }] : /* istanbul ignore next */ []));
|
|
627
650
|
}
|
|
628
651
|
async ngOnInit() {
|
|
629
652
|
this.setCanCallAction();
|
|
@@ -719,7 +742,8 @@ class ConfigurationPreviewComponent {
|
|
|
719
742
|
binary: { file },
|
|
720
743
|
// No id — the drawer treats this as a new entry, but carries the
|
|
721
744
|
// configuration type so the user can review and edit before saving.
|
|
722
|
-
mo: { configurationType: snapshot.configurationType }
|
|
745
|
+
mo: { configurationType: snapshot.configurationType },
|
|
746
|
+
isDeviceContext: true
|
|
723
747
|
});
|
|
724
748
|
if (saved) {
|
|
725
749
|
this.deviceConfigurationService.updateConfigurations(true);
|
|
@@ -739,11 +763,34 @@ class ConfigurationPreviewComponent {
|
|
|
739
763
|
Permissions.ROLE_BINARY_CREATE
|
|
740
764
|
])));
|
|
741
765
|
}
|
|
766
|
+
ngOnChanges(changes) {
|
|
767
|
+
if (changes.configSnapshot) {
|
|
768
|
+
void this.detectBinaryContent();
|
|
769
|
+
}
|
|
770
|
+
}
|
|
742
771
|
ngOnDestroy() {
|
|
743
772
|
if (this.operationsSubscription) {
|
|
744
773
|
this.operationsSubscription.unsubscribe();
|
|
745
774
|
}
|
|
746
775
|
}
|
|
776
|
+
async detectBinaryContent() {
|
|
777
|
+
const snapshot = this.configSnapshot;
|
|
778
|
+
this.inspectedSnapshot = snapshot;
|
|
779
|
+
if (!snapshot?.binary) {
|
|
780
|
+
this.isBinaryContent.set(false);
|
|
781
|
+
return;
|
|
782
|
+
}
|
|
783
|
+
// Prefer the original bytes when they were preserved; otherwise re-encode the text the
|
|
784
|
+
// platform already decoded, which keeps null and replacement characters intact.
|
|
785
|
+
const file = snapshot.binaryFile ??
|
|
786
|
+
new File([snapshot.binary], snapshot.name ?? '', { type: snapshot.binaryType });
|
|
787
|
+
// Decide from the content, not the declared MIME type: platform-served binaries are
|
|
788
|
+
// often labelled text/plain.
|
|
789
|
+
const isBinary = await isBinaryFile(file, { ignoreMimeType: true });
|
|
790
|
+
if (this.inspectedSnapshot === snapshot) {
|
|
791
|
+
this.isBinaryContent.set(isBinary);
|
|
792
|
+
}
|
|
793
|
+
}
|
|
747
794
|
async updateSnapshotsOnConfigUpload(operation) {
|
|
748
795
|
if (operation[DeviceConfigurationOperation.UPLOAD_CONFIG] &&
|
|
749
796
|
operation.status === OperationStatus.SUCCESSFUL) {
|
|
@@ -751,7 +798,7 @@ class ConfigurationPreviewComponent {
|
|
|
751
798
|
}
|
|
752
799
|
}
|
|
753
800
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: ConfigurationPreviewComponent, deps: [{ token: DeviceConfigurationService }, { token: i2.OperationRealtimeService }, { token: i3$1.UserService }, { token: i2.AppStateService }, { token: i3.RepositoryService }, { token: i3$1.OperationService }, { token: i2.AlertService }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
754
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.19", type: ConfigurationPreviewComponent, isStandalone: true, selector: "c8y-device-configuration-preview", inputs: { device: "device", configurationType: "configurationType", configSnapshot: "configSnapshot", canSaveSnapshot: "canSaveSnapshot", actionButtonText: "actionButtonText", actionButtonIcon: "actionButtonIcon", isLegacy: "isLegacy", operationToTrigger: "operationToTrigger", editableRepositoryMo: "editableRepositoryMo" }, outputs: { editInRepository: "editInRepository" }, ngImport: i0, template: "<div class=\"content-flex-55 p-b-16\">\n <div class=\"col-7 p-t-4\">\n <p>\n <span\n class=\"text-label-small text-uppercase m-r-4\"\n translate\n >Configuration</span\n >\n @if (configSnapshot?.name) {\n <span>\n <strong>{{ configSnapshot.name }}</strong>\n </span>\n } @else {\n ---\n }\n </p>\n <p>\n <span\n class=\"text-label-small text-uppercase m-r-4\"\n translate\n >Last updated</span\n >\n @if (configSnapshot?.time) {\n <small>\n {{ configSnapshot.time | c8yDate }}\n </small>\n } @else {\n ---\n }\n </p>\n </div>\n <div class=\"col-5 d-flex j-c-end gap-4\">\n @if (
|
|
801
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.19", type: ConfigurationPreviewComponent, isStandalone: true, selector: "c8y-device-configuration-preview", inputs: { device: "device", configurationType: "configurationType", configSnapshot: "configSnapshot", canSaveSnapshot: "canSaveSnapshot", actionButtonText: "actionButtonText", actionButtonIcon: "actionButtonIcon", isLegacy: "isLegacy", operationToTrigger: "operationToTrigger", editableRepositoryMo: "editableRepositoryMo" }, outputs: { editInRepository: "editInRepository" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"content-flex-55 p-b-16 flex-no-shrink\">\n <div class=\"col-7 p-t-4\">\n <p>\n <span\n class=\"text-label-small text-uppercase m-r-4\"\n translate\n >Configuration</span\n >\n @if (configSnapshot?.name) {\n <span>\n <strong>{{ configSnapshot.name }}</strong>\n </span>\n } @else {\n ---\n }\n </p>\n <p>\n <span\n class=\"text-label-small text-uppercase m-r-4\"\n translate\n >Last updated</span\n >\n @if (configSnapshot?.time) {\n <small>\n {{ configSnapshot.time | c8yDate }}\n </small>\n } @else {\n ---\n }\n </p>\n </div>\n <div class=\"col-5 d-flex j-c-end gap-4\">\n @if (canCallAction) {\n <button\n class=\"btn btn-primary btn-sm\"\n title=\"{{ actionButtonText | translate }}\"\n id=\"action-btn\"\n type=\"button\"\n (click)=\"createDeviceOperation()\"\n [disabled]=\"isCreateOperationDisabled()\"\n >\n <i [c8yIcon]=\"actionButtonIcon\"></i>\n {{ actionButtonText | translate }}\n </button>\n }\n </div>\n</div>\n<fieldset class=\"c8y-fieldset p-l-16 p-r-16 p-b-16 flex-grow d-flex d-col min-height-0\">\n <legend translate>Preview</legend>\n @if (showOperation()) {\n <div>\n <c8y-operation-details [operation]=\"operation\"></c8y-operation-details>\n </div>\n }\n @if (!configSnapshot?.binary && showBinary()) {\n <div class=\"c8y-empty-state text-left\">\n <h1 [c8yIcon]=\"'file-image-o'\"></h1>\n <p>\n <strong translate>No preview available.</strong>\n <br />\n @if (configSnapshot?.binary !== '') {\n <small translate>\n Try getting a snapshot from the device or open it in the repository\n </small>\n } @else {\n <small translate>The file is empty.</small>\n }\n </p>\n </div>\n }\n @if (configSnapshot?.binary && showBinary()) {\n <div class=\"flex-grow d-flex d-col min-height-0\">\n @if (isBinaryContent()) {\n <c8y-ui-empty-state\n class=\"flex-grow\"\n [icon]=\"'file-o'\"\n [title]=\"'No preview available.' | translate\"\n [subtitle]=\"\n 'This configuration is a binary file and cannot be shown as text.' | translate\n \"\n [horizontal]=\"true\"\n ></c8y-ui-empty-state>\n } @else {\n <c8y-source-code-preview\n class=\"d-contents\"\n [text]=\"configSnapshot.binary\"\n [binaryType]=\"configSnapshot.binaryType\"\n [isDisabled]=\"true\"\n ></c8y-source-code-preview>\n }\n @if (canSaveSnapshot) {\n <div class=\"p-t-16 flex-no-shrink\">\n <button\n class=\"btn btn-default btn-sm pull-right m-l-8\"\n title=\"{{ 'Download' | translate }}\"\n type=\"button\"\n (click)=\"download()\"\n >\n <i\n c8yIcon=\"download\"\n aria-hidden=\"true\"\n ></i>\n {{ 'Download' | translate }}\n </button>\n @if (hasPermission()) {\n <button\n class=\"btn btn-default btn-sm pull-right\"\n title=\"{{ 'Save to repository' | translate }}\"\n type=\"button\"\n (click)=\"saveToRepository()\"\n >\n <i\n c8yIcon=\"archive-file\"\n aria-hidden=\"true\"\n ></i>\n {{ 'Save to repository' | translate }}\n </button>\n }\n </div>\n }\n </div>\n }\n @if (editableRepositoryMo) {\n <div class=\"d-flex j-c-end p-t-8 flex-no-shrink\">\n <button\n class=\"btn btn-default btn-sm\"\n title=\"{{ 'Edit in repository' | translate }}\"\n type=\"button\"\n (click)=\"editInRepository.emit(editableRepositoryMo)\"\n >\n <i\n [c8yIcon]=\"'pencil'\"\n aria-hidden=\"true\"\n ></i>\n {{ 'Edit in repository' | translate }}\n </button>\n </div>\n }\n</fieldset>\n", dependencies: [{ kind: "directive", type: C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "directive", type: IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "component", type: SourceCodePreviewComponent, selector: "c8y-source-code-preview", inputs: ["isDisabled", "text", "binaryType"] }, { kind: "component", type: OperationDetailsComponent, selector: "c8y-operation-details", inputs: ["operation"] }, { 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 }); }
|
|
755
802
|
}
|
|
756
803
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: ConfigurationPreviewComponent, decorators: [{
|
|
757
804
|
type: Component,
|
|
@@ -761,8 +808,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImpo
|
|
|
761
808
|
SourceCodePreviewComponent,
|
|
762
809
|
OperationDetailsComponent,
|
|
763
810
|
C8yTranslatePipe,
|
|
764
|
-
DatePipe
|
|
765
|
-
|
|
811
|
+
DatePipe,
|
|
812
|
+
EmptyStateComponent
|
|
813
|
+
], changeDetection: ChangeDetectionStrategy.Eager, template: "<div class=\"content-flex-55 p-b-16 flex-no-shrink\">\n <div class=\"col-7 p-t-4\">\n <p>\n <span\n class=\"text-label-small text-uppercase m-r-4\"\n translate\n >Configuration</span\n >\n @if (configSnapshot?.name) {\n <span>\n <strong>{{ configSnapshot.name }}</strong>\n </span>\n } @else {\n ---\n }\n </p>\n <p>\n <span\n class=\"text-label-small text-uppercase m-r-4\"\n translate\n >Last updated</span\n >\n @if (configSnapshot?.time) {\n <small>\n {{ configSnapshot.time | c8yDate }}\n </small>\n } @else {\n ---\n }\n </p>\n </div>\n <div class=\"col-5 d-flex j-c-end gap-4\">\n @if (canCallAction) {\n <button\n class=\"btn btn-primary btn-sm\"\n title=\"{{ actionButtonText | translate }}\"\n id=\"action-btn\"\n type=\"button\"\n (click)=\"createDeviceOperation()\"\n [disabled]=\"isCreateOperationDisabled()\"\n >\n <i [c8yIcon]=\"actionButtonIcon\"></i>\n {{ actionButtonText | translate }}\n </button>\n }\n </div>\n</div>\n<fieldset class=\"c8y-fieldset p-l-16 p-r-16 p-b-16 flex-grow d-flex d-col min-height-0\">\n <legend translate>Preview</legend>\n @if (showOperation()) {\n <div>\n <c8y-operation-details [operation]=\"operation\"></c8y-operation-details>\n </div>\n }\n @if (!configSnapshot?.binary && showBinary()) {\n <div class=\"c8y-empty-state text-left\">\n <h1 [c8yIcon]=\"'file-image-o'\"></h1>\n <p>\n <strong translate>No preview available.</strong>\n <br />\n @if (configSnapshot?.binary !== '') {\n <small translate>\n Try getting a snapshot from the device or open it in the repository\n </small>\n } @else {\n <small translate>The file is empty.</small>\n }\n </p>\n </div>\n }\n @if (configSnapshot?.binary && showBinary()) {\n <div class=\"flex-grow d-flex d-col min-height-0\">\n @if (isBinaryContent()) {\n <c8y-ui-empty-state\n class=\"flex-grow\"\n [icon]=\"'file-o'\"\n [title]=\"'No preview available.' | translate\"\n [subtitle]=\"\n 'This configuration is a binary file and cannot be shown as text.' | translate\n \"\n [horizontal]=\"true\"\n ></c8y-ui-empty-state>\n } @else {\n <c8y-source-code-preview\n class=\"d-contents\"\n [text]=\"configSnapshot.binary\"\n [binaryType]=\"configSnapshot.binaryType\"\n [isDisabled]=\"true\"\n ></c8y-source-code-preview>\n }\n @if (canSaveSnapshot) {\n <div class=\"p-t-16 flex-no-shrink\">\n <button\n class=\"btn btn-default btn-sm pull-right m-l-8\"\n title=\"{{ 'Download' | translate }}\"\n type=\"button\"\n (click)=\"download()\"\n >\n <i\n c8yIcon=\"download\"\n aria-hidden=\"true\"\n ></i>\n {{ 'Download' | translate }}\n </button>\n @if (hasPermission()) {\n <button\n class=\"btn btn-default btn-sm pull-right\"\n title=\"{{ 'Save to repository' | translate }}\"\n type=\"button\"\n (click)=\"saveToRepository()\"\n >\n <i\n c8yIcon=\"archive-file\"\n aria-hidden=\"true\"\n ></i>\n {{ 'Save to repository' | translate }}\n </button>\n }\n </div>\n }\n </div>\n }\n @if (editableRepositoryMo) {\n <div class=\"d-flex j-c-end p-t-8 flex-no-shrink\">\n <button\n class=\"btn btn-default btn-sm\"\n title=\"{{ 'Edit in repository' | translate }}\"\n type=\"button\"\n (click)=\"editInRepository.emit(editableRepositoryMo)\"\n >\n <i\n [c8yIcon]=\"'pencil'\"\n aria-hidden=\"true\"\n ></i>\n {{ 'Edit in repository' | translate }}\n </button>\n </div>\n }\n</fieldset>\n" }]
|
|
766
814
|
}], ctorParameters: () => [{ type: DeviceConfigurationService }, { type: i2.OperationRealtimeService }, { type: i3$1.UserService }, { type: i2.AppStateService }, { type: i3.RepositoryService }, { type: i3$1.OperationService }, { type: i2.AlertService }], propDecorators: { device: [{
|
|
767
815
|
type: Input
|
|
768
816
|
}], configurationType: [{
|
|
@@ -887,8 +935,13 @@ class DeviceConfigurationComponent {
|
|
|
887
935
|
allowExternal: false
|
|
888
936
|
});
|
|
889
937
|
if (binary) {
|
|
890
|
-
|
|
891
|
-
|
|
938
|
+
// Replace the snapshot rather than mutating it: the preview binds to this object
|
|
939
|
+
// and only re-inspects the content when the reference changes.
|
|
940
|
+
this.repositorySnapshot = {
|
|
941
|
+
...this.repositorySnapshot,
|
|
942
|
+
binary: await binary.text(),
|
|
943
|
+
binaryType: binary.type || undefined
|
|
944
|
+
};
|
|
892
945
|
}
|
|
893
946
|
}
|
|
894
947
|
catch {
|
|
@@ -924,14 +977,15 @@ class DeviceConfigurationComponent {
|
|
|
924
977
|
deviceType: mo.deviceType,
|
|
925
978
|
description: mo.description,
|
|
926
979
|
binary: { file: fileBinary, url: mo.url },
|
|
927
|
-
mo
|
|
980
|
+
mo,
|
|
981
|
+
isDeviceContext: true
|
|
928
982
|
});
|
|
929
983
|
if (saved) {
|
|
930
984
|
this.updateSnapshots(true);
|
|
931
985
|
}
|
|
932
986
|
}
|
|
933
987
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: DeviceConfigurationComponent, deps: [{ token: i1.ActivatedRoute }, { token: DeviceConfigurationService }, { token: i3.RepositoryService }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
934
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.19", type: DeviceConfigurationComponent, isStandalone: true, selector: "c8y-device-configuration", viewQueries: [{ propertyName: "textBasedConfigurationComponent", first: true, predicate: TextBasedConfigurationComponent, descendants: true }], ngImport: i0, template: "<c8y-action-bar-item [placement]=\"'right'\">\n <button\n class=\"btn btn-link\"\n title=\"{{ 'Reload' | translate }}\"\n (click)=\"updateSnapshots()\"\n >\n <i\n c8yIcon=\"refresh\"\n [ngClass]=\"{ 'icon-spin': reloading }\"\n ></i>\n {{ 'Reload' | translate }}\n </button>\n</c8y-action-bar-item>\n\n<div class=\"card content-fullpage card-has-tabs\">\n <tabset>\n @if (showBinaryBasedConfig && !showTextBasedConfig) {\n <div class=\"card-header separator\">\n <div class=\"card-title\">{{ 'Configurations' | translate }}</div>\n </div>\n }\n @if (!showBinaryBasedConfig && showTextBasedConfig) {\n <div class=\"card-header separator\">\n <div class=\"card-title\">{{ 'Text-based configuration' | translate }}</div>\n </div>\n }\n @if (showBinaryBasedConfig) {\n <tab heading=\"{{ 'Configurations' | translate }}\">\n <div class=\"card--grid card grid__col--4-8--md grid__row--6-6--md m-b-0\">\n <!-- DEVICE SUPPORTED CONFIGURATIONS -->\n <div class=\"card--grid__inner-scroll bg-level-1\">\n <div class=\"p-l-16 p-r-16\">\n <h5 class=\"legend form-block\">\n <span translate>Device-supported configurations</span>\n </h5>\n </div>\n <c8y-device-configuration-list\n [itemIcon]=\"'gears'\"\n [items]=\"supportedConfigurations\"\n (configSelected)=\"onConfigTypeSelected($event)\"\n ></c8y-device-configuration-list>\n </div>\n <!-- CONFIGURATION PREVIEW -->\n <div class=\"card--grid__inner-scroll d-flex d-col flex-grow\">\n <div class=\"card-block d-flex d-col flex-grow\">\n <h5 class=\"legend form-block\"><span translate>Preview</span></h5>\n <!-- EMPTY STATE -->\n @if (!configurationType) {\n <c8y-ui-empty-state\n [icon]=\"'file-text'\"\n [title]=\"'No configuration selected.' | translate\"\n [subtitle]=\"'Select a configuration to preview.' | translate\"\n [horizontal]=\"true\"\n ></c8y-ui-empty-state>\n }\n <!-- PREVIEW AVAILABLE STATE -->\n @if (configurationType) {\n <c8y-device-configuration-preview\n class=\"d-flex d-col flex-grow\"\n [actionButtonIcon]=\"'download'\"\n [device]=\"device\"\n [configurationType]=\"configurationType\"\n [configSnapshot]=\"configSnapshot\"\n [canSaveSnapshot]=\"true\"\n [operationToTrigger]=\"'c8y_UploadConfigFile'\"\n [actionButtonText]=\"'Get snapshot from device' | translate\"\n [isLegacy]=\"isLegacy\"\n ></c8y-device-configuration-preview>\n }\n </div>\n </div>\n <!-- AVAILABLE SUPPORTED CONFIGURATIONS -->\n <div class=\"card--grid__inner-scroll bg-level-1\">\n <div class=\"p-l-16 p-r-16\">\n <h5\n class=\"legend form-block\"\n translate\n >\n Available supported configurations\n </h5>\n </div>\n <!-- EMPTY STATE -->\n @if (!configurationType) {\n <c8y-ui-empty-state\n [icon]=\"'gears'\"\n [title]=\"'No selection.' | translate\"\n [subtitle]=\"\n 'Select a configuration from the device-supported configuration list.' | translate\n \"\n [horizontal]=\"true\"\n ></c8y-ui-empty-state>\n }\n @if (configurationType) {\n <div class=\"p-r-16\">\n <c8y-device-configuration-list\n [itemIcon]=\"'file-text'\"\n [items]=\"repositorySnapshots\"\n [emptyState]=\"repositorySnapshotsEmptyState\"\n [isFilterEnabled]=\"true\"\n (configSelected)=\"onRepositoryConfigSelected($event)\"\n ></c8y-device-configuration-list>\n </div>\n }\n </div>\n <!-- CONFIGURATION PREVIEW -->\n <div class=\"card--grid__inner-scroll d-flex d-col flex-grow\">\n <div class=\"card-block flex-grow d-flex d-col\">\n <h5\n class=\"legend form-block\"\n translate\n >\n Preview\n </h5>\n <!-- EMPTY STATE -->\n @if (!repositorySnapshot) {\n <c8y-ui-empty-state\n [icon]=\"'file-text'\"\n [title]=\"'No configuration selected.' | translate\"\n [subtitle]=\"'Select a configuration to preview.' | translate\"\n [horizontal]=\"true\"\n ></c8y-ui-empty-state>\n }\n <!-- CONFIGURATION SELECTED STATE -->\n @if (repositorySnapshot) {\n <c8y-device-configuration-preview\n class=\"d-flex d-col flex-grow\"\n [actionButtonIcon]=\"'upload'\"\n [device]=\"device\"\n [configurationType]=\"configurationType\"\n [configSnapshot]=\"repositorySnapshot\"\n [operationToTrigger]=\"'c8y_DownloadConfigFile'\"\n [actionButtonText]=\"'Send configuration to device' | translate\"\n [isLegacy]=\"isLegacy\"\n [editableRepositoryMo]=\"selectedRepositoryMo\"\n (editInRepository)=\"openEditInRepository($event)\"\n ></c8y-device-configuration-preview>\n }\n </div>\n </div>\n </div>\n </tab>\n }\n @if (showTextBasedConfig) {\n <tab heading=\"{{ 'Text-based configuration' | translate }}\">\n <c8y-text-based-configuration></c8y-text-based-configuration>\n </tab>\n }\n </tabset>\n</div>\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: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: TabsetAriaDirective, selector: "tabset" }, { kind: "component", type: TabsetComponent, selector: "tabset", inputs: ["vertical", "justified", "type"] }, { kind: "directive", type: TabDirective, selector: "tab, [tab]", inputs: ["heading", "id", "disabled", "removable", "tabOrder", "customClass", "active"], outputs: ["selectTab", "deselect", "removed"], exportAs: ["tab"] }, { kind: "directive", type: C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "component", type: DeviceConfigurationListComponent, selector: "c8y-device-configuration-list", inputs: ["items", "itemIcon", "emptyState", "isFilterEnabled"], outputs: ["configSelected"] }, { kind: "component", type: EmptyStateComponent, selector: "c8y-ui-empty-state", inputs: ["icon", "title", "subtitle", "horizontal"] }, { kind: "component", type: ConfigurationPreviewComponent, selector: "c8y-device-configuration-preview", inputs: ["device", "configurationType", "configSnapshot", "canSaveSnapshot", "actionButtonText", "actionButtonIcon", "isLegacy", "operationToTrigger", "editableRepositoryMo"], outputs: ["editInRepository"] }, { kind: "component", type: TextBasedConfigurationComponent, selector: "c8y-text-based-configuration" }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.Eager }); }
|
|
988
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.19", type: DeviceConfigurationComponent, isStandalone: true, selector: "c8y-device-configuration", viewQueries: [{ propertyName: "textBasedConfigurationComponent", first: true, predicate: TextBasedConfigurationComponent, descendants: true }], ngImport: i0, template: "<c8y-action-bar-item [placement]=\"'right'\">\n <button\n class=\"btn btn-link\"\n title=\"{{ 'Reload' | translate }}\"\n (click)=\"updateSnapshots()\"\n >\n <i\n c8yIcon=\"refresh\"\n [ngClass]=\"{ 'icon-spin': reloading }\"\n ></i>\n {{ 'Reload' | translate }}\n </button>\n</c8y-action-bar-item>\n\n<div class=\"card content-fullpage card-has-tabs\">\n <div class=\"card-header separator\">\n <div\n class=\"card-title\"\n translate\n >\n Configurations\n </div>\n </div>\n <tabset>\n @if (showBinaryBasedConfig && !showTextBasedConfig) {\n <div class=\"card-header separator\">\n <div class=\"card-title\">{{ 'From repository' | translate }}</div>\n </div>\n }\n @if (!showBinaryBasedConfig && showTextBasedConfig) {\n <div class=\"card-header separator\">\n <div class=\"card-title\">{{ 'Custom' | translate }}</div>\n </div>\n }\n @if (showBinaryBasedConfig) {\n <tab>\n <ng-template tabHeading>\n <i\n c8yIcon=\"gears\"\n aria-hidden=\"true\"\n ></i>\n {{ 'From repository' | translate }}\n </ng-template>\n <c8y-resizable-grid\n [orientation]=\"'vertical'\"\n [trackId]=\"'c8y-device-configuration-split-view'\"\n [leftColumnWidth]=\"'50%'\"\n [collapsible]=\"false\"\n >\n <!-- ON DEVICE -->\n <div\n class=\"d-flex d-col fit-h min-height-0\"\n left-pane\n >\n <div class=\"p-l-16 p-r-16\">\n <h5 class=\"legend form-block\">\n <span translate>On device</span>\n </h5>\n </div>\n <div class=\"card--grid grid__col--4-8--md m-b-0 flex-grow min-height-0\">\n <!-- DEVICE SUPPORTED CONFIGURATIONS -->\n <div class=\"card--grid__inner-scroll bg-level-1\">\n <c8y-device-configuration-list\n [itemIcon]=\"'gears'\"\n [items]=\"supportedConfigurations\"\n (configSelected)=\"onConfigTypeSelected($event)\"\n ></c8y-device-configuration-list>\n </div>\n <!-- CONFIGURATION PREVIEW -->\n <div\n class=\"card--grid__inner-scroll d-flex d-col flex-grow min-height-0 bg-component\"\n >\n <div class=\"card-block d-flex d-col flex-grow min-height-0\">\n <!-- EMPTY STATE -->\n @if (!configurationType) {\n <fieldset\n class=\"c8y-fieldset p-l-16 p-r-16 p-b-16 flex-grow d-flex d-col min-height-0\"\n >\n <legend translate>Preview</legend>\n <c8y-ui-empty-state\n [icon]=\"'file-text'\"\n [title]=\"'No configuration selected.' | translate\"\n [subtitle]=\"'Select a configuration to preview.' | translate\"\n [horizontal]=\"true\"\n ></c8y-ui-empty-state>\n </fieldset>\n }\n <!-- PREVIEW AVAILABLE STATE -->\n @if (configurationType) {\n <c8y-device-configuration-preview\n class=\"d-flex d-col flex-grow min-height-0\"\n [actionButtonIcon]=\"'arrow-down'\"\n [device]=\"device\"\n [configurationType]=\"configurationType\"\n [configSnapshot]=\"configSnapshot\"\n [canSaveSnapshot]=\"true\"\n [operationToTrigger]=\"'c8y_UploadConfigFile'\"\n [actionButtonText]=\"'Get snapshot from device' | translate\"\n [isLegacy]=\"isLegacy\"\n ></c8y-device-configuration-preview>\n }\n </div>\n </div>\n </div>\n </div>\n\n <!-- AVAILABLE FROM REPOSITORY: depends on the on-device selection above -->\n <div\n class=\"d-flex d-col fit-h min-height-0\"\n right-pane\n >\n <div class=\"p-l-16 p-r-16\">\n <h5 class=\"legend form-block\">\n <span\n class=\"m-r-8\"\n translate\n >\n Available from repository\n </span>\n <button\n class=\"btn-help\"\n [attr.aria-label]=\"'Help' | translate\"\n popover=\"{{\n 'Supported predefined configurations you can send to this device' | translate\n }}\"\n placement=\"right\"\n triggers=\"focus\"\n container=\"body\"\n type=\"button\"\n >\n <i c8yIcon=\"question-circle-o\"></i>\n </button>\n </h5>\n </div>\n <div class=\"card--grid grid__col--4-8--md m-b-0 flex-grow min-height-0\">\n <!-- AVAILABLE SUPPORTED CONFIGURATIONS -->\n <div class=\"card--grid__inner-scroll bg-level-1\">\n <!-- EMPTY STATE -->\n @if (!configurationType) {\n <c8y-ui-empty-state\n [icon]=\"'gears'\"\n [title]=\"'No configuration selected.' | translate\"\n [subtitle]=\"\n 'Select a configuration type from the list above to view matching repository items.'\n | translate\n \"\n [horizontal]=\"true\"\n ></c8y-ui-empty-state>\n }\n @if (configurationType) {\n <div class=\"p-r-16\">\n <c8y-device-configuration-list\n [itemIcon]=\"'file-text'\"\n [items]=\"repositorySnapshots\"\n [emptyState]=\"repositorySnapshotsEmptyState\"\n [isFilterEnabled]=\"true\"\n (configSelected)=\"onRepositoryConfigSelected($event)\"\n ></c8y-device-configuration-list>\n </div>\n }\n </div>\n <!-- CONFIGURATION PREVIEW -->\n <div\n class=\"card--grid__inner-scroll d-flex d-col flex-grow min-height-0 bg-component\"\n >\n <div class=\"card-block d-flex d-col flex-grow min-height-0\">\n <!-- EMPTY STATE -->\n @if (!repositorySnapshot) {\n <fieldset\n class=\"c8y-fieldset p-l-16 p-r-16 p-b-16 flex-grow d-flex d-col min-height-0\"\n >\n <legend translate>Preview</legend>\n <c8y-ui-empty-state\n [icon]=\"'file-text'\"\n [title]=\"'No configuration selected.' | translate\"\n [subtitle]=\"'Select a configuration to preview.' | translate\"\n [horizontal]=\"true\"\n ></c8y-ui-empty-state>\n </fieldset>\n }\n <!-- CONFIGURATION SELECTED STATE -->\n @if (repositorySnapshot) {\n <c8y-device-configuration-preview\n class=\"d-flex d-col flex-grow min-height-0\"\n [actionButtonIcon]=\"'arrow-up'\"\n [device]=\"device\"\n [configurationType]=\"configurationType\"\n [configSnapshot]=\"repositorySnapshot\"\n [operationToTrigger]=\"'c8y_DownloadConfigFile'\"\n [actionButtonText]=\"'Send configuration to device' | translate\"\n [isLegacy]=\"isLegacy\"\n [editableRepositoryMo]=\"selectedRepositoryMo\"\n (editInRepository)=\"openEditInRepository($event)\"\n ></c8y-device-configuration-preview>\n }\n </div>\n </div>\n </div>\n </div>\n </c8y-resizable-grid>\n </tab>\n }\n @if (showTextBasedConfig) {\n <tab>\n <ng-template tabHeading>\n <i\n c8yIcon=\"code\"\n aria-hidden=\"true\"\n ></i>\n {{ 'Custom' | translate }}\n </ng-template>\n <c8y-text-based-configuration></c8y-text-based-configuration>\n </tab>\n }\n </tabset>\n</div>\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: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: TabsetAriaDirective, selector: "tabset" }, { kind: "component", type: TabsetComponent, selector: "tabset", inputs: ["vertical", "justified", "type"] }, { kind: "directive", type: TabDirective, selector: "tab, [tab]", inputs: ["heading", "id", "disabled", "removable", "tabOrder", "customClass", "active"], outputs: ["selectTab", "deselect", "removed"], exportAs: ["tab"] }, { kind: "directive", type: TabHeadingDirective, selector: "[tabHeading]" }, { kind: "directive", type: PopoverDirective, selector: "[popover]", inputs: ["adaptivePosition", "boundariesElement", "popover", "popoverContext", "popoverTitle", "placement", "outsideClick", "triggers", "container", "containerClass", "isOpen", "delay"], outputs: ["onShown", "onHidden"], exportAs: ["bs-popover"] }, { kind: "directive", type: C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "component", type: DeviceConfigurationListComponent, selector: "c8y-device-configuration-list", inputs: ["items", "itemIcon", "emptyState", "isFilterEnabled"], outputs: ["configSelected"] }, { kind: "component", type: EmptyStateComponent, selector: "c8y-ui-empty-state", inputs: ["icon", "title", "subtitle", "horizontal"] }, { kind: "component", type: ConfigurationPreviewComponent, selector: "c8y-device-configuration-preview", inputs: ["device", "configurationType", "configSnapshot", "canSaveSnapshot", "actionButtonText", "actionButtonIcon", "isLegacy", "operationToTrigger", "editableRepositoryMo"], outputs: ["editInRepository"] }, { kind: "component", type: TextBasedConfigurationComponent, selector: "c8y-text-based-configuration" }, { kind: "component", type: ResizableGridComponent, selector: "c8y-resizable-grid", inputs: ["leftColumnWidth", "trackId", "collapseThreshold", "collapsible", "orientation"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.Eager }); }
|
|
935
989
|
}
|
|
936
990
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: DeviceConfigurationComponent, decorators: [{
|
|
937
991
|
type: Component,
|
|
@@ -942,13 +996,16 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImpo
|
|
|
942
996
|
TabsetAriaDirective,
|
|
943
997
|
TabsetComponent,
|
|
944
998
|
TabDirective,
|
|
999
|
+
TabHeadingDirective,
|
|
1000
|
+
PopoverDirective,
|
|
945
1001
|
C8yTranslateDirective,
|
|
946
1002
|
DeviceConfigurationListComponent,
|
|
947
1003
|
EmptyStateComponent,
|
|
948
1004
|
ConfigurationPreviewComponent,
|
|
949
1005
|
TextBasedConfigurationComponent,
|
|
950
|
-
C8yTranslatePipe
|
|
951
|
-
|
|
1006
|
+
C8yTranslatePipe,
|
|
1007
|
+
ResizableGridComponent
|
|
1008
|
+
], changeDetection: ChangeDetectionStrategy.Eager, template: "<c8y-action-bar-item [placement]=\"'right'\">\n <button\n class=\"btn btn-link\"\n title=\"{{ 'Reload' | translate }}\"\n (click)=\"updateSnapshots()\"\n >\n <i\n c8yIcon=\"refresh\"\n [ngClass]=\"{ 'icon-spin': reloading }\"\n ></i>\n {{ 'Reload' | translate }}\n </button>\n</c8y-action-bar-item>\n\n<div class=\"card content-fullpage card-has-tabs\">\n <div class=\"card-header separator\">\n <div\n class=\"card-title\"\n translate\n >\n Configurations\n </div>\n </div>\n <tabset>\n @if (showBinaryBasedConfig && !showTextBasedConfig) {\n <div class=\"card-header separator\">\n <div class=\"card-title\">{{ 'From repository' | translate }}</div>\n </div>\n }\n @if (!showBinaryBasedConfig && showTextBasedConfig) {\n <div class=\"card-header separator\">\n <div class=\"card-title\">{{ 'Custom' | translate }}</div>\n </div>\n }\n @if (showBinaryBasedConfig) {\n <tab>\n <ng-template tabHeading>\n <i\n c8yIcon=\"gears\"\n aria-hidden=\"true\"\n ></i>\n {{ 'From repository' | translate }}\n </ng-template>\n <c8y-resizable-grid\n [orientation]=\"'vertical'\"\n [trackId]=\"'c8y-device-configuration-split-view'\"\n [leftColumnWidth]=\"'50%'\"\n [collapsible]=\"false\"\n >\n <!-- ON DEVICE -->\n <div\n class=\"d-flex d-col fit-h min-height-0\"\n left-pane\n >\n <div class=\"p-l-16 p-r-16\">\n <h5 class=\"legend form-block\">\n <span translate>On device</span>\n </h5>\n </div>\n <div class=\"card--grid grid__col--4-8--md m-b-0 flex-grow min-height-0\">\n <!-- DEVICE SUPPORTED CONFIGURATIONS -->\n <div class=\"card--grid__inner-scroll bg-level-1\">\n <c8y-device-configuration-list\n [itemIcon]=\"'gears'\"\n [items]=\"supportedConfigurations\"\n (configSelected)=\"onConfigTypeSelected($event)\"\n ></c8y-device-configuration-list>\n </div>\n <!-- CONFIGURATION PREVIEW -->\n <div\n class=\"card--grid__inner-scroll d-flex d-col flex-grow min-height-0 bg-component\"\n >\n <div class=\"card-block d-flex d-col flex-grow min-height-0\">\n <!-- EMPTY STATE -->\n @if (!configurationType) {\n <fieldset\n class=\"c8y-fieldset p-l-16 p-r-16 p-b-16 flex-grow d-flex d-col min-height-0\"\n >\n <legend translate>Preview</legend>\n <c8y-ui-empty-state\n [icon]=\"'file-text'\"\n [title]=\"'No configuration selected.' | translate\"\n [subtitle]=\"'Select a configuration to preview.' | translate\"\n [horizontal]=\"true\"\n ></c8y-ui-empty-state>\n </fieldset>\n }\n <!-- PREVIEW AVAILABLE STATE -->\n @if (configurationType) {\n <c8y-device-configuration-preview\n class=\"d-flex d-col flex-grow min-height-0\"\n [actionButtonIcon]=\"'arrow-down'\"\n [device]=\"device\"\n [configurationType]=\"configurationType\"\n [configSnapshot]=\"configSnapshot\"\n [canSaveSnapshot]=\"true\"\n [operationToTrigger]=\"'c8y_UploadConfigFile'\"\n [actionButtonText]=\"'Get snapshot from device' | translate\"\n [isLegacy]=\"isLegacy\"\n ></c8y-device-configuration-preview>\n }\n </div>\n </div>\n </div>\n </div>\n\n <!-- AVAILABLE FROM REPOSITORY: depends on the on-device selection above -->\n <div\n class=\"d-flex d-col fit-h min-height-0\"\n right-pane\n >\n <div class=\"p-l-16 p-r-16\">\n <h5 class=\"legend form-block\">\n <span\n class=\"m-r-8\"\n translate\n >\n Available from repository\n </span>\n <button\n class=\"btn-help\"\n [attr.aria-label]=\"'Help' | translate\"\n popover=\"{{\n 'Supported predefined configurations you can send to this device' | translate\n }}\"\n placement=\"right\"\n triggers=\"focus\"\n container=\"body\"\n type=\"button\"\n >\n <i c8yIcon=\"question-circle-o\"></i>\n </button>\n </h5>\n </div>\n <div class=\"card--grid grid__col--4-8--md m-b-0 flex-grow min-height-0\">\n <!-- AVAILABLE SUPPORTED CONFIGURATIONS -->\n <div class=\"card--grid__inner-scroll bg-level-1\">\n <!-- EMPTY STATE -->\n @if (!configurationType) {\n <c8y-ui-empty-state\n [icon]=\"'gears'\"\n [title]=\"'No configuration selected.' | translate\"\n [subtitle]=\"\n 'Select a configuration type from the list above to view matching repository items.'\n | translate\n \"\n [horizontal]=\"true\"\n ></c8y-ui-empty-state>\n }\n @if (configurationType) {\n <div class=\"p-r-16\">\n <c8y-device-configuration-list\n [itemIcon]=\"'file-text'\"\n [items]=\"repositorySnapshots\"\n [emptyState]=\"repositorySnapshotsEmptyState\"\n [isFilterEnabled]=\"true\"\n (configSelected)=\"onRepositoryConfigSelected($event)\"\n ></c8y-device-configuration-list>\n </div>\n }\n </div>\n <!-- CONFIGURATION PREVIEW -->\n <div\n class=\"card--grid__inner-scroll d-flex d-col flex-grow min-height-0 bg-component\"\n >\n <div class=\"card-block d-flex d-col flex-grow min-height-0\">\n <!-- EMPTY STATE -->\n @if (!repositorySnapshot) {\n <fieldset\n class=\"c8y-fieldset p-l-16 p-r-16 p-b-16 flex-grow d-flex d-col min-height-0\"\n >\n <legend translate>Preview</legend>\n <c8y-ui-empty-state\n [icon]=\"'file-text'\"\n [title]=\"'No configuration selected.' | translate\"\n [subtitle]=\"'Select a configuration to preview.' | translate\"\n [horizontal]=\"true\"\n ></c8y-ui-empty-state>\n </fieldset>\n }\n <!-- CONFIGURATION SELECTED STATE -->\n @if (repositorySnapshot) {\n <c8y-device-configuration-preview\n class=\"d-flex d-col flex-grow min-height-0\"\n [actionButtonIcon]=\"'arrow-up'\"\n [device]=\"device\"\n [configurationType]=\"configurationType\"\n [configSnapshot]=\"repositorySnapshot\"\n [operationToTrigger]=\"'c8y_DownloadConfigFile'\"\n [actionButtonText]=\"'Send configuration to device' | translate\"\n [isLegacy]=\"isLegacy\"\n [editableRepositoryMo]=\"selectedRepositoryMo\"\n (editInRepository)=\"openEditInRepository($event)\"\n ></c8y-device-configuration-preview>\n }\n </div>\n </div>\n </div>\n </div>\n </c8y-resizable-grid>\n </tab>\n }\n @if (showTextBasedConfig) {\n <tab>\n <ng-template tabHeading>\n <i\n c8yIcon=\"code\"\n aria-hidden=\"true\"\n ></i>\n {{ 'Custom' | translate }}\n </ng-template>\n <c8y-text-based-configuration></c8y-text-based-configuration>\n </tab>\n }\n </tabset>\n</div>\n" }]
|
|
952
1009
|
}], ctorParameters: () => [{ type: i1.ActivatedRoute }, { type: DeviceConfigurationService }, { type: i3.RepositoryService }], propDecorators: { textBasedConfigurationComponent: [{
|
|
953
1010
|
type: ViewChild,
|
|
954
1011
|
args: [TextBasedConfigurationComponent]
|