UNPKG

@c8y/ngx-components

Version:

Angular modules for Cumulocity IoT applications

886 lines 134 kB
import * as i0 from '@angular/core';
import { Component, Injectable, NgModule, EventEmitter, Output, ViewChild } from '@angular/core';
import * as i1 from '@angular/router';
import * as i3 from '@c8y/client';
import { OperationStatus } from '@c8y/client';
import * as i3$1 from '@c8y/ngx-components';
import { gettext, ModalSelectionMode, hookRoute, ViewContext, CoreModule, ValidationPattern, Status, memoize, BuiltInActionType, NavigatorNode, hookNavigator, FormsModule } from '@c8y/ngx-components';
import * as i2 from '@c8y/ngx-components/repository/shared';
import { PRODUCT_EXPERIENCE_REPOSITORY_SHARED, RepositoryType, RepositorySelectModalComponent, SharedRepositoryModule, RepositoryItemNameGridColumn, DescriptionGridColumn, DeviceTypeGridColumn, VersionsGridColumn } from '@c8y/ngx-components/repository/shared';
import { isEmpty, get, assign, indexOf, has, isUndefined, property } from 'lodash-es';
import * as i1$1 from 'ngx-bootstrap/modal';
import { BehaviorSubject, from, combineLatest, of, merge, pipe, Subject, defer, map as map$1 } from 'rxjs';
import { map, filter, switchMap, shareReplay, take, distinctUntilChanged, debounceTime, tap, distinctUntilKeyChanged, withLatestFrom, takeUntil } from 'rxjs/operators';
import * as i7 from '@angular/common';
import { CommonModule } from '@angular/common';
import * as i7$1 from '@c8y/ngx-components/operations/operation-details';
import { OperationDetailsModule } from '@c8y/ngx-components/operations/operation-details';
import * as i5 from '@angular/forms';
import 'ngx-bootstrap/dropdown';
import * as i6 from 'ngx-bootstrap/popover';
import { PopoverModule } from 'ngx-bootstrap/popover';
import { __decorate, __metadata } from 'tslib';
import * as i5$1 from '@ngx-translate/core';
import * as i10 from 'ngx-bootstrap/tooltip';
import { TooltipModule } from 'ngx-bootstrap/tooltip';
import { DeviceGridModule } from '@c8y/ngx-components/device-grid';

class FirmwareDeviceTabComponent {
    constructor(route, repository, inventory, bsModal, gainsightService) {
        this.route = route;
        this.repository = repository;
        this.inventory = inventory;
        this.bsModal = bsModal;
        this.gainsightService = gainsightService;
        this.PRODUCT_EXPERIENCE = PRODUCT_EXPERIENCE_REPOSITORY_SHARED;
        this.isEmpty = isEmpty;
        this.reloading = false;
        this.device$ = new BehaviorSubject(this.route.parent.snapshot.data.contextData);
        this.deviceFirmwareFragment$ = this.device$.pipe(map(device => device.c8y_Firmware));
        this.firmwareBinary$ = this.deviceFirmwareFragment$.pipe(filter(deviceFirmwareFragment => !isEmpty(deviceFirmwareFragment)), switchMap(deviceFirmwareFragment => from(this.repository.getRepositoryBinaryMoByVersion(deviceFirmwareFragment, RepositoryType.FIRMWARE))), shareReplay(1));
        this.repositoryEntry$ = this.firmwareBinary$.pipe(switchMap(mo => this.repository.getRepositoryEntryMO$(mo)), shareReplay(1));
        this.patches$ = combineLatest(this.firmwareBinary$, this.repositoryEntry$).pipe(switchMap(([firmwareBinary, repositoryEntry]) => {
            if (repositoryEntry && firmwareBinary) {
                const version = this.repository.getBaseVersionFromMO(firmwareBinary);
                return from(this.repository.listPatchVersions(repositoryEntry, version)).pipe(map(({ data }) => data));
            }
            else {
                return of([]);
            }
        }), shareReplay(1));
        this.supportsFirmwareOperations$ = this.device$.pipe(map((device) => get(device, 'c8y_SupportedOperations', []).indexOf('c8y_Firmware') > -1));
        this.changesOperation$ = new BehaviorSubject(null);
        this.changesInProgress$ = this.changesOperation$.pipe(map(operation => this.isInProgress(operation)));
    }
    async ngOnInit() {
        // TODO check route snapshot, why is not refreshing device.
        // Scenario: missing deviceFirmwareFragment => install new version => switch tabs.
        // Expected: device should be set.
        await this.loadDevice();
        await this.loadOperation();
    }
    installFirmware() {
        const initialState = {
            repositoryEntriesWithVersions$: of([]),
            repositoryEntriesWithVersionsFn$: modal => this.getRepositoryEntriesWithVersions$(modal.content.searchTerm),
            repositoryType: RepositoryType.FIRMWARE,
            title: gettext('Install firmware'),
            subTitle: gettext('Available firmwares matching the device type'),
            icon: 'c8y-firmware',
            mode: ModalSelectionMode.SINGLE,
            labels: { ok: gettext('Install') },
            disableSelected: false
        };
        this.deviceFirmwareFragment$
            .pipe(take(1), switchMap(deviceFirmwareFragment => {
            if (deviceFirmwareFragment) {
                const { name, version } = deviceFirmwareFragment;
                const selected = [{ name, version }];
                assign(initialState, { selected });
            }
            const modal = this.bsModal.show(RepositorySelectModalComponent, {
                ignoreBackdropClick: true,
                initialState
            });
            if (initialState.repositoryEntriesWithVersionsFn$) {
                modal.content.repositoryEntriesWithVersions$ =
                    initialState.repositoryEntriesWithVersionsFn$(modal);
            }
            modal.content.load.next();
            return modal.content.resultEmitter;
        }))
            .subscribe(([selectedFirmware]) => {
            this.handleOperation(selectedFirmware);
        });
    }
    getRepositoryEntriesWithVersions$(searchTerm$) {
        return searchTerm$.pipe(distinctUntilChanged(), switchMap(searchTerm => this.repository.listRepositoryEntries(RepositoryType.FIRMWARE, {
            query: this.repository.getDeviceTypeQuery(RepositoryType.FIRMWARE, this.device$.value),
            partialName: searchTerm?.name,
            params: { pageSize: 100 }
        })), map(({ data }) => data), map(mos => this.getAndAssignRepositoryBinaries(mos)), shareReplay(1));
    }
    getAndAssignRepositoryBinaries(mos) {
        mos.forEach(mo => {
            mo.versions = this.repository.listBaseVersions(mo);
        });
        return mos;
    }
    addPatch() {
        const initialState = {
            repositoryType: RepositoryType.FIRMWARE,
            repositoryEntriesWithVersions$: this.getRepositoryEntryWithPatches$(),
            title: gettext('Install firmware'),
            subTitle: gettext('Available firmwares matching the device type'),
            icon: 'c8y-firmware',
            mode: ModalSelectionMode.SINGLE,
            labels: { ok: gettext('Install') },
            disableSelected: false
        };
        this.deviceFirmwareFragment$
            .pipe(take(1), switchMap(deviceFirmwareFragment => {
            if (deviceFirmwareFragment) {
                const { name, version } = deviceFirmwareFragment;
                const selected = [{ name, version }];
                assign(initialState, { selected });
            }
            const modal = this.bsModal.show(RepositorySelectModalComponent, {
                ignoreBackdropClick: true,
                initialState
            });
            modal.content.load.next();
            return modal.content.resultEmitter;
        }))
            .subscribe(([selectedOption]) => {
            this.handleOperation(selectedOption);
        });
    }
    getRepositoryEntryWithPatches$() {
        return combineLatest(this.repositoryEntry$, this.patches$).pipe(map(([repositoryEntry, patches]) => {
            return [{ ...repositoryEntry, versions: patches }];
        }));
    }
    async loadDevice() {
        this.reloading = true;
        const deviceId = this.device$.value.id;
        const device = (await this.inventory.detail(deviceId, { withChildren: false })).data;
        this.device$.next(device);
        this.reloading = false;
    }
    async handleOperation(selectedFirmware) {
        const operation = await this.repository.createFirmwareUpdateOperation(this.device$.value, selectedFirmware);
        this.trackOperation(operation);
        this.gainsightService.triggerEvent(PRODUCT_EXPERIENCE_REPOSITORY_SHARED.FIRMWARE.EVENTS.DEVICE_TAB, {
            component: PRODUCT_EXPERIENCE_REPOSITORY_SHARED.FIRMWARE.COMPONENTS.FIRMWARE_DEVICE_TAB,
            result: PRODUCT_EXPERIENCE_REPOSITORY_SHARED.FIRMWARE.RESULTS.CREATE_FIRMWARE_UPDATE_OPERATION
        });
    }
    async loadOperation() {
        const deviceId = this.device$.value.id;
        const operation = await this.repository.getLastFirmwareUpdateOperation(deviceId);
        this.trackOperation(operation);
    }
    trackOperation(operation) {
        if ([OperationStatus.SUCCESSFUL, OperationStatus.FAILED].includes(operation?.status)) {
            this.changesOperation$.next(undefined);
        }
        else
            this.changesOperation$.next(operation);
        if (this.isInProgress(operation)) {
            this.repository.observeOperation(operation).subscribe(operationUpdate => {
                this.changesOperation$.next(operationUpdate);
                if (operationUpdate.status === OperationStatus.SUCCESSFUL) {
                    this.loadDevice();
                }
            }, operationUpdate => {
                this.changesOperation$.next(operationUpdate);
            });
        }
    }
    isInProgress(operation) {
        return (operation && [OperationStatus.PENDING, OperationStatus.EXECUTING].includes(operation.status));
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FirmwareDeviceTabComponent, deps: [{ token: i1.ActivatedRoute }, { token: i2.RepositoryService }, { token: i3.InventoryService }, { token: i1$1.BsModalService }, { token: i3$1.GainsightService }], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: FirmwareDeviceTabComponent, selector: "c8y-firmware-device-tab", ngImport: i0, template: "<div class=\"row\">\n  <div class=\"col-lg-12 col-lg-max\">\n    <div class=\"card split-view--7-5 m-b-0\">\n      <div class=\"d-flex d-col flex-grow split-view__list\">\n        <div class=\"card-header separator\">\n          <div\n            class=\"card-title\"\n            translate\n          >\n            Current firmware\n          </div>\n        </div>\n        <div class=\"inner-scroll\">\n          <div class=\"card-block p-t-0 p-b-0\">\n            <!-- EMPTY STATE -->\n            <ng-container *ngIf=\"isEmpty(deviceFirmwareFragment$ | async); else firmwareBlock\">\n              <div class=\"c8y-empty-state text-center\">\n                <div\n                  class=\"h1 c8y-icon-duocolor\"\n                  c8yIcon=\"c8y-firmware\"\n                ></div>\n                <p>\n                  <strong translate>No firmware installed.</strong>\n                  <br />\n                  <small translate>Click below to install firmware into this device.</small>\n                </p>\n              </div>\n            </ng-container>\n\n            <!-- FIRMWARE -->\n            <ng-template #firmwareBlock>\n              <c8y-list-group class=\"no-border-last\">\n                <c8y-li>\n                  <c8y-li-icon>\n                    <i c8yIcon=\"c8y-firmware\"></i>\n                  </c8y-li-icon>\n\n                  <c8y-li-body *ngIf=\"deviceFirmwareFragment$ | async as deviceFirmwareFragment\">\n                    <!-- Firmware title -->\n                    <p class=\"text-medium\">\n                      {{ deviceFirmwareFragment.name }}\n                    </p>\n                    <!-- Firmware description -->\n                    <div *ngIf=\"repositoryEntry$ | async as repositoryEntry\">\n                      <span\n                        class=\"text-label-small m-r-4\"\n                        translate\n                      >\n                        Description\n                      </span>\n                      <span>\n                        {{ repositoryEntry.description }}\n                      </span>\n                    </div>\n\n                    <!-- BASE/PATCH VERSION -->\n                    <div class=\"d-flex a-i-baseline\">\n                      <p\n                        class=\"text-label-small m-r-4\"\n                        translate\n                      >\n                        Version\n                      </p>\n                      <p *ngIf=\"deviceFirmwareFragment.version; else versionNotSpecified\">\n                        {{ deviceFirmwareFragment.version }}\n                      </p>\n                      <ng-template #versionNotSpecified>\n                        <p>\n                          <em class=\"text-muted\">({{ 'not specified`version`' | translate }})</em>\n                        </p>\n                      </ng-template>\n                    </div>\n\n                    <!-- ADD PATCH -->\n                    <button\n                      class=\"btn btn-xs btn-primary\"\n                      title=\"{{ 'Patches available' | translate }}\"\n                      *ngIf=\"\n                        (supportsFirmwareOperations$ | async) && (this.patches$ | async)?.length > 0\n                      \"\n                      (click)=\"addPatch()\"\n                      [disabled]=\"changesInProgress$ | async\"\n                      c8yProductExperience\n                      [actionName]=\"PRODUCT_EXPERIENCE.FIRMWARE.EVENTS.DEVICE_TAB\"\n                      [actionData]=\"{\n                        component: PRODUCT_EXPERIENCE.FIRMWARE.COMPONENTS.FIRMWARE_DEVICE_TAB,\n                        action:\n                          PRODUCT_EXPERIENCE.FIRMWARE.ACTIONS.OPEN_INSTALL_FIRMWARE_PATCH_DIALOG\n                      }\"\n                    >\n                      {{ 'Patches available' | translate }}\n                    </button>\n                  </c8y-li-body>\n                </c8y-li>\n              </c8y-list-group>\n            </ng-template>\n          </div>\n        </div>\n        <div\n          class=\"card-footer separator-top\"\n          *ngIf=\"supportsFirmwareOperations$ | async\"\n        >\n          <!-- INSTALL FIRMWARE -->\n          <button\n            class=\"btn btn-primary\"\n            title=\"{{ 'Install firmware' | translate }}\"\n            *ngIf=\"isEmpty(deviceFirmwareFragment$ | async)\"\n            (click)=\"installFirmware()\"\n            c8yProductExperience\n            [actionName]=\"PRODUCT_EXPERIENCE.FIRMWARE.EVENTS.DEVICE_TAB\"\n            [actionData]=\"{\n              component: PRODUCT_EXPERIENCE.FIRMWARE.COMPONENTS.FIRMWARE_DEVICE_TAB,\n              action: PRODUCT_EXPERIENCE.FIRMWARE.ACTIONS.OPEN_INSTALL_FIRMWARE_DIALOG\n            }\"\n          >\n            {{ 'Install firmware' | translate }}\n          </button>\n\n          <!-- REPLACE FIRMWARE -->\n          <button\n            class=\"btn btn-primary\"\n            title=\"{{ 'Replace firmware' | translate }}\"\n            *ngIf=\"!isEmpty(deviceFirmwareFragment$ | async)\"\n            (click)=\"installFirmware()\"\n            [disabled]=\"changesInProgress$ | async\"\n            c8yProductExperience\n            [actionName]=\"PRODUCT_EXPERIENCE.FIRMWARE.EVENTS.DEVICE_TAB\"\n            [actionData]=\"{\n              component: PRODUCT_EXPERIENCE.FIRMWARE.COMPONENTS.FIRMWARE_DEVICE_TAB,\n              action: PRODUCT_EXPERIENCE.FIRMWARE.ACTIONS.OPEN_REPLACE_FIRMWARE_DIALOG\n            }\"\n          >\n            {{ 'Replace firmware' | translate }}\n          </button>\n        </div>\n      </div>\n      <div class=\"inner-scroll d-flex d-col bg-level-1 split-view__detail\">\n        <div class=\"card-header separator large-padding sticky-top\">\n          <div\n            class=\"card-title\"\n            translate\n          >\n            Firmware changes\n          </div>\n        </div>\n        <div class=\"flex-grow\">\n          <fieldset\n            class=\"card-block large-padding bg-level-2 p-0\"\n            id=\"operation-block\"\n            *ngIf=\"changesOperation$ | async\"\n          >\n            <c8y-operation-details [operation]=\"changesOperation$ | async\"></c8y-operation-details>\n          </fieldset>\n        </div>\n      </div>\n    </div>\n  </div>\n</div>\n", dependencies: [{ kind: "directive", type: i7.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3$1.IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "directive", type: i3$1.C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "component", type: i3$1.ListGroupComponent, selector: "c8y-list-group" }, { kind: "component", type: i3$1.ListItemComponent, selector: "c8y-list-item, c8y-li", inputs: ["active", "highlighted", "emptyActions", "dense", "collapsed", "selectable"], outputs: ["collapsedChange"] }, { kind: "component", type: i3$1.ListItemIconComponent, selector: "c8y-list-item-icon, c8y-li-icon", inputs: ["icon", "status"] }, { kind: "component", type: i3$1.ListItemBodyComponent, selector: "c8y-list-item-body, c8y-li-body", inputs: ["body"] }, { kind: "directive", type: i3$1.ProductExperienceDirective, selector: "[c8yProductExperience]", inputs: ["actionName", "actionData", "inherit", "suppressDataOverriding"] }, { kind: "component", type: i7$1.OperationDetailsComponent, selector: "c8y-operation-details", inputs: ["operation"] }, { kind: "pipe", type: i7.AsyncPipe, name: "async" }, { kind: "pipe", type: i3$1.C8yTranslatePipe, name: "translate" }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FirmwareDeviceTabComponent, decorators: [{
            type: Component,
            args: [{ selector: 'c8y-firmware-device-tab', template: "<div class=\"row\">\n  <div class=\"col-lg-12 col-lg-max\">\n    <div class=\"card split-view--7-5 m-b-0\">\n      <div class=\"d-flex d-col flex-grow split-view__list\">\n        <div class=\"card-header separator\">\n          <div\n            class=\"card-title\"\n            translate\n          >\n            Current firmware\n          </div>\n        </div>\n        <div class=\"inner-scroll\">\n          <div class=\"card-block p-t-0 p-b-0\">\n            <!-- EMPTY STATE -->\n            <ng-container *ngIf=\"isEmpty(deviceFirmwareFragment$ | async); else firmwareBlock\">\n              <div class=\"c8y-empty-state text-center\">\n                <div\n                  class=\"h1 c8y-icon-duocolor\"\n                  c8yIcon=\"c8y-firmware\"\n                ></div>\n                <p>\n                  <strong translate>No firmware installed.</strong>\n                  <br />\n                  <small translate>Click below to install firmware into this device.</small>\n                </p>\n              </div>\n            </ng-container>\n\n            <!-- FIRMWARE -->\n            <ng-template #firmwareBlock>\n              <c8y-list-group class=\"no-border-last\">\n                <c8y-li>\n                  <c8y-li-icon>\n                    <i c8yIcon=\"c8y-firmware\"></i>\n                  </c8y-li-icon>\n\n                  <c8y-li-body *ngIf=\"deviceFirmwareFragment$ | async as deviceFirmwareFragment\">\n                    <!-- Firmware title -->\n                    <p class=\"text-medium\">\n                      {{ deviceFirmwareFragment.name }}\n                    </p>\n                    <!-- Firmware description -->\n                    <div *ngIf=\"repositoryEntry$ | async as repositoryEntry\">\n                      <span\n                        class=\"text-label-small m-r-4\"\n                        translate\n                      >\n                        Description\n                      </span>\n                      <span>\n                        {{ repositoryEntry.description }}\n                      </span>\n                    </div>\n\n                    <!-- BASE/PATCH VERSION -->\n                    <div class=\"d-flex a-i-baseline\">\n                      <p\n                        class=\"text-label-small m-r-4\"\n                        translate\n                      >\n                        Version\n                      </p>\n                      <p *ngIf=\"deviceFirmwareFragment.version; else versionNotSpecified\">\n                        {{ deviceFirmwareFragment.version }}\n                      </p>\n                      <ng-template #versionNotSpecified>\n                        <p>\n                          <em class=\"text-muted\">({{ 'not specified`version`' | translate }})</em>\n                        </p>\n                      </ng-template>\n                    </div>\n\n                    <!-- ADD PATCH -->\n                    <button\n                      class=\"btn btn-xs btn-primary\"\n                      title=\"{{ 'Patches available' | translate }}\"\n                      *ngIf=\"\n                        (supportsFirmwareOperations$ | async) && (this.patches$ | async)?.length > 0\n                      \"\n                      (click)=\"addPatch()\"\n                      [disabled]=\"changesInProgress$ | async\"\n                      c8yProductExperience\n                      [actionName]=\"PRODUCT_EXPERIENCE.FIRMWARE.EVENTS.DEVICE_TAB\"\n                      [actionData]=\"{\n                        component: PRODUCT_EXPERIENCE.FIRMWARE.COMPONENTS.FIRMWARE_DEVICE_TAB,\n                        action:\n                          PRODUCT_EXPERIENCE.FIRMWARE.ACTIONS.OPEN_INSTALL_FIRMWARE_PATCH_DIALOG\n                      }\"\n                    >\n                      {{ 'Patches available' | translate }}\n                    </button>\n                  </c8y-li-body>\n                </c8y-li>\n              </c8y-list-group>\n            </ng-template>\n          </div>\n        </div>\n        <div\n          class=\"card-footer separator-top\"\n          *ngIf=\"supportsFirmwareOperations$ | async\"\n        >\n          <!-- INSTALL FIRMWARE -->\n          <button\n            class=\"btn btn-primary\"\n            title=\"{{ 'Install firmware' | translate }}\"\n            *ngIf=\"isEmpty(deviceFirmwareFragment$ | async)\"\n            (click)=\"installFirmware()\"\n            c8yProductExperience\n            [actionName]=\"PRODUCT_EXPERIENCE.FIRMWARE.EVENTS.DEVICE_TAB\"\n            [actionData]=\"{\n              component: PRODUCT_EXPERIENCE.FIRMWARE.COMPONENTS.FIRMWARE_DEVICE_TAB,\n              action: PRODUCT_EXPERIENCE.FIRMWARE.ACTIONS.OPEN_INSTALL_FIRMWARE_DIALOG\n            }\"\n          >\n            {{ 'Install firmware' | translate }}\n          </button>\n\n          <!-- REPLACE FIRMWARE -->\n          <button\n            class=\"btn btn-primary\"\n            title=\"{{ 'Replace firmware' | translate }}\"\n            *ngIf=\"!isEmpty(deviceFirmwareFragment$ | async)\"\n            (click)=\"installFirmware()\"\n            [disabled]=\"changesInProgress$ | async\"\n            c8yProductExperience\n            [actionName]=\"PRODUCT_EXPERIENCE.FIRMWARE.EVENTS.DEVICE_TAB\"\n            [actionData]=\"{\n              component: PRODUCT_EXPERIENCE.FIRMWARE.COMPONENTS.FIRMWARE_DEVICE_TAB,\n              action: PRODUCT_EXPERIENCE.FIRMWARE.ACTIONS.OPEN_REPLACE_FIRMWARE_DIALOG\n            }\"\n          >\n            {{ 'Replace firmware' | translate }}\n          </button>\n        </div>\n      </div>\n      <div class=\"inner-scroll d-flex d-col bg-level-1 split-view__detail\">\n        <div class=\"card-header separator large-padding sticky-top\">\n          <div\n            class=\"card-title\"\n            translate\n          >\n            Firmware changes\n          </div>\n        </div>\n        <div class=\"flex-grow\">\n          <fieldset\n            class=\"card-block large-padding bg-level-2 p-0\"\n            id=\"operation-block\"\n            *ngIf=\"changesOperation$ | async\"\n          >\n            <c8y-operation-details [operation]=\"changesOperation$ | async\"></c8y-operation-details>\n          </fieldset>\n        </div>\n      </div>\n    </div>\n  </div>\n</div>\n" }]
        }], ctorParameters: () => [{ type: i1.ActivatedRoute }, { type: i2.RepositoryService }, { type: i3.InventoryService }, { type: i1$1.BsModalService }, { type: i3$1.GainsightService }] });

const FIRMWARE_FRAGMENT = 'c8y_Firmware';
const SUPPORTED_OPERATIONS_FRAGMENT = 'c8y_SupportedOperations';
class FirmwareDeviceTabGuard {
    canActivate(route) {
        const contextData = get(route, 'data.contextData') || get(route, 'parent.data.contextData');
        const supportedOperations = get(contextData, SUPPORTED_OPERATIONS_FRAGMENT);
        return ((!!supportedOperations ? indexOf(supportedOperations, FIRMWARE_FRAGMENT) >= 0 : false) ||
            has(contextData, 'c8y_Firmware'));
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FirmwareDeviceTabGuard, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
    static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FirmwareDeviceTabGuard }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FirmwareDeviceTabGuard, decorators: [{
            type: Injectable
        }] });

