UNPKG

@c8y/ngx-components

Version:

Angular modules for Cumulocity IoT applications

1,114 lines 140 kB
import * as i0 from '@angular/core';
import { Injectable, EventEmitter, forwardRef, Component, Input, inject, DestroyRef, NgModule } from '@angular/core';
import * as i2 from '@c8y/ngx-components';
import { NavigatorNode, gettext, PRODUCT_EXPERIENCE_EVENT_SOURCE, ModalSelectionMode, BuiltInActionType, Status, ManagedObjectRealtimeService, ViewContext, CoreModule, CommonModule, hookNavigator, hookRoute } from '@c8y/ngx-components';
import * as i1 from '@c8y/client';
import { QueriesUtil, OperationStatus } from '@c8y/client';
import { get, isEmpty, mapValues, omitBy, keyBy, uniqBy, keys, pickBy, sortBy, toArray, isNil, assign, concat, uniqWith, isEqual, has, cloneDeep } from 'lodash-es';
import * as i1$1 from '@c8y/ngx-components/repository/shared';
import { PRODUCT_EXPERIENCE_REPOSITORY_SHARED, RepositoryType, RepositorySelectModalComponent, RepositoryItemNameGridColumn, DeviceTypeGridColumn, SharedRepositoryModule } from '@c8y/ngx-components/repository/shared';
import { Subject, from, BehaviorSubject, pipe, combineLatest } from 'rxjs';
import { switchMap, map, take, distinctUntilChanged, shareReplay, filter, tap } from 'rxjs/operators';
import * as i2$1 from '@angular/common';
import * as i5 from '@angular/router';
import { RouterModule } from '@angular/router';
import * as i2$2 from 'ngx-bootstrap/dropdown';
import { BsDropdownModule } from 'ngx-bootstrap/dropdown';
import * as i10 from 'ngx-bootstrap/popover';
import { PopoverModule } from 'ngx-bootstrap/popover';
import * as i9 from 'ngx-bootstrap/tooltip';
import { TooltipModule } from 'ngx-bootstrap/tooltip';
import { ButtonsModule } from 'ngx-bootstrap/buttons';
import * as i8 from '@angular/forms';
import { ReactiveFormsModule } from '@angular/forms';
import * as i4 from 'ngx-bootstrap/modal';
import * as i4$1 from '@ngx-translate/core';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
import * as i6 from '@c8y/ngx-components/operations/operation-details';
import { OperationDetailsModule } from '@c8y/ngx-components/operations/operation-details';

class DeviceProfileNavigationFactory {
    async get() {
        if (!this.nodeItem) {
            this.nodeItem = new NavigatorNode({
                label: gettext('Device profiles'),
                path: '/device-profiles',
                icon: 'c8y-device-profile',
                parent: gettext('Management')
            });
        }
        return this.nodeItem;
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DeviceProfileNavigationFactory, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
    static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DeviceProfileNavigationFactory }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DeviceProfileNavigationFactory, decorators: [{
            type: Injectable
        }] });

class DeviceProfileService {
    constructor(inventoryService, operationService, alertService) {
        this.inventoryService = inventoryService;
        this.operationService = operationService;
        this.alertService = alertService;
        this.dateFrom = new Date(0);
        this.dateTo = new Date(Date.now() + 86400000); // 1 day in the future
        this.NOT_INSTALLED_WARNING = gettext('Not installed on the device');
        this.VERSION_MISSMATCH_WARNING = gettext('Version mismatch');
        this.SAME_URL_WARNING = gettext('Installed configuration has the same URL but different name or type than the one in the profile');
        this.queriesUtil = new QueriesUtil();
    }
    createDeviceProfile(deviceProfile) {
        if (get(deviceProfile, 'c8y_Filter.type') === '') {
            delete deviceProfile.c8y_Filter.type;
        }
        return this.inventoryService.create(deviceProfile);
    }
    /**
     * Determines the available device profiles for a given device by considering device type
     * and the supported software types declared by the devices. Because of limitations in the
     * Inventory Query API the methods return profile that contain at least one of the supported
     * software types and omits profiles having only non-supported software types. Resulting device
     * profiles need to be further filtered on the client side to exclude the ones that contain
     * non-supported software types next to the supported ones.
     *
     * @param device A device MO
     * @param name Optional device profile name filter
     * @returns Candidate device profiles that contain at least on software with supported type.
     */
    getDeviceProfilesByDevice(device, name = null) {
        const deviceTypeFilter = {
            __or: [
                { 'c8y_Filter.type': device.type },
                { 'c8y_Filter.type': '' },
                { __not: { __has: 'c8y_Filter.type' } }
            ]
        };
        let softwareTypeFilter = {};
        if (!isEmpty(device.c8y_SupportedSoftwareTypes)) {
            softwareTypeFilter = {
                __hasany: device.c8y_SupportedSoftwareTypes.map((type) => `softwareType!${type}`)
            };
        }
        let query = this.queriesUtil.addAndFilter(deviceTypeFilter, softwareTypeFilter);
        let profileNameFilter = {};
        if (!isEmpty(name)) {
            profileNameFilter = { name: `*${name}*` };
        }
        query = this.queriesUtil.addAndFilter(query, profileNameFilter);
        return this.getDeviceProfiles(query);
    }
    /**
     * @deprecated Use `getDeviceProfilesByDevice` instead as it also considers the supported software types.
     */
    getDeviceProfilesByDeviceType(deviceType) {
        const deviceTypeFilter = {
            __or: [
                { 'c8y_Filter.type': deviceType },
                { 'c8y_Filter.type': '' },
                { __not: { __has: 'c8y_Filter.type' } }
            ]
        };
        return this.getDeviceProfiles(deviceTypeFilter);
    }
    getDeviceProfiles(andQuery) {
        let query = {
            type: 'c8y_Profile'
        };
        const filter = {
            pageSize: 100,
            withTotalPages: true
        };
        query = this.queriesUtil.addAndFilter(query, andQuery || {});
        return this.inventoryService.listQuery(query, filter);
    }
    async getProfileOperation(deviceId) {
        const filter = {
            deviceId,
            fragmentType: 'c8y_DeviceProfile',
            dateFrom: this.dateFrom.toISOString(),
            dateTo: this.dateTo.toISOString(),
            revert: true,
            pageSize: 1
        };
        const operation = (await this.operationService.list(filter)).data[0];
        return operation && operation.status !== OperationStatus.SUCCESSFUL ? operation : undefined;
    }
    async createProfileOperation(device, deviceProfile) {
        let operation;
        const operationCfg = {
            deviceId: device.id,
            profileId: deviceProfile.id,
            profileName: deviceProfile.name,
            c8y_DeviceProfile: deviceProfile.c8y_DeviceProfile,
            description: `Assign device profile ${deviceProfile.name} to device ${device.name}`
        };
        try {
            const { data } = await this.operationService.create(operationCfg);
            operation = data;
        }
        catch (ex) {
            this.alertService.addServerFailure(ex);
        }
        return operation;
    }
    getFirmwareItems(device, selectedProfile) {
        const deviceFirmware = device.c8y_Firmware;
        const profileFirmware = get(selectedProfile, 'c8y_DeviceProfile.firmware');
        const deviceItems = [];
        const profileItems = [];
        if (deviceFirmware) {
            deviceItems.push(deviceFirmware);
        }
        if (profileFirmware) {
            profileItems.push(profileFirmware);
        }
        return this.createProfileComparison(deviceItems, profileItems, 'name', 'version', null, this.getAlert('firmware'));
    }
    getSoftwareItems(device, selectedProfile) {
        const deviceSoftware = device.c8y_SoftwareList;
        const profileSoftware = get(selectedProfile, 'c8y_DeviceProfile.software');
        return this.createProfileComparison(deviceSoftware, profileSoftware, 'name', 'version', 'softwareType', this.getAlert('software'));
    }
    getConfigurationItems(device, selectedProfile) {
        const deviceConfiguration = [];
        Object.keys(device).forEach(key => {
            if (key.slice(0, 18) === 'c8y_Configuration_') {
                deviceConfiguration.push(device[key]);
            }
        });
        const profileConfiguration = get(selectedProfile, 'c8y_DeviceProfile.configuration');
        return this.createProfileComparison(deviceConfiguration, profileConfiguration, 'url', null, 'type', this.getAlert('configuration'));
    }
    /**
     * Aligns device profile managed object's `softwareType!*` fragments to the software items
     * included in the device profile. Removes obsolete software type fragments and adds new.
     *
     * @param profilePartial The device profile managed object which `softwareType!*` fragments will be adjusted.
     * @returns The adjusted device profile managed object.
     */
    alignSoftwareTypeFragments(profilePartial, profile) {
        if (!profilePartial?.c8y_DeviceProfile?.software || !profile) {
            return profilePartial;
        }
        const removedSoftwareTypes = mapValues(omitBy(profile, (_, key) => typeof key === 'string' && !key.startsWith('softwareType!')), () => null);
        const softwareTypesToAdd = mapValues(keyBy(uniqBy(profilePartial.c8y_DeviceProfile.software, 'softwareType'), (profile) => `softwareType!${profile.softwareType}`), () => ({}));
        const result = { ...profilePartial, ...removedSoftwareTypes, ...softwareTypesToAdd };
        return result;
    }
    getSoftwareTypes(profile) {
        return keys(pickBy(profile, (_, key) => typeof key === 'string' && key.startsWith('softwareType!'))).map(softwareType => softwareType.substr('softwareType!'.length));
    }
    getAlert(itemType) {
        const notInstalled = (comparisionResult) => {
            return !comparisionResult.device ? this.NOT_INSTALLED_WARNING : '';
        };
        switch (itemType) {
            case 'firmware':
            case 'software':
                return (comparisionResult) => {
                    return comparisionResult.device &&
                        comparisionResult.profile &&
                        comparisionResult.device.itemDetails !== comparisionResult.profile.itemDetails
                        ? this.VERSION_MISSMATCH_WARNING
                        : notInstalled(comparisionResult);
                };
            case 'configuration':
                return (comparisionResult) => {
                    return comparisionResult.device &&
                        comparisionResult.profile &&
                        (comparisionResult.device.itemName !== comparisionResult.profile.itemName ||
                            comparisionResult.device.itemDetails !== comparisionResult.profile.itemDetails)
                        ? this.SAME_URL_WARNING
                        : notInstalled(comparisionResult);
                };
            default:
                return notInstalled;
        }
    }
    createProfileComparison(deviceItems = [], profileItems = [], mergeByProperty, propertyNameWithDetails, propertyNameWithType, getAlert) {
        const comparisonObj = this.createProfileComparisonFromDeviceItems(deviceItems, mergeByProperty, propertyNameWithDetails, propertyNameWithType);
        const extendedComparisonObj = this.extendProfileComparisonWithProfileItems(comparisonObj, profileItems, mergeByProperty, propertyNameWithDetails, propertyNameWithType, getAlert);
        return sortBy(toArray(extendedComparisonObj), 'name');
    }
    createProfileComparisonFromDeviceItems(deviceItems, mergeByProperty, propertyNameWithDetails, propertyNameWithType) {
        return deviceItems.reduce((comapritionItem, deviceItem) => Object.assign(comapritionItem, {
            [deviceItem[mergeByProperty]]: {
                device: omitBy({
                    itemName: deviceItem.name,
                    itemDetails: deviceItem[propertyNameWithDetails],
                    itemType: deviceItem[propertyNameWithType],
                    itemUrl: deviceItem.url
                }, isNil),
                profile: undefined
            }
        }), {});
    }
    extendProfileComparisonWithProfileItems(comparisonObj, profileItems, mergeByProperty, propertyNameWithDetails, propertyNameWithType, getAlert) {
        profileItems.forEach(profileItem => {
            const comparisionResult = {
                profile: omitBy({
                    itemName: profileItem.name,
                    itemDetails: profileItem[propertyNameWithDetails],
                    itemType: profileItem[propertyNameWithType],
                    itemUrl: profileItem.url
                }, isNil),
                device: comparisonObj[profileItem[mergeByProperty]]
                    ? comparisonObj[profileItem[mergeByProperty]].device
                    : undefined
            };
            comparisionResult.comparisonAlert = getAlert(comparisionResult);
            comparisonObj[profileItem[mergeByProperty]] = comparisionResult;
        });
        return comparisonObj;
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DeviceProfileService, deps: [{ token: i1.InventoryService }, { token: i1.OperationService }, { token: i2.AlertService }], target: i0.ɵɵFactoryTarget.Injectable }); }
    static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DeviceProfileService }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DeviceProfileService, decorators: [{
            type: Injectable
        }], ctorParameters: () => [{ type: i1.InventoryService }, { type: i1.OperationService }, { type: i2.AlertService }] });

class SelectConfigurationModalComponent {
    constructor(repositoryService) {
        this.repositoryService = repositoryService;
        this.PRODUCT_EXPERIENCE = PRODUCT_EXPERIENCE_REPOSITORY_SHARED;
        this.title = gettext('Select configuration');
        this.load = new Subject();
        this.configurations = this.load.pipe(switchMap(() => this.getItems()), map(({ data }) => this.aggregate(data)));
        this.resultEmitter = new EventEmitter();
        this.deviceTypeQuery = {};
        this.searchQuery = {};
        this.labels = { ok: gettext('Save') };
        this.queriesUtil = new QueriesUtil();
    }
    search(searchTerm) {
        if (!searchTerm) {
            this.searchQuery = {};
        }
        else {
            this.searchQuery = this.queriesUtil.addOrFilter({ name: `*${searchTerm}*` }, { configurationType: `*${searchTerm}*` });
        }
        this.load.next();
    }
    result(selectedItems) {
        this.resultEmitter.emit(selectedItems);
    }
    getItems() {
        return this.repositoryService.listRepositoryEntries(RepositoryType.CONFIGURATION, {
            query: this.queriesUtil.addOrFilter(this.deviceTypeQuery, this.searchQuery),
            params: { pageSize: 100 }
        });
    }
    aggregate(mos) {
        const selectedItems = this.selected;
        return mos.reduce((acc, curr) => {
            curr.configurationType = curr.configurationType || curr.name;
            const selected = selectedItems && selectedItems.filter(val => val.url === curr.url).length > 0;
            const selectModalOption = {
                body: [{ value: curr.name }],
                obj: curr,
                selected
            };
            let selectModalObject = acc.find(val => val.body[0].value === curr.configurationType);
            if (selectModalObject) {
                selectModalObject.options.push(selectModalOption);
            }
            else {
                selectModalObject = {
                    groupId: curr.id,
                    body: [{ value: curr.configurationType }],
                    options: [selectModalOption]
                };
                acc.push(selectModalObject);
            }
            return acc;
        }, []);
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: SelectConfigurationModalComponent, deps: [{ token: i1$1.RepositoryService }], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.14", type: SelectConfigurationModalComponent, isStandalone: false, selector: "c8y-select-configuration-modal", providers: [
            {
                provide: PRODUCT_EXPERIENCE_EVENT_SOURCE,
                useExisting: forwardRef(() => SelectConfigurationModalComponent)
            }
        ], ngImport: i0, template: "<c8y-select-modal\n  [icon]=\"'gears'\"\n  [title]=\"title\"\n  [items]=\"configurations | async\"\n  [mode]=\"'multi'\"\n  (result)=\"result($event)\"\n  (search)=\"search($event)\"\n  [disableSelected]=\"true\"\n  [labels]=\"labels\"\n  c8yProductExperience\n  inherit\n  suppressDataOverriding\n  [actionData]=\"{ component: PRODUCT_EXPERIENCE.SHARED.COMPONENTS.SELECT_CONFIGURATION_MODAL }\"\n></c8y-select-modal>\n", dependencies: [{ kind: "component", type: i2.SelectModalComponent, selector: "c8y-select-modal", inputs: ["icon", "title", "subTitle", "items", "mode", "disableSelected", "showFilter", "additionalFilterTemplate", "areMoreEntries", "labels", "noItemsMessage", "hideEmptyItems"], outputs: ["result", "search", "onChoiceUpdated"] }, { kind: "directive", type: i2.ProductExperienceDirective, selector: "[c8yProductExperience]", inputs: ["actionName", "actionData", "inherit", "suppressDataOverriding"] }, { kind: "pipe", type: i2$1.AsyncPipe, name: "async" }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: SelectConfigurationModalComponent, decorators: [{
            type: Component,
            args: [{ selector: 'c8y-select-configuration-modal', providers: [
                        {
                            provide: PRODUCT_EXPERIENCE_EVENT_SOURCE,
                            useExisting: forwardRef(() => SelectConfigurationModalComponent)
                        }
                    ], standalone: false, template: "<c8y-select-modal\n  [icon]=\"'gears'\"\n  [title]=\"title\"\n  [items]=\"configurations | async\"\n  [mode]=\"'multi'\"\n  (result)=\"result($event)\"\n  (search)=\"search($event)\"\n  [disableSelected]=\"true\"\n  [labels]=\"labels\"\n  c8yProductExperience\n  inherit\n  suppressDataOverriding\n  [actionData]=\"{ component: PRODUCT_EXPERIENCE.SHARED.COMPONENTS.SELECT_CONFIGURATION_MODAL }\"\n></c8y-select-modal>\n" }]
        }], ctorParameters: () => [{ type: i1$1.RepositoryService }] });

