import { __decorate, __metadata } from 'tslib';
import * as i0 from '@angular/core';
import { EventEmitter, Component, Output, ViewChildren, Input, ViewChild, NgModule } from '@angular/core';
import * as i3 from '@c8y/ngx-components';
import { gettext, ListItemRadioComponent, memoize, Status, CoreModule, FormsModule } from '@c8y/ngx-components';
import * as i1 from '@c8y/ngx-components/repository/shared';
import { RepositoryType, SharedRepositoryModule } from '@c8y/ngx-components/repository/shared';
import * as i2 from '@ngx-translate/core';
import { get, uniqWith, isEqual, property, uniq, has } from 'lodash-es';
import { BehaviorSubject, combineLatest, from, Observable } from 'rxjs';
import { switchMap, shareReplay, debounceTime, distinctUntilChanged } from 'rxjs/operators';
import * as i4 from '@angular/common';
import * as i5 from '@angular/forms';
import { ReactiveFormsModule } from '@angular/forms';
import * as i3$1 from '@c8y/ngx-components/operations/stepper-frames';
import { StepperFramesModule } from '@c8y/ngx-components/operations/stepper-frames';
import * as i3$2 from '@c8y/ngx-components/operations/bulk-operation-stepper';
import { BaseStepperComponent, BulkOperationStepperModule } from '@c8y/ngx-components/operations/bulk-operation-stepper';
import { BulkOperationType, hookListBulkType, baseUrl } from '@c8y/ngx-components/operations/bulk-operations-service';

