import * as i0 from '@angular/core';
import { Injectable, Input, ViewChild, HostBinding, Optional, Component } from '@angular/core';
import { gettext } from '@c8y/ngx-components/gettext';
import * as i3 from '@c8y/ngx-components';
import { toObservable, Status, CoreModule, C8yStepper, UserPreferencesConfigurationStrategy, DATA_GRID_CONFIGURATION_STRATEGY, DATA_GRID_CONFIGURATION_CONTEXT_PROVIDER } from '@c8y/ngx-components';
import * as i2 from '@c8y/ngx-components/device-grid';
import { DeviceGridModule, DeviceGridService } from '@c8y/ngx-components/device-grid';
import { DeviceSelectorModule } from '@c8y/ngx-components/operations/device-selector';
import * as i7 from 'ngx-bootstrap/collapse';
import { CollapseModule } from 'ngx-bootstrap/collapse';
import * as i8 from 'ngx-bootstrap/popover';
import { PopoverModule } from 'ngx-bootstrap/popover';
import * as i6 from 'ngx-bootstrap/tooltip';
import { TooltipModule } from 'ngx-bootstrap/tooltip';
import { shareReplay, distinctUntilChanged, tap, switchMap, catchError, map, scan, withLatestFrom, concatMap, share } from 'rxjs/operators';
import * as i1 from '@c8y/client';
import { QueriesUtil, AuditRecordType } from '@c8y/client';
import { pick, cloneDeep } from 'lodash-es';
import { BehaviorSubject, Subject, of, combineLatest, forkJoin, from, pipe } from 'rxjs';
import * as i4 from '@angular/common';
import * as i5 from '@angular/cdk/stepper';

const REPLACE_DEVICE_STEP_STATES = [
    'Pending',
    'Executing',
    'Skipped',
    'Failed',
    'Successful'
];
function isValidReplaceDeviceStepState(state) {
    return REPLACE_DEVICE_STEP_STATES.includes(state);
}
const REPLACE_DEVICE_STEP_STATE = {
    PENDING: gettext('Pending'),
    EXECUTING: gettext('Executing'),
    SKIPPED: gettext('Skipped'),
    FAILED: gettext('Failed'),
    SUCCESSFUL: gettext('Successful')
};
const REPLACE_DEVICE_STEP_STATES_MAP = {
    Pending: {
        icon: 'clock-o',
        styleClass: 'text-info'
    },
    Executing: {
        icon: 'refresh',
        styleClass: 'text-info'
    },
    Skipped: {
        icon: 'skip',
        styleClass: 'text-info'
    },
    Failed: {
        icon: 'exclamation-circle',
        styleClass: 'text-danger'
    },
    Successful: {
        icon: 'check-circle',
        styleClass: 'text-success'
    }
};