var DeviceProfileOperation;
(function (DeviceProfileOperation) {
    DeviceProfileOperation["APPLY_PROFILE"] = "c8y_DeviceProfile";
})(DeviceProfileOperation || (DeviceProfileOperation = {}));
const PRODUCT_EXPERIENCE_DEVICE_PROFILE = {
    EVENTS: {
        REPOSITORY: 'deviceProfileRepository',
        DEVICE_TAB: 'deviceProfileTab'
    },
    COMPONENTS: {
        DEVICE_PROFILE_LIST: 'device-profile-list',
        ADD_DEVICE_PROFILE: 'add-device-profile',
        DEVICE_PROFILE: 'device-profile',
        DEVICE_TAB_PROFILE: 'device-tab-profile'
    },
    ACTIONS: {
        CANCEL: 'cancel',
        CREATE: 'create',
        REMOVE: 'remove',
        ADD: 'add',
        SAVE: 'save',
        ASSIGN_DEVICE_PROFILE: 'assignDeviceProfile'
    },
    RESULTS: {
        ADD_SOFTWARE: 'addSoftware'
    },
    FRAGMENTS: {
        FIRMWARE: 'firmware',
        SOFTWARE: 'software',
        CONFGIURATION: 'configuration'
    }
};

class DeviceProfileComponent {
    constructor(route, alertService, inventoryService, bsModal, repositoryService, deviceProfileService) {
        this.route = route;
        this.alertService = alertService;
        this.inventoryService = inventoryService;
        this.bsModal = bsModal;
        this.repositoryService = repositoryService;
        this.deviceProfileService = deviceProfileService;
        this.DEVICE_TYPE_POPOVER = gettext('The device profile will be available for assignments on devices of the specified type. Otherwise, it will be available for all device types.');
        this.DEVICE_TYPE_DISABLED_POPOVER = gettext('Device type cannot be changed on profiles with already defined firmware, software or configuration since they may not be applicable to devices of the new device type.');
        this.PRODUCT_EXPERIENCE = PRODUCT_EXPERIENCE_DEVICE_PROFILE;
        this.productExperienceEvent = {
            eventName: PRODUCT_EXPERIENCE_DEVICE_PROFILE.EVENTS.REPOSITORY,
            data: {
                component: PRODUCT_EXPERIENCE_DEVICE_PROFILE.COMPONENTS.DEVICE_PROFILE
            }
        };
        this.queriesUtil = new QueriesUtil();
    }
    async ngOnInit() {
        const profileId = this.route.snapshot.paramMap.get('id');
        this.deviceProfile = (await this.getDeviceProfile(profileId));
        if (this.deviceProfile) {
            this.profileName = this.deviceProfile.name;
            if (!this.deviceProfile.c8y_DeviceProfile.software) {
                this.deviceProfile.c8y_DeviceProfile.software = [];
            }
            if (!this.deviceProfile.c8y_DeviceProfile.configuration) {
                this.deviceProfile.c8y_DeviceProfile.configuration = [];
            }
        }
    }
    addFirmware() {
        const initialState = {
            deviceTypeQuery: this.getDeviceTypeQuery(RepositoryType.FIRMWARE),
            repositoryType: RepositoryType.FIRMWARE,
            repositoryEntriesWithVersionsFn$: modalDialog => this.getRepositoryEntriesWithVersions$(modalDialog.content.searchTerm, RepositoryType.FIRMWARE),
            icon: 'c8y-firmware',
            title: gettext('Select firmware'),
            mode: ModalSelectionMode.SINGLE,
            productExperienceEvent: this.productExperienceEvent
        };
        const modal = this.bsModal.show(RepositorySelectModalComponent, {
            ignoreBackdropClick: true,
            keyboard: false,
            ariaLabelledBy: 'modal-title',
            initialState
        });
        if (initialState.repositoryEntriesWithVersionsFn$) {
            modal.content.repositoryEntriesWithVersions$ =
                initialState.repositoryEntriesWithVersionsFn$(modal);
        }
        modal.content.load.next();
        modal.content.resultEmitter.pipe(take(1)).subscribe(firmwareList => {
            const [firmware] = firmwareList;
            if (!firmware) {
                return;
            }
            const deviceProfilePartial = {
                c8y_DeviceProfile: this.deviceProfile.c8y_DeviceProfile || {}
            };
            assign(deviceProfilePartial.c8y_DeviceProfile, {
                firmware: {
                    name: firmware.name,
                    version: firmware.version,
                    url: firmware.url,
                    isPatch: firmware.isPatch,
                    patchDependency: firmware.patchDependency
                }
            });
            this.updateDeviceProfile(deviceProfilePartial);
        });
    }
    getRepositoryEntriesWithVersions$(searchTerm$, repoType) {
        return searchTerm$.pipe(distinctUntilChanged(), switchMap(searchTerm => this.repositoryService.listRepositoryEntries(repoType, {
            query: this.getDeviceTypeQuery(repoType),
            partialName: searchTerm.name,
            params: { pageSize: 100 },
            skipLegacy: true
        })), map(({ data }) => data), map(mos => this.getAndAssignRepositoryBinaries(mos)), shareReplay(1));
    }
    getAndAssignRepositoryBinaries(mos) {
        mos.forEach(mo => {
            mo.versions = this.repositoryService.listBaseVersions(mo);
        });
        return mos;
    }
    addConfiguration() {
        const modal = this.bsModal.show(SelectConfigurationModalComponent, {
            ignoreBackdropClick: true,
            keyboard: false,
            ariaLabelledBy: 'modal-title',
            initialState: {
                productExperienceEvent: this.productExperienceEvent
            }
        });
        modal.content.deviceTypeQuery = this.getDeviceTypeQuery(RepositoryType.CONFIGURATION);
        modal.content.selected = this.deviceProfile.c8y_DeviceProfile.configuration;
        modal.content.load.next();
        modal.content.resultEmitter.pipe(take(1)).subscribe(selectedConfigurations => {
            const selectedMapped = selectedConfigurations.map(selectedItem => {
                return assign({
                    url: selectedItem.url,
                    name: selectedItem.name
                }, selectedItem.configurationType ? { type: selectedItem.configurationType } : {});
            });
            const merged = concat(selectedMapped, this.deviceProfile.c8y_DeviceProfile.configuration || []);
            const configuration = uniqWith(merged, (arrVal, othVal) => {
                return arrVal.type && othVal.type && arrVal.type === othVal.type;
            });
            const deviceProfilePartial = {
                c8y_DeviceProfile: this.deviceProfile.c8y_DeviceProfile || {}
            };
            assign(deviceProfilePartial.c8y_DeviceProfile, { configuration });
            this.updateDeviceProfile(deviceProfilePartial);
        });
    }
    addSoftware() {
        const initialState = {
            deviceTypeQuery: this.getDeviceTypeQuery(RepositoryType.SOFTWARE),
            repositoryType: RepositoryType.SOFTWARE,
            repositoryEntriesWithVersionsFn$: modalDialog => this.getRepositoryEntriesWithVersions$(modalDialog.content.searchTerm, RepositoryType.SOFTWARE),
            selected: this.deviceProfile.c8y_DeviceProfile.software,
            icon: 'c8y-tools',
            title: gettext('Select software'),
            mode: ModalSelectionMode.MULTI,
            productExperienceEvent: this.productExperienceEvent
        };
        const modal = this.bsModal.show(RepositorySelectModalComponent, {
            ignoreBackdropClick: true,
            keyboard: false,
            ariaLabelledBy: 'modal-title',
            initialState
        });
        if (initialState.repositoryEntriesWithVersionsFn$) {
            modal.content.repositoryEntriesWithVersions$ =
                initialState.repositoryEntriesWithVersionsFn$(modal);
        }
        modal.content.load.next();
        modal.content.resultEmitter.pipe(take(1)).subscribe(selectedSoftware => {
            const selectedMapped = selectedSoftware.map(selectedItem => {
                return {
                    name: selectedItem.name,
                    version: selectedItem.version,
                    url: selectedItem.url,
                    softwareType: selectedItem.softwareType,
                    action: 'install'
                };
            });
            const merged = concat(selectedMapped, this.deviceProfile.c8y_DeviceProfile.software || []);
            const software = uniqWith(merged, (arrVal, othVal) => {
                return arrVal.name && othVal.name && arrVal.name === othVal.name;
            });
            const deviceProfilePartial = {
                c8y_DeviceProfile: this.deviceProfile.c8y_DeviceProfile || {}
            };
            assign(deviceProfilePartial.c8y_DeviceProfile, { software });
            this.updateDeviceProfile(deviceProfilePartial);
        });
    }
    get isDeviceProfileEmpty() {
        const isSoftware = this.deviceProfile.c8y_DeviceProfile.software &&
            this.deviceProfile.c8y_DeviceProfile.software.length > 0;
        const isFirmware = Boolean(this.deviceProfile.c8y_DeviceProfile.firmware);
        const isConfiguration = this.deviceProfile.c8y_DeviceProfile.configuration &&
            this.deviceProfile.c8y_DeviceProfile.configuration.length > 0;
        return isSoftware || isFirmware || isConfiguration;
    }
    removeItem(removedItem, category) {
        const deviceProfilePartial = {
            c8y_DeviceProfile: this.deviceProfile.c8y_DeviceProfile
        };
        const filtered = deviceProfilePartial.c8y_DeviceProfile[category].filter(item => !isEqual(removedItem, item));
        deviceProfilePartial.c8y_DeviceProfile[category] = filtered;
        this.updateDeviceProfile(deviceProfilePartial);
    }
    removeFirmware() {
        delete this.deviceProfile.c8y_DeviceProfile.firmware;
        this.updateDeviceProfile({ c8y_DeviceProfile: this.deviceProfile.c8y_DeviceProfile });
    }
    async updateDeviceProfile(partialDeviceProfile) {
        if (partialDeviceProfile.c8y_Filter && partialDeviceProfile.c8y_Filter.type === '') {
            delete partialDeviceProfile.c8y_Filter.type;
        }
        Object.assign(partialDeviceProfile, { id: this.deviceProfile.id });
        try {
            const profileWithSoftwareTypeFragments = this.deviceProfileService.alignSoftwareTypeFragments(partialDeviceProfile, this.deviceProfile);
            const { data } = await this.inventoryService.update(profileWithSoftwareTypeFragments);
            this.deviceProfile = data;
            this.profileName = this.deviceProfile.name;
            this.alertService.success(gettext('Device profile changed.'));
        }
        catch (ex) {
            this.alertService.addServerFailure(ex);
        }
    }
    async getDeviceProfile(profileId) {
        try {
            const { data } = await this.inventoryService.detail(profileId);
            return data;
        }
        catch (ex) {
            this.alertService.addServerFailure(ex);
        }
    }
    getDeviceTypeQuery(repositoryType) {
        if (has(this.deviceProfile, 'c8y_Filter.type') &&
            !isEmpty(this.deviceProfile.c8y_Filter.type)) {
            if (repositoryType === RepositoryType.CONFIGURATION) {
                return this.queriesUtil.addOrFilter({ deviceType: this.deviceProfile.c8y_Filter.type }, { __not: { __has: `deviceType` } });
            }
            else {
                return this.queriesUtil.addOrFilter({ 'c8y_Filter.type': this.deviceProfile.c8y_Filter.type }, {
                    __or: [{ 'c8y_Filter.type': '' }, { __not: { __has: `c8y_Filter.type` } }]
                });
            }
        }
        return {};
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DeviceProfileComponent, deps: [{ token: i5.ActivatedRoute }, { token: i2.AlertService }, { token: i1.InventoryService }, { token: i4.BsModalService }, { token: i1$1.RepositoryService }, { token: DeviceProfileService }], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.14", type: DeviceProfileComponent, isStandalone: false, selector: "c8y-device-profile", providers: [
            {
                provide: PRODUCT_EXPERIENCE_EVENT_SOURCE,
                useExisting: forwardRef(() => DeviceProfileComponent)
            }
        ], ngImport: i0, template: "<c8y-title>{{ profileName }}</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-device-profile'\"\n    [label]=\"'Device profiles' | translate\"\n    [path]=\"'device-profiles'\"\n  ></c8y-breadcrumb-item>\n  <c8y-breadcrumb-item\n    icon=\"c8y-device-profile\"\n    label=\"{{ profileName }}\"\n  ></c8y-breadcrumb-item>\n</c8y-breadcrumb>\n\n<div\n  class=\"row\"\n  *ngIf=\"deviceProfile\"\n>\n  <div class=\"col-lg-12 col-lg-max\">\n    <div\n      class=\"card card--fullpage\"\n      *ngIf=\"deviceProfile\"\n    >\n      <div class=\"card-block bg-level-1 flex-no-shrink p-t-24 p-b-24 overflow-visible\">\n        <div class=\"content-flex-70\">\n          <div class=\"text-center\">\n            <i class=\"c8y-icon-duocolor icon-48 c8y-icon c8y-icon-device-profile\"></i>\n            <p>\n              <small class=\"label label-info\">{{ 'Device profile' | translate }}</small>\n            </p>\n          </div>\n          <div class=\"flex-grow col-10\">\n            <div class=\"row\">\n              <div class=\"col-md-4\">\n                <form #editNameForm=\"ngForm\">\n                  <c8y-form-group>\n                    <label\n                      class=\"control-label\"\n                      translate\n                    >\n                      Name\n                    </label>\n                    <div class=\"input-group input-group-editable\">\n                      <input\n                        class=\"form-control\"\n                        placeholder=\"{{ 'e.g. My device profile' | translate }}\"\n                        name=\"name\"\n                        type=\"text\"\n                        required\n                        [(ngModel)]=\"deviceProfile.name\"\n                        data-cy=\"device-profile--add-device-profile-name\"\n                        size=\"{{ deviceProfile.name?.length || 1 }}\"\n                      />\n                      <span></span>\n                      <div class=\"input-group-btn\">\n                        <button\n                          class=\"btn btn-primary\"\n                          title=\"{{ 'Save' | translate }}\"\n                          type=\"button\"\n                          data-cy=\"device-profile--save\"\n                          (click)=\"\n                            updateDeviceProfile({ name: deviceProfile.name });\n                            editNameForm.form.markAsPristine()\n                          \"\n                          [disabled]=\"editNameForm.form.invalid\"\n                          c8yProductExperience\n                          inherit\n                          [actionData]=\"{ action: PRODUCT_EXPERIENCE.ACTIONS.SAVE }\"\n                        >\n                          {{ 'Save' | translate }}\n                        </button>\n                      </div>\n                    </div>\n                  </c8y-form-group>\n                </form>\n              </div>\n              <div class=\"col-md-4\">\n                <form #editTypeForm=\"ngForm\">\n                  <c8y-form-group>\n                    <label class=\"control-label\">\n                      {{ 'Device type' | translate }}\n                      <button\n                        class=\"btn-help\"\n                        [attr.aria-label]=\"'Help' | translate\"\n                        [popover]=\"\n                          (DEVICE_TYPE_POPOVER | translate) +\n                          (isDeviceProfileEmpty\n                            ? ' ' + (DEVICE_TYPE_DISABLED_POPOVER | translate)\n                            : '')\n                        \"\n                        placement=\"right\"\n                        triggers=\"focus\"\n                        container=\"body\"\n                        type=\"button\"\n                      ></button>\n                    </label>\n                    <div class=\"input-group input-group-editable\">\n                      <input\n                        class=\"form-control\"\n                        placeholder=\"{{ 'e.g.' | translate }} c8y_Linux\"\n                        name=\"type\"\n                        type=\"text\"\n                        [(ngModel)]=\"deviceProfile.c8y_Filter.type\"\n                        data-cy=\"device-profile--device-type\"\n                        size=\"{{ deviceProfile.c8y_Filter.type?.length || 14 }}\"\n                        [disabled]=\"isDeviceProfileEmpty\"\n                      />\n                      <span></span>\n                      <div class=\"input-group-btn\">\n                        <button\n                          class=\"btn btn-primary\"\n                          title=\"{{ 'Save' | translate }}\"\n                          type=\"button\"\n                          (click)=\"\n                            updateDeviceProfile({\n                              c8y_Filter: { type: deviceProfile.c8y_Filter.type }\n                            });\n                            editTypeForm.form.markAsPristine()\n                          \"\n                          [disabled]=\"isDeviceProfileEmpty\"\n                          c8yProductExperience\n                          inherit\n                          [actionData]=\"{ action: PRODUCT_EXPERIENCE.ACTIONS.SAVE }\"\n                        >\n                          {{ 'Save' | translate }}\n                        </button>\n                      </div>\n                    </div>\n                  </c8y-form-group>\n                </form>\n              </div>\n            </div>\n          </div>\n        </div>\n      </div>\n      <div class=\"inner-scroll\">\n        <div class=\"card-header separator-top-bottom bg-content sticky-top\">\n          <div class=\"card-icon\">\n            <i\n              class=\"c8y-icon-duocolor\"\n              [c8yIcon]=\"'c8y-firmware'\"\n            ></i>\n          </div>\n          <div\n            class=\"card-title\"\n            translate\n          >\n            Firmware\n          </div>\n        </div>\n        <div\n          class=\"card-block p-t-0\"\n          *ngIf=\"deviceProfile.c8y_DeviceProfile.firmware\"\n        >\n          <c8y-list-group>\n            <c8y-li>\n              <c8y-li-icon>\n                <i [c8yIcon]=\"'c8y-firmware'\"></i>\n              </c8y-li-icon>\n              <c8y-li-body class=\"content-flex-50 m-l-4\">\n                <div class=\"col-4\">\n                  <span\n                    class=\"text-truncate\"\n                    title=\"{{ deviceProfile.c8y_DeviceProfile.firmware.name }}\"\n                  >\n                    <span\n                      class=\"text-label-small m-r-8\"\n                      translate\n                    >\n                      Name\n                    </span>\n                    {{ deviceProfile.c8y_DeviceProfile.firmware.name }}\n                  </span>\n                </div>\n                <div class=\"col-4\"></div>\n                <div class=\"col-3 d-flex a-i-center\">\n                  <span\n                    class=\"text-truncate\"\n                    title=\"{{ deviceProfile.c8y_DeviceProfile.firmware.version }}\"\n                  >\n                    <span\n                      class=\"text-label-small m-r-4\"\n                      translate\n                    >\n                      Version\n                    </span>\n                    {{ deviceProfile.c8y_DeviceProfile.firmware.version }}\n                  </span>\n                  <button\n                    class=\"btn btn-danger btn-xs visible-xs m-l-auto m-r-8 m-t-8\"\n                    title=\"{{ 'Remove`firmware`' | translate }}\"\n                    type=\"button\"\n                    (click)=\"removeFirmware()\"\n                    c8yProductExperience\n                    inherit\n                    [actionData]=\"{\n                      action: PRODUCT_EXPERIENCE.ACTIONS.REMOVE,\n                      fragment: PRODUCT_EXPERIENCE.FRAGMENTS.FIRMWARE\n                    }\"\n                  >\n                    <i c8yIcon=\"minus-circle\"></i>\n                    {{ 'Remove`firmware`' | translate }}\n                  </button>\n                </div>\n                <div class=\"m-l-auto p-r-8 hidden-xs\">\n                  <button\n                    class=\"btn btn-dot showOnHover text-danger\"\n                    [attr.aria-label]=\"'Remove`firmware`' | translate\"\n                    tooltip=\"{{ 'Remove`firmware`' | translate }}\"\n                    placement=\"right\"\n                    type=\"button\"\n                    [delay]=\"500\"\n                    (click)=\"removeFirmware()\"\n                    c8yProductExperience\n                    inherit\n                    [actionData]=\"{\n                      action: PRODUCT_EXPERIENCE.ACTIONS.REMOVE,\n                      fragment: PRODUCT_EXPERIENCE.FRAGMENTS.FIRMWARE\n                    }\"\n                  >\n                    <i c8yIcon=\"minus-circle\"></i>\n                  </button>\n                </div>\n              </c8y-li-body>\n            </c8y-li>\n          </c8y-list-group>\n        </div>\n        <div\n          class=\"card-block p-t-16\"\n          *ngIf=\"!deviceProfile.c8y_DeviceProfile.firmware\"\n        >\n          <c8y-ui-empty-state\n            class=\"p-t-16 d-block\"\n            icon=\"c8y-firmware\"\n            [title]=\"'No firmware defined.' | translate\"\n            [horizontal]=\"true\"\n          ></c8y-ui-empty-state>\n        </div>\n        <div\n          class=\"card-footer p-t-0\"\n          *ngIf=\"!deviceProfile.c8y_DeviceProfile.firmware\"\n        >\n          <button\n            class=\"btn btn-default\"\n            title=\"{{ 'Add firmware' | translate }}\"\n            type=\"button\"\n            data-cy=\"device-profile--Add-firmware-button\"\n            (click)=\"addFirmware()\"\n            c8yProductExperience\n            inherit\n            [actionData]=\"{\n              action: PRODUCT_EXPERIENCE.ACTIONS.ADD,\n              fragment: PRODUCT_EXPERIENCE.FRAGMENTS.FIRMWARE\n            }\"\n          >\n            <i c8yIcon=\"plus-circle\"></i>\n            {{ 'Add firmware' | translate }}\n          </button>\n        </div>\n\n        <div class=\"card-header separator-top-bottom sticky-top bg-component\">\n          <div class=\"card-icon\">\n            <i\n              class=\"c8y-icon-duocolor\"\n              [c8yIcon]=\"'c8y-tools'\"\n            ></i>\n          </div>\n          <div\n            class=\"card-title\"\n            translate\n          >\n            Software\n          </div>\n        </div>\n        <div\n          class=\"card-block p-t-0\"\n          *ngIf=\"deviceProfile.c8y_DeviceProfile.software?.length > 0\"\n        >\n          <c8y-list-group>\n            <c8y-li *ngFor=\"let software of deviceProfile.c8y_DeviceProfile.software\">\n              <c8y-li-icon>\n                <i [c8yIcon]=\"'c8y-tools'\"></i>\n              </c8y-li-icon>\n              <c8y-li-body class=\"content-flex-50 m-l-4\">\n                <div class=\"col-4\">\n                  <span\n                    class=\"text-truncate-wrap\"\n                    title=\"{{ software.name }}\"\n                  >\n                    <span\n                      class=\"text-label-small m-r-8\"\n                      translate\n                    >\n                      Name\n                    </span>\n                    {{ software.name }}\n                  </span>\n                </div>\n                <div class=\"col-4\">\n                  <span\n                    class=\"text-truncate-wrap\"\n                    title=\"{{ software.name }}\"\n                  >\n                    <span\n                      class=\"text-label-small m-r-8\"\n                      translate\n                    >\n                      Type\n                    </span>\n                    <span\n                      class=\"label label-info m-l-4\"\n                      *ngIf=\"!!software.softwareType\"\n                    >\n                      {{ software.softwareType }}\n                    </span>\n                  </span>\n                </div>\n                <div class=\"col-3 d-flex a-i-center\">\n                  <span\n                    class=\"text-truncate-wrap\"\n                    title=\"{{ software.version }}\"\n                  >\n                    <span\n                      class=\"text-label-small m-r-8\"\n                      translate\n                    >\n                      Version\n                    </span>\n                    {{ software.version }}\n                  </span>\n                  <button\n                    class=\"btn btn-danger btn-xs visible-xs m-l-auto m-r-8 m-t-8\"\n                    title=\"{{ 'Remove`software`' | translate }}\"\n                    type=\"button\"\n                    ((click)=\"removeItem(software, 'software')\"\n                    c8yProductExperience\n                    inherit\n                    [actionData]=\"{\n                      action: PRODUCT_EXPERIENCE.ACTIONS.REMOVE,\n                      fragment: PRODUCT_EXPERIENCE.FRAGMENTS.SOFTWARE\n                    }\"\n                  >\n                    <i c8yIcon=\"minus-circle\"></i>\n                    {{ 'Remove`software`' | translate }}\n                  </button>\n                </div>\n                <div class=\"m-l-auto p-r-8 hidden-xs\">\n                  <button\n                    class=\"btn btn-dot showOnHover text-danger\"\n                    [attr.aria-label]=\"'Remove`software`' | translate\"\n                    tooltip=\"{{ 'Remove`software`' | translate }}\"\n                    placement=\"right\"\n                    type=\"button\"\n                    [delay]=\"500\"\n                    (click)=\"removeItem(software, 'software')\"\n                    c8yProductExperience\n                    inherit\n                    [actionData]=\"{\n                      action: PRODUCT_EXPERIENCE.ACTIONS.REMOVE,\n                      fragment: PRODUCT_EXPERIENCE.FRAGMENTS.SOFTWARE\n                    }\"\n                  >\n                    <i\n                      c8yIcon=\"minus-circle\"\n                      data-cy=\"device-profile--Remove-icon\"\n                    ></i>\n                  </button>\n                </div>\n              </c8y-li-body>\n            </c8y-li>\n          </c8y-list-group>\n        </div>\n        <div\n          class=\"card-block p-t-16\"\n          *ngIf=\"deviceProfile.c8y_DeviceProfile.software?.length === 0\"\n        >\n          <c8y-ui-empty-state\n            icon=\"c8y-tools\"\n            [title]=\"'No software defined.' | translate\"\n            [horizontal]=\"true\"\n          ></c8y-ui-empty-state>\n        </div>\n        <div class=\"card-footer p-t-0\">\n          <button\n            class=\"btn btn-default m-b-0\"\n            title=\"{{ 'Add software' | translate }}\"\n            type=\"button\"\n            data-cy=\"device-profile--Add-software-button\"\n            (click)=\"addSoftware()\"\n            c8yProductExperience\n            inherit\n            [actionData]=\"{\n              action: PRODUCT_EXPERIENCE.ACTIONS.ADD,\n              fragment: PRODUCT_EXPERIENCE.FRAGMENTS.SOFTWARE\n            }\"\n          >\n            <i c8yIcon=\"plus-circle\"></i>\n            {{ 'Add software' | translate }}\n          </button>\n        </div>\n\n        <div class=\"card-header separator-top-bottom bg-component sticky-top\">\n          <div class=\"card-icon\">\n            <i\n              class=\"c8y-icon-duocolor\"\n              [c8yIcon]=\"'gears'\"\n            ></i>\n          </div>\n          <div\n            class=\"card-title\"\n            translate\n          >\n            Configuration\n          </div>\n        </div>\n        <div\n          class=\"card-block p-t-0\"\n          *ngIf=\"deviceProfile.c8y_DeviceProfile.configuration?.length > 0\"\n        >\n          <c8y-list-group>\n            <c8y-li *ngFor=\"let configuration of deviceProfile.c8y_DeviceProfile.configuration\">\n              <c8y-li-icon>\n                <i [c8yIcon]=\"'gears'\"></i>\n              </c8y-li-icon>\n              <c8y-li-body class=\"content-flex-50\">\n                <div class=\"col-4\">\n                  <span\n                    class=\"text-truncate\"\n                    title=\"{{ configuration.name }}\"\n                  >\n                    <span\n                      class=\"text-label-small m-r-8\"\n                      translate\n                    >\n                      Name\n                    </span>\n                    {{ configuration.name }}\n                  </span>\n                </div>\n                <div class=\"col-4\">\n                  <span\n                    class=\"text-label-small m-r-8\"\n                    translate\n                  >\n                    Type\n                  </span>\n                  <span class=\"label label-info\">{{ configuration.type }}</span>\n                  <button\n                    class=\"btn btn-danger btn-xs visible-xs m-l-auto m-r-8 m-t-8\"\n                    title=\"{{ 'Remove`configuration`' | translate }}\"\n                    type=\"button\"\n                    (click)=\"removeItem(configuration, 'configuration')\"\n                    c8yProductExperience\n                    inherit\n                    [actionData]=\"{\n                      action: PRODUCT_EXPERIENCE.ACTIONS.REMOVE,\n                      fragment: PRODUCT_EXPERIENCE.FRAGMENTS.CONFGIURATION\n                    }\"\n                  >\n                    <i c8yIcon=\"minus-circle\"></i>\n                    {{ 'Remove`configuration`' | translate }}\n                  </button>\n                </div>\n                <div class=\"col-3 d-flex a-i-center\"></div>\n                <div class=\"m-l-auto p-r-8 hidden-xs\">\n                  <button\n                    class=\"btn btn-dot showOnHover text-danger\"\n                    [attr.aria-label]=\"'Remove`configuration`' | translate\"\n                    tooltip=\"{{ 'Remove`configuration`' | translate }}\"\n                    placement=\"top\"\n                    type=\"button\"\n                    (click)=\"removeItem(configuration, 'configuration')\"\n                    [delay]=\"500\"\n                    c8yProductExperience\n                    inherit\n                    [actionData]=\"{\n                      action: PRODUCT_EXPERIENCE.ACTIONS.REMOVE,\n                      fragment: PRODUCT_EXPERIENCE.FRAGMENTS.CONFGIURATION\n                    }\"\n                  >\n                    <i\n                      c8yIcon=\"minus-circle\"\n                      data-cy=\"device-profile--Remove-icon\"\n                    ></i>\n                  </button>\n                </div>\n              </c8y-li-body>\n            </c8y-li>\n          </c8y-list-group>\n        </div>\n        <div\n          class=\"card-block p-t-16\"\n          *ngIf=\"deviceProfile.c8y_DeviceProfile.configuration?.length === 0\"\n        >\n          <c8y-ui-empty-state\n            icon=\"gears\"\n            [title]=\"'No configuration defined.' | translate\"\n            [horizontal]=\"true\"\n          ></c8y-ui-empty-state>\n        </div>\n        <div class=\"card-footer p-t-0\">\n          <div class=\"p-t-8\">\n            <button\n              class=\"btn btn-default m-b-0\"\n              title=\"{{ 'Add configuration' | translate }}\"\n              type=\"button\"\n              data-cy=\"device-profile--Add-configuration-button\"\n              (click)=\"addConfiguration()\"\n              c8yProductExperience\n              inherit\n              [actionData]=\"{\n                action: PRODUCT_EXPERIENCE.ACTIONS.ADD,\n                fragment: PRODUCT_EXPERIENCE.FRAGMENTS.CONFGIURATION\n              }\"\n            >\n              <i c8yIcon=\"plus-circle\"></i>\n              {{ 'Add configuration' | translate }}\n            </button>\n          </div>\n        </div>\n      </div>\n    </div>\n  </div>\n</div>\n", dependencies: [{ kind: "component", type: i2.BreadcrumbComponent, selector: "c8y-breadcrumb" }, { kind: "component", type: i2.BreadcrumbItemComponent, selector: "c8y-breadcrumb-item", inputs: ["icon", "translate", "label", "path", "injector"] }, { kind: "component", type: i2.EmptyStateComponent, selector: "c8y-ui-empty-state", inputs: ["icon", "title", "subtitle", "horizontal"] }, { kind: "directive", type: i2.IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "directive", type: i2.C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "directive", type: i2$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i2.TitleComponent, selector: "c8y-title", inputs: ["pageTitleUpdate"] }, { kind: "directive", type: i8.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i8.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: i8.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i8.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i8.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i8.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i8.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: i2.FormGroupComponent, selector: "c8y-form-group", inputs: ["hasError", "hasWarning", "hasSuccess", "novalidation", "status"] }, { kind: "directive", type: i2.RequiredInputPlaceholderDirective, selector: "input[required], input[formControlName]" }, { kind: "component", type: i2.ListGroupComponent, selector: "c8y-list-group" }, { kind: "component", type: i2.ListItemComponent, selector: "c8y-list-item, c8y-li", inputs: ["active", "highlighted", "emptyActions", "dense", "collapsed", "selectable"], outputs: ["collapsedChange"] }, { kind: "component", type: i2.ListItemIconComponent, selector: "c8y-list-item-icon, c8y-li-icon", inputs: ["icon", "status"] }, { kind: "component", type: i2.ListItemBodyComponent, selector: "c8y-list-item-body, c8y-li-body", inputs: ["body"] }, { kind: "directive", type: i2.ProductExperienceDirective, selector: "[c8yProductExperience]", inputs: ["actionName", "actionData", "inherit", "suppressDataOverriding"] }, { kind: "directive", type: i9.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: "directive", type: i10.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: i2.C8yTranslatePipe, name: "translate" }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DeviceProfileComponent, decorators: [{
            type: Component,
            args: [{ selector: 'c8y-device-profile', providers: [
                        {
                            provide: PRODUCT_EXPERIENCE_EVENT_SOURCE,
                            useExisting: forwardRef(() => DeviceProfileComponent)
                        }
                    ], standalone: false, template: "<c8y-title>{{ profileName }}</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-device-profile'\"\n    [label]=\"'Device profiles' | translate\"\n    [path]=\"'device-profiles'\"\n  ></c8y-breadcrumb-item>\n  <c8y-breadcrumb-item\n    icon=\"c8y-device-profile\"\n    label=\"{{ profileName }}\"\n  ></c8y-breadcrumb-item>\n</c8y-breadcrumb>\n\n<div\n  class=\"row\"\n  *ngIf=\"deviceProfile\"\n>\n  <div class=\"col-lg-12 col-lg-max\">\n    <div\n      class=\"card card--fullpage\"\n      *ngIf=\"deviceProfile\"\n    >\n      <div class=\"card-block bg-level-1 flex-no-shrink p-t-24 p-b-24 overflow-visible\">\n        <div class=\"content-flex-70\">\n          <div class=\"text-center\">\n            <i class=\"c8y-icon-duocolor icon-48 c8y-icon c8y-icon-device-profile\"></i>\n            <p>\n              <small class=\"label label-info\">{{ 'Device profile' | translate }}</small>\n            </p>\n          </div>\n          <div class=\"flex-grow col-10\">\n            <div class=\"row\">\n              <div class=\"col-md-4\">\n                <form #editNameForm=\"ngForm\">\n                  <c8y-form-group>\n                    <label\n                      class=\"control-label\"\n                      translate\n                    >\n                      Name\n                    </label>\n                    <div class=\"input-group input-group-editable\">\n                      <input\n                        class=\"form-control\"\n                        placeholder=\"{{ 'e.g. My device profile' | translate }}\"\n                        name=\"name\"\n                        type=\"text\"\n                        required\n                        [(ngModel)]=\"deviceProfile.name\"\n                        data-cy=\"device-profile--add-device-profile-name\"\n                        size=\"{{ deviceProfile.name?.length || 1 }}\"\n                      />\n                      <span></span>\n                      <div class=\"input-group-btn\">\n                        <button\n                          class=\"btn btn-primary\"\n                          title=\"{{ 'Save' | translate }}\"\n                          type=\"button\"\n                          data-cy=\"device-profile--save\"\n                          (click)=\"\n                            updateDeviceProfile({ name: deviceProfile.name });\n                            editNameForm.form.markAsPristine()\n                          \"\n                          [disabled]=\"editNameForm.form.invalid\"\n                          c8yProductExperience\n                          inherit\n                          [actionData]=\"{ action: PRODUCT_EXPERIENCE.ACTIONS.SAVE }\"\n                        >\n                          {{ 'Save' | translate }}\n                        </button>\n                      </div>\n                    </div>\n                  </c8y-form-group>\n                </form>\n              </div>\n              <div class=\"col-md-4\">\n                <form #editTypeForm=\"ngForm\">\n                  <c8y-form-group>\n                    <label class=\"control-label\">\n                      {{ 'Device type' | translate }}\n                      <button\n                        class=\"btn-help\"\n                        [attr.aria-label]=\"'Help' | translate\"\n                        [popover]=\"\n                          (DEVICE_TYPE_POPOVER | translate) +\n                          (isDeviceProfileEmpty\n                            ? ' ' + (DEVICE_TYPE_DISABLED_POPOVER | translate)\n                            : '')\n                        \"\n                        placement=\"right\"\n                        triggers=\"focus\"\n                        container=\"body\"\n                        type=\"button\"\n                      ></button>\n                    </label>\n                    <div class=\"input-group input-group-editable\">\n                      <input\n                        class=\"form-control\"\n                        placeholder=\"{{ 'e.g.' | translate }} c8y_Linux\"\n                        name=\"type\"\n                        type=\"text\"\n                        [(ngModel)]=\"deviceProfile.c8y_Filter.type\"\n                        data-cy=\"device-profile--device-type\"\n                        size=\"{{ deviceProfile.c8y_Filter.type?.length || 14 }}\"\n                        [disabled]=\"isDeviceProfileEmpty\"\n                      />\n                      <span></span>\n                      <div class=\"input-group-btn\">\n                        <button\n                          class=\"btn btn-primary\"\n                          title=\"{{ 'Save' | translate }}\"\n                          type=\"button\"\n                          (click)=\"\n                            updateDeviceProfile({\n                              c8y_Filter: { type: deviceProfile.c8y_Filter.type }\n                            });\n                            editTypeForm.form.markAsPristine()\n                          \"\n                          [disabled]=\"isDeviceProfileEmpty\"\n                          c8yProductExperience\n                          inherit\n                          [actionData]=\"{ action: PRODUCT_EXPERIENCE.ACTIONS.SAVE }\"\n                        >\n                          {{ 'Save' | translate }}\n                        </button>\n                      </div>\n                    </div>\n                  </c8y-form-group>\n                </form>\n              </div>\n            </div>\n          </div>\n        </div>\n      </div>\n      <div class=\"inner-scroll\">\n        <div class=\"card-header separator-top-bottom bg-content sticky-top\">\n          <div class=\"card-icon\">\n            <i\n              class=\"c8y-icon-duocolor\"\n              [c8yIcon]=\"'c8y-firmware'\"\n            ></i>\n          </div>\n          <div\n            class=\"card-title\"\n            translate\n          >\n            Firmware\n          </div>\n        </div>\n        <div\n          class=\"card-block p-t-0\"\n          *ngIf=\"deviceProfile.c8y_DeviceProfile.firmware\"\n        >\n          <c8y-list-group>\n            <c8y-li>\n              <c8y-li-icon>\n                <i [c8yIcon]=\"'c8y-firmware'\"></i>\n              </c8y-li-icon>\n              <c8y-li-body class=\"content-flex-50 m-l-4\">\n                <div class=\"col-4\">\n                  <span\n                    class=\"text-truncate\"\n                    title=\"{{ deviceProfile.c8y_DeviceProfile.firmware.name }}\"\n                  >\n                    <span\n                      class=\"text-label-small m-r-8\"\n                      translate\n                    >\n                      Name\n                    </span>\n                    {{ deviceProfile.c8y_DeviceProfile.firmware.name }}\n                  </span>\n                </div>\n                <div class=\"col-4\"></div>\n                <div class=\"col-3 d-flex a-i-center\">\n                  <span\n                    class=\"text-truncate\"\n                    title=\"{{ deviceProfile.c8y_DeviceProfile.firmware.version }}\"\n                  >\n                    <span\n                      class=\"text-label-small m-r-4\"\n                      translate\n                    >\n                      Version\n                    </span>\n                    {{ deviceProfile.c8y_DeviceProfile.firmware.version }}\n                  </span>\n                  <button\n                    class=\"btn btn-danger btn-xs visible-xs m-l-auto m-r-8 m-t-8\"\n                    title=\"{{ 'Remove`firmware`' | translate }}\"\n                    type=\"button\"\n                    (click)=\"removeFirmware()\"\n                    c8yProductExperience\n                    inherit\n                    [actionData]=\"{\n                      action: PRODUCT_EXPERIENCE.ACTIONS.REMOVE,\n                      fragment: PRODUCT_EXPERIENCE.FRAGMENTS.FIRMWARE\n                    }\"\n                  >\n                    <i c8yIcon=\"minus-circle\"></i>\n                    {{ 'Remove`firmware`' | translate }}\n                  </button>\n                </div>\n                <div class=\"m-l-auto p-r-8 hidden-xs\">\n                  <button\n                    class=\"btn btn-dot showOnHover text-danger\"\n                    [attr.aria-label]=\"'Remove`firmware`' | translate\"\n                    tooltip=\"{{ 'Remove`firmware`' | translate }}\"\n                    placement=\"right\"\n                    type=\"button\"\n                    [delay]=\"500\"\n                    (click)=\"removeFirmware()\"\n                    c8yProductExperience\n                    inherit\n                    [actionData]=\"{\n                      action: PRODUCT_EXPERIENCE.ACTIONS.REMOVE,\n                      fragment: PRODUCT_EXPERIENCE.FRAGMENTS.FIRMWARE\n                    }\"\n                  >\n                    <i c8yIcon=\"minus-circle\"></i>\n                  </button>\n                </div>\n              </c8y-li-body>\n            </c8y-li>\n          </c8y-list-group>\n        </div>\n        <div\n          class=\"card-block p-t-16\"\n          *ngIf=\"!deviceProfile.c8y_DeviceProfile.firmware\"\n        >\n          <c8y-ui-empty-state\n            class=\"p-t-16 d-block\"\n            icon=\"c8y-firmware\"\n            [title]=\"'No firmware defined.' | translate\"\n            [horizontal]=\"true\"\n          ></c8y-ui-empty-state>\n        </div>\n        <div\n          class=\"card-footer p-t-0\"\n          *ngIf=\"!deviceProfile.c8y_DeviceProfile.firmware\"\n        >\n          <button\n            class=\"btn btn-default\"\n            title=\"{{ 'Add firmware' | translate }}\"\n            type=\"button\"\n            data-cy=\"device-profile--Add-firmware-button\"\n            (click)=\"addFirmware()\"\n            c8yProductExperience\n            inherit\n            [actionData]=\"{\n              action: PRODUCT_EXPERIENCE.ACTIONS.ADD,\n              fragment: PRODUCT_EXPERIENCE.FRAGMENTS.FIRMWARE\n            }\"\n          >\n            <i c8yIcon=\"plus-circle\"></i>\n            {{ 'Add firmware' | translate }}\n          </button>\n        </div>\n\n        <div class=\"card-header separator-top-bottom sticky-top bg-component\">\n          <div class=\"card-icon\">\n            <i\n              class=\"c8y-icon-duocolor\"\n              [c8yIcon]=\"'c8y-tools'\"\n            ></i>\n          </div>\n          <div\n            class=\"card-title\"\n            translate\n          >\n            Software\n          </div>\n        </div>\n        <div\n          class=\"card-block p-t-0\"\n          *ngIf=\"deviceProfile.c8y_DeviceProfile.software?.length > 0\"\n        >\n          <c8y-list-group>\n            <c8y-li *ngFor=\"let software of deviceProfile.c8y_DeviceProfile.software\">\n              <c8y-li-icon>\n                <i [c8yIcon]=\"'c8y-tools'\"></i>\n              </c8y-li-icon>\n              <c8y-li-body class=\"content-flex-50 m-l-4\">\n                <div class=\"col-4\">\n                  <span\n                    class=\"text-truncate-wrap\"\n                    title=\"{{ software.name }}\"\n                  >\n                    <span\n                      class=\"text-label-small m-r-8\"\n                      translate\n                    >\n                      Name\n                    </span>\n                    {{ software.name }}\n                  </span>\n                </div>\n                <div class=\"col-4\">\n                  <span\n                    class=\"text-truncate-wrap\"\n                    title=\"{{ software.name }}\"\n                  >\n                    <span\n                      class=\"text-label-small m-r-8\"\n                      translate\n                    >\n                      Type\n                    </span>\n                    <span\n                      class=\"label label-info m-l-4\"\n                      *ngIf=\"!!software.softwareType\"\n                    >\n                      {{ software.softwareType }}\n                    </span>\n                  </span>\n                </div>\n                <div class=\"col-3 d-flex a-i-center\">\n                  <span\n                    class=\"text-truncate-wrap\"\n                    title=\"{{ software.version }}\"\n                  >\n                    <span\n                      class=\"text-label-small m-r-8\"\n                      translate\n                    >\n                      Version\n                    </span>\n                    {{ software.version }}\n                  </span>\n                  <button\n                    class=\"btn btn-danger btn-xs visible-xs m-l-auto m-r-8 m-t-8\"\n                    title=\"{{ 'Remove`software`' | translate }}\"\n                    type=\"button\"\n                    ((click)=\"removeItem(software, 'software')\"\n                    c8yProductExperience\n                    inherit\n                    [actionData]=\"{\n                      action: PRODUCT_EXPERIENCE.ACTIONS.REMOVE,\n                      fragment: PRODUCT_EXPERIENCE.FRAGMENTS.SOFTWARE\n                    }\"\n                  >\n                    <i c8yIcon=\"minus-circle\"></i>\n                    {{ 'Remove`software`' | translate }}\n                  </button>\n                </div>\n                <div class=\"m-l-auto p-r-8 hidden-xs\">\n                  <button\n                    class=\"btn btn-dot showOnHover text-danger\"\n                    [attr.aria-label]=\"'Remove`software`' | translate\"\n                    tooltip=\"{{ 'Remove`software`' | translate }}\"\n                    placement=\"right\"\n                    type=\"button\"\n                    [delay]=\"500\"\n                    (click)=\"removeItem(software, 'software')\"\n                    c8yProductExperience\n                    inherit\n                    [actionData]=\"{\n                      action: PRODUCT_EXPERIENCE.ACTIONS.REMOVE,\n                      fragment: PRODUCT_EXPERIENCE.FRAGMENTS.SOFTWARE\n                    }\"\n                  >\n                    <i\n                      c8yIcon=\"minus-circle\"\n                      data-cy=\"device-profile--Remove-icon\"\n                    ></i>\n                  </button>\n                </div>\n              </c8y-li-body>\n            </c8y-li>\n          </c8y-list-group>\n        </div>\n        <div\n          class=\"card-block p-t-16\"\n          *ngIf=\"deviceProfile.c8y_DeviceProfile.software?.length === 0\"\n        >\n          <c8y-ui-empty-state\n            icon=\"c8y-tools\"\n            [title]=\"'No software defined.' | translate\"\n            [horizontal]=\"true\"\n          ></c8y-ui-empty-state>\n        </div>\n        <div class=\"card-footer p-t-0\">\n          <button\n            class=\"btn btn-default m-b-0\"\n            title=\"{{ 'Add software' | translate }}\"\n            type=\"button\"\n            data-cy=\"device-profile--Add-software-button\"\n            (click)=\"addSoftware()\"\n            c8yProductExperience\n            inherit\n            [actionData]=\"{\n              action: PRODUCT_EXPERIENCE.ACTIONS.ADD,\n              fragment: PRODUCT_EXPERIENCE.FRAGMENTS.SOFTWARE\n            }\"\n          >\n            <i c8yIcon=\"plus-circle\"></i>\n            {{ 'Add software' | translate }}\n          </button>\n        </div>\n\n        <div class=\"card-header separator-top-bottom bg-component sticky-top\">\n          <div class=\"card-icon\">\n            <i\n              class=\"c8y-icon-duocolor\"\n              [c8yIcon]=\"'gears'\"\n            ></i>\n          </div>\n          <div\n            class=\"card-title\"\n            translate\n          >\n            Configuration\n          </div>\n        </div>\n        <div\n          class=\"card-block p-t-0\"\n          *ngIf=\"deviceProfile.c8y_DeviceProfile.configuration?.length > 0\"\n        >\n          <c8y-list-group>\n            <c8y-li *ngFor=\"let configuration of deviceProfile.c8y_DeviceProfile.configuration\">\n              <c8y-li-icon>\n                <i [c8yIcon]=\"'gears'\"></i>\n              </c8y-li-icon>\n              <c8y-li-body class=\"content-flex-50\">\n                <div class=\"col-4\">\n                  <span\n                    class=\"text-truncate\"\n                    title=\"{{ configuration.name }}\"\n                  >\n                    <span\n                      class=\"text-label-small m-r-8\"\n                      translate\n                    >\n                      Name\n                    </span>\n                    {{ configuration.name }}\n                  </span>\n                </div>\n                <div class=\"col-4\">\n                  <span\n                    class=\"text-label-small m-r-8\"\n                    translate\n                  >\n                    Type\n                  </span>\n                  <span class=\"label label-info\">{{ configuration.type }}</span>\n                  <button\n                    class=\"btn btn-danger btn-xs visible-xs m-l-auto m-r-8 m-t-8\"\n                    title=\"{{ 'Remove`configuration`' | translate }}\"\n                    type=\"button\"\n                    (click)=\"removeItem(configuration, 'configuration')\"\n                    c8yProductExperience\n                    inherit\n                    [actionData]=\"{\n                      action: PRODUCT_EXPERIENCE.ACTIONS.REMOVE,\n                      fragment: PRODUCT_EXPERIENCE.FRAGMENTS.CONFGIURATION\n                    }\"\n                  >\n                    <i c8yIcon=\"minus-circle\"></i>\n                    {{ 'Remove`configuration`' | translate }}\n                  </button>\n                </div>\n                <div class=\"col-3 d-flex a-i-center\"></div>\n                <div class=\"m-l-auto p-r-8 hidden-xs\">\n                  <button\n                    class=\"btn btn-dot showOnHover text-danger\"\n                    [attr.aria-label]=\"'Remove`configuration`' | translate\"\n                    tooltip=\"{{ 'Remove`configuration`' | translate }}\"\n                    placement=\"top\"\n                    type=\"button\"\n                    (click)=\"removeItem(configuration, 'configuration')\"\n                    [delay]=\"500\"\n                    c8yProductExperience\n                    inherit\n                    [actionData]=\"{\n                      action: PRODUCT_EXPERIENCE.ACTIONS.REMOVE,\n                      fragment: PRODUCT_EXPERIENCE.FRAGMENTS.CONFGIURATION\n                    }\"\n                  >\n                    <i\n                      c8yIcon=\"minus-circle\"\n                      data-cy=\"device-profile--Remove-icon\"\n                    ></i>\n                  </button>\n                </div>\n              </c8y-li-body>\n            </c8y-li>\n          </c8y-list-group>\n        </div>\n        <div\n          class=\"card-block p-t-16\"\n          *ngIf=\"deviceProfile.c8y_DeviceProfile.configuration?.length === 0\"\n        >\n          <c8y-ui-empty-state\n            icon=\"gears\"\n            [title]=\"'No configuration defined.' | translate\"\n            [horizontal]=\"true\"\n          ></c8y-ui-empty-state>\n        </div>\n        <div class=\"card-footer p-t-0\">\n          <div class=\"p-t-8\">\n            <button\n              class=\"btn btn-default m-b-0\"\n              title=\"{{ 'Add configuration' | translate }}\"\n              type=\"button\"\n              data-cy=\"device-profile--Add-configuration-button\"\n              (click)=\"addConfiguration()\"\n              c8yProductExperience\n              inherit\n              [actionData]=\"{\n                action: PRODUCT_EXPERIENCE.ACTIONS.ADD,\n                fragment: PRODUCT_EXPERIENCE.FRAGMENTS.CONFGIURATION\n              }\"\n            >\n              <i c8yIcon=\"plus-circle\"></i>\n              {{ 'Add configuration' | translate }}\n            </button>\n          </div>\n        </div>\n      </div>\n    </div>\n  </div>\n</div>\n" }]
        }], ctorParameters: () => [{ type: i5.ActivatedRoute }, { type: i2.AlertService }, { type: i1.InventoryService }, { type: i4.BsModalService }, { type: i1$1.RepositoryService }, { type: DeviceProfileService }] });