class FirmwareRepositoryDeviceTabModule {
    static forRoot() {
        return {
            ngModule: FirmwareRepositoryDeviceTabModule,
            providers: [
                FirmwareDeviceTabGuard,
                hookRoute({
                    context: ViewContext.Device,
                    path: 'firmware',
                    component: FirmwareDeviceTabComponent,
                    label: gettext('Firmware'),
                    icon: 'c8y-firmware',
                    priority: 500,
                    canActivate: [FirmwareDeviceTabGuard]
                })
            ]
        };
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FirmwareRepositoryDeviceTabModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
    static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "18.2.13", ngImport: i0, type: FirmwareRepositoryDeviceTabModule, declarations: [FirmwareDeviceTabComponent], imports: [CommonModule, CoreModule, SharedRepositoryModule, OperationDetailsModule] }); }
    static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FirmwareRepositoryDeviceTabModule, imports: [CommonModule, CoreModule, SharedRepositoryModule, OperationDetailsModule] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FirmwareRepositoryDeviceTabModule, decorators: [{
            type: NgModule,
            args: [{
                    imports: [CommonModule, CoreModule, SharedRepositoryModule, OperationDetailsModule],
                    declarations: [FirmwareDeviceTabComponent]
                }]
        }] });

class AddFirmwarePatchModalComponent {
    constructor(modal, repository, alert) {
        this.modal = modal;
        this.repository = repository;
        this.alert = alert;
        this.PRODUCT_EXPERIENCE = PRODUCT_EXPERIENCE_REPOSITORY_SHARED;
        this.saved = new EventEmitter();
        this.textForFirmwareUrlPopover = gettext(`Path for binaries can vary depending on device agent implementation, for example:
    /firmware/binaries/firmware1.bin
    https://firmware/binary/123
    ftp://firmware/binary/123.tar.gz
  `);
        this.model = {
            selected: undefined,
            dependency: null,
            patchVersion: undefined,
            binary: {
                file: undefined,
                url: undefined
            }
        };
        this.firmwareInput$ = new BehaviorSubject('');
        this.firmwares$ = this.firmwareInput$.pipe(debounceTime(300), distinctUntilChanged(), switchMap(searchStr => from(this.repository.listRepositoryEntries(RepositoryType.FIRMWARE, {
            partialName: searchStr,
            skipLegacy: true
        }))), shareReplay(1));
        this.firmwareSelected$ = new BehaviorSubject(null);
        this.patchDependencyInput$ = new BehaviorSubject('');
        this.saving = false;
        this.firmwarePreselected = false;
        this.baseVersions$ = merge(this.firmwareInput$.pipe(tap(() => {
            this.model.dependency = null;
            if (this.form) {
                this.form.form.get('patchDependency').reset();
            }
        }), switchMap(() => of(null))), this.firmwareSelected$).pipe(switchMap(selectedFirmware => selectedFirmware ? this.repository.listBaseVersions(selectedFirmware) : of(null)), shareReplay(1));
        this.baseVersionsFilterPipe = pipe(switchMap((data) => this.patchDependencyInput$.pipe(map(partialVersion => data.filter((mo) => {
            const version = mo.c8y_Firmware.version?.toLowerCase();
            return (partialVersion.length === 0 || version?.indexOf(partialVersion.toLowerCase()) > -1);
        })))));
    }
    async ngOnInit() {
        this.setInitialState();
    }
    setInitialState() {
        if (this.model.selected) {
            this.firmwarePreselected = true;
            this.firmwareSelected$.next(this.model.selected);
        }
    }
    async save() {
        this.saving = true;
        this.repository
            .create(this.model, RepositoryType.FIRMWARE)
            .then(savedFirmware => {
            this.successMsg();
            this.saving = false;
            this.saved.next(savedFirmware);
            this.cancel();
        })
            .catch(e => {
            this.saving = false;
            this.saved.error(e);
            this.cancel();
        });
    }
    successMsg() {
        const msg = gettext('Firmware patch added.');
        this.alert.success(msg);
    }
    cancel() {
        this.modal.hide();
        this.saved.complete();
    }
    onFile(dropped) {
        if (!isUndefined(dropped.url)) {
            this.model.binary = {
                url: dropped.url
            };
            return;
        }
        else if (dropped.droppedFiles) {
            this.model.binary = {
                file: dropped.droppedFiles[0].file
            };
            return;
        }
        else {
            this.model.binary = {
                file: undefined,
                url: undefined
            };
        }
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AddFirmwarePatchModalComponent, deps: [{ token: i1$1.BsModalRef }, { token: i2.RepositoryService }, { token: i3$1.AlertService }], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: AddFirmwarePatchModalComponent, selector: "c8y-add-firmware-patch-modal.component", outputs: { saved: "saved" }, viewQueries: [{ propertyName: "dropdown", first: true, predicate: ["dropdown"], descendants: true }, { propertyName: "form", first: true, predicate: ["firmwarePatchForm"], descendants: true }], ngImport: i0, template: "<div class=\"viewport-modal\">\n  <div class=\"modal-header dialog-header\">\n    <i [c8yIcon]=\"'c8y-firmware'\"></i>\n    <h4 translate id=\"addFirmwarePatchModalTitle\">Add firmware patch</h4>\n  </div>\n  <div class=\"p-16 text-center separator-bottom\" id=\"addFirmwarePatchModalDescription\">\n    <p class=\"text-medium text-16 m-0\" translate>Select a firmware version</p>\n  </div>\n\n  <form\n    class=\"d-contents\"\n    autocomplete=\"off\"\n    #firmwarePatchForm=\"ngForm\"\n    (ngSubmit)=\"firmwarePatchForm.form.valid && save()\"\n  >\n    <div class=\"modal-inner-scroll\">\n      <div class=\"modal-body\">\n        <div [hidden]=\"firmwarePreselected\">\n          <c8y-form-group>\n            <label for=\"firmwareName\" translate>Firmware</label>\n            <c8y-typeahead\n              [ngModel]=\"model.selected\"\n              name=\"firmwareName\"\n              placeholder=\"{{ 'Select or enter' | translate }}\"\n              (onSearch)=\"firmwareInput$.next($event)\"\n              [allowFreeEntries]=\"false\"\n              [required]=\"true\"\n            >\n              <c8y-li\n                *c8yFor=\"let firmware of firmwares$ | async; loadMore: 'auto'\"\n                class=\"p-l-8 p-r-8 c8y-list__item--link\"\n                (click)=\"model.selected = firmware; firmwareSelected$.next(firmware)\"\n                [active]=\"model.selected === firmware\"\n              >\n                <c8y-highlight\n                  [text]=\"firmware.name || '--'\"\n                  [pattern]=\"firmwareInput$ | async\"\n                ></c8y-highlight>\n              </c8y-li>\n            </c8y-typeahead>\n            <c8y-messages>\n              <c8y-message\n                name=\"notExisting\"\n                [text]=\"'Select one of the existing firmwares.' | translate\"\n              ></c8y-message>\n            </c8y-messages>\n          </c8y-form-group>\n        </div>\n\n        <c8y-form-group>\n          <label for=\"patchDependency\" class=\"m-r-8\" translate>Version</label>\n          <c8y-typeahead\n            [ngModel]=\"model.dependency\"\n            name=\"patchDependency\"\n            data-cy=\"add-firmware-patch-modal--patchDependency\"\n            placeholder=\"{{ 'Select or enter' | translate }}\"\n            (onSearch)=\"patchDependencyInput$.next($event)\"\n            [displayProperty]=\"'c8y_Firmware.version'\"\n            [allowFreeEntries]=\"false\"\n            [disabled]=\"\n              (baseVersions$ | async) === null || (baseVersions$ | async)?.data.length === 0\n            \"\n            [required]=\"true\"\n          >\n            <c8y-li\n              *c8yFor=\"\n                let baseVersion of baseVersions$;\n                loadMore: 'auto';\n                pipe: baseVersionsFilterPipe\n              \"\n              class=\"p-l-8 p-r-8 c8y-list__item--link\"\n              (click)=\"model.dependency = baseVersion\"\n              [active]=\"model.dependency === baseVersion\"\n            >\n              <c8y-highlight\n                [text]=\"baseVersion.c8y_Firmware.version || '--'\"\n                [pattern]=\"patchDependencyInput$ | async\"\n              ></c8y-highlight>\n            </c8y-li>\n          </c8y-typeahead>\n          <c8y-messages>\n            <c8y-message\n              name=\"notExisting\"\n              [text]=\"'Select one of the existing versions.' | translate\"\n            ></c8y-message>\n          </c8y-messages>\n        </c8y-form-group>\n\n        <c8y-form-group>\n          <label for=\"patchVersion\" translate>Patch</label>\n          <input\n            id=\"patchVersion\"\n            class=\"form-control\"\n            autocomplete=\"off\"\n            name=\"patchVersion\"\n            data-cy=\"add-firmware-patch-modal--patchVersion\"\n            [(ngModel)]=\"model.patchVersion\"\n            placeholder=\"{{ 'e.g.' | translate }} 1.0.0\"\n            required\n          />\n        </c8y-form-group>\n\n        <c8y-form-group>\n          <div class=\"legend form-block m-t-40\" translate>Patch file</div>\n          <c8y-file-picker\n            [maxAllowedFiles]=\"1\"\n            (onFilesPicked)=\"onFile($event)\"\n            [fileUrlPopover]=\"textForFirmwareUrlPopover\"\n          ></c8y-file-picker>\n        </c8y-form-group>\n      </div>\n    </div>\n    <div class=\"modal-footer\">\n      <button\n        title=\"{{ 'Cancel' | translate }}\"\n        data-cy=\"add-firmware-patch-modal--cancel-btn\"\n        class=\"btn btn-default\"\n        type=\"button\"\n        (click)=\"cancel()\"\n        [disabled]=\"saving\"\n        translate\n      >\n        Cancel\n      </button>\n      <button\n        title=\"{{ 'Add firmware patch' | translate }}\"\n        class=\"btn btn-primary\"\n        type=\"submit\"\n        [ngClass]=\"{ 'btn-pending': saving }\"\n        [disabled]=\"\n          !firmwarePatchForm.form.valid ||\n          firmwarePatchForm.form.pristine ||\n          (!model.binary?.url && !model.binary?.file) ||\n          saving\n        \"\n        translate\n        c8yProductExperience\n        [actionName]=\"PRODUCT_EXPERIENCE.FIRMWARE.EVENTS.REPOSITORY\"\n        [actionData]=\"{\n          component: PRODUCT_EXPERIENCE.FIRMWARE.COMPONENTS.ADD_FIRMWAR_PATCH_MODAL,\n          result: PRODUCT_EXPERIENCE.FIRMWARE.RESULTS.ADD_FIRMWARE_PATCH\n        }\"\n      >\n        Add firmware patch\n      </button>\n    </div>\n  </form>\n</div>\n", dependencies: [{ kind: "directive", type: i7.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i3$1.IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "directive", type: i3$1.C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "directive", type: i3$1.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: i3$1.HighlightComponent, selector: "c8y-highlight", inputs: ["pattern", "text", "elementClass", "shouldTrimPattern"] }, { kind: "component", type: i3$1.TypeaheadComponent, selector: "c8y-typeahead", inputs: ["required", "maxlength", "disabled", "allowFreeEntries", "placeholder", "displayProperty", "icon", "name", "autoClose", "hideNew", "container", "selected", "highlightFirstItem"], outputs: ["onSearch", "onIconClick"] }, { kind: "directive", type: i5.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i5.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: i5.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i5.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i5.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i5.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i5.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: i3$1.FormGroupComponent, selector: "c8y-form-group", inputs: ["hasError", "hasWarning", "hasSuccess", "novalidation", "status"] }, { kind: "directive", type: i3$1.MessageDirective, selector: "c8y-message", inputs: ["name", "text"] }, { kind: "component", type: i3$1.MessagesComponent, selector: "c8y-messages", inputs: ["show", "defaults", "helpMessage"] }, { kind: "directive", type: i3$1.RequiredInputPlaceholderDirective, selector: "input[required], input[formControlName]" }, { kind: "component", type: i3$1.ListItemComponent, selector: "c8y-list-item, c8y-li", inputs: ["active", "highlighted", "emptyActions", "dense", "collapsed", "selectable"], outputs: ["collapsedChange"] }, { kind: "component", type: i3$1.FilePickerComponent, selector: "c8y-file-picker", inputs: ["maxAllowedFiles", "uploadChoice", "fileUrl", "fileBinary", "config", "filePickerIndex", "fileUrlPopover"], outputs: ["onFilesPicked"] }, { kind: "directive", type: i3$1.ProductExperienceDirective, selector: "[c8yProductExperience]", inputs: ["actionName", "actionData", "inherit", "suppressDataOverriding"] }, { kind: "pipe", type: i7.AsyncPipe, name: "async" }, { kind: "pipe", type: i3$1.C8yTranslatePipe, name: "translate" }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AddFirmwarePatchModalComponent, decorators: [{
            type: Component,
            args: [{ selector: 'c8y-add-firmware-patch-modal.component', template: "<div class=\"viewport-modal\">\n  <div class=\"modal-header dialog-header\">\n    <i [c8yIcon]=\"'c8y-firmware'\"></i>\n    <h4 translate id=\"addFirmwarePatchModalTitle\">Add firmware patch</h4>\n  </div>\n  <div class=\"p-16 text-center separator-bottom\" id=\"addFirmwarePatchModalDescription\">\n    <p class=\"text-medium text-16 m-0\" translate>Select a firmware version</p>\n  </div>\n\n  <form\n    class=\"d-contents\"\n    autocomplete=\"off\"\n    #firmwarePatchForm=\"ngForm\"\n    (ngSubmit)=\"firmwarePatchForm.form.valid && save()\"\n  >\n    <div class=\"modal-inner-scroll\">\n      <div class=\"modal-body\">\n        <div [hidden]=\"firmwarePreselected\">\n          <c8y-form-group>\n            <label for=\"firmwareName\" translate>Firmware</label>\n            <c8y-typeahead\n              [ngModel]=\"model.selected\"\n              name=\"firmwareName\"\n              placeholder=\"{{ 'Select or enter' | translate }}\"\n              (onSearch)=\"firmwareInput$.next($event)\"\n              [allowFreeEntries]=\"false\"\n              [required]=\"true\"\n            >\n              <c8y-li\n                *c8yFor=\"let firmware of firmwares$ | async; loadMore: 'auto'\"\n                class=\"p-l-8 p-r-8 c8y-list__item--link\"\n                (click)=\"model.selected = firmware; firmwareSelected$.next(firmware)\"\n                [active]=\"model.selected === firmware\"\n              >\n                <c8y-highlight\n                  [text]=\"firmware.name || '--'\"\n                  [pattern]=\"firmwareInput$ | async\"\n                ></c8y-highlight>\n              </c8y-li>\n            </c8y-typeahead>\n            <c8y-messages>\n              <c8y-message\n                name=\"notExisting\"\n                [text]=\"'Select one of the existing firmwares.' | translate\"\n              ></c8y-message>\n            </c8y-messages>\n          </c8y-form-group>\n        </div>\n\n        <c8y-form-group>\n          <label for=\"patchDependency\" class=\"m-r-8\" translate>Version</label>\n          <c8y-typeahead\n            [ngModel]=\"model.dependency\"\n            name=\"patchDependency\"\n            data-cy=\"add-firmware-patch-modal--patchDependency\"\n            placeholder=\"{{ 'Select or enter' | translate }}\"\n            (onSearch)=\"patchDependencyInput$.next($event)\"\n            [displayProperty]=\"'c8y_Firmware.version'\"\n            [allowFreeEntries]=\"false\"\n            [disabled]=\"\n              (baseVersions$ | async) === null || (baseVersions$ | async)?.data.length === 0\n            \"\n            [required]=\"true\"\n          >\n            <c8y-li\n              *c8yFor=\"\n                let baseVersion of baseVersions$;\n                loadMore: 'auto';\n                pipe: baseVersionsFilterPipe\n              \"\n              class=\"p-l-8 p-r-8 c8y-list__item--link\"\n              (click)=\"model.dependency = baseVersion\"\n              [active]=\"model.dependency === baseVersion\"\n            >\n              <c8y-highlight\n                [text]=\"baseVersion.c8y_Firmware.version || '--'\"\n                [pattern]=\"patchDependencyInput$ | async\"\n              ></c8y-highlight>\n            </c8y-li>\n          </c8y-typeahead>\n          <c8y-messages>\n            <c8y-message\n              name=\"notExisting\"\n              [text]=\"'Select one of the existing versions.' | translate\"\n            ></c8y-message>\n          </c8y-messages>\n        </c8y-form-group>\n\n        <c8y-form-group>\n          <label for=\"patchVersion\" translate>Patch</label>\n          <input\n            id=\"patchVersion\"\n            class=\"form-control\"\n            autocomplete=\"off\"\n            name=\"patchVersion\"\n            data-cy=\"add-firmware-patch-modal--patchVersion\"\n            [(ngModel)]=\"model.patchVersion\"\n            placeholder=\"{{ 'e.g.' | translate }} 1.0.0\"\n            required\n          />\n        </c8y-form-group>\n\n        <c8y-form-group>\n          <div class=\"legend form-block m-t-40\" translate>Patch file</div>\n          <c8y-file-picker\n            [maxAllowedFiles]=\"1\"\n            (onFilesPicked)=\"onFile($event)\"\n            [fileUrlPopover]=\"textForFirmwareUrlPopover\"\n          ></c8y-file-picker>\n        </c8y-form-group>\n      </div>\n    </div>\n    <div class=\"modal-footer\">\n      <button\n        title=\"{{ 'Cancel' | translate }}\"\n        data-cy=\"add-firmware-patch-modal--cancel-btn\"\n        class=\"btn btn-default\"\n        type=\"button\"\n        (click)=\"cancel()\"\n        [disabled]=\"saving\"\n        translate\n      >\n        Cancel\n      </button>\n      <button\n        title=\"{{ 'Add firmware patch' | translate }}\"\n        class=\"btn btn-primary\"\n        type=\"submit\"\n        [ngClass]=\"{ 'btn-pending': saving }\"\n        [disabled]=\"\n          !firmwarePatchForm.form.valid ||\n          firmwarePatchForm.form.pristine ||\n          (!model.binary?.url && !model.binary?.file) ||\n          saving\n        \"\n        translate\n        c8yProductExperience\n        [actionName]=\"PRODUCT_EXPERIENCE.FIRMWARE.EVENTS.REPOSITORY\"\n        [actionData]=\"{\n          component: PRODUCT_EXPERIENCE.FIRMWARE.COMPONENTS.ADD_FIRMWAR_PATCH_MODAL,\n          result: PRODUCT_EXPERIENCE.FIRMWARE.RESULTS.ADD_FIRMWARE_PATCH\n        }\"\n      >\n        Add firmware patch\n      </button>\n    </div>\n  </form>\n</div>\n" }]
        }], ctorParameters: () => [{ type: i1$1.BsModalRef }, { type: i2.RepositoryService }, { type: i3$1.AlertService }], propDecorators: { saved: [{
                type: Output
            }], dropdown: [{
                type: ViewChild,
                args: ['dropdown', { static: false }]
            }], form: [{
                type: ViewChild,
                args: ['firmwarePatchForm', { static: false }]
            }] } });

class AddFirmwareModalComponent {
    constructor(modal, repositoryService, alert) {
        this.modal = modal;
        this.repositoryService = repositoryService;
        this.alert = alert;
        this.PRODUCT_EXPERIENCE = PRODUCT_EXPERIENCE_REPOSITORY_SHARED;
        this.saved = new EventEmitter();
        this.onInput = new BehaviorSubject('');
        this.model = {
            selected: undefined,
            version: undefined,
            description: undefined,
            deviceType: undefined,
            binary: {
                file: undefined,
                url: undefined
            }
        };
        this.saving = false;
        this.firmwarePreselected = false;
        this.textForFirmwareUrlPopover = gettext(`Path for binaries can vary depending on device agent implementation, for example:
    /firmware/binaries/firmware1.bin
    https://firmware/binary/123
    ftp://firmware/binary/123.tar.gz
  `);
        this.ValidationPattern = ValidationPattern;
    }
    ngOnInit() {
        this.setInitialState();
        this.loadFirmwares();
    }
    setInitialState() {
        if (this.model.selected) {
            this.firmwarePreselected = true;
        }
    }
    loadFirmwares() {
        this.inputSubscription$ = this.onInput
            .pipe(tap(() => {
            if (!this.firmwarePreselected) {
                this.model.description = null;
                if (this.form) {
                    this.form.form.get('description').reset();
                }
            }
        }), debounceTime(300), distinctUntilChanged(), switchMap(searchStr => this.getFirmwareResult(searchStr)))
            .subscribe(result => {
            this.firmwaresResult = result;
        });
    }
    getFirmwareResult(searchStr) {
        return from(this.repositoryService.listRepositoryEntries(RepositoryType.FIRMWARE, {
            partialName: searchStr,
            skipLegacy: true
        }));
    }
    async save() {
        this.saving = true;
        this.repositoryService
            .create(this.model, RepositoryType.FIRMWARE)
            .then(savedFirmware => {
            this.successMsg();
            this.saving = false;
            this.saved.next(savedFirmware);
            this.cancel();
        })
            .catch(e => {
            this.saving = false;
            this.saved.error(e);
            this.cancel();
        });
    }
    successMsg() {
        const msg = gettext('Firmware added.');
        this.alert.success(msg);
    }
    cancel() {
        this.modal.hide();
        this.saved.complete();
    }
    ngOnDestroy() {
        this.inputSubscription$.unsubscribe();
    }
    onFile(dropped) {
        if (!isUndefined(dropped.url)) {
            this.model.binary = {
                url: dropped.url
            };
            return;
        }
        else if (dropped.droppedFiles) {
            this.model.binary = {
                file: dropped.droppedFiles[0].file
            };
            return;
        }
        else {
            this.model.binary = {
                file: undefined,
                url: undefined
            };
        }
    }
    onFirmwareSelect(firmware) {
        assign(this.model, {
            selected: firmware,
            description: firmware.description,
            deviceType: get(firmware, 'c8y_Filter.type')
        });
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AddFirmwareModalComponent, deps: [{ token: i1$1.BsModalRef }, { token: i2.RepositoryService }, { token: i3$1.AlertService }], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: AddFirmwareModalComponent, selector: "c8y-add-firmware-software-modal", outputs: { saved: "saved" }, viewQueries: [{ propertyName: "form", first: true, predicate: ["firmwareForm"], descendants: true }], ngImport: i0, template: "<div class=\"viewport-modal\">\n  <div class=\"modal-header dialog-header\">\n    <i [c8yIcon]=\"'c8y-firmware'\"></i>\n    <div class=\"modal-title\" translate id=\"addFirmwareModalTitle\">Add firmware</div>\n  </div>\n  <div class=\"p-16 text-center separator-bottom\" *ngIf=\"!firmwarePreselected\">\n    <p class=\"text-medium text-16 m-0\" translate>Select or create new firmware</p>\n  </div>\n  <form\n    class=\"d-contents\"\n    autocomplete=\"off\"\n    #firmwareForm=\"ngForm\"\n    (ngSubmit)=\"firmwareForm.form.valid && save()\"\n  >\n    <div class=\"modal-inner-scroll\">\n      <div class=\"modal-body\" id=\"addFirmwareModalDescription\">\n        <div [hidden]=\"firmwarePreselected\">\n          <c8y-form-group>\n            <label for=\"firmwareName\" translate>Firmware</label>\n            <c8y-typeahead\n              [(ngModel)]=\"model.selected\"\n              name=\"firmwareName\"\n              placeholder=\"{{ 'Select or enter' | translate }}\"\n              data-cy=\"add-firmware-modal--input-name\"\n              (onSearch)=\"onInput.next($event)\"\n              [required]=\"true\"\n            >\n              <c8y-li\n                *c8yFor=\"\n                  let firmware of firmwaresResult;\n                  loadMore: 'auto';\n                  notFound: notFoundTemplate\n                \"\n                class=\"p-l-8 p-r-8 c8y-list__item--link\"\n                (click)=\"onFirmwareSelect(firmware)\"\n                [active]=\"model.selected === firmware\"\n              >\n                <c8y-highlight\n                  [text]=\"firmware.name || '--'\"\n                  [pattern]=\"onInput | async\"\n                ></c8y-highlight>\n              </c8y-li>\n              <ng-template #notFoundTemplate>\n                <c8y-li class=\"bg-level-2 p-8\" *ngIf=\"(onInput | async)?.length > 0\">\n                  <span translate>No match found.</span>\n                  <button\n                    class=\"btn btn-primary btn-xs m-l-8\"\n                    type=\"button\"\n                    title=\"{{ 'Add new`firmware`' | translate }}\"\n                    translate\n                  >\n                    Add new`firmware`\n                  </button>\n                </c8y-li>\n              </ng-template>\n            </c8y-typeahead>\n          </c8y-form-group>\n\n          <c8y-form-group>\n            <label for=\"firmwareDescription\" translate>Description</label>\n            <input\n              id=\"firmwareDescription\"\n              data-cy=\"add-firmware-modal--input-description\"\n              class=\"form-control\"\n              autocomplete=\"off\"\n              name=\"description\"\n              [(ngModel)]=\"model.description\"\n              placeholder=\"{{ 'e.g. Firmware for hardware revision B' | translate }}\"\n              [disabled]=\"model.selected?.id\"\n              [required]=\"true\"\n              [pattern]=\"ValidationPattern.rules.noWhiteSpaceOnly.pattern\"\n            />\n          </c8y-form-group>\n\n          <c8y-form-group>\n            <label class=\"control-label\" for=\"firmwareDeviceTypeFilter\">\n              {{ 'Device type filter' | translate }}\n              <button\n                class=\"btn-help\"\n                type=\"button\"\n                [attr.aria-label]=\"'Help' | translate\"\n                popover=\"{{\n                  'If the filter is set, the firmware will show up for installation only for devices of that type. If no filter is set, it will be available for all devices.'\n                    | translate\n                }}\"\n                triggers=\"focus\"\n                placement=\"right\"\n                container=\"body\"\n              ></button>\n            </label>\n            <input\n              id=\"firmwareDeviceTypeFilter\"\n              data-cy=\"add-firmware-modal--firmwareDeviceTypeFilter\"\n              class=\"form-control\"\n              name=\"firmwareDeviceTypeFilter\"\n              [(ngModel)]=\"model.deviceType\"\n              placeholder=\"{{ 'e.g.' | translate }} c8y_Linux\"\n              [disabled]=\"model.selected?.id\"\n              [pattern]=\"ValidationPattern.rules.noWhiteSpaceOnly.pattern\"\n            />\n          </c8y-form-group>\n        </div>\n\n        <c8y-form-group>\n          <label for=\"firmwareVersion\" translate>Version</label>\n          <input\n            id=\"firmwareVersion\"\n            data-cy=\"add-firmware-modal--firmwareVersion\"\n            class=\"form-control\"\n            autocomplete=\"off\"\n            name=\"version\"\n            [(ngModel)]=\"model.version\"\n            placeholder=\"{{ 'e.g.' | translate }} 1.0.0\"\n            [required]=\"true\"\n            [pattern]=\"ValidationPattern.rules.noWhiteSpaceOnly.pattern\"\n          />\n        </c8y-form-group>\n\n        <c8y-form-group>\n          <div class=\"legend form-block m-t-40\" translate>Firmware file</div>\n          <c8y-file-picker\n            [maxAllowedFiles]=\"1\"\n            (onFilesPicked)=\"onFile($event)\"\n            [fileUrlPopover]=\"textForFirmwareUrlPopover\"\n          ></c8y-file-picker>\n        </c8y-form-group>\n      </div>\n    </div>\n    <div class=\"modal-footer\">\n      <button\n        class=\"btn btn-default\"\n        type=\"button\"\n        title=\"{{ 'Cancel' | translate }}\"\n        data-cy=\"add-firmware-modal--cancel-btn\"\n        (click)=\"cancel()\"\n        [disabled]=\"saving\"\n        translate\n      >\n        Cancel\n      </button>\n\n      <button\n        class=\"btn btn-primary\"\n        type=\"submit\"\n        title=\"{{ 'Add firmware' | translate }}\"\n        [ngClass]=\"{ 'btn-pending': saving }\"\n        [disabled]=\"\n          !firmwareForm.form.valid ||\n          firmwareForm.form.pristine ||\n          saving ||\n          (!model.binary?.url && !model.binary?.file)\n        \"\n        [actionName]=\"PRODUCT_EXPERIENCE.FIRMWARE.EVENTS.REPOSITORY\"\n        [actionData]=\"{\n          component: PRODUCT_EXPERIENCE.FIRMWARE.COMPONENTS.ADD_FIRMWARE_MODAL,\n          result:\n            firmwarePreselected || model.selected?.id\n              ? PRODUCT_EXPERIENCE.FIRMWARE.RESULTS.ADD_FIRMWARE_VERSION\n              : PRODUCT_EXPERIENCE.FIRMWARE.RESULTS.ADD_FIRMWARE\n        }\"\n        translate\n        c8yProductExperience\n      >\n        Add firmware\n      </button>\n    </div>\n  </form>\n</div>\n", dependencies: [{ kind: "directive", type: i7.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i7.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3$1.IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "directive", type: i3$1.C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "directive", type: i3$1.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: i3$1.HighlightComponent, selector: "c8y-highlight", inputs: ["pattern", "text", "elementClass", "shouldTrimPattern"] }, { kind: "component", type: i3$1.TypeaheadComponent, selector: "c8y-typeahead", inputs: ["required", "maxlength", "disabled", "allowFreeEntries", "placeholder", "displayProperty", "icon", "name", "autoClose", "hideNew", "container", "selected", "highlightFirstItem"], outputs: ["onSearch", "onIconClick"] }, { kind: "directive", type: i5.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i5.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: i5.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i5.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i5.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i5.PatternValidator, selector: "[pattern][formControlName],[pattern][formControl],[pattern][ngModel]", inputs: ["pattern"] }, { kind: "directive", type: i5.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i5.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: i3$1.FormGroupComponent, selector: "c8y-form-group", inputs: ["hasError", "hasWarning", "hasSuccess", "novalidation", "status"] }, { kind: "directive", type: i3$1.RequiredInputPlaceholderDirective, selector: "input[required], input[formControlName]" }, { kind: "component", type: i3$1.ListItemComponent, selector: "c8y-list-item, c8y-li", inputs: ["active", "highlighted", "emptyActions", "dense", "collapsed", "selectable"], outputs: ["collapsedChange"] }, { kind: "component", type: i3$1.FilePickerComponent, selector: "c8y-file-picker", inputs: ["maxAllowedFiles", "uploadChoice", "fileUrl", "fileBinary", "config", "filePickerIndex", "fileUrlPopover"], outputs: ["onFilesPicked"] }, { kind: "directive", type: i3$1.ProductExperienceDirective, selector: "[c8yProductExperience]", inputs: ["actionName", "actionData", "inherit", "suppressDataOverriding"] }, { kind: "directive", type: i6.PopoverDirective, selector: "[popover]", inputs: ["adaptivePosition", "boundariesElement", "popover", "popoverContext", "popoverTitle", "placement", "outsideClick", "triggers", "container", "containerClass", "isOpen", "delay"], outputs: ["onShown", "onHidden"], exportAs: ["bs-popover"] }, { kind: "pipe", type: i7.AsyncPipe, name: "async" }, { kind: "pipe", type: i3$1.C8yTranslatePipe, name: "translate" }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AddFirmwareModalComponent, decorators: [{
            type: Component,
            args: [{ selector: 'c8y-add-firmware-software-modal', template: "<div class=\"viewport-modal\">\n  <div class=\"modal-header dialog-header\">\n    <i [c8yIcon]=\"'c8y-firmware'\"></i>\n    <div class=\"modal-title\" translate id=\"addFirmwareModalTitle\">Add firmware</div>\n  </div>\n  <div class=\"p-16 text-center separator-bottom\" *ngIf=\"!firmwarePreselected\">\n    <p class=\"text-medium text-16 m-0\" translate>Select or create new firmware</p>\n  </div>\n  <form\n    class=\"d-contents\"\n    autocomplete=\"off\"\n    #firmwareForm=\"ngForm\"\n    (ngSubmit)=\"firmwareForm.form.valid && save()\"\n  >\n    <div class=\"modal-inner-scroll\">\n      <div class=\"modal-body\" id=\"addFirmwareModalDescription\">\n        <div [hidden]=\"firmwarePreselected\">\n          <c8y-form-group>\n            <label for=\"firmwareName\" translate>Firmware</label>\n            <c8y-typeahead\n              [(ngModel)]=\"model.selected\"\n              name=\"firmwareName\"\n              placeholder=\"{{ 'Select or enter' | translate }}\"\n              data-cy=\"add-firmware-modal--input-name\"\n              (onSearch)=\"onInput.next($event)\"\n              [required]=\"true\"\n            >\n              <c8y-li\n                *c8yFor=\"\n                  let firmware of firmwaresResult;\n                  loadMore: 'auto';\n                  notFound: notFoundTemplate\n                \"\n                class=\"p-l-8 p-r-8 c8y-list__item--link\"\n                (click)=\"onFirmwareSelect(firmware)\"\n                [active]=\"model.selected === firmware\"\n              >\n                <c8y-highlight\n                  [text]=\"firmware.name || '--'\"\n                  [pattern]=\"onInput | async\"\n                ></c8y-highlight>\n              </c8y-li>\n              <ng-template #notFoundTemplate>\n                <c8y-li class=\"bg-level-2 p-8\" *ngIf=\"(onInput | async)?.length > 0\">\n                  <span translate>No match found.</span>\n                  <button\n                    class=\"btn btn-primary btn-xs m-l-8\"\n                    type=\"button\"\n                    title=\"{{ 'Add new`firmware`' | translate }}\"\n                    translate\n                  >\n                    Add new`firmware`\n                  </button>\n                </c8y-li>\n              </ng-template>\n            </c8y-typeahead>\n          </c8y-form-group>\n\n          <c8y-form-group>\n            <label for=\"firmwareDescription\" translate>Description</label>\n            <input\n              id=\"firmwareDescription\"\n              data-cy=\"add-firmware-modal--input-description\"\n              class=\"form-control\"\n              autocomplete=\"off\"\n              name=\"description\"\n              [(ngModel)]=\"model.description\"\n              placeholder=\"{{ 'e.g. Firmware for hardware revision B' | translate }}\"\n              [disabled]=\"model.selected?.id\"\n              [required]=\"true\"\n              [pattern]=\"ValidationPattern.rules.noWhiteSpaceOnly.pattern\"\n            />\n          </c8y-form-group>\n\n          <c8y-form-group>\n            <label class=\"control-label\" for=\"firmwareDeviceTypeFilter\">\n              {{ 'Device type filter' | translate }}\n              <button\n                class=\"btn-help\"\n                type=\"button\"\n                [attr.aria-label]=\"'Help' | translate\"\n                popover=\"{{\n                  'If the filter is set, the firmware will show up for installation only for devices of that type. If no filter is set, it will be available for all devices.'\n                    | translate\n                }}\"\n                triggers=\"focus\"\n                placement=\"right\"\n                container=\"body\"\n              ></button>\n            </label>\n            <input\n              id=\"firmwareDeviceTypeFilter\"\n              data-cy=\"add-firmware-modal--firmwareDeviceTypeFilter\"\n              class=\"form-control\"\n              name=\"firmwareDeviceTypeFilter\"\n              [(ngModel)]=\"model.deviceType\"\n              placeholder=\"{{ 'e.g.' | translate }} c8y_Linux\"\n              [disabled]=\"model.selected?.id\"\n              [pattern]=\"ValidationPattern.rules.noWhiteSpaceOnly.pattern\"\n            />\n          </c8y-form-group>\n        </div>\n\n        <c8y-form-group>\n          <label for=\"firmwareVersion\" translate>Version</label>\n          <input\n            id=\"firmwareVersion\"\n            data-cy=\"add-firmware-modal--firmwareVersion\"\n            class=\"form-control\"\n            autocomplete=\"off\"\n            name=\"version\"\n            [(ngModel)]=\"model.version\"\n            placeholder=\"{{ 'e.g.' | translate }} 1.0.0\"\n            [required]=\"true\"\n            [pattern]=\"ValidationPattern.rules.noWhiteSpaceOnly.pattern\"\n          />\n        </c8y-form-group>\n\n        <c8y-form-group>\n          <div class=\"legend form-block m-t-40\" translate>Firmware file</div>\n          <c8y-file-picker\n            [maxAllowedFiles]=\"1\"\n            (onFilesPicked)=\"onFile($event)\"\n            [fileUrlPopover]=\"textForFirmwareUrlPopover\"\n          ></c8y-file-picker>\n        </c8y-form-group>\n      </div>\n    </div>\n    <div class=\"modal-footer\">\n      <button\n        class=\"btn btn-default\"\n        type=\"button\"\n        title=\"{{ 'Cancel' | translate }}\"\n        data-cy=\"add-firmware-modal--cancel-btn\"\n        (click)=\"cancel()\"\n        [disabled]=\"saving\"\n        translate\n      >\n        Cancel\n      </button>\n\n      <button\n        class=\"btn btn-primary\"\n        type=\"submit\"\n        title=\"{{ 'Add firmware' | translate }}\"\n        [ngClass]=\"{ 'btn-pending': saving }\"\n        [disabled]=\"\n          !firmwareForm.form.valid ||\n          firmwareForm.form.pristine ||\n          saving ||\n          (!model.binary?.url && !model.binary?.file)\n        \"\n        [actionName]=\"PRODUCT_EXPERIENCE.FIRMWARE.EVENTS.REPOSITORY\"\n        [actionData]=\"{\n          component: PRODUCT_EXPERIENCE.FIRMWARE.COMPONENTS.ADD_FIRMWARE_MODAL,\n          result:\n            firmwarePreselected || model.selected?.id\n              ? PRODUCT_EXPERIENCE.FIRMWARE.RESULTS.ADD_FIRMWARE_VERSION\n              : PRODUCT_EXPERIENCE.FIRMWARE.RESULTS.ADD_FIRMWARE\n        }\"\n        translate\n        c8yProductExperience\n      >\n        Add firmware\n      </button>\n    </div>\n  </form>\n</div>\n" }]
        }], ctorParameters: () => [{ type: i1$1.BsModalRef }, { type: i2.RepositoryService }, { type: i3$1.AlertService }], propDecorators: { form: [{
                type: ViewChild,
                args: ['firmwareForm', { static: false }]
            }], saved: [{
                type: Output
            }] } });

class FirmwareDetailsComponent {
    constructor(activatedRoute, inventoryService, repositoryService, alertService, translateService, modalService, bsModalService, gainsightService, router) {
        this.activatedRoute = activatedRoute;
        this.inventoryService = inventoryService;
        this.repositoryService = repositoryService;
        this.alertService = alertService;
        this.translateService = translateService;
        this.modalService = modalService;
        this.bsModalService = bsModalService;
        this.gainsightService = gainsightService;
        this.router = router;
        this.reload$ = new Subject();
        this.reloading$ = new BehaviorSubject(false);
        this.updateFirmware$ = new Subject();
        this.firmwareUpdated$ = new Subject();
        this.baseVersionsUpdated$ = new Subject();
        this.patchVersionsUpdated$ = new Subject();
        this.firmware$ = merge(this.activatedRoute.params.pipe(map(params => params.id), switchMap(id => defer(() => this.inventoryService.detail(id).then(result => result.data)))), this.reload$.pipe(tap(() => this.reloading$.next(true)), switchMap(() => this.activatedRoute.params), map(params => params.id), switchMap(id => defer(() => this.inventoryService.detail(id).then(result => result.data))), tap(() => this.reloading$.next(false))), this.firmwareUpdated$).pipe(shareReplay(1));
        this.baseVersions$ = merge(this.firmware$.pipe(distinctUntilKeyChanged('id')), this.baseVersionsUpdated$, this.patchVersionsUpdated$, this.reload$).pipe(switchMap(() => this.firmware$), switchMap(firmware => this.repositoryService.listBaseVersions(firmware)), shareReplay(1));
        this.isLegacy$ = this.firmware$.pipe(map(firmware => this.repositoryService.isLegacyEntry(firmware)), shareReplay(1));
        this.canAddPatchVersions$ = combineLatest(this.isLegacy$, this.baseVersions$.pipe(map(({ data }) => data.length > 0))).pipe(map(([isLegacy, hasBaseVersions]) => !isLegacy && hasBaseVersions));
        this.expanded = {};
        this.destroy$ = new Subject();
    }
    ngOnInit() {
        this.updateFirmware$
            .pipe(withLatestFrom(this.firmware$), switchMap(([firmwarePartial, firmware]) => this.inventoryService.update({
            id: firmware.id,
            ...firmwarePartial
        })), map(({ data }) => data), tap(firmware => this.firmwareUpdated$.next(firmware)), tap(() => this.gainsightService.triggerEvent(PRODUCT_EXPERIENCE_REPOSITORY_SHARED.FIRMWARE.EVENTS.REPOSITORY, {
            result: PRODUCT_EXPERIENCE_REPOSITORY_SHARED.FIRMWARE.RESULTS.EDIT_FIRMWARE
        })), tap(() => this.alertService.success(gettext('Saved.'))), takeUntil(this.destroy$))
            .subscribe();
        this.firmware$.subscribe(firmware => {
            this.firmware = firmware;
        });
    }
    getPatchVersionsCount$(baseVersion) {
        return merge(this.firmware$.pipe(distinctUntilKeyChanged('id')), this.baseVersionsUpdated$, this.patchVersionsUpdated$, this.reload$).pipe(switchMap(() => this.firmware$), switchMap(firmware => this.repositoryService.getPatchVersionsCount$(firmware, baseVersion)), shareReplay(1));
    }
    getBinaryName$(binaryUrl) {
        return this.repositoryService.getBinaryName$(binaryUrl);
    }
    getPatchVersions$(baseVersion) {
        return merge(this.firmware$.pipe(distinctUntilKeyChanged('id')), this.patchVersionsUpdated$, this.reload$).pipe(switchMap(() => this.firmware$), switchMap(firmware => this.repositoryService.listPatchVersions(firmware, baseVersion)), shareReplay(1));
    }
    addBaseVersion() {
        this.firmware$
            .pipe(take(1), switchMap(firmware => {
            const initialState = {
                model: {
                    selected: firmware,
                    description: firmware.description
                }
            };
            const config = {
                class: 'modal-sm',
                ignoreBackdropClick: true,
                keyboard: false,
                ariaDescribedby: 'addFirmwareModalDescription',
                ariaLabelledBy: 'addFirmwareModalTitle',
                initialState
            };
            const modalRef = this.bsModalService.show(AddFirmwareModalComponent, config);
            return modalRef.content.saved;
        }))
            .subscribe(() => this.baseVersionsUpdated$.next());
    }
    addPatchVersion() {
        this.firmware$
            .pipe(take(1), switchMap(firmware => {
            const initialState = {
                model: {
                    selected: firmware
                }
            };
            const config = {
                class: 'modal-sm',
                ignoreBackdropClick: true,
                keyboard: false,
                ariaDescribedby: 'addFirmwarePatchModalDescription',
                ariaLabelledBy: 'addFirmwarePatchModalTitle',
                initialState
            };
            const modalRef = this.bsModalService.show(AddFirmwarePatchModalComponent, config);
            return modalRef.content.saved;
        }))
            .subscribe(() => this.patchVersionsUpdated$.next());
    }
    async deleteBaseVersion(baseVersion) {
        try {
            const title = gettext('Delete firmware');
            const body = `
        ${this.translateService.instant(gettext('You are about to delete firmware {{ version }} with all its patches.'), { version: baseVersion.c8y_Firmware.version })}
        ${this.translateService.instant(gettext('This operation is irreversible.'))}
        ${this.translateService.instant(gettext('Do you want to proceed?'))}
      `;
            const labels = {
                ok: gettext('Delete')
            };
            await this.modalService.confirm(title, body, Status.DANGER, labels, {}, { eventName: PRODUCT_EXPERIENCE_REPOSITORY_SHARED.FIRMWARE.EVENTS.REPOSITORY });
            const isLastVersion = await this.baseVersions$
                .pipe(map(versions => versions?.data?.length === 1), take(1))
                .toPromise();
            if (isLastVersion) {
                await this.repositoryService.delete(this.firmware);
                this.router.navigateByUrl('/firmware');
            }
            else {
                await this.repositoryService.delete(baseVersion);
                this.baseVersionsUpdated$.next();
            }
            this.alertService.success(gettext('Firmware deleted.'));
        }
        catch (ex) {
            // only if not cancel from modal
            if (ex) {
                this.alertService.addServerFailure(ex);
            }
        }
    }
    async deletePatchVersion(patchVersion) {
        try {
            const title = gettext('Delete firmware patch');
            const body = `
        ${this.translateService.instant(gettext('You are about to delete firmware patch {{ version }}.'), { version: patchVersion.c8y_Firmware.version })}
        ${this.translateService.instant(gettext('This operation is irreversible.'))}
        ${this.translateService.instant(gettext('Do you want to proceed?'))}
      `;
            const labels = {
                ok: gettext('Delete')
            };
            await this.modalService.confirm(title, body, Status.DANGER, labels, {}, { eventName: PRODUCT_EXPERIENCE_REPOSITORY_SHARED.FIRMWARE.EVENTS.REPOSITORY });
            await this.repositoryService.delete(patchVersion);
            this.alertService.success(gettext('Firmware patch deleted.'));
            this.patchVersionsUpdated$.next();
        }
        catch (ex) {
            // only if not cancel from modal
            if (ex) {
                this.alertService.addServerFailure(ex);
            }
        }
    }
    ngOnDestroy() {
        this.destroy$.next(true);
        this.destroy$.unsubscribe();
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FirmwareDetailsComponent, deps: [{ token: i1.ActivatedRoute }, { token: i3.InventoryService }, { token: i2.RepositoryService }, { token: i3$1.AlertService }, { token: i5$1.TranslateService }, { token: i3$1.ModalService }, { token: i1$1.BsModalService }, { token: i3$1.GainsightService }, { token: i1.Router }], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: FirmwareDetailsComponent, selector: "c8y-firmware-details", ngImport: i0, template: "<c8y-title>\n  {{ (firmware$ | async)?.name }}\n</c8y-title>\n\n<c8y-breadcrumb>\n  <c8y-breadcrumb-item\n    label=\"{{ 'Management' | translate }}\"\n    icon=\"c8y-management\"\n  ></c8y-breadcrumb-item>\n  <c8y-breadcrumb-item\n    path=\"#/firmware\"\n    label=\"{{ 'Firmware repository' | translate }}\"\n    icon=\"c8y-firmware\"\n  ></c8y-breadcrumb-item>\n  <c8y-breadcrumb-item\n    label=\"{{ (firmware$ | async)?.name }}\"\n    icon=\"c8y-firmware\"\n  ></c8y-breadcrumb-item>\n</c8y-breadcrumb>\n\n<c8y-action-bar-item [placement]=\"'right'\">\n  <button\n    *ngIf=\"!(isLegacy$ | async)\"\n    class=\"btn btn-link\"\n    type=\"button\"\n    title=\"{{ 'Add firmware' | translate }}\"\n    data-cy=\"firmware-details--add-firmware-btn\"\n    (click)=\"addBaseVersion()\"\n  >\n    <i c8yIcon=\"plus-circle\"></i>\n    {{ 'Add firmware' | translate }}\n  </button>\n</c8y-action-bar-item>\n\n<c8y-action-bar-item [placement]=\"'right'\">\n  <button\n    *ngIf=\"canAddPatchVersions$ | async\"\n    class=\"btn btn-link\"\n    type=\"button\"\n    title=\"{{ 'Add firmware patch' | translate }}\"\n    data-cy=\"firmware-details--add-firmware-patch-btn\"\n    (click)=\"addPatchVersion()\"\n  >\n    <i c8yIcon=\"plus-circle\"></i>\n    {{ 'Add firmware patch' | translate }}\n  </button>\n</c8y-action-bar-item>\n\n<c8y-action-bar-item [placement]=\"'right'\">\n  <button\n    class=\"btn btn-link\"\n    type=\"button\"\n    title=\"{{ 'Reload' | translate }}\"\n    (click)=\"reload$.next()\"\n  >\n    <i c8yIcon=\"refresh\" [ngClass]=\"{ 'icon-spin': reloading$ | async }\"></i>\n    {{ 'Reload' | translate }}\n  </button>\n</c8y-action-bar-item>\n\n<div class=\"row\">\n  <div class=\"col-lg-12 col-lg-max\">\n    <div class=\"card card--fullpage\">\n      <div class=\"card-block bg-level-1 flex-no-shrink p-t-24 p-b-24\">\n        <div class=\"content-flex-70\">\n          <div class=\"text-center\">\n            <i class=\"c8y-icon-duocolor icon-48 c8y-icon c8y-icon-firmware\"></i>\n            <p>\n              <small class=\"label label-info\">Firmware</small>\n            </p>\n          </div>\n          <div class=\"flex-grow col-10\">\n            <div class=\"row\">\n              <div class=\"col-md-4\">\n                <c8y-form-group>\n                  <label class=\"control-label\">\n                    {{ 'Name' | translate }}\n                  </label>\n                  <div class=\"input-group input-group-editable\">\n                    <input\n                      #nameInput\n                      type=\"text\"\n                      class=\"form-control\"\n                      [ngModel]=\"(firmware$ | async)?.name\"\n                      #nameModel=\"ngModel\"\n                      placeholder=\"{{ 'e.g. My firmware' | translate }}\"\n                      data-cy=\"firmware-details--name-input\"\n                      [ngStyle]=\"{ 'width.ch': (firmware$ | async)?.name?.length + 2 || 36 }\"\n                      required\n                    />\n                    <span></span>\n                    <div class=\"input-group-btn\">\n                      <button\n                        class=\"btn btn-primary\"\n                        type=\"button\"\n                        title=\"{{ 'Save' | translate }}\"\n                        data-cy=\"firmware-details--name-save-btn\"\n                        (click)=\"updateFirmware$.next({ name: nameInput.value }); nameModel.reset()\"\n                        [disabled]=\"nameInput.value.length == 0\"\n                      >\n                        {{ 'Save' | translate }}\n                      </button>\n                    </div>\n                  </div>\n                </c8y-form-group>\n              </div>\n              <div class=\"col-md-4\">\n                <c8y-form-group>\n                  <label class=\"control-label\">\n                    {{ 'Description' | translate }}\n                  </label>\n                  <div class=\"input-group input-group-editable\">\n                    <input\n                      #descriptionInput\n                      type=\"text\"\n                      class=\"form-control\"\n                      [ngModel]=\"(firmware$ | async)?.description\"\n                      #descriptionModel=\"ngModel\"\n                      placeholder=\"{{ 'e.g. Firmware for hardware revision B' | translate }}\"\n                      data-cy=\"firmware-details--description-input\"\n                      [ngStyle]=\"{ 'width.ch': (firmware$ | async)?.description?.length || 36 }\"\n                    />\n                    <span></span>\n                    <div class=\"input-group-btn\">\n                      <button\n                        class=\"btn btn-primary\"\n                        type=\"button\"\n                        title=\"{{ 'Save' | translate }}\"\n                        data-cy=\"firmware-details--description-save-btn\"\n                        (click)=\"\n                          updateFirmware$.next({ description: descriptionInput.value });\n                          descriptionModel.reset()\n                        \"\n                      >\n                        {{ 'Save' | translate }}\n                      </button>\n                    </div>\n                  </div>\n                </c8y-form-group>\n              </div>\n              <div class=\"col-md-4\">\n                <c8y-form-group>\n                  <label class=\"control-label\">\n                    {{ 'Device type filter' | translate }}\n\n                    <button\n                      class=\"btn-help\"\n                      type=\"button\"\n                      [attr.aria-label]=\"'Help' | translate\"\n                      popover=\"{{\n                        'If the filter is set, the firmware will show up for installation only for devices of that type. If no filter is set, it will be available for all devices.'\n                          | translate\n                      }}\"\n                      placement=\"right\"\n                      triggers=\"focus\"\n                      container=\"body\"\n                    >\n                      <i c8yIcon=\"question-circle-o\"></i>\n                    </button>\n                  </label>\n                  <div class=\"input-group input-group-editable\">\n                    <input\n                      #deviceTypeInput\n                      type=\"text\"\n                      class=\"form-control\"\n                      [ngModel]=\"(firmware$ | async)?.c8y_Filter?.type\"\n                      #deviceTypeModel=\"ngModel\"\n                      placeholder=\"{{ 'e.g.' | translate }} c8y_Linux\"\n                      data-cy=\"firmware-details--device-type-filter-input\"\n                      [ngStyle]=\"{ 'width.ch': (firmware$ | async)?.type?.length || 36 }\"\n                    />\n                    <span></span>\n                    <div class=\"input-group-btn\">\n                      <button\n                        class=\"btn btn-primary\"\n                        type=\"button\"\n                        title=\"{{ 'Save' | translate }}\"\n                        data-cy=\"firmware-details--device-type-filter-save-btn\"\n                        (click)=\"\n                          updateFirmware$.next({ c8y_Filter: { type: deviceTypeInput.value } });\n                          deviceTypeModel.reset()\n                        \"\n                      >\n                        {{ 'Save' | translate }}\n                      </button>\n                    </div>\n                  </div>\n                </c8y-form-group>\n              </div>\n            </div>\n          </div>\n        </div>\n      </div>\n      <div class=\"inner-scroll\">\n        <div class=\"card-header separator-top-bottom bg-component sticky-top\">\n          <div class=\"card-title\" translate>Versions and patches</div>\n        </div>\n\n        <div class=\"card-block p-t-0 p-b-24\">\n          <div *ngIf=\"(baseVersions$ | async)?.data.length === 0\">\n            <c8y-ui-empty-state\n              [icon]=\"'c8y-firmware'\"\n              [title]=\"'No versions to display.' | translate\"\n              [subtitle]=\"'Add a new version by clicking below.' | translate\"\n              [horizontal]=\"true\"\n            >\n              <button\n                class=\"btn btn-sm btn-default m-t-8\"\n                type=\"button\"\n                title=\"{{ 'Add firmware' | translate }}\"\n                (click)=\"addBaseVersion()\"\n              >\n                <i c8yIcon=\"plus-circle\"></i>\n                {{ 'Add firmware' | translate }}\n              </button>\n            </c8y-ui-empty-state>\n          </div>\n\n          <c8y-list-group *ngIf=\"(baseVersions$ | async)?.data.length > 0\">\n            <c8y-li\n              *c8yFor=\"let baseVersion of baseVersions$ | async; let i = index; loadMore: 'auto'\"\n              [emptyActions]=\"!(getPatchVersions$(baseVersion) | async)?.data.length\"\n              [collapsed]=\"!expanded[baseVersion.id]\"\n              (collapsedChange)=\"expanded[baseVersion.id] = !$event\"\n            >\n              <c8y-li-icon>\n                <i c8yIcon=\"c8y-firmware\"></i>\n              </c8y-li-icon>\n\n              <c8y-li-body class=\"content-flex-50\">\n                <div class=\"col-4\">\n                  <p class=\"text-truncate\" title=\"{{ baseVersion.c8y_Firmware.version }}\">\n                    {{ baseVersion.c8y_Firmware.version }}\n                  </p>\n                </div>\n                <div class=\"col-5\">\n                  <p class=\"text-truncate\">\n                    <span class=\"text-label-small m-r-8\" translate>File</span>\n                    <span title=\"{{ getBinaryName$(baseVersion.c8y_Firmware.url) | async }}\">\n                      <c8y-file-download\n                        url=\"{{ baseVersion.c8y_Firmware.url }}\"\n                      ></c8y-file-download>\n                    </span>\n                  </p>\n                </div>\n                <div class=\"col-2 d-flex a-i-start\">\n                  <span *ngIf=\"isLegacy$ | async\" class=\"label label-warning m-l-auto-sm\">\n                    {{ 'Legacy' | translate }}\n                  </span>\n\n                  <span *ngIf=\"!(isLegacy$ | async)\">\n                    <span *ngIf=\"(getPatchVersionsCount$(baseVersion) | async) === null\">\n                      <span class=\"label label-info\">\n                        <i c8yIcon=\"circle-o-notch\" class=\"icon-spin\"></i>\n                      </span>\n                    </span>\n                    <span *ngIf=\"(getPatchVersionsCount$(baseVersion) | async) !== null\">\n                      <span [ngPlural]=\"getPatchVersionsCount$(baseVersion) | async\">\n                        <ng-template ngPluralCase=\"=0\">\n                          <span class=\"label label-default m-l-auto-sm\">\n                            <span translate>No patches</span>\n                          </span>\n                        </ng-template>\n                        <ng-template ngPluralCase=\"=1\">\n                          <span class=\"label label-info\">\n                            <span translate>1 patch</span>\n                          </span>\n                        </ng-template>\n                        <ng-template ngPluralCase=\"other\">\n                          <span class=\"label label-info\">\n                            <span\n                              ngNonBindable\n                              translate\n                              [translateParams]=\"{\n                                count: getPatchVersionsCount$(baseVersion) | async\n                              }\"\n                            >\n                              {{ count }} patches\n                            </span>\n                          </span>\n                        </ng-template>\n                      </span>\n                    </span>\n                  </span>\n                </div>\n                <div class=\"fit-h-20 visible-xs\" *ngIf=\"!(isLegacy$ | async)\">\n                  <button\n                    class=\"btn btn-default btn-sm m-t-8\"\n                    type=\"button\"\n                    title=\"{{ 'Delete' | translate }}\"\n                    (click)=\"deleteBaseVersion(baseVersion)\"\n                  >\n                    <i c8yIcon=\"delete\"></i>\n                    {{ 'Delete' | translate }}\n                  </button>\n                </div>\n                <div *ngIf=\"!(isLegacy$ | async)\" class=\"m-l-auto fit-h-20 p-r-8 hidden-xs\">\n                  <button\n                    class=\"btn btn-dot btn-dot--danger showOnHover\"\n                    type=\"button\"\n                    [attr.aria-label]=\"'Delete' | translate\"\n                    data-cy=\"firmware-details--delete-base-version\"\n                    tooltip=\"{{ 'Delete' | translate }}\"\n                    [delay]=\"500\"\n                    (click)=\"deleteBaseVersion(baseVersion)\"\n                  >\n                    <i c8yIcon=\"delete\"></i>\n                  </button>\n                </div>\n              </c8y-li-body>\n              <c8y-li-collapse *ngIf=\"(getPatchVersions$(baseVersion) | async)?.data.length\">\n                <c8y-list-group class=\"separator-top\">\n                  <c8y-li\n                    *c8yFor=\"\n                      let patchVersion of getPatchVersions$(baseVersion) | async;\n                      let i = index;\n                      loadMore: 'auto'\n                    \"\n                  >\n                    <c8y-li-icon>\n                      <i c8yIcon=\"c8y-firmware\"></i>\n                    </c8y-li-icon>\n                    <c8y-li-body class=\"content-flex-50\">\n                      <div class=\"col-4\">\n                        {{ patchVersion.c8y_Firmware.version }}\n                      </div>\n                      <div class=\"col-5\">\n                        <div class=\"text-truncate\">\n                          <span class=\"text-label-small m-r-8\" translate>File</span>\n                          <c8y-file-download\n                            url=\"{{ patchVersion.c8y_Firmware.url }}\"\n                          ></c8y-file-download>\n                        </div>\n                      </div>\n                      <div class=\"visible-xs m-t-8\">\n                        <button\n                          class=\"btn btn-danger btn-xs\"\n                          type=\"button\"\n                          title=\"{{ 'Delete' | translate }}\"\n                          data-cy=\"firmware-details--delete-patch-version\"\n                          (click)=\"deletePatchVersion(patchVersion)\"\n                        >\n                          <i c8yIcon=\"delete\"></i>\n                          {{ 'Delete' | translate }}\n                        </button>\n                      </div>\n                      <div class=\"m-l-auto p-r-8 hidden-xs fit-h-20\">\n                        <button\n                          class=\"btn btn-dot text-danger showOnHover\"\n                          type=\"button\"\n                          [attr.aria-label]=\"'Delete' | translate\"\n                          tooltip=\"{{ 'Delete' | translate }}\"\n                          placement=\"right\"\n                          [delay]=\"500\"\n                          (click)=\"deletePatchVersion(patchVersion)\"\n                        >\n                          <i c8yIcon=\"delete\" data-cy=\"firmware-details--Remove-icon\"></i>\n                        </button>\n                      </div>\n                    </c8y-li-body>\n                  </c8y-li>\n                </c8y-list-group>\n              </c8y-li-collapse>\n            </c8y-li>\n          </c8y-list-group>\n        </div>\n      </div>\n    </div>\n  </div>\n</div>\n", dependencies: [{ kind: "directive", type: i7.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i7.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i7.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: i7.NgPlural, selector: "[ngPlural]", inputs: ["ngPlural"] }, { kind: "directive", type: i7.NgPluralCase, selector: "[ngPluralCase]" }, { kind: "component", type: i3$1.ActionBarItemComponent, selector: "c8y-action-bar-item", inputs: ["placement", "priority", "itemClass", "injector", "groupId", "inGroupPriority"] }, { kind: "component", type: i3$1.BreadcrumbComponent, selector: "c8y-breadcrumb" }, { kind: "component", type: i3$1.BreadcrumbItemComponent, selector: "c8y-breadcrumb-item", inputs: ["icon", "translate", "label", "path", "injector"] }, { kind: "component", type: i3$1.EmptyStateComponent, selector: "c8y-ui-empty-state", inputs: ["icon", "title", "subtitle", "horizontal"] }, { kind: "directive", type: i3$1.IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "directive", type: i3$1.C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "directive", type: i3$1.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: i3$1.TitleComponent, selector: "c8y-title", inputs: ["pageTitleUpdate"] }, { kind: "directive", type: i5.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: i5.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i5.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i5.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i3$1.FormGroupComponent, selector: "c8y-form-group", inputs: ["hasError", "hasWarning", "hasSuccess", "novalidation", "status"] }, { kind: "directive", type: i3$1.RequiredInputPlaceholderDirective, selector: "input[required], input[formControlName]" }, { kind: "component", type: i3$1.ListGroupComponent, selector: "c8y-list-group" }, { kind: "component", type: i3$1.ListItemComponent, selector: "c8y-list-item, c8y-li", inputs: ["active", "highlighted", "emptyActions", "dense", "collapsed", "selectable"], outputs: ["collapsedChange"] }, { kind: "component", type: i3$1.ListItemIconComponent, selector: "c8y-list-item-icon, c8y-li-icon", inputs: ["icon", "status"] }, { kind: "component", type: i3$1.ListItemBodyComponent, selector: "c8y-list-item-body, c8y-li-body", inputs: ["body"] }, { kind: "component", type: i3$1.ListItemCollapseComponent, selector: "c8y-list-item-collapse, c8y-li-collapse", inputs: ["collapseWay"] }, { kind: "directive", type: i6.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: i10.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: i2.FileDownloadComponent, selector: "c8y-file-download", inputs: ["url"] }, { kind: "pipe", type: i7.AsyncPipe, name: "async" }, { kind: "pipe", type: i3$1.C8yTranslatePipe, name: "translate" }] }); }
}
__decorate([
    memoize(property('id')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object]),
    __metadata("design:returntype", void 0)
], FirmwareDetailsComponent.prototype, "getPatchVersionsCount$", null);
__decorate([
    memoize(),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object]),
    __metadata("design:returntype", void 0)
], FirmwareDetailsComponent.prototype, "getBinaryName$", null);
__decorate([
    memoize(property('id')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object]),
    __metadata("design:returntype", void 0)
], FirmwareDetailsComponent.prototype, "getPatchVersions$", null);
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FirmwareDetailsComponent, decorators: [{
            type: Component,
            args: [{ selector: 'c8y-firmware-details', template: "<c8y-title>\n  {{ (firmware$ | async)?.name }}\n</c8y-title>\n\n<c8y-breadcrumb>\n  <c8y-breadcrumb-item\n    label=\"{{ 'Management' | translate }}\"\n    icon=\"c8y-management\"\n  ></c8y-breadcrumb-item>\n  <c8y-breadcrumb-item\n    path=\"#/firmware\"\n    label=\"{{ 'Firmware repository' | translate }}\"\n    icon=\"c8y-firmware\"\n  ></c8y-breadcrumb-item>\n  <c8y-breadcrumb-item\n    label=\"{{ (firmware$ | async)?.name }}\"\n    icon=\"c8y-firmware\"\n  ></c8y-breadcrumb-item>\n</c8y-breadcrumb>\n\n<c8y-action-bar-item [placement]=\"'right'\">\n  <button\n    *ngIf=\"!(isLegacy$ | async)\"\n    class=\"btn btn-link\"\n    type=\"button\"\n    title=\"{{ 'Add firmware' | translate }}\"\n    data-cy=\"firmware-details--add-firmware-btn\"\n    (click)=\"addBaseVersion()\"\n  >\n    <i c8yIcon=\"plus-circle\"></i>\n    {{ 'Add firmware' | translate }}\n  </button>\n</c8y-action-bar-item>\n\n<c8y-action-bar-item [placement]=\"'right'\">\n  <button\n    *ngIf=\"canAddPatchVersions$ | async\"\n    class=\"btn btn-link\"\n    type=\"button\"\n    title=\"{{ 'Add firmware patch' | translate }}\"\n    data-cy=\"firmware-details--add-firmware-patch-btn\"\n    (click)=\"addPatchVersion()\"\n  >\n    <i c8yIcon=\"plus-circle\"></i>\n    {{ 'Add firmware patch' | translate }}\n  </button>\n</c8y-action-bar-item>\n\n<c8y-action-bar-item [placement]=\"'right'\">\n  <button\n    class=\"btn btn-link\"\n    type=\"button\"\n    title=\"{{ 'Reload' | translate }}\"\n    (click)=\"reload$.next()\"\n  >\n    <i c8yIcon=\"refresh\" [ngClass]=\"{ 'icon-spin': reloading$ | async }\"></i>\n    {{ 'Reload' | translate }}\n  </button>\n</c8y-action-bar-item>\n\n<div class=\"row\">\n  <div class=\"col-lg-12 col-lg-max\">\n    <div class=\"card card--fullpage\">\n      <div class=\"card-block bg-level-1 flex-no-shrink p-t-24 p-b-24\">\n        <div class=\"content-flex-70\">\n          <div class=\"text-center\">\n            <i class=\"c8y-icon-duocolor icon-48 c8y-icon c8y-icon-firmware\"></i>\n            <p>\n              <small class=\"label label-info\">Firmware</small>\n            </p>\n          </div>\n          <div class=\"flex-grow col-10\">\n            <div class=\"row\">\n              <div class=\"col-md-4\">\n                <c8y-form-group>\n                  <label class=\"control-label\">\n                    {{ 'Name' | translate }}\n                  </label>\n                  <div class=\"input-group input-group-editable\">\n                    <input\n                      #nameInput\n                      type=\"text\"\n                      class=\"form-control\"\n                      [ngModel]=\"(firmware$ | async)?.name\"\n                      #nameModel=\"ngModel\"\n                      placeholder=\"{{ 'e.g. My firmware' | translate }}\"\n                      data-cy=\"firmware-details--name-input\"\n                      [ngStyle]=\"{ 'width.ch': (firmware$ | async)?.name?.length + 2 || 36 }\"\n                      required\n                    />\n                    <span></span>\n                    <div class=\"input-group-btn\">\n                      <button\n                        class=\"btn btn-primary\"\n                        type=\"button\"\n                        title=\"{{ 'Save' | translate }}\"\n                        data-cy=\"firmware-details--name-save-btn\"\n                        (click)=\"updateFirmware$.next({ name: nameInput.value }); nameModel.reset()\"\n                        [disabled]=\"nameInput.value.length == 0\"\n                      >\n                        {{ 'Save' | translate }}\n                      </button>\n                    </div>\n                  </div>\n                </c8y-form-group>\n              </div>\n              <div class=\"col-md-4\">\n                <c8y-form-group>\n                  <label class=\"control-label\">\n                    {{ 'Description' | translate }}\n                  </label>\n                  <div class=\"input-group input-group-editable\">\n                    <input\n                      #descriptionInput\n                      type=\"text\"\n                      class=\"form-control\"\n                      [ngModel]=\"(firmware$ | async)?.description\"\n                      #descriptionModel=\"ngModel\"\n                      placeholder=\"{{ 'e.g. Firmware for hardware revision B' | translate }}\"\n                      data-cy=\"firmware-details--description-input\"\n                      [ngStyle]=\"{ 'width.ch': (firmware$ | async)?.description?.length || 36 }\"\n                    />\n                    <span></span>\n                    <div class=\"input-group-btn\">\n                      <button\n                        class=\"btn btn-primary\"\n                        type=\"button\"\n                        title=\"{{ 'Save' | translate }}\"\n                        data-cy=\"firmware-details--description-save-btn\"\n                        (click)=\"\n                          updateFirmware$.next({ description: descriptionInput.value });\n                          descriptionModel.reset()\n                        \"\n                      >\n                        {{ 'Save' | translate }}\n                      </button>\n                    </div>\n                  </div>\n                </c8y-form-group>\n              </div>\n              <div class=\"col-md-4\">\n                <c8y-form-group>\n                  <label class=\"control-label\">\n                    {{ 'Device type filter' | translate }}\n\n                    <button\n                      class=\"btn-help\"\n                      type=\"button\"\n                      [attr.aria-label]=\"'Help' | translate\"\n                      popover=\"{{\n                        'If the filter is set, the firmware will show up for installation only for devices of that type. If no filter is set, it will be available for all devices.'\n                          | translate\n                      }}\"\n                      placement=\"right\"\n                      triggers=\"focus\"\n                      container=\"body\"\n                    >\n                      <i c8yIcon=\"question-circle-o\"></i>\n                    </button>\n                  </label>\n                  <div class=\"input-group input-group-editable\">\n                    <input\n                      #deviceTypeInput\n                      type=\"text\"\n                      class=\"form-control\"\n                      [ngModel]=\"(firmware$ | async)?.c8y_Filter?.type\"\n                      #deviceTypeModel=\"ngModel\"\n                      placeholder=\"{{ 'e.g.' | translate }} c8y_Linux\"\n                      data-cy=\"firmware-details--device-type-filter-input\"\n                      [ngStyle]=\"{ 'width.ch': (firmware$ | async)?.type?.length || 36 }\"\n                    />\n                    <span></span>\n                    <div class=\"input-group-btn\">\n                      <button\n                        class=\"btn btn-primary\"\n                        type=\"button\"\n                        title=\"{{ 'Save' | translate }}\"\n                        data-cy=\"firmware-details--device-type-filter-save-btn\"\n                        (click)=\"\n                          updateFirmware$.next({ c8y_Filter: { type: deviceTypeInput.value } });\n                          deviceTypeModel.reset()\n                        \"\n                      >\n                        {{ 'Save' | translate }}\n                      </button>\n                    </div>\n                  </div>\n                </c8y-form-group>\n              </div>\n            </div>\n          </div>\n        </div>\n      </div>\n      <div class=\"inner-scroll\">\n        <div class=\"card-header separator-top-bottom bg-component sticky-top\">\n          <div class=\"card-title\" translate>Versions and patches</div>\n        </div>\n\n        <div class=\"card-block p-t-0 p-b-24\">\n          <div *ngIf=\"(baseVersions$ | async)?.data.length === 0\">\n            <c8y-ui-empty-state\n              [icon]=\"'c8y-firmware'\"\n              [title]=\"'No versions to display.' | translate\"\n              [subtitle]=\"'Add a new version by clicking below.' | translate\"\n              [horizontal]=\"true\"\n            >\n              <button\n                class=\"btn btn-sm btn-default m-t-8\"\n                type=\"button\"\n                title=\"{{ 'Add firmware' | translate }}\"\n                (click)=\"addBaseVersion()\"\n              >\n                <i c8yIcon=\"plus-circle\"></i>\n                {{ 'Add firmware' | translate }}\n              </button>\n            </c8y-ui-empty-state>\n          </div>\n\n          <c8y-list-group *ngIf=\"(baseVersions$ | async)?.data.length > 0\">\n            <c8y-li\n              *c8yFor=\"let baseVersion of baseVersions$ | async; let i = index; loadMore: 'auto'\"\n              [emptyActions]=\"!(getPatchVersions$(baseVersion) | async)?.data.length\"\n              [collapsed]=\"!expanded[baseVersion.id]\"\n              (collapsedChange)=\"expanded[baseVersion.id] = !$event\"\n            >\n              <c8y-li-icon>\n                <i c8yIcon=\"c8y-firmware\"></i>\n              </c8y-li-icon>\n\n              <c8y-li-body class=\"content-flex-50\">\n                <div class=\"col-4\">\n                  <p class=\"text-truncate\" title=\"{{ baseVersion.c8y_Firmware.version }}\">\n                    {{ baseVersion.c8y_Firmware.version }}\n                  </p>\n                </div>\n                <div class=\"col-5\">\n                  <p class=\"text-truncate\">\n                    <span class=\"text-label-small m-r-8\" translate>File</span>\n                    <span title=\"{{ getBinaryName$(baseVersion.c8y_Firmware.url) | async }}\">\n                      <c8y-file-download\n                        url=\"{{ baseVersion.c8y_Firmware.url }}\"\n                      ></c8y-file-download>\n                    </span>\n                  </p>\n                </div>\n                <div class=\"col-2 d-flex a-i-start\">\n                  <span *ngIf=\"isLegacy$ | async\" class=\"label label-warning m-l-auto-sm\">\n                    {{ 'Legacy' | translate }}\n                  </span>\n\n                  <span *ngIf=\"!(isLegacy$ | async)\">\n                    <span *ngIf=\"(getPatchVersionsCount$(baseVersion) | async) === null\">\n                      <span class=\"label label-info\">\n                        <i c8yIcon=\"circle-o-notch\" class=\"icon-spin\"></i>\n                      </span>\n                    </span>\n                    <span *ngIf=\"(getPatchVersionsCount$(baseVersion) | async) !== null\">\n                      <span [ngPlural]=\"getPatchVersionsCount$(baseVersion) | async\">\n                        <ng-template ngPluralCase=\"=0\">\n                          <span class=\"label label-default m-l-auto-sm\">\n                            <span translate>No patches</span>\n                          </span>\n                        </ng-template>\n                        <ng-template ngPluralCase=\"=1\">\n                          <span class=\"label label-info\">\n                            <span translate>1 patch</span>\n                          </span>\n                        </ng-template>\n                        <ng-template ngPluralCase=\"other\">\n                          <span class=\"label label-info\">\n                            <span\n                              ngNonBindable\n                              translate\n                              [translateParams]=\"{\n                                count: getPatchVersionsCount$(baseVersion) | async\n                              }\"\n                            >\n                              {{ count }} patches\n                            </span>\n                          </span>\n                        </ng-template>\n                      </span>\n                    </span>\n                  </span>\n                </div>\n                <div class=\"fit-h-20 visible-xs\" *ngIf=\"!(isLegacy$ | async)\">\n                  <button\n                    class=\"btn btn-default btn-sm m-t-8\"\n                    type=\"button\"\n                    title=\"{{ 'Delete' | translate }}\"\n                    (click)=\"deleteBaseVersion(baseVersion)\"\n                  >\n                    <i c8yIcon=\"delete\"></i>\n                    {{ 'Delete' | translate }}\n                  </button>\n                </div>\n                <div *ngIf=\"!(isLegacy$ | async)\" class=\"m-l-auto fit-h-20 p-r-8 hidden-xs\">\n                  <button\n                    class=\"btn btn-dot btn-dot--danger showOnHover\"\n                    type=\"button\"\n                    [attr.aria-label]=\"'Delete' | translate\"\n                    data-cy=\"firmware-details--delete-base-version\"\n                    tooltip=\"{{ 'Delete' | translate }}\"\n                    [delay]=\"500\"\n                    (click)=\"deleteBaseVersion(baseVersion)\"\n                  >\n                    <i c8yIcon=\"delete\"></i>\n                  </button>\n                </div>\n              </c8y-li-body>\n              <c8y-li-collapse *ngIf=\"(getPatchVersions$(baseVersion) | async)?.data.length\">\n                <c8y-list-group class=\"separator-top\">\n                  <c8y-li\n                    *c8yFor=\"\n                      let patchVersion of getPatchVersions$(baseVersion) | async;\n                      let i = index;\n                      loadMore: 'auto'\n                    \"\n                  >\n                    <c8y-li-icon>\n                      <i c8yIcon=\"c8y-firmware\"></i>\n                    </c8y-li-icon>\n                    <c8y-li-body class=\"content-flex-50\">\n                      <div class=\"col-4\">\n                        {{ patchVersion.c8y_Firmware.version }}\n                      </div>\n                      <div class=\"col-5\">\n                        <div class=\"text-truncate\">\n                          <span class=\"text-label-small m-r-8\" translate>File</span>\n                          <c8y-file-download\n                            url=\"{{ patchVersion.c8y_Firmware.url }}\"\n                          ></c8y-file-download>\n                        </div>\n                      </div>\n                      <div class=\"visible-xs m-t-8\">\n                        <button\n                          class=\"btn btn-danger btn-xs\"\n                          type=\"button\"\n                          title=\"{{ 'Delete' | translate }}\"\n                          data-cy=\"firmware-details--delete-patch-version\"\n                          (click)=\"deletePatchVersion(patchVersion)\"\n                        >\n                          <i c8yIcon=\"delete\"></i>\n                          {{ 'Delete' | translate }}\n                        </button>\n                      </div>\n                      <div class=\"m-l-auto p-r-8 hidden-xs fit-h-20\">\n                        <button\n                          class=\"btn btn-dot text-danger showOnHover\"\n                          type=\"button\"\n                          [attr.aria-label]=\"'Delete' | translate\"\n                          tooltip=\"{{ 'Delete' | translate }}\"\n                          placement=\"right\"\n                          [delay]=\"500\"\n                          (click)=\"deletePatchVersion(patchVersion)\"\n                        >\n                          <i c8yIcon=\"delete\" data-cy=\"firmware-details--Remove-icon\"></i>\n                        </button>\n                      </div>\n                    </c8y-li-body>\n                  </c8y-li>\n                </c8y-list-group>\n              </c8y-li-collapse>\n            </c8y-li>\n          </c8y-list-group>\n        </div>\n      </div>\n    </div>\n  </div>\n</div>\n" }]
        }], ctorParameters: () => [{ type: i1.ActivatedRoute }, { type: i3.InventoryService }, { type: i2.RepositoryService }, { type: i3$1.AlertService }, { type: i5$1.TranslateService }, { type: i3$1.ModalService }, { type: i1$1.BsModalService }, { type: i3$1.GainsightService }, { type: i1.Router }], propDecorators: { getPatchVersionsCount$: [], getBinaryName$: [], getPatchVersions$: [] } });