class ReplaceDeviceWizardService {
    static { this.NON_REENTRANT_STATES = [
        'Executing',
        'Successful'
    ]; }
    get deviceToReplace$() {
        return this.deviceToReplaceObs$;
    }
    get replacementDeviceId$() {
        return this.replacementDeviceIdObs$;
    }
    constructor(inventory, identity, audit, event, user, appState, alert) {
        this.inventory = inventory;
        this.identity = identity;
        this.audit = audit;
        this.event = event;
        this.user = user;
        this.appState = appState;
        this.alert = alert;
        this.steps = [];
        this.deviceToReplaceSubject$ = new BehaviorSubject(null);
        this.deviceToReplaceObs$ = this.deviceToReplaceSubject$
            .asObservable()
            .pipe(shareReplay());
        this.replacementDeviceIdSubject$ = new Subject();
        this.replacementDeviceIdObs$ = this.replacementDeviceIdSubject$
            .asObservable()
            .pipe(shareReplay());
        this.checkExternalId$ = new Subject();
        this.externalIdsLoadingSubject$ = new BehaviorSubject(false);
        this.triggerDeviceReplacementSubject$ = new Subject();
        this.deviceReplacementInProgressSubject$ = new Subject();
        this.queriesUtil = new QueriesUtil();
        this.externalIdsLoading$ = this.externalIdsLoadingSubject$.asObservable().pipe(shareReplay());
        this.externalIds$ = this.replacementDeviceIdSubject$.pipe(distinctUntilChanged(), tap(() => this.externalIdsLoadingSubject$.next(true)), switchMap(deviceId => this.identity.list(deviceId)), tap(() => this.externalIdsLoadingSubject$.next(false)), tap(() => this.checkExternalId(null, false)), catchError(err => {
            this.alert.addServerFailure(err);
            return of(null);
        }), shareReplay());
        this.externalIdsWithSelection$ = combineLatest([
            this.externalIds$.pipe(map(result => result?.data), map(externalIds => externalIds?.map(id => ({ id, selected: true })))),
            this.checkExternalId$
        ]).pipe(scan((acc, val) => {
            const [selectedIds, lastAction] = acc;
            const [_, checkAction] = val;
            if (!(lastAction?.checked === checkAction?.checked &&
                this.areExtIdsEqual(lastAction?.id, checkAction?.id))) {
                selectedIds.forEach(id => (id.selected = this.areExtIdsEqual(id.id, checkAction.id)
                    ? checkAction.checked
                    : id.selected));
            }
            return val;
        }), map(([externalIds]) => externalIds), shareReplay());
        this.selectedExternalIds$ = this.externalIdsWithSelection$.pipe(map(ids => ids.filter(id => id.selected).map(id => id.id)), shareReplay());
        this.defineSteps();
        const toContext = ([_, deviceToReplace, replacementDeviceId, newExternalIds]) => ({
            deviceToReplace,
            replacementDeviceId,
            newExternalIds
        });
        this.deviceReplaced$ = this.triggerDeviceReplacementSubject$.pipe(tap(() => this.deviceReplacementInProgressSubject$.next(true)), withLatestFrom(this.deviceToReplace$, this.replacementDeviceId$, this.selectedExternalIds$), map(toContext), concatMap(context => this.steps
            .map(step => this.executeStep(step))
            .reduce((ctx, step) => ctx.pipe(step), of(context))), tap(() => this.deviceReplacementInProgressSubject$.next(false)), map(() => !this.steps.some(step => step.state === 'Failed')), share());
        this.deviceReplacementInProgress$ = this.deviceReplacementInProgressSubject$
            .asObservable()
            .pipe(shareReplay());
    }
    forDevice(deviceToReplace) {
        this.deviceToReplaceSubject$.next(deviceToReplace);
    }
    changeReplacementDeviceId(replacementDeviceId) {
        this.replacementDeviceIdSubject$.next(replacementDeviceId);
    }
    checkExternalId(id, checked) {
        this.checkExternalId$.next({ id, checked });
    }
    replaceDevice() {
        this.triggerDeviceReplacementSubject$.next();
    }
    retryStep(step) {
        this.steps.forEach(s => {
            if ((s.label === step?.label || !step) &&
                !ReplaceDeviceWizardService.NON_REENTRANT_STATES.includes(s.state)) {
                s.skip = false;
                s.seed = s.context;
                s.state = 'Pending';
                delete s.error;
            }
            else {
                s.skip = true;
            }
        });
        this.replaceDevice();
    }
    defineSteps() {
        this.steps = [
            {
                label: gettext('Gather required data'),
                overrideContext: true,
                action: (context) => {
                    const { deviceToReplace, replacementDeviceId, newExternalIds } = context;
                    if (deviceToReplace.id === replacementDeviceId) {
                        throw new Error(gettext('The device to replace and the replacement device cannot be one and the same device.'));
                    }
                    return forkJoin([
                        from(this.inventory.list({
                            query: this.queriesUtil.buildQuery({ owner: deviceToReplace.owner })
                        })).pipe(map(result => result?.data?.length === 1)),
                        from(this.inventory.detail(replacementDeviceId)).pipe(map(result => result?.data)),
                        from(this.identity.list(deviceToReplace.id)).pipe(map(result => result?.data))
                    ]).pipe(map(([deleteReplacedDeviceOwner, replacementDevice, oldExternalIds]) => ({
                        deviceToReplace,
                        replacementDevice,
                        newExternalIds,
                        oldExternalIds,
                        deleteReplacedDeviceOwner,
                        time: new Date().toISOString()
                    })));
                }
            },
            {
                label: gettext('Delete external IDs of replacement device'),
                action: (context) => {
                    const { newExternalIds } = context;
                    return forkJoin(newExternalIds.map(id => this.identity.delete(id)));
                }
            },
            {
                label: gettext('Create new external IDs for the original device'),
                action: (context) => {
                    const { newExternalIds, deviceToReplace } = context;
                    return forkJoin(newExternalIds
                        .map(extId => ({
                        ...pick(extId, ['type', 'externalId']),
                        managedObject: { ...pick(deviceToReplace, ['id']) }
                    }))
                        .map(id => this.identity.create(id)));
                }
            },
            {
                label: gettext('Delete old external IDs of original device'),
                action: (context) => {
                    const { oldExternalIds } = context;
                    return oldExternalIds?.length
                        ? forkJoin(oldExternalIds.map(id => this.identity.delete(id)))
                        : of(REPLACE_DEVICE_STEP_STATE.SKIPPED);
                },
                info: {
                    getMessage: (_, step) => step.state === 'Skipped'
                        ? gettext('No existing external IDs were determined.')
                        : undefined
                }
            },
            {
                label: gettext('Change owner of original device`owner may be a human or system user`'),
                action: (context) => {
                    const { deviceToReplace, replacementDevice, oldExternalIds, time } = context;
                    return this.inventory.update({
                        id: deviceToReplace.id,
                        owner: replacementDevice.owner,
                        c8y_LastReplacement: {
                            time,
                            user: this.appState.currentUser.value.id,
                            previousExternalIds: oldExternalIds.map(id => pick(id, ['externalId', 'type']))
                        }
                    });
                }
            },
            {
                label: gettext('Delete old owner of original device'),
                action: (context) => {
                    const { deleteReplacedDeviceOwner, deviceToReplace } = context;
                    return deleteReplacedDeviceOwner
                        ? this.user.delete(deviceToReplace.owner)
                        : of(REPLACE_DEVICE_STEP_STATE.SKIPPED);
                },
                info: {
                    getMessage: (_, step) => step.state === 'Skipped'
                        ? gettext('User was not deleted because it is assigned as an owner of other devices.')
                        : undefined
                }
            },
            {
                label: gettext('Delete replacement device'),
                action: (context) => {
                    const { replacementDevice } = context;
                    return this.inventory.delete(replacementDevice.id);
                }
            },
            {
                label: gettext('Create event'),
                action: (context) => {
                    const { deviceToReplace, oldExternalIds, newExternalIds, time } = context;
                    return this.event.create({
                        source: { id: deviceToReplace.id },
                        text: `Device with external ID(s) ${this.extIdsToString(oldExternalIds)} was replaced by device with external ID(s) ${this.extIdsToString(newExternalIds)}`,
                        time,
                        type: 'c8y_DeviceReplaced'
                    });
                }
            },
            {
                label: gettext('Create audit log'),
                action: (context) => {
                    const { deviceToReplace, oldExternalIds, newExternalIds, time } = context;
                    return this.audit.create({
                        activity: gettext('Device replaced'),
                        source: { id: deviceToReplace.id },
                        text: `Device with external ID(s) ${this.extIdsToString(oldExternalIds)} was replaced by device with external ID(s) ${this.extIdsToString(newExternalIds)}`,
                        time,
                        type: AuditRecordType.INVENTORY,
                        user: this.appState.currentUser.value.id
                    });
                }
            }
        ];
    }
    executeStep(step) {
        return pipe(tap((ctx) => (step.state = step?.skip || ctx.skip ? step.state : REPLACE_DEVICE_STEP_STATE.EXECUTING)), concatMap((ctx) => {
            if (!step.context && !ctx.skip) {
                step.context = cloneDeep(ctx);
            }
            const context = cloneDeep(step.seed ?? ctx);
            return step?.skip || ctx.skip
                ? of(context)
                : toObservable(this.unwrapStepAction(context, step.action)).pipe(tap(result => (step.state = isValidReplaceDeviceStepState(result)
                    ? result
                    : REPLACE_DEVICE_STEP_STATE.SUCCESSFUL)), catchError(err => {
                    step.state = REPLACE_DEVICE_STEP_STATE.FAILED;
                    step.error = this.toError(err);
                    context.skip = step.overrideContext;
                    return of(context);
                }), tap(() => {
                    if (typeof step.info?.getMessage === 'function') {
                        step.info.msg = step.info.getMessage(context, step);
                    }
                }), map(result => (step.overrideContext ? result : context)));
        }));
    }
    unwrapStepAction(context, action) {
        try {
            return action(context);
        }
        catch (err) {
            // bubble up any runtime errors
            return of({}).pipe(tap(() => {
                throw err;
            }));
        }
    }
    areExtIdsEqual(idA, idB) {
        return idA?.type === idB?.type && idA?.externalId === idB?.externalId;
    }
    extIdsToString(extnernalIds) {
        return extnernalIds?.map(id => `${id.externalId} [${id.type}]`).join(', ');
    }
    toError(err) {
        const { data, res, message } = err;
        let text = data?.message || message;
        let detailedData;
        if (data) {
            if (typeof data === 'object') {
                detailedData = data.exceptionMessage;
            }
            else if (typeof data === 'string') {
                detailedData = data;
            }
        }
        const hasRelevantMessage = !!(text || detailedData);
        if (!text) {
            text = gettext('A server error occurred.');
        }
        if (res && !hasRelevantMessage) {
            detailedData = pick(res, ['status', 'statusText']);
        }
        return { text, detailedData };
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: ReplaceDeviceWizardService, deps: [{ token: i1.InventoryService }, { token: i1.IdentityService }, { token: i1.AuditService }, { token: i1.EventService }, { token: i1.UserService }, { token: i3.AppStateService }, { token: i3.AlertService }], target: i0.ɵɵFactoryTarget.Injectable }); }
    static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: ReplaceDeviceWizardService }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: ReplaceDeviceWizardService, decorators: [{
            type: Injectable
        }], ctorParameters: () => [{ type: i1.InventoryService }, { type: i1.IdentityService }, { type: i1.AuditService }, { type: i1.EventService }, { type: i1.UserService }, { type: i3.AppStateService }, { type: i3.AlertService }] });