class AddDeviceProfileComponent {
    constructor(modal, deviceProfileService) {
        this.modal = modal;
        this.deviceProfileService = deviceProfileService;
        this.DEVICE_TYPE_POPOVER = gettext('The device profile will be available for assignments on devices of the specified type. Otherwise, it will be available for all device types.');
        this.PRODUCT_EXPERIENCE = PRODUCT_EXPERIENCE_DEVICE_PROFILE;
        this.deviceProfile = {
            name: '',
            type: 'c8y_Profile',
            c8y_Filter: {},
            c8y_DeviceProfile: {}
        };
        this.result = new Promise((resolve, reject) => {
            this._save = resolve;
            this._cancel = reject;
        });
    }
    async create() {
        const mo = (await this.deviceProfileService.createDeviceProfile(this.deviceProfile)).data;
        this._save(mo.id);
    }
    close() {
        this._cancel();
        this.modal.hide();
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: AddDeviceProfileComponent, deps: [{ token: i4.BsModalRef }, { token: DeviceProfileService }], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.14", type: AddDeviceProfileComponent, isStandalone: false, selector: "c8y-add-device-profile", providers: [
            {
                provide: PRODUCT_EXPERIENCE_EVENT_SOURCE,
                useExisting: forwardRef(() => AddDeviceProfileComponent)
            }
        ], ngImport: i0, template: "<div class=\"viewport-modal\">\n  <div class=\"modal-header dialog-header\">\n    <i [c8yIcon]=\"'c8y-device-profile'\"></i>\n    <div\n      class=\"modal-title\"\n      id=\"addDeviceProfileModalTitle\"\n      translate\n    >\n      Add device profile\n    </div>\n  </div>\n\n  <form\n    #createDeviceProfile=\"ngForm\"\n    (ngSubmit)=\"createDeviceProfile.form.valid && create()\"\n  >\n    <div class=\"modal-inner-scroll\">\n      <div\n        class=\"modal-body\"\n        id=\"addDeviceProfileModalDescription\"\n      >\n        <c8y-form-group>\n          <label\n            for=\"name\"\n            translate\n          >\n            Name\n          </label>\n          <input\n            class=\"form-control\"\n            id=\"name\"\n            placeholder=\"{{ 'e.g. My device profile' | translate }}\"\n            name=\"name\"\n            type=\"text\"\n            autocomplete=\"off\"\n            required\n            [(ngModel)]=\"deviceProfile.name\"\n            data-cy=\"add-device-profile--device-profile-name\"\n          />\n        </c8y-form-group>\n        <c8y-form-group>\n          <label>\n            {{ 'Device type' | translate }}\n            <button\n              class=\"btn-help btn-help--sm\"\n              [attr.aria-label]=\"'Help' | translate\"\n              popover=\"{{ DEVICE_TYPE_POPOVER | translate }}\"\n              placement=\"right\"\n              triggers=\"focus\"\n              type=\"button\"\n            ></button>\n          </label>\n          <input\n            class=\"form-control\"\n            id=\"deviceType\"\n            placeholder=\"{{ 'e.g.' | translate }} c8y_Linux\"\n            name=\"deviceType\"\n            [(ngModel)]=\"deviceProfile.c8y_Filter.type\"\n            data-cy=\"add-device-profile--device-type\"\n          />\n        </c8y-form-group>\n      </div>\n    </div>\n    <div class=\"modal-footer\">\n      <button\n        class=\"btn btn-default\"\n        title=\"{{ 'Cancel' | translate }}\"\n        type=\"button\"\n        (click)=\"close()\"\n        c8yProductExperience\n        inherit\n        suppressDataOverriding\n        [actionData]=\"{ action: PRODUCT_EXPERIENCE.ACTIONS.CANCEL }\"\n      >\n        {{ 'Cancel' | translate }}\n      </button>\n\n      <button\n        class=\"btn btn-primary\"\n        title=\"{{ 'Continue' | translate }}\"\n        type=\"submit\"\n        [disabled]=\"createDeviceProfile.form.invalid\"\n        c8yProductExperience\n        inherit\n        suppressDataOverriding\n        [actionData]=\"{ action: PRODUCT_EXPERIENCE.ACTIONS.CREATE }\"\n      >\n        {{ 'Continue' | translate }}\n      </button>\n    </div>\n  </form>\n</div>\n", dependencies: [{ kind: "directive", type: i2.IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "directive", type: i2.C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "directive", type: i8.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i8.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: i8.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i8.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i8.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i8.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i8.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: i2.FormGroupComponent, selector: "c8y-form-group", inputs: ["hasError", "hasWarning", "hasSuccess", "novalidation", "status"] }, { kind: "directive", type: i2.RequiredInputPlaceholderDirective, selector: "input[required], input[formControlName]" }, { kind: "directive", type: i2.ProductExperienceDirective, selector: "[c8yProductExperience]", inputs: ["actionName", "actionData", "inherit", "suppressDataOverriding"] }, { kind: "directive", type: i10.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: i2.C8yTranslatePipe, name: "translate" }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: AddDeviceProfileComponent, decorators: [{
            type: Component,
            args: [{ selector: 'c8y-add-device-profile', providers: [
                        {
                            provide: PRODUCT_EXPERIENCE_EVENT_SOURCE,
                            useExisting: forwardRef(() => AddDeviceProfileComponent)
                        }
                    ], standalone: false, template: "<div class=\"viewport-modal\">\n  <div class=\"modal-header dialog-header\">\n    <i [c8yIcon]=\"'c8y-device-profile'\"></i>\n    <div\n      class=\"modal-title\"\n      id=\"addDeviceProfileModalTitle\"\n      translate\n    >\n      Add device profile\n    </div>\n  </div>\n\n  <form\n    #createDeviceProfile=\"ngForm\"\n    (ngSubmit)=\"createDeviceProfile.form.valid && create()\"\n  >\n    <div class=\"modal-inner-scroll\">\n      <div\n        class=\"modal-body\"\n        id=\"addDeviceProfileModalDescription\"\n      >\n        <c8y-form-group>\n          <label\n            for=\"name\"\n            translate\n          >\n            Name\n          </label>\n          <input\n            class=\"form-control\"\n            id=\"name\"\n            placeholder=\"{{ 'e.g. My device profile' | translate }}\"\n            name=\"name\"\n            type=\"text\"\n            autocomplete=\"off\"\n            required\n            [(ngModel)]=\"deviceProfile.name\"\n            data-cy=\"add-device-profile--device-profile-name\"\n          />\n        </c8y-form-group>\n        <c8y-form-group>\n          <label>\n            {{ 'Device type' | translate }}\n            <button\n              class=\"btn-help btn-help--sm\"\n              [attr.aria-label]=\"'Help' | translate\"\n              popover=\"{{ DEVICE_TYPE_POPOVER | translate }}\"\n              placement=\"right\"\n              triggers=\"focus\"\n              type=\"button\"\n            ></button>\n          </label>\n          <input\n            class=\"form-control\"\n            id=\"deviceType\"\n            placeholder=\"{{ 'e.g.' | translate }} c8y_Linux\"\n            name=\"deviceType\"\n            [(ngModel)]=\"deviceProfile.c8y_Filter.type\"\n            data-cy=\"add-device-profile--device-type\"\n          />\n        </c8y-form-group>\n      </div>\n    </div>\n    <div class=\"modal-footer\">\n      <button\n        class=\"btn btn-default\"\n        title=\"{{ 'Cancel' | translate }}\"\n        type=\"button\"\n        (click)=\"close()\"\n        c8yProductExperience\n        inherit\n        suppressDataOverriding\n        [actionData]=\"{ action: PRODUCT_EXPERIENCE.ACTIONS.CANCEL }\"\n      >\n        {{ 'Cancel' | translate }}\n      </button>\n\n      <button\n        class=\"btn btn-primary\"\n        title=\"{{ 'Continue' | translate }}\"\n        type=\"submit\"\n        [disabled]=\"createDeviceProfile.form.invalid\"\n        c8yProductExperience\n        inherit\n        suppressDataOverriding\n        [actionData]=\"{ action: PRODUCT_EXPERIENCE.ACTIONS.CREATE }\"\n      >\n        {{ 'Continue' | translate }}\n      </button>\n    </div>\n  </form>\n</div>\n" }]
        }], ctorParameters: () => [{ type: i4.BsModalRef }, { type: DeviceProfileService }] });