class FirmwareListComponent {
    constructor(repositoryService, gridService, modalService, bsModalService, translateService, alertService, router, activatedRoute) {
        this.repositoryService = repositoryService;
        this.gridService = gridService;
        this.modalService = modalService;
        this.bsModalService = bsModalService;
        this.translateService = translateService;
        this.alertService = alertService;
        this.router = router;
        this.activatedRoute = activatedRoute;
        this.sizeRequestDone = false;
        this.refresh$ = new EventEmitter();
        this.isDataPresent$ = from(this.repositoryService.listRepositoryEntries(RepositoryType.FIRMWARE, { skipLegacy: true })).pipe(map$1(({ data }) => data.length > 0));
        this.columns = [
            new RepositoryItemNameGridColumn({
                filterLabel: gettext('Filter firmware by name'),
                placeholder: gettext('ubuntu core')
            }),
            new DescriptionGridColumn({
                filterLabel: gettext('Filter firmware by description'),
                placeholder: gettext('Firmware for hardware revision B')
            }),
            new DeviceTypeGridColumn({ filterLabel: gettext('Filter firmware by device type') }),
            new VersionsGridColumn()
        ];
        this.actionControls = [];
        this.pagination = {
            pageSize: 50,
            currentPage: 1
        };
        this.noResultsMessage = gettext('No results to display.');
        this.noDataMessage = gettext('No firmware to display.');
        this.noResultsSubtitle = gettext('Refine your search terms or check your spelling.');
        this.noDataSubtitle = gettext('Add a new firmware by clicking below.');
        this.serverSideDataCallback = this.onDataSourceModifier.bind(this);
    }
    ngOnInit() {
        this.actionControls.push({
            type: BuiltInActionType.Edit,
            callback: this.editFirmware.bind(this)
        });
        this.actionControls.push({
            type: BuiltInActionType.Delete,
            callback: this.deleteFirmware.bind(this)
        });
    }
    addFirmware() {
        const config = {
            class: 'modal-sm',
            ariaDescribedby: 'addFirmwareModalDescription',
            ariaLabelledBy: 'addFirmwareModalTitle',
            ignoreBackdropClick: true,
            keyboard: false
        };
        const modalRef = this.bsModalService.show(AddFirmwareModalComponent, config);
        modalRef.content.saved.subscribe(savedFirmware => this.editFirmware(savedFirmware));
    }
    addFirmwarePatch() {
        const config = {
            class: 'modal-sm',
            ariaDescribedby: 'addFirmwarePatchModalDescription',
            ariaLabelledBy: 'addFirmwarePatchModalTitle',
            ignoreBackdropClick: true,
            keyboard: false
        };
        const modalRef = this.bsModalService.show(AddFirmwarePatchModalComponent, config);
        modalRef.content.saved.subscribe(savedFirmware => this.editFirmware(savedFirmware));
    }
    editFirmware(firmware) {
        this.router.navigate([firmware.id], { relativeTo: this.activatedRoute });
    }
    async deleteFirmware(firmware) {
        try {
            const title = gettext('Delete firmware');
            const body = `
        ${this.translateService.instant(gettext('You are about to delete firmware "{{ name }}" with all its versions and patches.'), { name: firmware.name })}
        ${this.translateService.instant(gettext('This operation is irreversible.'))}
        ${this.translateService.instant(gettext('Do you want to proceed?'))}
      `;
            const labels = {
                ok: gettext('Delete')
            };
            await this.modalService.confirm(title, body, Status.DANGER, labels, {}, { eventName: PRODUCT_EXPERIENCE_REPOSITORY_SHARED.FIRMWARE.EVENTS.REPOSITORY });
            await this.repositoryService.delete(firmware);
            this.alertService.success(gettext('Firmware deleted.'));
            this.refresh$.next();
        }
        catch (ex) {
            // only if not cancel from modal
            if (ex) {
                this.alertService.addServerFailure(ex);
            }
        }
    }
    async onDataSourceModifier(dataSourceModifier) {
        const dataRequest = this.repositoryService.listRepositoryEntries(RepositoryType.FIRMWARE, {
            query: this.gridService.getQueryObj(dataSourceModifier.columns),
            skipDefaultOrder: true,
            params: {
                pageSize: dataSourceModifier.pagination.pageSize,
                currentPage: dataSourceModifier.pagination.currentPage
            }
        });
        const filtererdSizeRequest = this.repositoryService
            .listRepositoryEntries(RepositoryType.FIRMWARE, {
            skipDefaultOrder: true,
            query: this.gridService.getQueryObj(dataSourceModifier.columns),
            params: { pageSize: 1 }
        })
            .then(response => response?.paging?.totalPages);
        this.sizeRequest = this.repositoryService
            .listRepositoryEntries(RepositoryType.FIRMWARE, {
            skipDefaultOrder: true,
            params: { pageSize: 1 }
        })
            .then(response => {
            this.sizeRequestDone = true;
            return response?.paging?.totalPages;
        });
        const [dataResponse, size, filteredSize] = await Promise.all([
            dataRequest,
            this.sizeRequest,
            filtererdSizeRequest
        ]);
        const { res, data, paging } = dataResponse;
        const serverSideDataResult = {
            res,
            data,
            paging,
            filteredSize,
            size
        };
        return serverSideDataResult;
    }
    trackByName(_index, column) {
        return column.name;
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FirmwareListComponent, deps: [{ token: i2.RepositoryService }, { token: i3$1.DataGridService }, { token: i3$1.ModalService }, { token: i1$1.BsModalService }, { token: i5$1.TranslateService }, { token: i3$1.AlertService }, { token: i1.Router }, { token: i1.ActivatedRoute }], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: FirmwareListComponent, selector: "c8y-firmware-list", ngImport: i0, template: "<c8y-title>\n  {{ 'Firmware repository' | translate }}\n</c8y-title>\n\n<c8y-breadcrumb>\n  <c8y-breadcrumb-item\n    icon=\"c8y-management\"\n    label=\"{{ 'Management' | translate }}\"\n  ></c8y-breadcrumb-item>\n  <c8y-breadcrumb-item\n    icon=\"c8y-firmware\"\n    label=\"{{ 'Firmware repository' | translate }}\"\n  ></c8y-breadcrumb-item>\n</c8y-breadcrumb>\n\n<c8y-action-bar-item [placement]=\"'right'\">\n  <button\n    class=\"btn btn-link\"\n    title=\"{{ 'Add firmware' | translate }}\"\n    (click)=\"addFirmware()\"\n    data-cy=\"firmware-list--toolbar-add-firmware-btn\"\n  >\n    <i c8yIcon=\"plus-circle\"></i>\n    {{ 'Add firmware' | translate }}\n  </button>\n</c8y-action-bar-item>\n\n<c8y-action-bar-item [placement]=\"'right'\">\n  <button\n    class=\"btn btn-link\"\n    title=\"{{ 'Add firmware patch' | translate }}\"\n    *ngIf=\"isDataPresent$ | async\"\n    (click)=\"addFirmwarePatch()\"\n  >\n    <i c8yIcon=\"plus-circle\"></i>\n    {{ 'Add firmware patch' | translate }}\n  </button>\n</c8y-action-bar-item>\n\n<c8y-help\n  src=\"/docs/device-management-application/managing-device-data/#managing-firmware\"\n></c8y-help>\n\n<div class=\"content-fullpage border-top border-bottom\">\n  <c8y-data-grid\n    [title]=\"'Firmware' | translate\"\n    [refresh]=\"refresh$\"\n    [pagination]=\"pagination\"\n    [columns]=\"columns\"\n    [actionControls]=\"actionControls\"\n    [infiniteScroll]=\"'auto'\"\n    [serverSideDataCallback]=\"serverSideDataCallback\"\n  >\n    <c8y-ui-empty-state\n      [icon]=\"stats?.size > 0 ? 'search' : 'c8y-tools'\"\n      [title]=\"stats?.size > 0 ? (noResultsMessage | translate) : (noDataMessage | translate)\"\n      [subtitle]=\"stats?.size > 0 ? (noResultsSubtitle | translate) : (noDataSubtitle | translate)\"\n      *emptyStateContext=\"let stats\"\n      [horizontal]=\"stats?.size > 0\"\n    >\n      <p *ngIf=\"stats?.size === 0\">\n        <button\n          class=\"btn btn-primary\"\n          title=\"{{ 'Add firmware' | translate }}\"\n          type=\"button\"\n          (click)=\"addFirmware()\"\n        >\n          {{ 'Add firmware' | translate }}\n        </button>\n      </p>\n    </c8y-ui-empty-state>\n    <ng-container *ngFor=\"let column of columns; trackBy: trackByName\">\n      <c8y-column [name]=\"column.name\"></c8y-column>\n    </ng-container>\n  </c8y-data-grid>\n</div>\n", dependencies: [{ kind: "directive", type: i7.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i7.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i3$1.ActionBarItemComponent, selector: "c8y-action-bar-item", inputs: ["placement", "priority", "itemClass", "injector", "groupId", "inGroupPriority"] }, { kind: "component", type: i3$1.BreadcrumbComponent, selector: "c8y-breadcrumb" }, { kind: "component", type: i3$1.BreadcrumbItemComponent, selector: "c8y-breadcrumb-item", inputs: ["icon", "translate", "label", "path", "injector"] }, { kind: "component", type: i3$1.EmptyStateComponent, selector: "c8y-ui-empty-state", inputs: ["icon", "title", "subtitle", "horizontal"] }, { kind: "directive", type: i3$1.EmptyStateContextDirective, selector: "[emptyStateContext]" }, { kind: "directive", type: i3$1.IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "directive", type: i3$1.ColumnDirective, selector: "c8y-column", inputs: ["name"] }, { kind: "component", type: i3$1.DataGridComponent, selector: "c8y-data-grid", inputs: ["title", "loadMoreItemsLabel", "loadingItemsLabel", "showSearch", "refresh", "columns", "rows", "pagination", "infiniteScroll", "serverSideDataCallback", "selectable", "singleSelection", "selectionPrimaryKey", "displayOptions", "actionControls", "bulkActionControls", "headerActionControls", "searchText", "configureColumnsEnabled", "showCounterWarning", "activeClassName", "expandableRows", "hideReload"], outputs: ["rowMouseOver", "rowMouseLeave", "rowClick", "onConfigChange", "onBeforeFilter", "onBeforeSearch", "onFilter", "itemsSelect", "onReload", "onAddCustomColumn", "onRemoveCustomColumn", "onColumnFilterReset", "onSort", "onPageSizeChange", "onColumnReordered", "onColumnVisibilityChange"] }, { kind: "component", type: i3$1.TitleComponent, selector: "c8y-title", inputs: ["pageTitleUpdate"] }, { kind: "component", type: i3$1.HelpComponent, selector: "c8y-help", inputs: ["src", "isCollapsed", "priority", "icon"] }, { kind: "pipe", type: i7.AsyncPipe, name: "async" }, { kind: "pipe", type: i3$1.C8yTranslatePipe, name: "translate" }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FirmwareListComponent, decorators: [{
            type: Component,
            args: [{ selector: 'c8y-firmware-list', template: "<c8y-title>\n  {{ 'Firmware repository' | translate }}\n</c8y-title>\n\n<c8y-breadcrumb>\n  <c8y-breadcrumb-item\n    icon=\"c8y-management\"\n    label=\"{{ 'Management' | translate }}\"\n  ></c8y-breadcrumb-item>\n  <c8y-breadcrumb-item\n    icon=\"c8y-firmware\"\n    label=\"{{ 'Firmware repository' | translate }}\"\n  ></c8y-breadcrumb-item>\n</c8y-breadcrumb>\n\n<c8y-action-bar-item [placement]=\"'right'\">\n  <button\n    class=\"btn btn-link\"\n    title=\"{{ 'Add firmware' | translate }}\"\n    (click)=\"addFirmware()\"\n    data-cy=\"firmware-list--toolbar-add-firmware-btn\"\n  >\n    <i c8yIcon=\"plus-circle\"></i>\n    {{ 'Add firmware' | translate }}\n  </button>\n</c8y-action-bar-item>\n\n<c8y-action-bar-item [placement]=\"'right'\">\n  <button\n    class=\"btn btn-link\"\n    title=\"{{ 'Add firmware patch' | translate }}\"\n    *ngIf=\"isDataPresent$ | async\"\n    (click)=\"addFirmwarePatch()\"\n  >\n    <i c8yIcon=\"plus-circle\"></i>\n    {{ 'Add firmware patch' | translate }}\n  </button>\n</c8y-action-bar-item>\n\n<c8y-help\n  src=\"/docs/device-management-application/managing-device-data/#managing-firmware\"\n></c8y-help>\n\n<div class=\"content-fullpage border-top border-bottom\">\n  <c8y-data-grid\n    [title]=\"'Firmware' | translate\"\n    [refresh]=\"refresh$\"\n    [pagination]=\"pagination\"\n    [columns]=\"columns\"\n    [actionControls]=\"actionControls\"\n    [infiniteScroll]=\"'auto'\"\n    [serverSideDataCallback]=\"serverSideDataCallback\"\n  >\n    <c8y-ui-empty-state\n      [icon]=\"stats?.size > 0 ? 'search' : 'c8y-tools'\"\n      [title]=\"stats?.size > 0 ? (noResultsMessage | translate) : (noDataMessage | translate)\"\n      [subtitle]=\"stats?.size > 0 ? (noResultsSubtitle | translate) : (noDataSubtitle | translate)\"\n      *emptyStateContext=\"let stats\"\n      [horizontal]=\"stats?.size > 0\"\n    >\n      <p *ngIf=\"stats?.size === 0\">\n        <button\n          class=\"btn btn-primary\"\n          title=\"{{ 'Add firmware' | translate }}\"\n          type=\"button\"\n          (click)=\"addFirmware()\"\n        >\n          {{ 'Add firmware' | translate }}\n        </button>\n      </p>\n    </c8y-ui-empty-state>\n    <ng-container *ngFor=\"let column of columns; trackBy: trackByName\">\n      <c8y-column [name]=\"column.name\"></c8y-column>\n    </ng-container>\n  </c8y-data-grid>\n</div>\n" }]
        }], ctorParameters: () => [{ type: i2.RepositoryService }, { type: i3$1.DataGridService }, { type: i3$1.ModalService }, { type: i1$1.BsModalService }, { type: i5$1.TranslateService }, { type: i3$1.AlertService }, { type: i1.Router }, { type: i1.ActivatedRoute }] });

class FirmwareRepositoryNavigationFactory {
    constructor() {
        this.node = new NavigatorNode({
            label: gettext('Firmware repository'),
            path: 'firmware',
            icon: 'c8y-firmware',
            parent: gettext('Management'),
            priority: 1000
        });
    }
    get() {
        return this.node;
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FirmwareRepositoryNavigationFactory, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
    static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FirmwareRepositoryNavigationFactory }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FirmwareRepositoryNavigationFactory, decorators: [{
            type: Injectable
        }], ctorParameters: () => [] });