class SelectSoftwareStepComponent {
    constructor(repositoryService, translate) {
        this.repositoryService = repositoryService;
        this.translate = translate;
        this.software = new EventEmitter();
        this.textFilter$ = new BehaviorSubject('');
        this.deviceType$ = new BehaviorSubject('');
        this.softwareTypeFilter$ = new BehaviorSubject('');
        this.deviceTypes = [];
        this.selectedDeviceType = { name: '' };
        this.isLegacy = this.repositoryService.isLegacyEntry.bind(this.repositoryService);
        this.software$ = combineLatest(this.textFilter$, this.deviceType$, this.softwareTypeFilter$).pipe(switchMap(([name, deviceType, softwareType]) => this.getSoftware(name, deviceType, softwareType)), shareReplay(1));
        this.NO_DEVICE_TYPE_AVAILABLE = gettext('No device type available');
        this.loadDeviceTypes();
    }
    getBaseVersionsCount$(software) {
        return this.repositoryService.getBaseVersionsCount$(software).pipe(shareReplay(1));
    }
    getVersions(software) {
        return this.repositoryService.listAllVersions(software);
    }
    getDeviceTypeTitle(software) {
        return get(software, 'c8y_Filter.type', this.translate.instant(this.NO_DEVICE_TYPE_AVAILABLE));
    }
    loadDeviceTypes() {
        this.deviceTypeSubscription = this.deviceType$
            .pipe(debounceTime(300), distinctUntilChanged(), switchMap(searchStr => {
            const query = { 'c8y_Filter.type': `*${searchStr}*` };
            return from(this.repositoryService.listRepositoryEntries(RepositoryType.SOFTWARE, { query }));
        }))
            .subscribe(result => {
            const { data } = result;
            this.deviceTypes = uniqWith(data.map(val => ({ name: val.c8y_Filter.type })), isEqual);
        });
    }
    ngOnDestroy() {
        this.deviceTypeSubscription.unsubscribe();
    }
    resetSelection() {
        this.radioButtons.map(radio => radio.reset());
    }
    selectSoftware({ option, software }) {
        software.selectedId = option.id;
        option.action = 'install';
        this.emitSoftware({ option, software });
    }
    emitSoftware({ option, software }) {
        const emitData = Object.assign({}, { software }, { version: option }, { action: option.action });
        this.software.emit(emitData);
    }
    getSoftware(name, deviceType, softwareType) {
        const query = name ? { name: `*${name}*` } : {};
        if (deviceType) {
            query.__or = [{ 'c8y_Filter.type': deviceType }, { __not: { __has: `c8y_Filter.type` } }];
        }
        if (softwareType) {
            query.__or = { softwareType };
        }
        return this.repositoryService.listRepositoryEntries(RepositoryType.SOFTWARE, { query });
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: SelectSoftwareStepComponent, deps: [{ token: i1.RepositoryService }, { token: i2.TranslateService }], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: SelectSoftwareStepComponent, selector: "c8y-select-software-step", outputs: { software: "software" }, viewQueries: [{ propertyName: "radioButtons", predicate: ListItemRadioComponent, descendants: true }], ngImport: i0, template: "<c8y-select-step-frame\n  [header]=\"'Select software' | translate\"\n  [noResults]=\"\n    ((textFilter$ | async)?.length ||\n      (deviceType$ | async)?.length ||\n      (softwareTypeFilter$ | async)?.length) &&\n    (software$ | async)?.data.length === 0\n  \"\n>\n  <div\n    class=\"row\"\n    filters\n  >\n    <div class=\"col-md-4 m-b-xs-8 m-b-sm-8\">\n      <div class=\"input-group input-group-search\">\n        <input\n          class=\"form-control\"\n          title=\"{{ 'Filter\u2026' | translate }}\"\n          placeholder=\"{{ 'Filter\u2026' | translate }}\"\n          type=\"search\"\n          [ngModel]=\"textFilter$ | async\"\n          (ngModelChange)=\"textFilter$.next($event)\"\n        />\n        <span class=\"input-group-addon\">\n          <i\n            c8yIcon=\"search\"\n            *ngIf=\"(textFilter$ | async).length === 0\"\n          ></i>\n          <i\n            class=\"text-muted\"\n            c8yIcon=\"times\"\n            *ngIf=\"(textFilter$ | async).length > 0\"\n            (click)=\"textFilter$.next('')\"\n          ></i>\n        </span>\n      </div>\n    </div>\n    <div class=\"col-md-4 m-b-xs-8 m-b-sm-8\">\n      <c8y-form-group class=\"m-0\">\n        <c8y-typeahead\n          placeholder=\"{{ 'Type to filter device types\u2026' | translate }}\"\n          name=\"deviceType\"\n          [(ngModel)]=\"selectedDeviceType\"\n          (onSearch)=\"deviceType$.next($event)\"\n          [allowFreeEntries]=\"false\"\n        >\n          <c8y-li\n            class=\"p-l-8 p-r-8 c8y-list__item--link\"\n            (click)=\"selectedDeviceType = { name: '' }; deviceType$.next('')\"\n            [active]=\"!selectedDeviceType?.name\"\n          >\n            <span>{{ 'All device types' | translate }}</span>\n          </c8y-li>\n          <c8y-li\n            class=\"p-l-8 p-r-8 c8y-list__item--link\"\n            *ngFor=\"let deviceType of deviceTypes\"\n            (click)=\"selectedDeviceType = deviceType; deviceType$.next(deviceType.name)\"\n            [active]=\"selectedDeviceType === deviceType\"\n          >\n            <c8y-highlight\n              [text]=\"deviceType.name\"\n              [pattern]=\"deviceType$ | 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 device types.' | translate\"\n          ></c8y-message>\n        </c8y-messages>\n      </c8y-form-group>\n    </div>\n    <div class=\"col-md-4\">\n      <c8y-form-group class=\"m-0\">\n        <c8y-software-type\n          [required]=\"false\"\n          [emitResultsOnly]=\"true\"\n          [showBtnInNotFoundMessage]=\"false\"\n          [allowFreeEntries]=\"false\"\n          [placeholder]=\"'Type to filter software types\u2026' | translate\"\n          [showClearSelectionOption]=\"true\"\n          (onSelectSoftware)=\"softwareTypeFilter$.next($event?.softwareType)\"\n        ></c8y-software-type>\n        <c8y-messages>\n          <c8y-message\n            name=\"notExisting\"\n            [text]=\"'Select one of the existing device types.' | translate\"\n          ></c8y-message>\n        </c8y-messages>\n      </c8y-form-group>\n    </div>\n  </div>\n  <c8y-li\n    class=\"hidden-sm hidden-xs m-r-8 m-l-8\"\n    header\n  >\n    <c8y-li-icon><i class=\"p-l-24\"></i></c8y-li-icon>\n    <c8y-li-body class=\"content-flex-40 p-r-32\">\n      <div class=\"col-5\">\n        <span\n          class=\"text-truncate\"\n          title=\" {{ 'Name' | translate }} \"\n        >\n          {{ 'Name' | translate }}\n        </span>\n      </div>\n      <div class=\"col-2\">\n        <span\n          class=\"text-truncate\"\n          title=\"{{ 'Device type' | translate }}\"\n        >\n          {{ 'Device type' | translate }}\n        </span>\n      </div>\n      <div class=\"col-3\">\n        <span\n          class=\"text-truncate\"\n          title=\"{{ 'Software type' | translate }}\"\n        >\n          {{ 'Software type' | translate }}\n        </span>\n      </div>\n      <div class=\"col-2\">\n        <span\n          class=\"text-truncate\"\n          title=\"{{ 'Versions' | translate }}\"\n        >\n          {{ 'Versions' | translate }}\n        </span>\n      </div>\n    </c8y-li-body>\n  </c8y-li>\n  <c8y-list-group list>\n    <c8y-li\n      *c8yFor=\"let software of software$ | async; loadMore: 'auto'\"\n      #li\n    >\n      <c8y-li-icon>\n        <i c8yIcon=\"c8y-tools\"></i>\n      </c8y-li-icon>\n      <div class=\"content-flex-40\">\n        <div class=\"col-5 m-b-xs-8\">\n          <button\n            class=\"btn-clean\"\n            title=\"{{ software.name }}\"\n            type=\"button\"\n            (click)=\"li.collapsed = !li.collapsed\"\n          >\n            <c8y-highlight\n              [text]=\"software.name\"\n              [pattern]=\"textFilter$ | async\"\n            ></c8y-highlight>\n          </button>\n        </div>\n        <div class=\"col-2 m-b-xs-8\">\n          <div\n            class=\"text-truncate\"\n            title=\"{{ 'Device type' | translate }}: {{ getDeviceTypeTitle(software) }}\"\n          >\n            <span\n              class=\"text-label-small m-r-8 visible-xs visible-sm\"\n              translate\n            >\n              Device type\n            </span>\n            <span *ngIf=\"software.c8y_Filter?.type; else noType\">\n              {{ software.c8y_Filter?.type }}\n            </span>\n            <ng-template #noType>\n              <small>\n                <em\n                  class=\"text-muted\"\n                  translate\n                >\n                  Undefined`device type`\n                </em>\n              </small>\n            </ng-template>\n          </div>\n        </div>\n        <div class=\"col-3 m-b-xs-8\">\n          <span\n            class=\"text-label-small m-r-8 visible-xs visible-sm\"\n            translate\n          >\n            Software type\n          </span>\n          <span\n            class=\"label label-info\"\n            *ngIf=\"software.softwareType; else emptyText\"\n          >\n            {{ software.softwareType }}\n          </span>\n          <ng-template #emptyText>\n            <small class=\"text-muted\">\n              <em translate>Undefined`software type`</em>\n            </small>\n          </ng-template>\n        </div>\n        <div class=\"col-2\">\n          <span\n            class=\"label label-warning m-l-auto-sm\"\n            *ngIf=\"isLegacy(software)\"\n          >\n            <span translate>Legacy</span>\n          </span>\n          <span *ngIf=\"!isLegacy(software)\">\n            <span *ngIf=\"(getBaseVersionsCount$(software) | async) === null\">\n              <span class=\"label label-info\">\n                <i\n                  class=\"icon-spin\"\n                  c8yIcon=\"circle-o-notch\"\n                ></i>\n              </span>\n            </span>\n            <span *ngIf=\"(getBaseVersionsCount$(software) | async) !== null\">\n              <span [ngPlural]=\"getBaseVersionsCount$(software) | async\">\n                <ng-template ngPluralCase=\"=1\">\n                  <span\n                    class=\"text-label-small m-r-8 visible-xs visible-sm\"\n                    translate\n                  >\n                    version\n                  </span>\n                  <span class=\"badge badge-info m-l-auto-sm\">1</span>\n                </ng-template>\n                <ng-template ngPluralCase=\"other\">\n                  <span\n                    class=\"text-label-small m-r-8 visible-xs visible-sm\"\n                    translate\n                  >\n                    versions\n                  </span>\n                  <span class=\"badge badge-info m-l-auto-sm\">\n                    {{ getBaseVersionsCount$(software) | async }}\n                  </span>\n                </ng-template>\n              </span>\n            </span>\n          </span>\n        </div>\n      </div>\n      <c8y-li-collapse>\n        <c8y-list-group>\n          <c8y-li *c8yFor=\"let option of getVersions(software) | async\">\n            <c8y-li-radio\n              [name]=\"software.id\"\n              (onSelect)=\"selectSoftware({ option: option, software: software })\"\n            ></c8y-li-radio>\n            <c8y-li-body class=\"content-flex-40 p-r-16\">\n              <div class=\"col-4\">\n                {{ option.c8y_Software.version }}\n              </div>\n              <div class=\"col-5\">\n                <div\n                  class=\"text-truncate\"\n                  title=\"{{ option.c8y_Software.url }}\"\n                >\n                  <span\n                    class=\"text-label-small m-r-4\"\n                    translate\n                  >\n                    File\n                  </span>\n                  <span>{{ option.c8y_Software.url }}</span>\n                </div>\n              </div>\n              <div\n                class=\"col-3 d-flex\"\n                *ngIf=\"option.id === software.selectedId\"\n              >\n                <div\n                  class=\"c8y-select-wrapper d-inline-block m-l-auto\"\n                  style=\"margin: -4px 0\"\n                >\n                  <select\n                    class=\"form-control input-sm\"\n                    id=\"action\"\n                    [(ngModel)]=\"option.action\"\n                    (change)=\"emitSoftware({ option: option, software: software })\"\n                  >\n                    <option [ngValue]=\"'install'\">\n                      {{ 'Install/update`software`' | translate }}\n                    </option>\n                    <option [ngValue]=\"'delete'\">{{ 'Remove`software`' | translate }}</option>\n                  </select>\n                  <span></span>\n                </div>\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</c8y-select-step-frame>\n", dependencies: [{ kind: "directive", type: i3.IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "directive", type: i3.C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "directive", type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i4.NgPlural, selector: "[ngPlural]", inputs: ["ngPlural"] }, { kind: "directive", type: i4.NgPluralCase, selector: "[ngPluralCase]" }, { kind: "directive", type: i3.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.HighlightComponent, selector: "c8y-highlight", inputs: ["pattern", "text", "elementClass", "shouldTrimPattern"] }, { kind: "component", type: i3.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.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i5.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { 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.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i5.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i5.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i3.FormGroupComponent, selector: "c8y-form-group", inputs: ["hasError", "hasWarning", "hasSuccess", "novalidation", "status"] }, { kind: "directive", type: i3.MessageDirective, selector: "c8y-message", inputs: ["name", "text"] }, { kind: "component", type: i3.MessagesComponent, selector: "c8y-messages", inputs: ["show", "defaults", "helpMessage"] }, { kind: "component", type: i3.ListGroupComponent, selector: "c8y-list-group" }, { kind: "component", type: i3.ListItemComponent, selector: "c8y-list-item, c8y-li", inputs: ["active", "highlighted", "emptyActions", "dense", "collapsed", "selectable"], outputs: ["collapsedChange"] }, { kind: "component", type: i3.ListItemIconComponent, selector: "c8y-list-item-icon, c8y-li-icon", inputs: ["icon", "status"] }, { kind: "component", type: i3.ListItemBodyComponent, selector: "c8y-list-item-body, c8y-li-body", inputs: ["body"] }, { kind: "component", type: i3.ListItemCollapseComponent, selector: "c8y-list-item-collapse, c8y-li-collapse", inputs: ["collapseWay"] }, { kind: "component", type: i3.ListItemRadioComponent, selector: "c8y-list-item-radio, c8y-li-radio", inputs: ["selected", "name", "disabled", "value"], outputs: ["onSelect"] }, { kind: "component", type: i1.SoftwareTypeComponent, selector: "c8y-software-type", inputs: ["softwareTypeMO", "disabled", "style", "required", "placeholder", "emitResultsOnly", "showBtnInNotFoundMessage", "allowFreeEntries", "showClearSelectionOption", "clearSelectionOptionLabel", "presetSoftwareTypes"], outputs: ["onSelectSoftware"] }, { kind: "component", type: i3$1.SelectStepFrameComponent, selector: "c8y-select-step-frame", inputs: ["header", "noResults"] }, { kind: "pipe", type: i3.C8yTranslatePipe, name: "translate" }, { kind: "pipe", type: i4.AsyncPipe, name: "async" }] }); }
}
__decorate([
    memoize(property('id')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object]),
    __metadata("design:returntype", Observable)
], SelectSoftwareStepComponent.prototype, "getBaseVersionsCount$", null);
__decorate([
    memoize(property('id')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object]),
    __metadata("design:returntype", void 0)
], SelectSoftwareStepComponent.prototype, "getVersions", null);
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: SelectSoftwareStepComponent, decorators: [{
            type: Component,
            args: [{ selector: 'c8y-select-software-step', template: "<c8y-select-step-frame\n  [header]=\"'Select software' | translate\"\n  [noResults]=\"\n    ((textFilter$ | async)?.length ||\n      (deviceType$ | async)?.length ||\n      (softwareTypeFilter$ | async)?.length) &&\n    (software$ | async)?.data.length === 0\n  \"\n>\n  <div\n    class=\"row\"\n    filters\n  >\n    <div class=\"col-md-4 m-b-xs-8 m-b-sm-8\">\n      <div class=\"input-group input-group-search\">\n        <input\n          class=\"form-control\"\n          title=\"{{ 'Filter\u2026' | translate }}\"\n          placeholder=\"{{ 'Filter\u2026' | translate }}\"\n          type=\"search\"\n          [ngModel]=\"textFilter$ | async\"\n          (ngModelChange)=\"textFilter$.next($event)\"\n        />\n        <span class=\"input-group-addon\">\n          <i\n            c8yIcon=\"search\"\n            *ngIf=\"(textFilter$ | async).length === 0\"\n          ></i>\n          <i\n            class=\"text-muted\"\n            c8yIcon=\"times\"\n            *ngIf=\"(textFilter$ | async).length > 0\"\n            (click)=\"textFilter$.next('')\"\n          ></i>\n        </span>\n      </div>\n    </div>\n    <div class=\"col-md-4 m-b-xs-8 m-b-sm-8\">\n      <c8y-form-group class=\"m-0\">\n        <c8y-typeahead\n          placeholder=\"{{ 'Type to filter device types\u2026' | translate }}\"\n          name=\"deviceType\"\n          [(ngModel)]=\"selectedDeviceType\"\n          (onSearch)=\"deviceType$.next($event)\"\n          [allowFreeEntries]=\"false\"\n        >\n          <c8y-li\n            class=\"p-l-8 p-r-8 c8y-list__item--link\"\n            (click)=\"selectedDeviceType = { name: '' }; deviceType$.next('')\"\n            [active]=\"!selectedDeviceType?.name\"\n          >\n            <span>{{ 'All device types' | translate }}</span>\n          </c8y-li>\n          <c8y-li\n            class=\"p-l-8 p-r-8 c8y-list__item--link\"\n            *ngFor=\"let deviceType of deviceTypes\"\n            (click)=\"selectedDeviceType = deviceType; deviceType$.next(deviceType.name)\"\n            [active]=\"selectedDeviceType === deviceType\"\n          >\n            <c8y-highlight\n              [text]=\"deviceType.name\"\n              [pattern]=\"deviceType$ | 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 device types.' | translate\"\n          ></c8y-message>\n        </c8y-messages>\n      </c8y-form-group>\n    </div>\n    <div class=\"col-md-4\">\n      <c8y-form-group class=\"m-0\">\n        <c8y-software-type\n          [required]=\"false\"\n          [emitResultsOnly]=\"true\"\n          [showBtnInNotFoundMessage]=\"false\"\n          [allowFreeEntries]=\"false\"\n          [placeholder]=\"'Type to filter software types\u2026' | translate\"\n          [showClearSelectionOption]=\"true\"\n          (onSelectSoftware)=\"softwareTypeFilter$.next($event?.softwareType)\"\n        ></c8y-software-type>\n        <c8y-messages>\n          <c8y-message\n            name=\"notExisting\"\n            [text]=\"'Select one of the existing device types.' | translate\"\n          ></c8y-message>\n        </c8y-messages>\n      </c8y-form-group>\n    </div>\n  </div>\n  <c8y-li\n    class=\"hidden-sm hidden-xs m-r-8 m-l-8\"\n    header\n  >\n    <c8y-li-icon><i class=\"p-l-24\"></i></c8y-li-icon>\n    <c8y-li-body class=\"content-flex-40 p-r-32\">\n      <div class=\"col-5\">\n        <span\n          class=\"text-truncate\"\n          title=\" {{ 'Name' | translate }} \"\n        >\n          {{ 'Name' | translate }}\n        </span>\n      </div>\n      <div class=\"col-2\">\n        <span\n          class=\"text-truncate\"\n          title=\"{{ 'Device type' | translate }}\"\n        >\n          {{ 'Device type' | translate }}\n        </span>\n      </div>\n      <div class=\"col-3\">\n        <span\n          class=\"text-truncate\"\n          title=\"{{ 'Software type' | translate }}\"\n        >\n          {{ 'Software type' | translate }}\n        </span>\n      </div>\n      <div class=\"col-2\">\n        <span\n          class=\"text-truncate\"\n          title=\"{{ 'Versions' | translate }}\"\n        >\n          {{ 'Versions' | translate }}\n        </span>\n      </div>\n    </c8y-li-body>\n  </c8y-li>\n  <c8y-list-group list>\n    <c8y-li\n      *c8yFor=\"let software of software$ | async; loadMore: 'auto'\"\n      #li\n    >\n      <c8y-li-icon>\n        <i c8yIcon=\"c8y-tools\"></i>\n      </c8y-li-icon>\n      <div class=\"content-flex-40\">\n        <div class=\"col-5 m-b-xs-8\">\n          <button\n            class=\"btn-clean\"\n            title=\"{{ software.name }}\"\n            type=\"button\"\n            (click)=\"li.collapsed = !li.collapsed\"\n          >\n            <c8y-highlight\n              [text]=\"software.name\"\n              [pattern]=\"textFilter$ | async\"\n            ></c8y-highlight>\n          </button>\n        </div>\n        <div class=\"col-2 m-b-xs-8\">\n          <div\n            class=\"text-truncate\"\n            title=\"{{ 'Device type' | translate }}: {{ getDeviceTypeTitle(software) }}\"\n          >\n            <span\n              class=\"text-label-small m-r-8 visible-xs visible-sm\"\n              translate\n            >\n              Device type\n            </span>\n            <span *ngIf=\"software.c8y_Filter?.type; else noType\">\n              {{ software.c8y_Filter?.type }}\n            </span>\n            <ng-template #noType>\n              <small>\n                <em\n                  class=\"text-muted\"\n                  translate\n                >\n                  Undefined`device type`\n                </em>\n              </small>\n            </ng-template>\n          </div>\n        </div>\n        <div class=\"col-3 m-b-xs-8\">\n          <span\n            class=\"text-label-small m-r-8 visible-xs visible-sm\"\n            translate\n          >\n            Software type\n          </span>\n          <span\n            class=\"label label-info\"\n            *ngIf=\"software.softwareType; else emptyText\"\n          >\n            {{ software.softwareType }}\n          </span>\n          <ng-template #emptyText>\n            <small class=\"text-muted\">\n              <em translate>Undefined`software type`</em>\n            </small>\n          </ng-template>\n        </div>\n        <div class=\"col-2\">\n          <span\n            class=\"label label-warning m-l-auto-sm\"\n            *ngIf=\"isLegacy(software)\"\n          >\n            <span translate>Legacy</span>\n          </span>\n          <span *ngIf=\"!isLegacy(software)\">\n            <span *ngIf=\"(getBaseVersionsCount$(software) | async) === null\">\n              <span class=\"label label-info\">\n                <i\n                  class=\"icon-spin\"\n                  c8yIcon=\"circle-o-notch\"\n                ></i>\n              </span>\n            </span>\n            <span *ngIf=\"(getBaseVersionsCount$(software) | async) !== null\">\n              <span [ngPlural]=\"getBaseVersionsCount$(software) | async\">\n                <ng-template ngPluralCase=\"=1\">\n                  <span\n                    class=\"text-label-small m-r-8 visible-xs visible-sm\"\n                    translate\n                  >\n                    version\n                  </span>\n                  <span class=\"badge badge-info m-l-auto-sm\">1</span>\n                </ng-template>\n                <ng-template ngPluralCase=\"other\">\n                  <span\n                    class=\"text-label-small m-r-8 visible-xs visible-sm\"\n                    translate\n                  >\n                    versions\n                  </span>\n                  <span class=\"badge badge-info m-l-auto-sm\">\n                    {{ getBaseVersionsCount$(software) | async }}\n                  </span>\n                </ng-template>\n              </span>\n            </span>\n          </span>\n        </div>\n      </div>\n      <c8y-li-collapse>\n        <c8y-list-group>\n          <c8y-li *c8yFor=\"let option of getVersions(software) | async\">\n            <c8y-li-radio\n              [name]=\"software.id\"\n              (onSelect)=\"selectSoftware({ option: option, software: software })\"\n            ></c8y-li-radio>\n            <c8y-li-body class=\"content-flex-40 p-r-16\">\n              <div class=\"col-4\">\n                {{ option.c8y_Software.version }}\n              </div>\n              <div class=\"col-5\">\n                <div\n                  class=\"text-truncate\"\n                  title=\"{{ option.c8y_Software.url }}\"\n                >\n                  <span\n                    class=\"text-label-small m-r-4\"\n                    translate\n                  >\n                    File\n                  </span>\n                  <span>{{ option.c8y_Software.url }}</span>\n                </div>\n              </div>\n              <div\n                class=\"col-3 d-flex\"\n                *ngIf=\"option.id === software.selectedId\"\n              >\n                <div\n                  class=\"c8y-select-wrapper d-inline-block m-l-auto\"\n                  style=\"margin: -4px 0\"\n                >\n                  <select\n                    class=\"form-control input-sm\"\n                    id=\"action\"\n                    [(ngModel)]=\"option.action\"\n                    (change)=\"emitSoftware({ option: option, software: software })\"\n                  >\n                    <option [ngValue]=\"'install'\">\n                      {{ 'Install/update`software`' | translate }}\n                    </option>\n                    <option [ngValue]=\"'delete'\">{{ 'Remove`software`' | translate }}</option>\n                  </select>\n                  <span></span>\n                </div>\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</c8y-select-step-frame>\n" }]
        }], ctorParameters: () => [{ type: i1.RepositoryService }, { type: i2.TranslateService }], propDecorators: { software: [{
                type: Output
            }], radioButtons: [{
                type: ViewChildren,
                args: [ListItemRadioComponent]
            }], getBaseVersionsCount$: [], getVersions: [] } });