class DeviceProfileListComponent {
    constructor(repositoryService, gridService, modalService, bsModalService, translateService, alertService, router, activatedRoute, deviceProfileService) {
        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.deviceProfileService = deviceProfileService;
        this.sizeRequestDone = false;
        this.refresh$ = new EventEmitter();
        this.isDataPresent$ = from(this.repositoryService.listRepositoryEntries(RepositoryType.PROFILE, { skipLegacy: true })).pipe(map(({ data }) => data.length > 0));
        this.columns = [
            new RepositoryItemNameGridColumn({
                filterLabel: gettext('Filter device profile by name'),
                placeholder: gettext('ubuntu core')
            }),
            new DeviceTypeGridColumn({ filterLabel: gettext('Filter device profile by device type') })
        ];
        this.actionControls = [];
        this.pagination = {
            pageSize: 50,
            currentPage: 1
        };
        this.productExperienceEvent = {
            eventName: PRODUCT_EXPERIENCE_DEVICE_PROFILE.EVENTS.REPOSITORY,
            data: {
                component: PRODUCT_EXPERIENCE_DEVICE_PROFILE.COMPONENTS.DEVICE_PROFILE_LIST
            }
        };
        this.noResultsMessage = gettext('No results to display.');
        this.noDataMessage = gettext('No device profiles to display.');
        this.noResultsSubtitle = gettext('Refine your search terms or check your spelling.');
        this.noDataSubtitle = gettext('Add a new device profile by clicking below.');
        this.serverSideDataCallback = this.onDataSourceModifier.bind(this);
    }
    ngOnInit() {
        this.actionControls.push({
            type: BuiltInActionType.Edit,
            callback: this.editDeviceProfile.bind(this)
        });
        this.actionControls.push({
            type: 'duplicate',
            icon: 'copy',
            text: gettext('Duplicate'),
            callback: this.duplicateDeviceProfile.bind(this)
        });
        this.actionControls.push({
            type: BuiltInActionType.Delete,
            callback: this.deleteDeviceProfile.bind(this)
        });
    }
    async onDataSourceModifier(dataSourceModifier) {
        const dataRequest = this.repositoryService.listRepositoryEntries(RepositoryType.PROFILE, {
            query: this.gridService.getQueryObj(dataSourceModifier.columns),
            skipDefaultOrder: true,
            params: {
                pageSize: dataSourceModifier.pagination.pageSize,
                currentPage: dataSourceModifier.pagination.currentPage
            }
        });
        const filtererdSizeRequest = this.repositoryService
            .listRepositoryEntries(RepositoryType.PROFILE, {
            skipDefaultOrder: true,
            query: this.gridService.getQueryObj(dataSourceModifier.columns),
            params: { pageSize: 1 }
        })
            .then(response => response?.paging?.totalPages);
        this.sizeRequest = this.repositoryService
            .listRepositoryEntries(RepositoryType.PROFILE, {
            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;
    }
    editDeviceProfile(deviceProfile) {
        this.router.navigate([deviceProfile.id], { relativeTo: this.activatedRoute });
    }
    async createDeviceProfile() {
        const modal = this.bsModalService.show(AddDeviceProfileComponent, {
            class: 'modal-sm',
            ariaDescribedby: 'addDeviceProfileModalDescription',
            ariaLabelledBy: 'addDeviceProfileModalTitle',
            ignoreBackdropClick: true,
            keyboard: false,
            initialState: {
                productExperienceEvent: {
                    ...this.productExperienceEvent,
                    data: {
                        ...this.productExperienceEvent.data,
                        component: PRODUCT_EXPERIENCE_DEVICE_PROFILE.COMPONENTS.ADD_DEVICE_PROFILE
                    }
                }
            }
        }).content;
        try {
            const profileId = await modal.result;
            modal.close();
            this.router.navigateByUrl(`/device-profiles/${profileId}`);
        }
        catch (ex) {
            // do nothing
        }
    }
    async duplicateDeviceProfile(deviceProfile) {
        const copy = cloneDeep(deviceProfile);
        copy.id = null;
        copy.name = 'Duplicate of ' + deviceProfile.name;
        const mo = (await this.deviceProfileService.createDeviceProfile(copy)).data;
        this.router.navigateByUrl(`/device-profiles/${mo.id}`);
    }
    async deleteDeviceProfile(deviceProfile) {
        const deviceProfileName = deviceProfile.name;
        const title = gettext('Delete device profile');
        const confirmationText = this.translateService.instant(gettext('You are about to delete a device profile "{{ deviceProfileName }}".'), { deviceProfileName });
        const finalQuestion = this.translateService.instant(gettext('Do you want to proceed?'));
        try {
            await this.modalService.confirm(title, `${confirmationText} ${finalQuestion}`, Status.DANGER, {
                ok: gettext('Delete')
            }, {}, this.productExperienceEvent);
            await this.delete(deviceProfile.id);
            this.refresh$.next();
        }
        catch (ex) {
            // do nothing
        }
    }
    trackByName(_index, column) {
        return column.name;
    }
    async delete(profileId) {
        try {
            await this.repositoryService.delete(profileId);
            this.alertService.success(gettext('Device profile deleted.'));
        }
        catch (ex) {
            this.alertService.addServerFailure(ex);
        }
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DeviceProfileListComponent, deps: [{ token: i1$1.RepositoryService }, { token: i2.DataGridService }, { token: i2.ModalService }, { token: i4.BsModalService }, { token: i4$1.TranslateService }, { token: i2.AlertService }, { token: i5.Router }, { token: i5.ActivatedRoute }, { token: DeviceProfileService }], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.14", type: DeviceProfileListComponent, isStandalone: false, selector: "c8y-device-profile-list", providers: [
            {
                provide: PRODUCT_EXPERIENCE_EVENT_SOURCE,
                useExisting: forwardRef(() => DeviceProfileListComponent)
            }
        ], ngImport: i0, template: "<c8y-title>{{ 'Device profiles' | translate }}</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-device-profile\"\n    label=\"{{ 'Device profiles' | 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 device profile' | translate }}\"\n    data-cy=\"device-profile-list--Add-device-profile\"\n    (click)=\"createDeviceProfile()\"\n  >\n    <i c8yIcon=\"plus-circle\"></i>\n    {{ 'Add device profile' | translate }}\n  </button>\n</c8y-action-bar-item>\n\n<c8y-help\n  src=\"/docs/device-management-application/managing-device-data/#managing-device-profiles\"\n></c8y-help>\n\n<div class=\"content-fullpage border-top border-bottom\">\n  <c8y-data-grid\n    [title]=\"'Device profiles' | 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 device profile' | translate }}\"\n          type=\"button\"\n          (click)=\"createDeviceProfile()\"\n        >\n          {{ 'Add device profile' | 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: "component", type: i2.ActionBarItemComponent, selector: "c8y-action-bar-item", inputs: ["placement", "priority", "itemClass", "injector", "groupId", "inGroupPriority"] }, { kind: "component", type: i2.BreadcrumbComponent, selector: "c8y-breadcrumb" }, { kind: "component", type: i2.BreadcrumbItemComponent, selector: "c8y-breadcrumb-item", inputs: ["icon", "translate", "label", "path", "injector"] }, { kind: "component", type: i2.EmptyStateComponent, selector: "c8y-ui-empty-state", inputs: ["icon", "title", "subtitle", "horizontal"] }, { kind: "directive", type: i2.EmptyStateContextDirective, selector: "[emptyStateContext]" }, { kind: "directive", type: i2.IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "directive", type: i2$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.ColumnDirective, selector: "c8y-column", inputs: ["name"] }, { kind: "component", type: i2.DataGridComponent, selector: "c8y-data-grid", inputs: ["title", "loadMoreItemsLabel", "loadingItemsLabel", "showSearch", "refresh", "columns", "rows", "pagination", "childNodePagination", "infiniteScroll", "serverSideDataCallback", "selectable", "singleSelection", "selectionPrimaryKey", "displayOptions", "actionControls", "bulkActionControls", "headerActionControls", "searchText", "configureColumnsEnabled", "showCounterWarning", "activeClassName", "expandableRows", "treeGrid", "hideReload", "childNodesProperty", "parentNodeLabelProperty"], outputs: ["rowMouseOver", "rowMouseLeave", "rowClick", "onConfigChange", "onBeforeFilter", "onBeforeSearch", "onFilter", "itemsSelect", "onReload", "onAddCustomColumn", "onRemoveCustomColumn", "onColumnFilterReset", "onSort", "onPageSizeChange", "onColumnReordered", "onColumnVisibilityChange"] }, { kind: "component", type: i2.TitleComponent, selector: "c8y-title", inputs: ["pageTitleUpdate"] }, { kind: "component", type: i2.HelpComponent, selector: "c8y-help", inputs: ["src", "isCollapsed", "priority", "icon"] }, { kind: "pipe", type: i2.C8yTranslatePipe, name: "translate" }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DeviceProfileListComponent, decorators: [{
            type: Component,
            args: [{ selector: 'c8y-device-profile-list', providers: [
                        {
                            provide: PRODUCT_EXPERIENCE_EVENT_SOURCE,
                            useExisting: forwardRef(() => DeviceProfileListComponent)
                        }
                    ], standalone: false, template: "<c8y-title>{{ 'Device profiles' | translate }}</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-device-profile\"\n    label=\"{{ 'Device profiles' | 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 device profile' | translate }}\"\n    data-cy=\"device-profile-list--Add-device-profile\"\n    (click)=\"createDeviceProfile()\"\n  >\n    <i c8yIcon=\"plus-circle\"></i>\n    {{ 'Add device profile' | translate }}\n  </button>\n</c8y-action-bar-item>\n\n<c8y-help\n  src=\"/docs/device-management-application/managing-device-data/#managing-device-profiles\"\n></c8y-help>\n\n<div class=\"content-fullpage border-top border-bottom\">\n  <c8y-data-grid\n    [title]=\"'Device profiles' | 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 device profile' | translate }}\"\n          type=\"button\"\n          (click)=\"createDeviceProfile()\"\n        >\n          {{ 'Add device profile' | 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: i1$1.RepositoryService }, { type: i2.DataGridService }, { type: i2.ModalService }, { type: i4.BsModalService }, { type: i4$1.TranslateService }, { type: i2.AlertService }, { type: i5.Router }, { type: i5.ActivatedRoute }, { type: DeviceProfileService }] });

class DeviceProfileGuard {
    canActivate(route) {
        const contextData = route.data.contextData || route.parent.data.contextData;
        if (!contextData) {
            return false;
        }
        return this.hasSupportedOperation(contextData, DeviceProfileOperation.APPLY_PROFILE);
    }
    hasSupportedOperation(mo, operation) {
        const supported = mo.c8y_SupportedOperations || [];
        if (!supported) {
            return false;
        }
        return !!supported.find(supportedOperation => supportedOperation === operation);
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DeviceProfileGuard, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
    static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DeviceProfileGuard }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DeviceProfileGuard, decorators: [{
            type: Injectable
        }] });

class DeviceProfileItemListComponent {
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DeviceProfileItemListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.14", type: DeviceProfileItemListComponent, isStandalone: false, selector: "c8y-device-profile-item-list", inputs: { icon: "icon", comparisonResults: "comparisonResults", showProfileItems: "showProfileItems", showTextLabel: "showTextLabel" }, ngImport: i0, template: "<div\n  class=\"d-contents\"\n  *ngFor=\"let comparisonResult of comparisonResults\"\n>\n  <div\n    class=\"p-l-16 p-r-16\"\n    *ngIf=\"showProfileItems\"\n  >\n    <div class=\"c8y-list__item fit-h\">\n      <div\n        class=\"c8y-list__item__block\"\n        *ngIf=\"comparisonResult.profile\"\n      >\n        <div class=\"c8y-list__item__icon\">\n          <i [c8yIcon]=\"icon\"></i>\n        </div>\n        <div class=\"c8y-list__item__body\">\n          <ng-container\n            *ngTemplateOutlet=\"comparisonResultInfo; context: comparisonResult.profile\"\n          ></ng-container>\n        </div>\n      </div>\n    </div>\n  </div>\n  <div class=\"p-l-16 p-r-16 bg-level-1\">\n    <div\n      class=\"c8y-list__item bg-level-1\"\n      [ngClass]=\"{\n        'has-warning': !!comparisonResult.comparisonAlert\n      }\"\n    >\n      <div class=\"c8y-list__item__block\">\n        <div class=\"c8y-list__item__icon\">\n          <i [c8yIcon]=\"icon\"></i>\n        </div>\n        <div class=\"c8y-list__item__body\">\n          <ng-container\n            *ngTemplateOutlet=\"\n              comparisonResultInfo;\n              context: comparisonResult.device ? comparisonResult.device : comparisonResult.profile\n            \"\n          ></ng-container>\n          <c8y-messages\n            class=\"m-0\"\n            style=\"margin-bottom: calc(var(--margin-base, 8px) * -1)\"\n            *ngIf=\"comparisonResult.comparisonAlert\"\n          >\n            <c8y-message>\n              {{ comparisonResult.comparisonAlert | translate }}\n            </c8y-message>\n          </c8y-messages>\n        </div>\n      </div>\n    </div>\n  </div>\n  <div\n    class=\"p-l-16 p-r-16 bg-level-0 hidden-xs hidden-sm\"\n    *ngIf=\"!showProfileItems\"\n  ></div>\n</div>\n\n<ng-template\n  #comparisonResultInfo\n  let-name=\"itemName\"\n  let-details=\"itemDetails\"\n  let-type=\"itemType\"\n>\n  <div class=\"content-flex-40\">\n    <div class=\"col-5\">\n      <span class=\"text-truncate\">\n        <span class=\"text-label-small m-r-4\">Name</span>\n        <span title=\"{{ name }}\">\n          {{ name }}\n        </span>\n      </span>\n    </div>\n    <div class=\"col-3\">\n      <span\n        class=\"text-truncate\"\n        *ngIf=\"!!type\"\n      >\n        <span class=\"text-label-small m-r-4\">Type</span>\n        <span title=\"{{ type }}\">\n          <span class=\"label label-info m-l-4\">\n            {{ type }}\n          </span>\n        </span>\n      </span>\n    </div>\n    <div class=\"col-4\">\n      <span\n        class=\"text-truncate\"\n        *ngIf=\"showTextLabel && details; else showInfoLabel\"\n      >\n        <span\n          class=\"text-label-small m-r-4\"\n          translate\n        >\n          Version\n        </span>\n        <span title=\"{{ details }}\">{{ details }}</span>\n      </span>\n      <ng-template #showInfoLabel>\n        <span class=\"label label-info\">{{ details }}</span>\n      </ng-template>\n    </div>\n  </div>\n</ng-template>\n", dependencies: [{ kind: "directive", type: i2.IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "directive", type: i2.C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "directive", type: i2$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2$1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i2.MessageDirective, selector: "c8y-message", inputs: ["name", "text"] }, { kind: "component", type: i2.MessagesComponent, selector: "c8y-messages", inputs: ["show", "defaults", "helpMessage"] }, { kind: "pipe", type: i2.C8yTranslatePipe, name: "translate" }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DeviceProfileItemListComponent, decorators: [{
            type: Component,
            args: [{ selector: 'c8y-device-profile-item-list', standalone: false, template: "<div\n  class=\"d-contents\"\n  *ngFor=\"let comparisonResult of comparisonResults\"\n>\n  <div\n    class=\"p-l-16 p-r-16\"\n    *ngIf=\"showProfileItems\"\n  >\n    <div class=\"c8y-list__item fit-h\">\n      <div\n        class=\"c8y-list__item__block\"\n        *ngIf=\"comparisonResult.profile\"\n      >\n        <div class=\"c8y-list__item__icon\">\n          <i [c8yIcon]=\"icon\"></i>\n        </div>\n        <div class=\"c8y-list__item__body\">\n          <ng-container\n            *ngTemplateOutlet=\"comparisonResultInfo; context: comparisonResult.profile\"\n          ></ng-container>\n        </div>\n      </div>\n    </div>\n  </div>\n  <div class=\"p-l-16 p-r-16 bg-level-1\">\n    <div\n      class=\"c8y-list__item bg-level-1\"\n      [ngClass]=\"{\n        'has-warning': !!comparisonResult.comparisonAlert\n      }\"\n    >\n      <div class=\"c8y-list__item__block\">\n        <div class=\"c8y-list__item__icon\">\n          <i [c8yIcon]=\"icon\"></i>\n        </div>\n        <div class=\"c8y-list__item__body\">\n          <ng-container\n            *ngTemplateOutlet=\"\n              comparisonResultInfo;\n              context: comparisonResult.device ? comparisonResult.device : comparisonResult.profile\n            \"\n          ></ng-container>\n          <c8y-messages\n            class=\"m-0\"\n            style=\"margin-bottom: calc(var(--margin-base, 8px) * -1)\"\n            *ngIf=\"comparisonResult.comparisonAlert\"\n          >\n            <c8y-message>\n              {{ comparisonResult.comparisonAlert | translate }}\n            </c8y-message>\n          </c8y-messages>\n        </div>\n      </div>\n    </div>\n  </div>\n  <div\n    class=\"p-l-16 p-r-16 bg-level-0 hidden-xs hidden-sm\"\n    *ngIf=\"!showProfileItems\"\n  ></div>\n</div>\n\n<ng-template\n  #comparisonResultInfo\n  let-name=\"itemName\"\n  let-details=\"itemDetails\"\n  let-type=\"itemType\"\n>\n  <div class=\"content-flex-40\">\n    <div class=\"col-5\">\n      <span class=\"text-truncate\">\n        <span class=\"text-label-small m-r-4\">Name</span>\n        <span title=\"{{ name }}\">\n          {{ name }}\n        </span>\n      </span>\n    </div>\n    <div class=\"col-3\">\n      <span\n        class=\"text-truncate\"\n        *ngIf=\"!!type\"\n      >\n        <span class=\"text-label-small m-r-4\">Type</span>\n        <span title=\"{{ type }}\">\n          <span class=\"label label-info m-l-4\">\n            {{ type }}\n          </span>\n        </span>\n      </span>\n    </div>\n    <div class=\"col-4\">\n      <span\n        class=\"text-truncate\"\n        *ngIf=\"showTextLabel && details; else showInfoLabel\"\n      >\n        <span\n          class=\"text-label-small m-r-4\"\n          translate\n        >\n          Version\n        </span>\n        <span title=\"{{ details }}\">{{ details }}</span>\n      </span>\n      <ng-template #showInfoLabel>\n        <span class=\"label label-info\">{{ details }}</span>\n      </ng-template>\n    </div>\n  </div>\n</ng-template>\n" }]
        }], propDecorators: { icon: [{
                type: Input
            }], comparisonResults: [{
                type: Input
            }], showProfileItems: [{
                type: Input
            }], showTextLabel: [{
                type: Input
            }] } });

class DeviceTabProfileDetailComponent {
    constructor() {
        this.emptyStateText = '';
        this.emptyStateDetails = '';
        this.showTextLabel = true;
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DeviceTabProfileDetailComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.14", type: DeviceTabProfileDetailComponent, isStandalone: false, selector: "c8y-device-tab-profile-detail", inputs: { sectionTitle: "sectionTitle", sectionIcon: "sectionIcon", emptyStateText: "emptyStateText", emptyStateDetails: "emptyStateDetails", isProfileSelected: "isProfileSelected", isEmpty: "isEmpty", items: "items", showTextLabel: "showTextLabel" }, ngImport: i0, template: "<div class=\"card--grid grid__col--6-6--md\">\n  <div class=\"bg-level-0 card-block sticky-top\">\n    <h5 class=\"legend form-block\">{{ sectionTitle | translate }}</h5>\n  </div>\n  <div class=\"bg-level-1  card-block sticky-top hidden-xs hidden-sm\">\n    <h5 class=\"legend form-block\">{{ sectionTitle | translate }}</h5>\n  </div>\n  <div class=\"bg-level-0 p-l-16 p-r-16\">\n    <hr class=\"m-0\" />\n  </div>\n  <div class=\"bg-level-1 p-l-16 p-r-16\">\n    <hr class=\"m-0\" />\n  </div>\n  <div class=\"d-contents\" *ngIf=\"!isProfileSelected || isEmpty\">\n    <div class=\"p-l-16 p-r-16\">\n      <div class=\"c8y-empty-state text-left\">\n        <h1 [c8yIcon]=\"sectionIcon\" class=\"c8y-icon-duocolor\"></h1>\n        <p>\n          <span>{{ emptyStateText | translate }}</span\n          ><br />\n          <small *ngIf=\"isProfileSelected; else noItems\">\n            {{ emptyStateDetails | translate }}\n          </small>\n          <ng-template #noItems>\n            <small translate>No device profile selected</small>\n          </ng-template>\n        </p>\n      </div>\n    </div>\n  </div>\n  <div class=\"bg-level-1\" *ngIf=\"items.length === 0\"></div>\n  <c8y-device-profile-item-list\n    *ngIf=\"items.length > 0\"\n    [icon]=\"sectionIcon\"\n    [comparisonResults]=\"items\"\n    [showProfileItems]=\"isProfileSelected && !isEmpty\"\n    [showTextLabel]=\"showTextLabel\"\n    class=\"d-contents\"\n  ></c8y-device-profile-item-list>\n  <div class=\"bg-level-0 p-t-24\" *ngIf=\"isProfileSelected && !isEmpty\"></div>\n  <div class=\"bg-level-1 p-t-24\" *ngIf=\"isProfileSelected && !isEmpty\"></div>\n</div>\n", dependencies: [{ kind: "directive", type: i2.IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "directive", type: i2.C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "directive", type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: DeviceProfileItemListComponent, selector: "c8y-device-profile-item-list", inputs: ["icon", "comparisonResults", "showProfileItems", "showTextLabel"] }, { kind: "pipe", type: i2.C8yTranslatePipe, name: "translate" }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DeviceTabProfileDetailComponent, decorators: [{
            type: Component,
            args: [{ selector: 'c8y-device-tab-profile-detail', standalone: false, template: "<div class=\"card--grid grid__col--6-6--md\">\n  <div class=\"bg-level-0 card-block sticky-top\">\n    <h5 class=\"legend form-block\">{{ sectionTitle | translate }}</h5>\n  </div>\n  <div class=\"bg-level-1  card-block sticky-top hidden-xs hidden-sm\">\n    <h5 class=\"legend form-block\">{{ sectionTitle | translate }}</h5>\n  </div>\n  <div class=\"bg-level-0 p-l-16 p-r-16\">\n    <hr class=\"m-0\" />\n  </div>\n  <div class=\"bg-level-1 p-l-16 p-r-16\">\n    <hr class=\"m-0\" />\n  </div>\n  <div class=\"d-contents\" *ngIf=\"!isProfileSelected || isEmpty\">\n    <div class=\"p-l-16 p-r-16\">\n      <div class=\"c8y-empty-state text-left\">\n        <h1 [c8yIcon]=\"sectionIcon\" class=\"c8y-icon-duocolor\"></h1>\n        <p>\n          <span>{{ emptyStateText | translate }}</span\n          ><br />\n          <small *ngIf=\"isProfileSelected; else noItems\">\n            {{ emptyStateDetails | translate }}\n          </small>\n          <ng-template #noItems>\n            <small translate>No device profile selected</small>\n          </ng-template>\n        </p>\n      </div>\n    </div>\n  </div>\n  <div class=\"bg-level-1\" *ngIf=\"items.length === 0\"></div>\n  <c8y-device-profile-item-list\n    *ngIf=\"items.length > 0\"\n    [icon]=\"sectionIcon\"\n    [comparisonResults]=\"items\"\n    [showProfileItems]=\"isProfileSelected && !isEmpty\"\n    [showTextLabel]=\"showTextLabel\"\n    class=\"d-contents\"\n  ></c8y-device-profile-item-list>\n  <div class=\"bg-level-0 p-t-24\" *ngIf=\"isProfileSelected && !isEmpty\"></div>\n  <div class=\"bg-level-1 p-t-24\" *ngIf=\"isProfileSelected && !isEmpty\"></div>\n</div>\n" }]
        }], propDecorators: { sectionTitle: [{
                type: Input
            }], sectionIcon: [{
                type: Input
            }], emptyStateText: [{
                type: Input
            }], emptyStateDetails: [{
                type: Input
            }], isProfileSelected: [{
                type: Input
            }], isEmpty: [{
                type: Input
            }], items: [{
                type: Input
            }], showTextLabel: [{
                type: Input
            }] } });

class DeviceTabProfileComponent {
    constructor(deviceRealtime, deviceProfileService, route, operationRealtime, alertService) {
        this.deviceRealtime = deviceRealtime;
        this.deviceProfileService = deviceProfileService;
        this.route = route;
        this.operationRealtime = operationRealtime;
        this.alertService = alertService;
        this.PRODUCT_EXPERIENCE = PRODUCT_EXPERIENCE_DEVICE_PROFILE;
        this.firmwareItems = [];
        this.softwareItems = [];
        this.configurationItems = [];
        this.pattern$ = new BehaviorSubject('');
        this.reload$ = new BehaviorSubject(true);
        this.productExperienceEvent = {
            eventName: PRODUCT_EXPERIENCE_DEVICE_PROFILE.EVENTS.DEVICE_TAB,
            data: {
                component: PRODUCT_EXPERIENCE_DEVICE_PROFILE.COMPONENTS.DEVICE_TAB_PROFILE
            }
        };
        this.destroyRef = inject(DestroyRef);
        this.device = this.route.snapshot.parent.data.contextData;
    }
    async ngOnInit() {
        this.getDeviceProfilesAndUpdateProfileItems();
        this.subscribeToManagedObjects();
        const supportedSoftwareTypes = new Set(this.device.c8y_SupportedSoftwareTypes);
        const isSubset = (profileTypes) => {
            return profileTypes.every(type => supportedSoftwareTypes.has(type));
        };
        this.filterPipe = pipe(map(data => {
            if (supportedSoftwareTypes.size) {
                return data.filter(mo => isSubset(this.deviceProfileService.getSoftwareTypes(mo)));
            }
            else {
                return data;
            }
        }));
    }
    async getDeviceProfilesAndUpdateProfileItems() {
        this.deviceProfiles$ = combineLatest([this.reload$.pipe(filter(Boolean)), this.pattern$]).pipe(switchMap(([_, name]) => this.deviceProfileService.getDeviceProfilesByDevice(this.device, name)), tap(async (profiles) => {
            if (this.device.c8y_Profile) {
                const profileId = this.device.c8y_Profile.profileId;
                this.selectedProfile = profiles.data.find(mo => mo.id === profileId);
            }
            this.updateProfileItems(this.device, this.selectedProfile);
            this.operation = await this.deviceProfileService.getProfileOperation(this.device.id);
            this.subscribeToOperations();
        }), tap(() => this.reload$.next(false)), takeUntilDestroyed(this.destroyRef));
    }
    selectProfile(mo) {
        this.selectedProfile = this.toProfileForDevice(mo);
        this.updateProfileItems(this.device, this.selectedProfile);
    }
    async createOperation() {
        this.operation = await this.deviceProfileService.createProfileOperation(this.device, this.selectedProfile);
    }
    updateProfileItems(device, profile) {
        this.firmwareItems = this.deviceProfileService.getFirmwareItems(device, profile);
        this.softwareItems = this.deviceProfileService.getSoftwareItems(device, profile);
        this.configurationItems = this.deviceProfileService.getConfigurationItems(device, profile);
    }
    subscribeToManagedObjects() {
        this.deviceRealtime
            .onUpdate$(this.device.id)
            .pipe(takeUntilDestroyed(this.destroyRef))
            .subscribe((managedObject) => {
            this.updateProfileItems(managedObject, this.selectedProfile);
        });
        this.deviceRealtime
            .onDelete$(this.device.id)
            .pipe(takeUntilDestroyed(this.destroyRef))
            .subscribe(() => {
            this.alertService.danger(gettext('This device has just been deleted. You will be redirected to "All devices" page now.'));
            window.location.href = '#/device';
        });
    }
    subscribeToOperations() {
        this.operationRealtime
            .onAll$(this.device.id)
            .pipe(map(({ data }) => data), filter(operation => operation.c8y_DeviceProfile), takeUntilDestroyed(this.destroyRef))
            .subscribe(operation => {
            this.operation = operation;
        });
    }
    toProfileForDevice(profile) {
        if (Array.from(profile?.c8y_DeviceProfile?.software || []).length === 0 ||
            has(this.device, 'c8y_SupportedSoftwareTypes')) {
            return profile;
        }
        else {
            return {
                ...profile,
                c8y_DeviceProfile: {
                    ...profile.c8y_DeviceProfile,
                    software: profile.c8y_DeviceProfile.software.map(sw => pickBy(sw, (_, key) => key !== 'softwareType'))
                }
            };
        }
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DeviceTabProfileComponent, deps: [{ token: i2.ManagedObjectRealtimeService }, { token: DeviceProfileService }, { token: i5.ActivatedRoute }, { token: i2.OperationRealtimeService }, { token: i2.AlertService }], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.14", type: DeviceTabProfileComponent, isStandalone: false, selector: "c8y-device-tab-profile", providers: [
            ManagedObjectRealtimeService,
            {
                provide: PRODUCT_EXPERIENCE_EVENT_SOURCE,
                useExisting: forwardRef(() => DeviceTabProfileComponent)
            }
        ], ngImport: i0, template: "<c8y-action-bar-item [placement]=\"'right'\">\n  <button\n    class=\"btn btn-link\"\n    title=\"{{ 'Reload' | translate }}\"\n    type=\"button\"\n    (click)=\"reload$.next(true)\"\n  >\n    <i\n      c8yIcon=\"refresh\"\n      [ngClass]=\"{ 'icon-spin': reload$.value }\"\n    ></i>\n    {{ 'Reload' | translate }}\n  </button>\n</c8y-action-bar-item>\n<c8y-action-bar-item [placement]=\"'right'\">\n  <c8y-realtime-btn [service]=\"deviceRealtime\"></c8y-realtime-btn>\n</c8y-action-bar-item>\n\n<div class=\"card card--grid--fullpage card--grid--fullpage card--grid grid__row--2-10--md\">\n  <div class=\"card--grid grid__col--6-6--md\">\n    <!-- AVAILABLE PROFILES -->\n    <div class=\"bg-level-0\">\n      <div class=\"card-header separator\">\n        <div\n          class=\"card-title\"\n          translate\n        >\n          Device profile\n        </div>\n      </div>\n      <div class=\"p-16\">\n        <form #deviceProfileForm=\"ngForm\">\n          <div class=\"input-group\">\n            <c8y-typeahead\n              class=\"flex-grow\"\n              placeholder=\"{{ 'Select device profile' | translate }}\"\n              name=\"selectProfile\"\n              data-cy=\"device-tab-profile--select-device-profile\"\n              [(ngModel)]=\"selectedProfile\"\n              (onSearch)=\"pattern$.next($event)\"\n              [allowFreeEntries]=\"false\"\n            >\n              <c8y-li\n                class=\"p-l-8 p-r-8 c8y-list__item--link\"\n                *c8yFor=\"let profile of deviceProfiles$; pipe: filterPipe\"\n                (click)=\"selectProfile(profile); pattern$.next('')\"\n              >\n                <c8y-highlight\n                  [text]=\"profile.name || '&#45;&#45;'\"\n                  [pattern]=\"pattern$.value\"\n                ></c8y-highlight>\n              </c8y-li>\n            </c8y-typeahead>\n            <div class=\"input-group-btn\">\n              <button\n                class=\"btn btn-primary\"\n                title=\"{{ 'Assign device profile' | translate }}\"\n                type=\"button\"\n                (click)=\"createOperation()\"\n                data-cy=\"device-tab-profile--Assign-device-profile-button\"\n                [disabled]=\"!selectedProfile?.id\"\n                c8yProductExperience\n                inherit\n                [actionData]=\"{ action: PRODUCT_EXPERIENCE.ACTIONS.ASSIGN_DEVICE_PROFILE }\"\n              >\n                <span>{{ 'Assign device profile' | translate }}</span>\n              </button>\n            </div>\n          </div>\n        </form>\n      </div>\n    </div>\n\n    <!-- INSTALL PROFILE OPERATION -->\n    <div class=\"bg-level-1\">\n      <div class=\"card-header separator\">\n        <div\n          class=\"card-title\"\n          translate\n        >\n          Currently installed\n        </div>\n      </div>\n      <div class=\"card-block\">\n        <c8y-operation-details\n          [operation]=\"operation\"\n          c8yProductExperience\n          inherit\n          suppressDataOverriding\n        ></c8y-operation-details>\n      </div>\n    </div>\n  </div>\n  <div class=\"card--grid__inner-scroll d-col no-align-items\">\n    <div class=\"d-contents\">\n      <!-- FIRMWARE -->\n      <c8y-device-tab-profile-detail\n        class=\"d-contents\"\n        [sectionIcon]=\"'c8y-firmware'\"\n        [sectionTitle]=\"'Firmware' | translate\"\n        [emptyStateText]=\"'No firmware to display.' | translate\"\n        [emptyStateDetails]=\"'No firmware assigned.' | translate\"\n        [isProfileSelected]=\"!!selectedProfile\"\n        [items]=\"firmwareItems\"\n        [isEmpty]=\"!selectedProfile?.c8y_DeviceProfile?.firmware?.name\"\n      ></c8y-device-tab-profile-detail>\n    </div>\n    <div class=\"d-contents\">\n      <!-- SOFTWARE -->\n      <c8y-device-tab-profile-detail\n        class=\"d-contents\"\n        [sectionIcon]=\"'c8y-tools'\"\n        [sectionTitle]=\"'Software' | translate\"\n        [emptyStateText]=\"'No software to display.' | translate\"\n        [emptyStateDetails]=\"'No software assigned.' | translate\"\n        [isProfileSelected]=\"!!selectedProfile\"\n        [items]=\"softwareItems\"\n        [isEmpty]=\"\n          !selectedProfile?.c8y_DeviceProfile?.software ||\n          selectedProfile?.c8y_DeviceProfile?.software?.length === 0\n        \"\n      ></c8y-device-tab-profile-detail>\n    </div>\n    <div class=\"d-contents\">\n      <!-- CONFIGURATION -->\n      <c8y-device-tab-profile-detail\n        class=\"d-contents\"\n        [sectionIcon]=\"'gears'\"\n        [sectionTitle]=\"'Configuration' | translate\"\n        [emptyStateText]=\"'No configuration to display' | translate\"\n        [emptyStateDetails]=\"'No configuration assigned' | translate\"\n        [isProfileSelected]=\"!!selectedProfile\"\n        [items]=\"configurationItems\"\n        [isEmpty]=\"\n          !selectedProfile?.c8y_DeviceProfile?.configuration ||\n          selectedProfile?.c8y_DeviceProfile?.configuration?.length === 0\n        \"\n      ></c8y-device-tab-profile-detail>\n    </div>\n    <!-- fill in the remanining vertical space when empty -->\n    <div class=\"card--grid grid__col--6-6--md flex-grow\">\n      <div class=\"bg-level-0\"></div>\n      <div class=\"bg-level-1\"></div>\n    </div>\n  </div>\n</div>\n", dependencies: [{ kind: "component", type: i2.ActionBarItemComponent, selector: "c8y-action-bar-item", inputs: ["placement", "priority", "itemClass", "injector", "groupId", "inGroupPriority"] }, { kind: "directive", type: i2.IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "directive", type: i2.C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "directive", type: i2$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2.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: i2.HighlightComponent, selector: "c8y-highlight", inputs: ["pattern", "text", "elementClass", "shouldTrimPattern"] }, { kind: "component", type: i2.TypeaheadComponent, selector: "c8y-typeahead", inputs: ["required", "maxlength", "disabled", "allowFreeEntries", "placeholder", "displayProperty", "icon", "name", "autoClose", "hideNew", "container", "selected", "highlightFirstItem"], outputs: ["onSearch", "onIconClick"] }, { kind: "directive", type: i8.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i8.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i8.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i8.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i8.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: i2.ListItemComponent, selector: "c8y-list-item, c8y-li", inputs: ["active", "highlighted", "emptyActions", "dense", "collapsed", "selectable"], outputs: ["collapsedChange"] }, { kind: "directive", type: i2.ProductExperienceDirective, selector: "[c8yProductExperience]", inputs: ["actionName", "actionData", "inherit", "suppressDataOverriding"] }, { kind: "component", type: i2.RealtimeButtonComponent, selector: "c8y-realtime-btn", inputs: ["service", "label", "title", "disabled"], outputs: ["onToggle"] }, { kind: "component", type: i6.OperationDetailsComponent, selector: "c8y-operation-details", inputs: ["operation"] }, { kind: "component", type: DeviceTabProfileDetailComponent, selector: "c8y-device-tab-profile-detail", inputs: ["sectionTitle", "sectionIcon", "emptyStateText", "emptyStateDetails", "isProfileSelected", "isEmpty", "items", "showTextLabel"] }, { kind: "pipe", type: i2.C8yTranslatePipe, name: "translate" }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DeviceTabProfileComponent, decorators: [{
            type: Component,
            args: [{ selector: 'c8y-device-tab-profile', providers: [
                        ManagedObjectRealtimeService,
                        {
                            provide: PRODUCT_EXPERIENCE_EVENT_SOURCE,
                            useExisting: forwardRef(() => DeviceTabProfileComponent)
                        }
                    ], standalone: false, template: "<c8y-action-bar-item [placement]=\"'right'\">\n  <button\n    class=\"btn btn-link\"\n    title=\"{{ 'Reload' | translate }}\"\n    type=\"button\"\n    (click)=\"reload$.next(true)\"\n  >\n    <i\n      c8yIcon=\"refresh\"\n      [ngClass]=\"{ 'icon-spin': reload$.value }\"\n    ></i>\n    {{ 'Reload' | translate }}\n  </button>\n</c8y-action-bar-item>\n<c8y-action-bar-item [placement]=\"'right'\">\n  <c8y-realtime-btn [service]=\"deviceRealtime\"></c8y-realtime-btn>\n</c8y-action-bar-item>\n\n<div class=\"card card--grid--fullpage card--grid--fullpage card--grid grid__row--2-10--md\">\n  <div class=\"card--grid grid__col--6-6--md\">\n    <!-- AVAILABLE PROFILES -->\n    <div class=\"bg-level-0\">\n      <div class=\"card-header separator\">\n        <div\n          class=\"card-title\"\n          translate\n        >\n          Device profile\n        </div>\n      </div>\n      <div class=\"p-16\">\n        <form #deviceProfileForm=\"ngForm\">\n          <div class=\"input-group\">\n            <c8y-typeahead\n              class=\"flex-grow\"\n              placeholder=\"{{ 'Select device profile' | translate }}\"\n              name=\"selectProfile\"\n              data-cy=\"device-tab-profile--select-device-profile\"\n              [(ngModel)]=\"selectedProfile\"\n              (onSearch)=\"pattern$.next($event)\"\n              [allowFreeEntries]=\"false\"\n            >\n              <c8y-li\n                class=\"p-l-8 p-r-8 c8y-list__item--link\"\n                *c8yFor=\"let profile of deviceProfiles$; pipe: filterPipe\"\n                (click)=\"selectProfile(profile); pattern$.next('')\"\n              >\n                <c8y-highlight\n                  [text]=\"profile.name || '&#45;&#45;'\"\n                  [pattern]=\"pattern$.value\"\n                ></c8y-highlight>\n              </c8y-li>\n            </c8y-typeahead>\n            <div class=\"input-group-btn\">\n              <button\n                class=\"btn btn-primary\"\n                title=\"{{ 'Assign device profile' | translate }}\"\n                type=\"button\"\n                (click)=\"createOperation()\"\n                data-cy=\"device-tab-profile--Assign-device-profile-button\"\n                [disabled]=\"!selectedProfile?.id\"\n                c8yProductExperience\n                inherit\n                [actionData]=\"{ action: PRODUCT_EXPERIENCE.ACTIONS.ASSIGN_DEVICE_PROFILE }\"\n              >\n                <span>{{ 'Assign device profile' | translate }}</span>\n              </button>\n            </div>\n          </div>\n        </form>\n      </div>\n    </div>\n\n    <!-- INSTALL PROFILE OPERATION -->\n    <div class=\"bg-level-1\">\n      <div class=\"card-header separator\">\n        <div\n          class=\"card-title\"\n          translate\n        >\n          Currently installed\n        </div>\n      </div>\n      <div class=\"card-block\">\n        <c8y-operation-details\n          [operation]=\"operation\"\n          c8yProductExperience\n          inherit\n          suppressDataOverriding\n        ></c8y-operation-details>\n      </div>\n    </div>\n  </div>\n  <div class=\"card--grid__inner-scroll d-col no-align-items\">\n    <div class=\"d-contents\">\n      <!-- FIRMWARE -->\n      <c8y-device-tab-profile-detail\n        class=\"d-contents\"\n        [sectionIcon]=\"'c8y-firmware'\"\n        [sectionTitle]=\"'Firmware' | translate\"\n        [emptyStateText]=\"'No firmware to display.' | translate\"\n        [emptyStateDetails]=\"'No firmware assigned.' | translate\"\n        [isProfileSelected]=\"!!selectedProfile\"\n        [items]=\"firmwareItems\"\n        [isEmpty]=\"!selectedProfile?.c8y_DeviceProfile?.firmware?.name\"\n      ></c8y-device-tab-profile-detail>\n    </div>\n    <div class=\"d-contents\">\n      <!-- SOFTWARE -->\n      <c8y-device-tab-profile-detail\n        class=\"d-contents\"\n        [sectionIcon]=\"'c8y-tools'\"\n        [sectionTitle]=\"'Software' | translate\"\n        [emptyStateText]=\"'No software to display.' | translate\"\n        [emptyStateDetails]=\"'No software assigned.' | translate\"\n        [isProfileSelected]=\"!!selectedProfile\"\n        [items]=\"softwareItems\"\n        [isEmpty]=\"\n          !selectedProfile?.c8y_DeviceProfile?.software ||\n          selectedProfile?.c8y_DeviceProfile?.software?.length === 0\n        \"\n      ></c8y-device-tab-profile-detail>\n    </div>\n    <div class=\"d-contents\">\n      <!-- CONFIGURATION -->\n      <c8y-device-tab-profile-detail\n        class=\"d-contents\"\n        [sectionIcon]=\"'gears'\"\n        [sectionTitle]=\"'Configuration' | translate\"\n        [emptyStateText]=\"'No configuration to display' | translate\"\n        [emptyStateDetails]=\"'No configuration assigned' | translate\"\n        [isProfileSelected]=\"!!selectedProfile\"\n        [items]=\"configurationItems\"\n        [isEmpty]=\"\n          !selectedProfile?.c8y_DeviceProfile?.configuration ||\n          selectedProfile?.c8y_DeviceProfile?.configuration?.length === 0\n        \"\n      ></c8y-device-tab-profile-detail>\n    </div>\n    <!-- fill in the remanining vertical space when empty -->\n    <div class=\"card--grid grid__col--6-6--md flex-grow\">\n      <div class=\"bg-level-0\"></div>\n      <div class=\"bg-level-1\"></div>\n    </div>\n  </div>\n</div>\n" }]
        }], ctorParameters: () => [{ type: i2.ManagedObjectRealtimeService }, { type: DeviceProfileService }, { type: i5.ActivatedRoute }, { type: i2.OperationRealtimeService }, { type: i2.AlertService }] });

const deviceProfilesRoutes = [
    {
        path: 'device-profiles/:id',
        component: DeviceProfileComponent
    },
    {
        path: 'device-profiles',
        component: DeviceProfileListComponent
    }
];
const deviceTabProfileRoutes = [
    {
        context: ViewContext.Device,
        path: 'device-profile',
        component: DeviceTabProfileComponent,
        label: gettext('Device profile'),
        icon: 'c8y-device-profile',
        canActivate: [DeviceProfileGuard]
    }
];
class DeviceProfileModule {
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DeviceProfileModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
    static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.2.14", ngImport: i0, type: DeviceProfileModule, declarations: [DeviceProfileComponent,
            DeviceProfileListComponent,
            AddDeviceProfileComponent,
            SelectConfigurationModalComponent,
            DeviceTabProfileComponent,
            DeviceTabProfileDetailComponent,
            DeviceProfileItemListComponent], imports: [CoreModule,
            CommonModule,
            SharedRepositoryModule, i5.RouterModule, i2$2.BsDropdownModule, TooltipModule,
            ReactiveFormsModule,
            ButtonsModule,
            PopoverModule,
            OperationDetailsModule] }); }
    static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DeviceProfileModule, providers: [
            hookNavigator(DeviceProfileNavigationFactory),
            hookRoute(deviceTabProfileRoutes),
            DeviceProfileService,
            DeviceProfileGuard
        ], imports: [CoreModule,
            CommonModule,
            SharedRepositoryModule,
            RouterModule.forChild(deviceProfilesRoutes),
            BsDropdownModule.forRoot(),
            TooltipModule,
            ReactiveFormsModule,
            ButtonsModule,
            PopoverModule,
            OperationDetailsModule] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DeviceProfileModule, decorators: [{
            type: NgModule,
            args: [{
                    declarations: [
                        DeviceProfileComponent,
                        DeviceProfileListComponent,
                        AddDeviceProfileComponent,
                        SelectConfigurationModalComponent,
                        DeviceTabProfileComponent,
                        DeviceTabProfileDetailComponent,
                        DeviceProfileItemListComponent
                    ],
                    exports: [],
                    imports: [
                        CoreModule,
                        CommonModule,
                        SharedRepositoryModule,
                        RouterModule.forChild(deviceProfilesRoutes),
                        BsDropdownModule.forRoot(),
                        TooltipModule,
                        ReactiveFormsModule,
                        ButtonsModule,
                        PopoverModule,
                        OperationDetailsModule
                    ],
                    providers: [
                        hookNavigator(DeviceProfileNavigationFactory),
                        hookRoute(deviceTabProfileRoutes),
                        DeviceProfileService,
                        DeviceProfileGuard
                    ]
                }]
        }] });

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

export { AddDeviceProfileComponent, DeviceProfileComponent, DeviceProfileGuard, DeviceProfileItemListComponent, DeviceProfileListComponent, DeviceProfileModule, DeviceProfileNavigationFactory, DeviceProfileOperation, DeviceProfileService, DeviceTabProfileComponent, DeviceTabProfileDetailComponent, PRODUCT_EXPERIENCE_DEVICE_PROFILE, SelectConfigurationModalComponent };
//# sourceMappingURL=c8y-ngx-components-device-profile.mjs.map