class FirmwareRepositoryListModule {
    static forRoot() {
        return {
            ngModule: FirmwareRepositoryListModule,
            providers: [
                hookNavigator(FirmwareRepositoryNavigationFactory),
                hookRoute([
                    {
                        path: 'firmware',
                        component: FirmwareListComponent
                    },
                    {
                        path: 'firmware/:id',
                        component: FirmwareDetailsComponent
                    }
                ])
            ]
        };
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FirmwareRepositoryListModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
    static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "18.2.13", ngImport: i0, type: FirmwareRepositoryListModule, declarations: [FirmwareListComponent,
            FirmwareDetailsComponent,
            AddFirmwareModalComponent,
            AddFirmwarePatchModalComponent], imports: [CommonModule,
            CoreModule,
            FormsModule,
            DeviceGridModule,
            PopoverModule,
            TooltipModule,
            SharedRepositoryModule] }); }
    static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FirmwareRepositoryListModule, imports: [CommonModule,
            CoreModule,
            FormsModule,
            DeviceGridModule,
            PopoverModule,
            TooltipModule,
            SharedRepositoryModule] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FirmwareRepositoryListModule, decorators: [{
            type: NgModule,
            args: [{
                    imports: [
                        CommonModule,
                        CoreModule,
                        FormsModule,
                        DeviceGridModule,
                        PopoverModule,
                        TooltipModule,
                        SharedRepositoryModule
                    ],
                    declarations: [
                        FirmwareListComponent,
                        FirmwareDetailsComponent,
                        AddFirmwareModalComponent,
                        AddFirmwarePatchModalComponent
                    ]
                }]
        }] });

class FirmwareRepositoryModule {
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FirmwareRepositoryModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
    static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "18.2.13", ngImport: i0, type: FirmwareRepositoryModule, imports: [FirmwareRepositoryListModule, FirmwareRepositoryDeviceTabModule] }); }
    static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FirmwareRepositoryModule, imports: [FirmwareRepositoryListModule.forRoot(), FirmwareRepositoryDeviceTabModule.forRoot()] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FirmwareRepositoryModule, decorators: [{
            type: NgModule,
            args: [{
                    imports: [FirmwareRepositoryListModule.forRoot(), FirmwareRepositoryDeviceTabModule.forRoot()]
                }]
        }] });

/**
 * Generated bundle index. Do not edit.
 */

export { AddFirmwareModalComponent, AddFirmwarePatchModalComponent, FirmwareDetailsComponent, FirmwareDeviceTabComponent, FirmwareDeviceTabGuard, FirmwareListComponent, FirmwareRepositoryDeviceTabModule, FirmwareRepositoryListModule, FirmwareRepositoryModule };
//# sourceMappingURL=c8y-ngx-components-repository-firmware.mjs.map