class ConfirmSoftwareSelectionStepComponent {
    ngOnChanges(changes) {
        if (changes.selectedItems) {
            const deviceTypes = this.deviceTypes;
            this.title =
                deviceTypes && deviceTypes.length
                    ? deviceTypes.join(', ')
                    : gettext('Undefined`device type`');
        }
    }
    get selectedToInstall() {
        return this.selectedItems.filter(software => software.action === 'install');
    }
    get selectedToDelete() {
        return this.selectedItems.filter(software => software.action === 'delete');
    }
    get deviceTypes() {
        return uniq(this.selectedItems
            .filter(val => has(val, ['software', 'c8y_Filter', 'type']))
            .map(val => val.software.c8y_Filter.type)
            .filter(val => !!val));
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ConfirmSoftwareSelectionStepComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: ConfirmSoftwareSelectionStepComponent, selector: "c8y-confirm-software-selection-step", inputs: { selectedItems: "selectedItems" }, usesOnChanges: true, ngImport: i0, template: "<c8y-preview-selection-frame [header]=\"'Confirm selection' | translate\">\n  <ng-container *previewBlock=\"'Device type' | translate\">\n    <ng-container *ngIf=\"deviceTypes.length > 0; else noType\">\n      <span *ngFor=\"let deviceType of deviceTypes; let last = last\"\n        >{{ deviceType }}{{ last ? '' : ', ' }}</span\n      >\n    </ng-container>\n    <ng-template #noType>\n      <em class=\"text-muted\" translate>Undefined`device type`</em>\n    </ng-template>\n  </ng-container>\n  <c8y-list-group\n    *previewBlock=\"'Installations/updates`software`' | translate; if: !!selectedToInstall.length\"\n  >\n    <c8y-li *ngFor=\"let selectedItem of selectedToInstall\">\n      <c8y-li-icon>\n        <i c8yIcon=\"c8y-tools\"></i>\n      </c8y-li-icon>\n      <c8y-li-body class=\"content-flex-10\">\n        <div class=\"col-6 text-truncate\" title=\"{{ selectedItem.software.name }}\">\n          {{ selectedItem.software.name }}\n        </div>\n        <div class=\"col-6 text-right\" *ngIf=\"!!selectedItem?.version?.c8y_Software?.version\">\n          <span class=\"text-label-small m-r-4\" translate> Version </span>\n          <span>\n            {{ selectedItem.version.c8y_Software.version }}\n          </span>\n        </div>\n      </c8y-li-body>\n    </c8y-li>\n  </c8y-list-group>\n  <c8y-list-group *previewBlock=\"'Removals`software`' | translate; if: !!selectedToDelete.length\">\n    <c8y-li *ngFor=\"let selectedItem of selectedToDelete\">\n      <c8y-li-icon>\n        <i c8yIcon=\"c8y-tools\"></i>\n      </c8y-li-icon>\n      <c8y-li-body class=\"content-flex-10\">\n        <div class=\"col-6\">\n          {{ selectedItem.software.name }}\n        </div>\n        <div class=\"col-6 text-right\">\n          <span class=\"text-label-small m-r-8\" translate> Version </span>\n          <span>\n            {{ selectedItem.version.c8y_Software.version }}\n          </span>\n        </div>\n      </c8y-li-body>\n    </c8y-li>\n  </c8y-list-group>\n</c8y-preview-selection-frame>\n", dependencies: [{ kind: "directive", type: i3.IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "directive", type: i3.C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "directive", type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i3.ListGroupComponent, selector: "c8y-list-group" }, { kind: "component", type: i3.ListItemComponent, selector: "c8y-list-item, c8y-li", inputs: ["active", "highlighted", "emptyActions", "dense", "collapsed", "selectable"], outputs: ["collapsedChange"] }, { kind: "component", type: i3.ListItemIconComponent, selector: "c8y-list-item-icon, c8y-li-icon", inputs: ["icon", "status"] }, { kind: "component", type: i3.ListItemBodyComponent, selector: "c8y-list-item-body, c8y-li-body", inputs: ["body"] }, { kind: "component", type: i3$1.PreviewSelectionFrameComponent, selector: "c8y-preview-selection-frame", inputs: ["header", "name", "description", "type"] }, { kind: "directive", type: i3$1.PreviewBlockDirective, selector: "[previewBlock]", inputs: ["previewBlock", "previewBlockIf"] }, { kind: "pipe", type: i3.C8yTranslatePipe, name: "translate" }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ConfirmSoftwareSelectionStepComponent, decorators: [{
            type: Component,
            args: [{ selector: 'c8y-confirm-software-selection-step', template: "<c8y-preview-selection-frame [header]=\"'Confirm selection' | translate\">\n  <ng-container *previewBlock=\"'Device type' | translate\">\n    <ng-container *ngIf=\"deviceTypes.length > 0; else noType\">\n      <span *ngFor=\"let deviceType of deviceTypes; let last = last\"\n        >{{ deviceType }}{{ last ? '' : ', ' }}</span\n      >\n    </ng-container>\n    <ng-template #noType>\n      <em class=\"text-muted\" translate>Undefined`device type`</em>\n    </ng-template>\n  </ng-container>\n  <c8y-list-group\n    *previewBlock=\"'Installations/updates`software`' | translate; if: !!selectedToInstall.length\"\n  >\n    <c8y-li *ngFor=\"let selectedItem of selectedToInstall\">\n      <c8y-li-icon>\n        <i c8yIcon=\"c8y-tools\"></i>\n      </c8y-li-icon>\n      <c8y-li-body class=\"content-flex-10\">\n        <div class=\"col-6 text-truncate\" title=\"{{ selectedItem.software.name }}\">\n          {{ selectedItem.software.name }}\n        </div>\n        <div class=\"col-6 text-right\" *ngIf=\"!!selectedItem?.version?.c8y_Software?.version\">\n          <span class=\"text-label-small m-r-4\" translate> Version </span>\n          <span>\n            {{ selectedItem.version.c8y_Software.version }}\n          </span>\n        </div>\n      </c8y-li-body>\n    </c8y-li>\n  </c8y-list-group>\n  <c8y-list-group *previewBlock=\"'Removals`software`' | translate; if: !!selectedToDelete.length\">\n    <c8y-li *ngFor=\"let selectedItem of selectedToDelete\">\n      <c8y-li-icon>\n        <i c8yIcon=\"c8y-tools\"></i>\n      </c8y-li-icon>\n      <c8y-li-body class=\"content-flex-10\">\n        <div class=\"col-6\">\n          {{ selectedItem.software.name }}\n        </div>\n        <div class=\"col-6 text-right\">\n          <span class=\"text-label-small m-r-8\" translate> Version </span>\n          <span>\n            {{ selectedItem.version.c8y_Software.version }}\n          </span>\n        </div>\n      </c8y-li-body>\n    </c8y-li>\n  </c8y-list-group>\n</c8y-preview-selection-frame>\n" }]
        }], propDecorators: { selectedItems: [{
                type: Input
            }] } });

class StepperBulkTypeSoftwareComponent extends BaseStepperComponent {
    constructor(modal, translate) {
        super();
        this.modal = modal;
        this.translate = translate;
        this.type = BulkOperationType.SOFTWARE;
        this.descriptionTemplateSingle = gettext('Update software to: {{ name }} (version {{ version }})');
        this.descriptionTemplateOneOther = gettext('Update software to: {{ name }} (version {{ version }}) and one other');
        this.descriptionTemplateMultiple = gettext('Update software to: {{ name }} (version {{ version }}) and {{ count }} others');
        this.selectedSoftware = [];
    }
    onSoftwareSelected(selectedItem) {
        this.selectedSoftware = this.selectedSoftware.filter(item => item.software.id !== selectedItem.software.id);
        this.selectedSoftware.push(selectedItem);
    }
    async confirmSoftwareSelection($event) {
        const deviceTypes = this.getUniqueDeviceTypes();
        this.deviceTypes = deviceTypes;
        if (deviceTypes.length > 1) {
            try {
                await this.modal.confirm(gettext('Selected software for various device types'), gettext('Operation may fail due to unsupported software. Do you want to proceed?'), Status.WARNING, { ok: gettext('Confirm'), cancel: gettext('Cancel') });
                $event.stepper.next();
            }
            catch (ex) {
                this.selectedSoftware = [];
                this.selectSoftware.resetSelection();
            }
        }
        else {
            $event.stepper.next();
        }
    }
    retrieveOperationPrototype() {
        const softwareList = this.selectedSoftware.map(item => ({
            name: item.software.name,
            version: item.version.c8y_Software.version,
            url: item.version.c8y_Software.url,
            action: item.action
        }));
        const interpolationParams = {
            name: softwareList[0].name,
            version: softwareList[0].version,
            count: softwareList.length - 1
        };
        let description;
        switch (softwareList.length) {
            case 1:
                description = this.translate.instant(this.descriptionTemplateSingle, interpolationParams);
                break;
            case 2:
                description = this.translate.instant(this.descriptionTemplateOneOther, interpolationParams);
                break;
            default:
                description = this.translate.instant(this.descriptionTemplateMultiple, interpolationParams);
        }
        return {
            name: gettext('Software update'),
            prototype: {
                description,
                c8y_SoftwareUpdate: softwareList
            }
        };
    }
    getUniqueDeviceTypes() {
        return uniq(this.selectedSoftware
            .map(item => item.software.c8y_Filter && item.software.c8y_Filter.type)
            .filter(type => !!type));
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: StepperBulkTypeSoftwareComponent, deps: [{ token: i3.ModalService }, { token: i2.TranslateService }], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: StepperBulkTypeSoftwareComponent, selector: "c8y-stepper-bulk-type-software", viewQueries: [{ propertyName: "selectSoftware", first: true, predicate: SelectSoftwareStepComponent, descendants: true }], usesInheritance: true, ngImport: i0, template: "<c8y-bulk-operation-stepper [type]=\"type\">\n  <ng-container\n    *customStep=\"\n      'Select software' | translate;\n      completed: !!selectedSoftware.length;\n      buttonsDisabled: !selectedSoftware.length;\n      onNext: confirmSoftwareSelection.bind(this)\n    \"\n  >\n    <c8y-select-software-step\n      (software)=\"onSoftwareSelected($event)\"\n      class=\"d-contents\"\n    ></c8y-select-software-step>\n  </ng-container>\n  <ng-container *customStep=\"'Confirm selected software' | translate\">\n    <c8y-confirm-software-selection-step\n      class=\"d-contents\"\n      [selectedItems]=\"selectedSoftware\"\n    ></c8y-confirm-software-selection-step>\n  </ng-container>\n</c8y-bulk-operation-stepper>\n", dependencies: [{ kind: "component", type: i3$2.BulkOperationStepper, selector: "c8y-bulk-operation-stepper", inputs: ["type"], outputs: ["selectionChange"] }, { kind: "directive", type: i3$2.CustomStep, selector: "[customStep]", inputs: ["customStep", "customStepCompleted", "customStepButtonsDisabled", "customStepOnNext"] }, { kind: "component", type: ConfirmSoftwareSelectionStepComponent, selector: "c8y-confirm-software-selection-step", inputs: ["selectedItems"] }, { kind: "component", type: SelectSoftwareStepComponent, selector: "c8y-select-software-step", outputs: ["software"] }, { kind: "pipe", type: i3.C8yTranslatePipe, name: "translate" }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: StepperBulkTypeSoftwareComponent, decorators: [{
            type: Component,
            args: [{ selector: 'c8y-stepper-bulk-type-software', template: "<c8y-bulk-operation-stepper [type]=\"type\">\n  <ng-container\n    *customStep=\"\n      'Select software' | translate;\n      completed: !!selectedSoftware.length;\n      buttonsDisabled: !selectedSoftware.length;\n      onNext: confirmSoftwareSelection.bind(this)\n    \"\n  >\n    <c8y-select-software-step\n      (software)=\"onSoftwareSelected($event)\"\n      class=\"d-contents\"\n    ></c8y-select-software-step>\n  </ng-container>\n  <ng-container *customStep=\"'Confirm selected software' | translate\">\n    <c8y-confirm-software-selection-step\n      class=\"d-contents\"\n      [selectedItems]=\"selectedSoftware\"\n    ></c8y-confirm-software-selection-step>\n  </ng-container>\n</c8y-bulk-operation-stepper>\n" }]
        }], ctorParameters: () => [{ type: i3.ModalService }, { type: i2.TranslateService }], propDecorators: { selectSoftware: [{
                type: ViewChild,
                args: [SelectSoftwareStepComponent, { static: false }]
            }] } });

/** Module for the 'Software update' operation type stepper */
class StepperBulkTypeSoftwareModule {
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: StepperBulkTypeSoftwareModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
    static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "18.2.13", ngImport: i0, type: StepperBulkTypeSoftwareModule, declarations: [StepperBulkTypeSoftwareComponent,
            ConfirmSoftwareSelectionStepComponent,
            SelectSoftwareStepComponent], imports: [CoreModule,
            FormsModule,
            ReactiveFormsModule,
            BulkOperationStepperModule,
            SharedRepositoryModule,
            StepperFramesModule], exports: [StepperBulkTypeSoftwareComponent] }); }
    static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: StepperBulkTypeSoftwareModule, providers: [
            hookListBulkType({
                type: BulkOperationType.SOFTWARE,
                c8yIcon: 'c8y-tools',
                name: gettext('Software update'),
                path: `${baseUrl}software`,
                component: StepperBulkTypeSoftwareComponent,
                fragments: ['c8y_SoftwareList', 'c8y_SoftwareUpdate'],
                selected: false
            })
        ], imports: [CoreModule,
            FormsModule,
            ReactiveFormsModule,
            BulkOperationStepperModule,
            SharedRepositoryModule,
            StepperFramesModule] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: StepperBulkTypeSoftwareModule, decorators: [{
            type: NgModule,
            args: [{
                    declarations: [
                        StepperBulkTypeSoftwareComponent,
                        ConfirmSoftwareSelectionStepComponent,
                        SelectSoftwareStepComponent
                    ],
                    imports: [
                        CoreModule,
                        FormsModule,
                        ReactiveFormsModule,
                        BulkOperationStepperModule,
                        SharedRepositoryModule,
                        StepperFramesModule
                    ],
                    providers: [
                        hookListBulkType({
                            type: BulkOperationType.SOFTWARE,
                            c8yIcon: 'c8y-tools',
                            name: gettext('Software update'),
                            path: `${baseUrl}software`,
                            component: StepperBulkTypeSoftwareComponent,
                            fragments: ['c8y_SoftwareList', 'c8y_SoftwareUpdate'],
                            selected: false
                        })
                    ],
                    exports: [StepperBulkTypeSoftwareComponent]
                }]
        }] });

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

export { ConfirmSoftwareSelectionStepComponent, SelectSoftwareStepComponent, StepperBulkTypeSoftwareComponent, StepperBulkTypeSoftwareModule };
//# sourceMappingURL=c8y-ngx-components-operations-stepper-bulk-type-software.mjs.map