class ReplaceDeviceWizardComponent {
    static { this.DEFAULT_VISIBLE_COLUMNS = [
        'status',
        'name',
        'serialNumber',
        'registrationDate',
        'systemId',
        'imei'
    ]; }
    set deviceToReplace(deviceToReplace) {
        this.service.forDevice(deviceToReplace);
    }
    constructor(service, deviceGridService, modal, drawerRef) {
        this.service = service;
        this.deviceGridService = deviceGridService;
        this.modal = modal;
        this.drawerRef = drawerRef;
        this.REPLACE_DEVICE_STEP_STATES_MAP = REPLACE_DEVICE_STEP_STATES_MAP;
        this.classes = 'd-contents';
        this.baseQuery$ = this.service.deviceToReplace$.pipe(map(device => ({
            __not: {
                id: {
                    __eq: device?.id
                }
            }
        })));
        this.columns = this.deviceGridService.getDefaultColumns().map(column => {
            column.visible = ReplaceDeviceWizardComponent.DEFAULT_VISIBLE_COLUMNS.includes(column.name);
            return column;
        });
    }
    getGridConfigContext() {
        return {
            key: 'replace-device-wizard-grid',
            configFilter: {
                filter: false
            }
        };
    }
    async replace() {
        try {
            await this.modal.confirm(gettext('Replace device'), gettext('You are about to replace a device. When the process is finished, the replacement device and its data will be deleted. Do you want to proceed?'), Status.DANGER, { ok: gettext('Replace'), cancel: gettext('Cancel') });
            this.service.replaceDevice();
            this.continue();
        }
        catch (ex) {
            // Intentionally empty
        }
    }
    continue() {
        this.stepper.selected.completed = true;
        this.stepper.next();
    }
    cancel() {
        this.close();
    }
    close() {
        if (this.drawerRef) {
            this.drawerRef.close();
        }
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: ReplaceDeviceWizardComponent, deps: [{ token: ReplaceDeviceWizardService }, { token: i2.DeviceGridService }, { token: i3.ModalService }, { token: i3.BottomDrawerRef, optional: true }], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.16", type: ReplaceDeviceWizardComponent, isStandalone: true, selector: "c8y-replace-device-wizard", inputs: { deviceToReplace: "deviceToReplace" }, host: { properties: { "class": "this.classes" } }, providers: [
            DeviceGridService,
            ReplaceDeviceWizardService,
            {
                provide: DATA_GRID_CONFIGURATION_STRATEGY,
                useClass: UserPreferencesConfigurationStrategy
            },
            {
                provide: DATA_GRID_CONFIGURATION_CONTEXT_PROVIDER,
                useExisting: ReplaceDeviceWizardComponent
            }
        ], viewQueries: [{ propertyName: "stepper", first: true, predicate: C8yStepper, descendants: true, static: true }], ngImport: i0, template: "<c8y-stepper\n  class=\"d-contents c8y-stepper--no-btns\"\n  [disableDefaultIcons]=\"{ edit: true, done: false }\"\n  id=\"modal-body\"\n  [customClasses]=\"[\n    'col-xs-10',\n    'col-xs-offset-1',\n    'col-sm-8',\n    'col-sm-offset-2',\n    'm-t-24',\n    'm-b-40',\n    'p-0',\n    'flex-no-shrink'\n  ]\"\n  linear\n>\n  <cdk-step [label]=\"'Replacement device' | translate\">\n    <div class=\"p-16 p-t-0 flex-no-shrink separator-bottom col-xs-12\">\n      <div class=\"row\">\n        <div class=\"col-md-6 col-md-offset-3 col-lg-4 col-lg-offset-4\">\n          <div class=\"h4 text-center text-medium\">\n            {{ 'Replacement device' | translate }}\n          </div>\n        </div>\n      </div>\n    </div>\n    <c8y-device-grid\n      class=\"flex-grow col-xs-12 no-gutter\"\n      [title]=\"'Select replacement device' | translate\"\n      [infiniteScroll]=\"'auto'\"\n      [actionControls]=\"[]\"\n      [columns]=\"columns\"\n      [selectable]=\"true\"\n      [singleSelection]=\"true\"\n      [baseQuery]=\"baseQuery$ | async\"\n      (itemsSelect)=\"replacementDeviceId = $event[0]\"\n    ></c8y-device-grid>\n    <c8y-stepper-buttons\n      class=\"d-block card-footer p-24 separator\"\n      [disabled]=\"!replacementDeviceId\"\n      (onCancel)=\"cancel()\"\n      (onNext)=\"service.changeReplacementDeviceId(replacementDeviceId); continue()\"\n    ></c8y-stepper-buttons>\n  </cdk-step>\n\n  <cdk-step [label]=\"'Select external IDs' | translate\">\n    <div class=\"p-16 p-t-0 flex-no-shrink col-xs-12\">\n      <div class=\"row\">\n        <div class=\"col-md-6 col-md-offset-3 col-lg-4 col-lg-offset-4\">\n          <div class=\"h4 text-center text-medium\">\n            {{ 'Select external IDs' | translate }}\n          </div>\n        </div>\n      </div>\n    </div>\n    <c8y-li class=\"page-sticky-header hidden-sm hidden-xs\">\n      <c8y-li-icon><i class=\"p-l-24\"></i></c8y-li-icon>\n      <c8y-li-body class=\"content-flex-40\">\n        <div class=\"col-4\">\n          <span\n            class=\"text-medium text-truncate\"\n            title=\" {{ 'Type' | translate }} \"\n          >\n            {{ 'Type' | translate }}\n          </span>\n        </div>\n        <div class=\"col-6\">\n          <span\n            class=\"text-medium text-truncate\"\n            title=\"{{ 'External ID' | translate }}\"\n          >\n            {{ 'External ID' | translate }}\n          </span>\n        </div>\n      </c8y-li-body>\n    </c8y-li>\n    <div\n      class=\"col-xs-12 flex-grow no-gutter\"\n      *ngIf=\"!(service.externalIdsLoading$ | async); else loading\"\n    >\n      <div\n        class=\"card-inner-scroll fit-h\"\n        *ngIf=\"(service.externalIdsWithSelection$ | async)?.length > 0; else noIds\"\n      >\n        <div class=\"card-block p-t-0 p-b-0\">\n          <c8y-list-group>\n            <c8y-li *ngFor=\"let extId of service.externalIdsWithSelection$ | async\">\n              <c8y-li-checkbox\n                [selected]=\"extId.selected\"\n                (onSelect)=\"service.checkExternalId(extId.id, $event)\"\n              ></c8y-li-checkbox>\n              <c8y-li-body class=\"content-flex-40\">\n                <div class=\"col-4 m-b-xs-8\">\n                  <div\n                    class=\"text-truncate\"\n                    title=\"{{ 'Type' | translate }}\"\n                  >\n                    <span\n                      class=\"text-label-small m-r-8 visible-xs visible-sm\"\n                      translate\n                    >\n                      Type\n                    </span>\n                    {{ extId.id.type }}\n                  </div>\n                </div>\n                <div class=\"col-6 m-b-xs-8\">\n                  <div\n                    class=\"text-truncate\"\n                    title=\"{{ 'External ID' | translate }}\"\n                  >\n                    <span\n                      class=\"text-label-small m-r-8 visible-xs visible-sm\"\n                      translate\n                    >\n                      External ID\n                    </span>\n                    {{ extId.id.externalId }}\n                  </div>\n                </div>\n              </c8y-li-body>\n            </c8y-li>\n          </c8y-list-group>\n        </div>\n      </div>\n      <ng-template #noIds>\n        <c8y-ui-empty-state\n          [icon]=\"'barcode'\"\n          [title]=\"'No external IDs assigned.'\"\n          [subtitle]=\"\n            'The selected replacement device does not have external IDs assigned. Go back to &quot;Replacement device&quot; and select a different device.'\n              | translate\n          \"\n          *ngIf=\"true\"\n        ></c8y-ui-empty-state>\n      </ng-template>\n    </div>\n    <ng-template #loading>\n      <div class=\"d-flex d-col a-i-center j-c-center fit-h\">\n        <c8y-loading></c8y-loading>\n      </div>\n    </ng-template>\n    <c8y-stepper-buttons\n      class=\"d-block card-footer p-24 separator\"\n      [disabled]=\"\n        (service.externalIdsLoading$ | async) || !(service.selectedExternalIds$ | async)?.length\n      \"\n      (onCancel)=\"cancel()\"\n      (onNext)=\"replace()\"\n      [labels]=\"{ next: ('Replace' | translate) }\"\n    ></c8y-stepper-buttons>\n  </cdk-step>\n\n  <cdk-step [label]=\"'Replace' | translate\">\n    <div class=\"p-16 p-t-0 flex-no-shrink col-xs-12 separator-bottom\">\n      <div class=\"row\">\n        <div class=\"col-md-6 col-md-offset-3 col-lg-4 col-lg-offset-4\">\n          <div class=\"h4 text-center text-medium\">\n            {{ 'Replace' | translate }}\n          </div>\n        </div>\n      </div>\n    </div>\n    <div class=\"d-flex d-col a-i-center j-c-center inner-scroll\">\n      <c8y-list-group class=\"col-sm-8 col-md-6\">\n        <c8y-li\n          *ngFor=\"let step of service.steps\"\n          [attr.data-cy]=\"'c8y-replace-device-wizard--step-' + step.label\"\n        >\n          <c8y-li-icon>\n            <i\n              [c8yIcon]=\"REPLACE_DEVICE_STEP_STATES_MAP[step.state || 'Pending']?.icon\"\n              [tooltip]=\"(step.state || 'Pending').toString() | translate\"\n              [ngClass]=\"REPLACE_DEVICE_STEP_STATES_MAP[step.state || 'Pending']?.styleClass\"\n            ></i>\n          </c8y-li-icon>\n          <c8y-li-body>\n            <span [ngClass]=\"{ 'text-bold': !!step.error }\">{{ step.label | translate }}</span>\n            <button\n              class=\"btn-help btn-help--sm pull-right\"\n              [attr.aria-label]=\"'Help' | translate\"\n              [attr.aria-label]=\"step.info.msg | translate\"\n              [popover]=\"step.info.msg | translate\"\n              placement=\"right\"\n              triggers=\"focus\"\n              type=\"button\"\n              *ngIf=\"!!step.info?.msg\"\n            >\n              <i c8yIcon=\"question-circle-o\"></i>\n            </button>\n          </c8y-li-body>\n          <c8y-li-collapse\n            #alert\n            *ngIf=\"step.error\"\n          >\n            <span class=\"message\">{{ step.error?.text | translate }}</span>\n            <p\n              class=\"text-muted m-t-8\"\n              *ngIf=\"step?.error?.detailedData\"\n            >\n              <button\n                class=\"btn btn-clean\"\n                (click)=\"alert.expanded = !alert.expanded\"\n              >\n                <i c8yIcon=\"chevron-down\"></i>\n                <span *ngIf=\"!alert.expanded\">Show details</span>\n                <span *ngIf=\"alert.expanded\">Hide details</span>\n              </button>\n            </p>\n            <div\n              [collapse]=\"!alert.expanded\"\n              [isAnimated]=\"true\"\n            >\n              {{ step.error.detailedData | json }}\n            </div>\n          </c8y-li-collapse>\n          <c8y-li-action\n            icon=\"play\"\n            label=\"{{ 'Retry this step`button`' | translate }}\"\n            *ngIf=\"step.state === 'Failed' && !step.overrideContext\"\n            (click)=\"service.retryStep(step)\"\n            data-cy=\"c8y-replace-device-wizard--retry-step\"\n          ></c8y-li-action>\n        </c8y-li>\n      </c8y-list-group>\n    </div>\n\n    <c8y-stepper-buttons\n      class=\"d-block card-footer p-24 separator\"\n      [pending]=\"service.deviceReplacementInProgress$ | async\"\n      (onBack)=\"close()\"\n      [labels]=\"{ back: 'Close' | translate }\"\n    >\n      <button\n        class=\"btn btn-primary\"\n        [title]=\"'Retry' | translate\"\n        type=\"button\"\n        *ngIf=\"(service.deviceReplaced$ | async) === false\"\n        (click)=\"service.retryStep()\"\n        [ngClass]=\"{ 'btn-pending': service.deviceReplacementInProgress$ | async }\"\n        [disabled]=\"service.deviceReplacementInProgress$ | async\"\n        data-cy=\"c8y-replace-device-wizard--btn-retry\"\n      >\n        {{ 'Retry' | translate }}\n      </button>\n    </c8y-stepper-buttons>\n  </cdk-step>\n</c8y-stepper>\n", dependencies: [{ kind: "ngmodule", type: CoreModule }, { kind: "component", type: i3.EmptyStateComponent, selector: "c8y-ui-empty-state", inputs: ["icon", "title", "subtitle", "horizontal"] }, { kind: "directive", type: i3.IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "directive", type: i3.C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "directive", type: i4.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { 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.LoadingComponent, selector: "c8y-loading", inputs: ["layout", "progress", "message"] }, { kind: "component", type: i3.C8yStepper, selector: "c8y-stepper", inputs: ["disableDefaultIcons", "disableProgressButtons", "customClasses", "hideStepProgress", "useStepLabelsAsTitlesOnly"], outputs: ["onStepChange"] }, { kind: "component", type: i5.CdkStep, selector: "cdk-step", inputs: ["stepControl", "label", "errorMessage", "aria-label", "aria-labelledby", "state", "editable", "optional", "completed", "hasError"], outputs: ["interacted"], exportAs: ["cdkStep"] }, { kind: "component", type: i3.C8yStepperButtons, selector: "c8y-stepper-buttons", inputs: ["labels", "pending", "disabled", "showButtons"], outputs: ["onCancel", "onNext", "onBack", "onCustom"] }, { 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.ListItemActionComponent, selector: "c8y-list-item-action, c8y-li-action", inputs: ["label", "icon", "disabled"], outputs: ["click"] }, { kind: "component", type: i3.ListItemCollapseComponent, selector: "c8y-list-item-collapse, c8y-li-collapse", inputs: ["collapseWay"] }, { kind: "component", type: i3.ListItemCheckboxComponent, selector: "c8y-list-item-checkbox, c8y-li-checkbox", inputs: ["selected", "indeterminate", "disabled", "displayAsSwitch"], outputs: ["onSelect"] }, { kind: "ngmodule", type: DeviceGridModule }, { kind: "component", type: i2.DeviceGridComponent, selector: "c8y-device-grid", inputs: ["dataCallback", "refresh", "title", "loadMoreItemsLabel", "loadingItemsLabel", "legacyConfigKey", "legacyFilterKey", "columns", "pagination", "infiniteScroll", "actionControls", "selectable", "singleSelection", "baseQuery", "bulkActionControls", "headerActionControls", "childDeviceGrid", "parentDeviceId", "withChildren", "showSearch", "activeClassName"], outputs: ["onColumnsChange", "onFilterChange", "onDeviceQueryStringChange", "itemsSelect"] }, { kind: "ngmodule", type: DeviceSelectorModule }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i6.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: "ngmodule", type: CollapseModule }, { kind: "directive", type: i7.CollapseDirective, selector: "[collapse]", inputs: ["display", "isAnimated", "collapse"], outputs: ["collapsed", "collapses", "expanded", "expands"], exportAs: ["bs-collapse"] }, { kind: "ngmodule", type: PopoverModule }, { kind: "directive", type: i8.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: i3.C8yTranslatePipe, name: "translate" }, { kind: "pipe", type: i4.AsyncPipe, name: "async" }, { kind: "pipe", type: i4.JsonPipe, name: "json" }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: ReplaceDeviceWizardComponent, decorators: [{
            type: Component,
            args: [{ standalone: true, selector: 'c8y-replace-device-wizard', imports: [
                        CoreModule,
                        DeviceGridModule,
                        DeviceSelectorModule,
                        TooltipModule,
                        CollapseModule,
                        PopoverModule
                    ], providers: [
                        DeviceGridService,
                        ReplaceDeviceWizardService,
                        {
                            provide: DATA_GRID_CONFIGURATION_STRATEGY,
                            useClass: UserPreferencesConfigurationStrategy
                        },
                        {
                            provide: DATA_GRID_CONFIGURATION_CONTEXT_PROVIDER,
                            useExisting: ReplaceDeviceWizardComponent
                        }
                    ], template: "<c8y-stepper\n  class=\"d-contents c8y-stepper--no-btns\"\n  [disableDefaultIcons]=\"{ edit: true, done: false }\"\n  id=\"modal-body\"\n  [customClasses]=\"[\n    'col-xs-10',\n    'col-xs-offset-1',\n    'col-sm-8',\n    'col-sm-offset-2',\n    'm-t-24',\n    'm-b-40',\n    'p-0',\n    'flex-no-shrink'\n  ]\"\n  linear\n>\n  <cdk-step [label]=\"'Replacement device' | translate\">\n    <div class=\"p-16 p-t-0 flex-no-shrink separator-bottom col-xs-12\">\n      <div class=\"row\">\n        <div class=\"col-md-6 col-md-offset-3 col-lg-4 col-lg-offset-4\">\n          <div class=\"h4 text-center text-medium\">\n            {{ 'Replacement device' | translate }}\n          </div>\n        </div>\n      </div>\n    </div>\n    <c8y-device-grid\n      class=\"flex-grow col-xs-12 no-gutter\"\n      [title]=\"'Select replacement device' | translate\"\n      [infiniteScroll]=\"'auto'\"\n      [actionControls]=\"[]\"\n      [columns]=\"columns\"\n      [selectable]=\"true\"\n      [singleSelection]=\"true\"\n      [baseQuery]=\"baseQuery$ | async\"\n      (itemsSelect)=\"replacementDeviceId = $event[0]\"\n    ></c8y-device-grid>\n    <c8y-stepper-buttons\n      class=\"d-block card-footer p-24 separator\"\n      [disabled]=\"!replacementDeviceId\"\n      (onCancel)=\"cancel()\"\n      (onNext)=\"service.changeReplacementDeviceId(replacementDeviceId); continue()\"\n    ></c8y-stepper-buttons>\n  </cdk-step>\n\n  <cdk-step [label]=\"'Select external IDs' | translate\">\n    <div class=\"p-16 p-t-0 flex-no-shrink col-xs-12\">\n      <div class=\"row\">\n        <div class=\"col-md-6 col-md-offset-3 col-lg-4 col-lg-offset-4\">\n          <div class=\"h4 text-center text-medium\">\n            {{ 'Select external IDs' | translate }}\n          </div>\n        </div>\n      </div>\n    </div>\n    <c8y-li class=\"page-sticky-header hidden-sm hidden-xs\">\n      <c8y-li-icon><i class=\"p-l-24\"></i></c8y-li-icon>\n      <c8y-li-body class=\"content-flex-40\">\n        <div class=\"col-4\">\n          <span\n            class=\"text-medium text-truncate\"\n            title=\" {{ 'Type' | translate }} \"\n          >\n            {{ 'Type' | translate }}\n          </span>\n        </div>\n        <div class=\"col-6\">\n          <span\n            class=\"text-medium text-truncate\"\n            title=\"{{ 'External ID' | translate }}\"\n          >\n            {{ 'External ID' | translate }}\n          </span>\n        </div>\n      </c8y-li-body>\n    </c8y-li>\n    <div\n      class=\"col-xs-12 flex-grow no-gutter\"\n      *ngIf=\"!(service.externalIdsLoading$ | async); else loading\"\n    >\n      <div\n        class=\"card-inner-scroll fit-h\"\n        *ngIf=\"(service.externalIdsWithSelection$ | async)?.length > 0; else noIds\"\n      >\n        <div class=\"card-block p-t-0 p-b-0\">\n          <c8y-list-group>\n            <c8y-li *ngFor=\"let extId of service.externalIdsWithSelection$ | async\">\n              <c8y-li-checkbox\n                [selected]=\"extId.selected\"\n                (onSelect)=\"service.checkExternalId(extId.id, $event)\"\n              ></c8y-li-checkbox>\n              <c8y-li-body class=\"content-flex-40\">\n                <div class=\"col-4 m-b-xs-8\">\n                  <div\n                    class=\"text-truncate\"\n                    title=\"{{ 'Type' | translate }}\"\n                  >\n                    <span\n                      class=\"text-label-small m-r-8 visible-xs visible-sm\"\n                      translate\n                    >\n                      Type\n                    </span>\n                    {{ extId.id.type }}\n                  </div>\n                </div>\n                <div class=\"col-6 m-b-xs-8\">\n                  <div\n                    class=\"text-truncate\"\n                    title=\"{{ 'External ID' | translate }}\"\n                  >\n                    <span\n                      class=\"text-label-small m-r-8 visible-xs visible-sm\"\n                      translate\n                    >\n                      External ID\n                    </span>\n                    {{ extId.id.externalId }}\n                  </div>\n                </div>\n              </c8y-li-body>\n            </c8y-li>\n          </c8y-list-group>\n        </div>\n      </div>\n      <ng-template #noIds>\n        <c8y-ui-empty-state\n          [icon]=\"'barcode'\"\n          [title]=\"'No external IDs assigned.'\"\n          [subtitle]=\"\n            'The selected replacement device does not have external IDs assigned. Go back to &quot;Replacement device&quot; and select a different device.'\n              | translate\n          \"\n          *ngIf=\"true\"\n        ></c8y-ui-empty-state>\n      </ng-template>\n    </div>\n    <ng-template #loading>\n      <div class=\"d-flex d-col a-i-center j-c-center fit-h\">\n        <c8y-loading></c8y-loading>\n      </div>\n    </ng-template>\n    <c8y-stepper-buttons\n      class=\"d-block card-footer p-24 separator\"\n      [disabled]=\"\n        (service.externalIdsLoading$ | async) || !(service.selectedExternalIds$ | async)?.length\n      \"\n      (onCancel)=\"cancel()\"\n      (onNext)=\"replace()\"\n      [labels]=\"{ next: ('Replace' | translate) }\"\n    ></c8y-stepper-buttons>\n  </cdk-step>\n\n  <cdk-step [label]=\"'Replace' | translate\">\n    <div class=\"p-16 p-t-0 flex-no-shrink col-xs-12 separator-bottom\">\n      <div class=\"row\">\n        <div class=\"col-md-6 col-md-offset-3 col-lg-4 col-lg-offset-4\">\n          <div class=\"h4 text-center text-medium\">\n            {{ 'Replace' | translate }}\n          </div>\n        </div>\n      </div>\n    </div>\n    <div class=\"d-flex d-col a-i-center j-c-center inner-scroll\">\n      <c8y-list-group class=\"col-sm-8 col-md-6\">\n        <c8y-li\n          *ngFor=\"let step of service.steps\"\n          [attr.data-cy]=\"'c8y-replace-device-wizard--step-' + step.label\"\n        >\n          <c8y-li-icon>\n            <i\n              [c8yIcon]=\"REPLACE_DEVICE_STEP_STATES_MAP[step.state || 'Pending']?.icon\"\n              [tooltip]=\"(step.state || 'Pending').toString() | translate\"\n              [ngClass]=\"REPLACE_DEVICE_STEP_STATES_MAP[step.state || 'Pending']?.styleClass\"\n            ></i>\n          </c8y-li-icon>\n          <c8y-li-body>\n            <span [ngClass]=\"{ 'text-bold': !!step.error }\">{{ step.label | translate }}</span>\n            <button\n              class=\"btn-help btn-help--sm pull-right\"\n              [attr.aria-label]=\"'Help' | translate\"\n              [attr.aria-label]=\"step.info.msg | translate\"\n              [popover]=\"step.info.msg | translate\"\n              placement=\"right\"\n              triggers=\"focus\"\n              type=\"button\"\n              *ngIf=\"!!step.info?.msg\"\n            >\n              <i c8yIcon=\"question-circle-o\"></i>\n            </button>\n          </c8y-li-body>\n          <c8y-li-collapse\n            #alert\n            *ngIf=\"step.error\"\n          >\n            <span class=\"message\">{{ step.error?.text | translate }}</span>\n            <p\n              class=\"text-muted m-t-8\"\n              *ngIf=\"step?.error?.detailedData\"\n            >\n              <button\n                class=\"btn btn-clean\"\n                (click)=\"alert.expanded = !alert.expanded\"\n              >\n                <i c8yIcon=\"chevron-down\"></i>\n                <span *ngIf=\"!alert.expanded\">Show details</span>\n                <span *ngIf=\"alert.expanded\">Hide details</span>\n              </button>\n            </p>\n            <div\n              [collapse]=\"!alert.expanded\"\n              [isAnimated]=\"true\"\n            >\n              {{ step.error.detailedData | json }}\n            </div>\n          </c8y-li-collapse>\n          <c8y-li-action\n            icon=\"play\"\n            label=\"{{ 'Retry this step`button`' | translate }}\"\n            *ngIf=\"step.state === 'Failed' && !step.overrideContext\"\n            (click)=\"service.retryStep(step)\"\n            data-cy=\"c8y-replace-device-wizard--retry-step\"\n          ></c8y-li-action>\n        </c8y-li>\n      </c8y-list-group>\n    </div>\n\n    <c8y-stepper-buttons\n      class=\"d-block card-footer p-24 separator\"\n      [pending]=\"service.deviceReplacementInProgress$ | async\"\n      (onBack)=\"close()\"\n      [labels]=\"{ back: 'Close' | translate }\"\n    >\n      <button\n        class=\"btn btn-primary\"\n        [title]=\"'Retry' | translate\"\n        type=\"button\"\n        *ngIf=\"(service.deviceReplaced$ | async) === false\"\n        (click)=\"service.retryStep()\"\n        [ngClass]=\"{ 'btn-pending': service.deviceReplacementInProgress$ | async }\"\n        [disabled]=\"service.deviceReplacementInProgress$ | async\"\n        data-cy=\"c8y-replace-device-wizard--btn-retry\"\n      >\n        {{ 'Retry' | translate }}\n      </button>\n    </c8y-stepper-buttons>\n  </cdk-step>\n</c8y-stepper>\n" }]
        }], ctorParameters: () => [{ type: ReplaceDeviceWizardService }, { type: i2.DeviceGridService }, { type: i3.ModalService }, { type: i3.BottomDrawerRef, decorators: [{
                    type: Optional
                }] }], propDecorators: { classes: [{
                type: HostBinding,
                args: ['class']
            }], stepper: [{
                type: ViewChild,
                args: [C8yStepper, { static: true }]
            }], deviceToReplace: [{
                type: Input
            }] } });

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

export { REPLACE_DEVICE_STEP_STATE, REPLACE_DEVICE_STEP_STATES_MAP, ReplaceDeviceWizardComponent, ReplaceDeviceWizardService, isValidReplaceDeviceStepState };
//# sourceMappingURL=c8y-ngx-components-replace-device-replace-device-wizard.mjs.map
