UNPKG

@c8y/ngx-components

Version:

Angular modules for Cumulocity IoT applications

2,367 lines 302 kB
import * as i0 from '@angular/core';
import { Input, Component, ViewChild, Injectable, EventEmitter, Output, inject, NgModule } from '@angular/core';
import * as i2 from '@c8y/ngx-components';
import { ListGroupComponent, ListItemTimelineComponent, ListItemComponent, ListItemIconComponent, ListItemBodyComponent, IconDirective, ListItemActionComponent, FormGroupComponent, C8yTranslatePipe, DatePipe, gettext, Status, LoadingComponent, PluginsService, PluginsExportScopes, ModalComponent, C8yTranslateDirective, ListItemFooterComponent, ListItemCollapseComponent, OperationResultComponent, Permissions, ViewContext, TitleComponent, BreadcrumbComponent, BreadcrumbItemComponent, AppIconComponent, TextareaAutoresizeDirective, PropertiesListComponent, RequiredInputPlaceholderDirective, MessagesComponent, MessageDirective, HumanizeAppNamePipe, WizardHeaderComponent, WizardBodyComponent, WizardFooterComponent, IfAllowedDirective, ActionBarItemComponent, ListDisplaySwitchComponent, HelpComponent, EmptyStateComponent, TypeaheadComponent, ForOfDirective, HighlightComponent, C8yStepper, PackageType, MarkdownToHtmlPipe, CoreModule, FormsModule as FormsModule$1, hookTab, hookRoute, hookWizard } from '@c8y/ngx-components';
import * as i1 from '@c8y/ngx-components/ecosystem/shared';
import { UploadArchiveComponent, packageProperties, PRODUCT_EXPERIENCE_ECOSYSTEM, AddApplicationComponent, defaultPackageAvailabilities, EcosystemWizards, ListFiltersComponent, ApplicationCardComponent, ApplicationPropertiesFormComponent, ERROR_TYPE, APP_STATE, PackageVersionSelectComponent, PACKAGE_TYPE_LABELS, TranslatePackageLabelPipe, defaultPackageTypes, defaultPackageContents, ArchivedFilterComponent, PackageChangelogComponent, SharedEcosystemModule } from '@c8y/ngx-components/ecosystem/shared';
import { NgFor, NgClass, NgIf, AsyncPipe, NgSwitch, NgSwitchCase, NgStyle } from '@angular/common';
import * as i3 from '@angular/forms';
import { Validators, FormsModule, ReactiveFormsModule } from '@angular/forms';
import * as i1$2 from '@angular/router';
import { Router, RouterModule } from '@angular/router';
import * as i4 from '@c8y/client';
import { Isolation, BillingMode, ApplicationType } from '@c8y/client';
import * as i6 from '@ngx-translate/core';
import * as i1$1 from 'ngx-bootstrap/modal';
import { isEmpty } from 'lodash';
import { BehaviorSubject, Subject, combineLatest, of, from } from 'rxjs';
import { PluginListComponent, ApplicationPluginsModule } from '@c8y/ngx-components/ecosystem/application-plugins';
import { TooltipDirective, TooltipModule } from 'ngx-bootstrap/tooltip';
import { IconSelectorWrapperComponent, IconSelectorModule } from '@c8y/ngx-components/icon-selector';
import { tap, switchMap, shareReplay, takeUntil, map } from 'rxjs/operators';
import { A11yModule } from '@angular/cdk/a11y';
import { ArchivedConfirmModule } from '@c8y/ngx-components/ecosystem/archived-confirm';
import { LicenseConfirmModule } from '@c8y/ngx-components/ecosystem/license-confirm';
import { BsDropdownDirective, BsDropdownToggleDirective, BsDropdownMenuDirective, BsDropdownModule } from 'ngx-bootstrap/dropdown';
import { PopoverModule } from 'ngx-bootstrap/popover';
import { pick } from 'lodash-es';

class ActivityLogComponent {
    constructor(ecosystemService, alertService) {
        this.ecosystemService = ecosystemService;
        this.alertService = alertService;
        this.hasAdminPermissions = false;
        this.archives = [];
        this.canReactivate = false;
    }
    get uploadProgress() {
        return this.ecosystemService.progress;
    }
    async ngOnInit() {
        this.canReactivate = this.showReactivate();
        this.refresh();
    }
    isActive(archive) {
        return this.application.activeVersionId === archive.id;
    }
    toActivate(archive) {
        return this.toActivateVersionId === archive.id;
    }
    checkIfLast(archive) {
        return archive.id === this.last.id;
    }
    showReactivate() {
        return this.ecosystemService.isApplication(this.application);
    }
    async setActive(archive) {
        const id = archive.id || archive;
        this.toActivateVersionId = id;
        this.isLoading = true;
        try {
            this.application = (await this.ecosystemService.setAppActiveVersion(this.application, id)).data;
        }
        catch (ex) {
            this.alertService.addServerFailure(ex);
        }
        this.isLoading = false;
        this.refresh();
    }
    async deleteArchive(archive) {
        await this.ecosystemService.deleteArchive(archive, this.application);
        this.refresh();
    }
    async downloadArchive(archive) {
        await this.ecosystemService.downloadArchive(this.application, archive);
    }
    async reactivateArchive() {
        await this.ecosystemService.reactivateArchive(this.application);
    }
    async onRefresh() {
        await this.refresh();
    }
    async refresh() {
        this.isLoading = true;
        this.archives = await this.ecosystemService.listArchives(this.application.id);
        if (this.application.manifest?.package === 'blueprint') {
            // filter out entries without description because using them as active may break application's
            //  manifest (changing isPackage property of deployed app to 'true')
            this.archives = this.archives.filter((archive) => !!archive.description);
        }
        this.archives.sort((a, b) => {
            return new Date(b.created) - new Date(a.created);
        });
        this.last = this.archives[this.archives.length - 1];
        this.isLoading = false;
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: ActivityLogComponent, deps: [{ token: i1.EcosystemService }, { token: i2.AlertService }], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.14", type: ActivityLogComponent, isStandalone: true, selector: "c8y-activity-log", inputs: { application: "application", hasAdminPermissions: "hasAdminPermissions" }, ngImport: i0, template: "<div class=\"inner-scroll bg-level-1 flex-grow inner-scroll--md overflow-visible-sm overflow-visible-xs\">\n  <div class=\"card-block overflow-visible\">\n    <c8y-list-group>\n      <c8y-li-timeline *ngFor=\"let archive of archives\" [ngClass]=\"{ active: isActive(archive) }\">\n        {{ archive.created | c8yDate: 'd MMM YYYY' }}\n        {{ archive.created | c8yDate: 'shortTime' }}\n        <c8y-li>\n          <c8y-li-icon\n            [icon]=\"checkIfLast(archive) ? 'flag-checkered' : 'file-zip-o'\"\n          ></c8y-li-icon>\n          <c8y-li-body>\n            <div class=\"d-flex a-i-start\">\n              <div style=\"min-width: 0; flex: 1\">\n                <span class=\"text-truncate-wrap\" title=\" {{ archive.description || archive.name }}\">\n                  {{ archive.description || archive.name }}\n                </span>\n                <small *ngIf=\"archive.description\" class=\"text-muted\">{{\n                  archive.description\n                }}</small>\n              </div>\n              <i\n                *ngIf=\"isLoading && toActivate(archive)\"\n                [c8yIcon]=\"'circle-o-notch'\"\n                class=\"icon-spin\"\n                title=\"{{ 'Activating' | translate }}\"\n              ></i>\n\n              <span *ngIf=\"isActive(archive)\" class=\"label label-primary m-l-auto m-t-4\">{{\n                'Active' | translate\n              }}</span>\n            </div>\n          </c8y-li-body>\n          <c8y-li-action\n            (click)=\"setActive(archive)\"\n            *ngIf=\"hasAdminPermissions && !isLoading && !isActive(archive)\"\n            icon=\"check-square-o\"\n          >\n            {{ 'Set as active`archive`' | translate }}\n          </c8y-li-action>\n          <c8y-li-action (click)=\"downloadArchive(archive)\" icon=\"download\">\n            {{ 'Download`archive`' | translate }}\n          </c8y-li-action>\n          <c8y-li-action\n            (click)=\"deleteArchive(archive)\"\n            *ngIf=\"\n              hasAdminPermissions &&\n              archives.length > 1 &&\n              !checkIfLast(archive) &&\n              !isActive(archive)\n            \"\n            icon=\"delete\"\n          >\n            {{ 'Delete`archive`' | translate }}\n          </c8y-li-action>\n          <c8y-li-action\n            (click)=\"reactivateArchive()\"\n            *ngIf=\"hasAdminPermissions && canReactivate && isActive(archive)\"\n            icon=\"undo\"\n          >\n            {{ 'Reactivate archive' | translate }}\n          </c8y-li-action>\n        </c8y-li>\n      </c8y-li-timeline>\n    </c8y-list-group>\n  </div>\n</div>\n<div class=\"card-footer\" *ngIf=\"!isLoading && hasAdminPermissions\">\n  <c8y-form-group class=\"m-auto\">\n    <c8y-upload-archive [(application)]=\"application\" (refresh)=\"onRefresh()\"></c8y-upload-archive>\n  </c8y-form-group>\n</div>\n", dependencies: [{ kind: "component", type: ListGroupComponent, selector: "c8y-list-group" }, { kind: "directive", type: NgFor, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "component", type: ListItemTimelineComponent, selector: "c8y-list-item-timeline, c8y-li-timeline" }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: ListItemComponent, selector: "c8y-list-item, c8y-li", inputs: ["active", "highlighted", "emptyActions", "dense", "collapsed", "selectable"], outputs: ["collapsedChange"] }, { kind: "component", type: ListItemIconComponent, selector: "c8y-list-item-icon, c8y-li-icon", inputs: ["icon", "status"] }, { kind: "component", type: ListItemBodyComponent, selector: "c8y-list-item-body, c8y-li-body", inputs: ["body"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "component", type: ListItemActionComponent, selector: "c8y-list-item-action, c8y-li-action", inputs: ["label", "icon", "disabled"], outputs: ["click"] }, { kind: "component", type: FormGroupComponent, selector: "c8y-form-group", inputs: ["hasError", "hasWarning", "hasSuccess", "novalidation", "status"] }, { kind: "component", type: UploadArchiveComponent, selector: "c8y-upload-archive", inputs: ["application", "uploadNewVersion", "preUploadCallback"], outputs: ["applicationChange", "refresh"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }, { kind: "pipe", type: DatePipe, name: "c8yDate" }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: ActivityLogComponent, decorators: [{
            type: Component,
            args: [{ selector: 'c8y-activity-log', imports: [
                        ListGroupComponent,
                        NgFor,
                        ListItemTimelineComponent,
                        NgClass,
                        ListItemComponent,
                        ListItemIconComponent,
                        ListItemBodyComponent,
                        NgIf,
                        IconDirective,
                        ListItemActionComponent,
                        FormGroupComponent,
                        UploadArchiveComponent,
                        C8yTranslatePipe,
                        DatePipe
                    ], template: "<div class=\"inner-scroll bg-level-1 flex-grow inner-scroll--md overflow-visible-sm overflow-visible-xs\">\n  <div class=\"card-block overflow-visible\">\n    <c8y-list-group>\n      <c8y-li-timeline *ngFor=\"let archive of archives\" [ngClass]=\"{ active: isActive(archive) }\">\n        {{ archive.created | c8yDate: 'd MMM YYYY' }}\n        {{ archive.created | c8yDate: 'shortTime' }}\n        <c8y-li>\n          <c8y-li-icon\n            [icon]=\"checkIfLast(archive) ? 'flag-checkered' : 'file-zip-o'\"\n          ></c8y-li-icon>\n          <c8y-li-body>\n            <div class=\"d-flex a-i-start\">\n              <div style=\"min-width: 0; flex: 1\">\n                <span class=\"text-truncate-wrap\" title=\" {{ archive.description || archive.name }}\">\n                  {{ archive.description || archive.name }}\n                </span>\n                <small *ngIf=\"archive.description\" class=\"text-muted\">{{\n                  archive.description\n                }}</small>\n              </div>\n              <i\n                *ngIf=\"isLoading && toActivate(archive)\"\n                [c8yIcon]=\"'circle-o-notch'\"\n                class=\"icon-spin\"\n                title=\"{{ 'Activating' | translate }}\"\n              ></i>\n\n              <span *ngIf=\"isActive(archive)\" class=\"label label-primary m-l-auto m-t-4\">{{\n                'Active' | translate\n              }}</span>\n            </div>\n          </c8y-li-body>\n          <c8y-li-action\n            (click)=\"setActive(archive)\"\n            *ngIf=\"hasAdminPermissions && !isLoading && !isActive(archive)\"\n            icon=\"check-square-o\"\n          >\n            {{ 'Set as active`archive`' | translate }}\n          </c8y-li-action>\n          <c8y-li-action (click)=\"downloadArchive(archive)\" icon=\"download\">\n            {{ 'Download`archive`' | translate }}\n          </c8y-li-action>\n          <c8y-li-action\n            (click)=\"deleteArchive(archive)\"\n            *ngIf=\"\n              hasAdminPermissions &&\n              archives.length > 1 &&\n              !checkIfLast(archive) &&\n              !isActive(archive)\n            \"\n            icon=\"delete\"\n          >\n            {{ 'Delete`archive`' | translate }}\n          </c8y-li-action>\n          <c8y-li-action\n            (click)=\"reactivateArchive()\"\n            *ngIf=\"hasAdminPermissions && canReactivate && isActive(archive)\"\n            icon=\"undo\"\n          >\n            {{ 'Reactivate archive' | translate }}\n          </c8y-li-action>\n        </c8y-li>\n      </c8y-li-timeline>\n    </c8y-list-group>\n  </div>\n</div>\n<div class=\"card-footer\" *ngIf=\"!isLoading && hasAdminPermissions\">\n  <c8y-form-group class=\"m-auto\">\n    <c8y-upload-archive [(application)]=\"application\" (refresh)=\"onRefresh()\"></c8y-upload-archive>\n  </c8y-form-group>\n</div>\n" }]
        }], ctorParameters: () => [{ type: i1.EcosystemService }, { type: i2.AlertService }], propDecorators: { application: [{
                type: Input
            }], hasAdminPermissions: [{
                type: Input
            }] } });

class SubscriptionModalComponent {
    constructor(bsModalRef, ecosystemService, tabsService, modal, applicationService, alertService, contextRouteService) {
        this.bsModalRef = bsModalRef;
        this.ecosystemService = ecosystemService;
        this.tabsService = tabsService;
        this.modal = modal;
        this.applicationService = applicationService;
        this.alertService = alertService;
        this.contextRouteService = contextRouteService;
        this.RETRY_TIMEOUT = 3000;
        this.isLoading = false;
        this.result = new Promise(resolve => {
            this._resolve = resolve;
        });
        this.retryCounter = 0;
        this.TABS = ['Logs', 'Status'];
    }
    ngOnInit() {
        if (this.isSubscribed) {
            this.unsubscribe();
        }
        else {
            this.subscribe();
        }
    }
    async subscribe() {
        this.retryCounter = 0;
        this.isLoading = true;
        this.message = gettext('Subscribing…');
        await this.ecosystemService.subscribeApp(this.application);
        this.getStatusDetails('subscribe');
    }
    async unsubscribe() {
        this.retryCounter = 0;
        this.isLoading = true;
        this.message = gettext('Unsubscribing…');
        await this.ecosystemService.unsubscribeApp(this.application);
        this.getStatusDetails('unsubscribe');
    }
    async getStatusDetails(action) {
        this.contextRouteService.refreshContext();
        const actionSuccessful = action === 'subscribe' ? await this.onSubscribe() : this.onUnsubscribe();
        if (actionSuccessful) {
            return this.hideSubscriptionModal();
        }
        if (this.retryCounter === 4) {
            this.showWarningModal(action);
            return this.hideSubscriptionModal();
        }
        this.retryCounter += 1;
        setTimeout(async () => {
            this.getStatusDetails(action);
        }, this.RETRY_TIMEOUT);
    }
    async onSubscribe() {
        try {
            if (!this.application.activeVersionId) {
                return true;
            }
            const res = (await this.applicationService.getStatusDetails(this.application)).data[0];
            return this.shouldShowMSSpecificTabs(res);
        }
        catch (er) {
            this.alertService.addServerFailure(er);
        }
    }
    // Checks if the UI should show tabs with logs and status
    shouldShowMSSpecificTabs(mo) {
        return !isEmpty(mo.c8y_Status?.instances) && !!mo.c8y_SupportedLogs;
    }
    onUnsubscribe() {
        return !this.tabsService.areAvailable(this.TABS);
    }
    hideSubscriptionModal() {
        this._resolve();
        this.bsModalRef.hide();
        this.isLoading = false;
    }
    showWarningModal(action) {
        const title = gettext('Warning');
        const body = action === 'subscribe'
            ? gettext('Something went wrong, please refresh the page or resubscribe the application.')
            : gettext('Something went wrong, please refresh the page or retry to unsubscribe from the application.');
        this.modal.acknowledge(title, body, Status.WARNING, gettext('Close'));
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: SubscriptionModalComponent, deps: [{ token: i1$1.BsModalRef }, { token: i1.EcosystemService }, { token: i2.TabsService }, { token: i2.ModalService }, { token: i4.ApplicationService }, { token: i2.AlertService }, { token: i2.ContextRouteService }], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.14", type: SubscriptionModalComponent, isStandalone: true, selector: "c8y-subscription-modal", ngImport: i0, template: "<div class=\"viewport-modal\">\n  <div class=\"modal-header dialog-header\">\n    <i c8yIcon=\"c8y-atom\"></i>\n    <h4 id=\"modal-title\">{{ message | translate }}</h4>\n  </div>\n  <div class=\"modal-body\" id=\"modal-body\" *ngIf=\"isLoading\">\n    <div class=\"p-16 text-center\">\n      <c8y-loading></c8y-loading>\n    </div>\n  </div>\n</div>\n", dependencies: [{ kind: "directive", type: IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: LoadingComponent, selector: "c8y-loading", inputs: ["layout", "progress", "message"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: SubscriptionModalComponent, decorators: [{
            type: Component,
            args: [{ selector: 'c8y-subscription-modal', imports: [IconDirective, NgIf, LoadingComponent, C8yTranslatePipe], template: "<div class=\"viewport-modal\">\n  <div class=\"modal-header dialog-header\">\n    <i c8yIcon=\"c8y-atom\"></i>\n    <h4 id=\"modal-title\">{{ message | translate }}</h4>\n  </div>\n  <div class=\"modal-body\" id=\"modal-body\" *ngIf=\"isLoading\">\n    <div class=\"p-16 text-center\">\n      <c8y-loading></c8y-loading>\n    </div>\n  </div>\n</div>\n" }]
        }], ctorParameters: () => [{ type: i1$1.BsModalRef }, { type: i1.EcosystemService }, { type: i2.TabsService }, { type: i2.ModalService }, { type: i4.ApplicationService }, { type: i2.AlertService }, { type: i2.ContextRouteService }] });

class UpdateApplicationModalComponent {
    constructor(inventoryService, ecosystemService, pluginsService) {
        this.inventoryService = inventoryService;
        this.ecosystemService = ecosystemService;
        this.pluginsService = pluginsService;
        this.isUpdateOngoing = false;
        this.updateFailure = false;
        this.result = new Promise((resolve, reject) => {
            this._resolve = resolve;
            this._reject = reject;
        });
        this.orphanedPlugins$ = new BehaviorSubject([]);
        this.newPlugins$ = new BehaviorSubject([]);
    }
    ngOnInit() {
        const hasDelta = this.getRemoteDelta();
        if (!hasDelta) {
            // start update directly if no remote delta detected
            this.updateApplication();
        }
    }
    /**
     * Checks if there is a delta between the current application and the source package remotes.
     * @returns {boolean} true if there is a delta between the current application and the source package remotes.
     */
    getRemoteDelta() {
        const currentRemotes = this.pluginsService.getMFExports(this.application, []);
        const possibleNewRemotes = this.pluginsService.getMFExports(this.sourcePackage, []);
        const installedRemotes = this.pluginsService.getMFRemotes(this.application);
        const installedRemotesIds = PluginsService.convertInstalledRemotesToIds(installedRemotes);
        const allRemotesToRemove = this.getAllRemotesToRemove(currentRemotes, possibleNewRemotes, installedRemotesIds);
        const allRemotesToAdd = this.getAllRemotesToAdd(possibleNewRemotes, currentRemotes);
        this.orphanedPlugins$.next(allRemotesToRemove);
        this.newPlugins$.next(allRemotesToAdd);
        return allRemotesToRemove.length !== 0 || allRemotesToAdd.length !== 0;
    }
    close() {
        this._reject();
        this.modal._dismiss();
    }
    done() {
        if (!this.updateFailure) {
            this._resolve();
            this.modal._dismiss();
            return;
        }
        this._reject();
        this.modal._dismiss();
    }
    async updateApplication() {
        try {
            this.isUpdateOngoing = true;
            const toInstallPlugins = this.newPlugins$.value.filter(({ selected }) => selected === true);
            const toRemovePlugins = this.orphanedPlugins$.value;
            this.orphanedPlugins$.next([]);
            this.newPlugins$.next([]);
            if (toRemovePlugins.length > 0) {
                const remotes = await this.pluginsService.removeRemotes(this.application, toRemovePlugins);
                this.application.config.remotes = remotes;
            }
            if (toInstallPlugins.length > 0) {
                const remotes = await this.pluginsService.addRemotes(this.application, toInstallPlugins);
                this.application.config.remotes = remotes;
            }
            const binaryMoId = this.sourcePackage.activeVersionId;
            await this.inventoryService.detail(binaryMoId); // only trying if we can access it
            await this.ecosystemService.uploadBinaryFromOtherPackage(this.sourcePackage, this.application, this.sourcePackage.activeVersionId);
        }
        catch (e) {
            if (e.res?.status === 404) {
                try {
                    this.updateFailure = !(await this.ecosystemService.fallbackToClone(this.application, this.sourcePackage));
                }
                catch (ex) {
                    this.updateFailure = true;
                    this.ecosystemService.alertError(e);
                }
            }
            else {
                this.updateFailure = true;
                this.ecosystemService.alertError(e);
            }
        }
        finally {
            this.isUpdateOngoing = false;
        }
    }
    getAllRemotesToAdd(possibleNewRemotes, currentRemotes) {
        return possibleNewRemotes
            .filter(possibleNewRemote => {
            const isUnchanged = !!currentRemotes.some(currentRemote => PluginsService.createPluginId(this.application.contextPath, possibleNewRemote.module, '', true) === currentRemote.idLatest);
            const isSelf = possibleNewRemote.scope === PluginsExportScopes.SELF ||
                possibleNewRemote.scope === PluginsExportScopes.SELF_OPTIONAL;
            return !isUnchanged && isSelf;
        })
            .map(newRemote => {
            newRemote.contextPath = this.application.contextPath;
            newRemote.id = `${newRemote.contextPath}/${newRemote.module}`;
            newRemote.selected = newRemote.scope === PluginsExportScopes.SELF;
            return newRemote;
        });
    }
    getAllRemotesToRemove(currentRemotes, possibleNewRemotes, installedRemotesIds) {
        return currentRemotes
            .filter(currentRemote => {
            const isUnchanged = !!possibleNewRemotes.some(newRemote => PluginsService.createPluginId(this.application.contextPath, newRemote.module, '', true) === currentRemote.idLatest);
            const isInstalled = installedRemotesIds
                ? !!installedRemotesIds.some(currentInstalled => currentRemote.id === currentInstalled || currentRemote.idLatest === currentInstalled)
                : false;
            const isSelf = currentRemote.scope === PluginsExportScopes.SELF ||
                currentRemote.scope === PluginsExportScopes.SELF_OPTIONAL;
            return !isUnchanged && isInstalled && isSelf;
        })
            .map(toRemoveRemote => {
            toRemoveRemote.contextPath = this.application.contextPath;
            toRemoveRemote.id = `${toRemoveRemote.contextPath}/${toRemoveRemote.module}`;
            toRemoveRemote.selected = true;
            return toRemoveRemote;
        });
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: UpdateApplicationModalComponent, deps: [{ token: i4.InventoryService }, { token: i1.EcosystemService }, { token: i2.PluginsService }], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.14", type: UpdateApplicationModalComponent, isStandalone: true, selector: "c8y-update-application-modal", viewQueries: [{ propertyName: "modal", first: true, predicate: ["modal"], descendants: true }], ngImport: i0, template: "<c8y-modal\n  [title]=\"'Update application' | translate\"\n  [headerClasses]=\"'dialog-header'\"\n  [customFooter]=\"true\"\n  #modal\n>\n  <ng-container c8y-modal-title>\n    <span class=\"dlt-c8y-icon-installing-updates\"></span>\n  </ng-container>\n\n  <ng-container\n    *ngIf=\"\n      (orphanedPlugins$ | async).length > 0 || (newPlugins$ | async).length > 0;\n      else updateProgress\n    \"\n  >\n    <p\n      class=\"text-center text-break-word p-24 text-14\"\n      translate\n    >\n      Updating this blueprint will change the default plugins. Review the plugin changes before\n      proceeding.\n    </p>\n    <c8y-list-group *ngIf=\"(orphanedPlugins$ | async).length > 0\">\n      <c8y-li [collapsed]=\"true\">\n        <c8y-li-icon>\n          <span class=\"badge badge-danger\">{{ (orphanedPlugins$ | async).length }}</span>\n        </c8y-li-icon>\n        <c8y-li-body>\n          <div translate>Orphaned plugins</div>\n        </c8y-li-body>\n        <c8y-li-footer translate>\n          Some plugins are not contained in the new version of this blueprint and will therefore get\n          removed.\n        </c8y-li-footer>\n        <c8y-li-collapse>\n          <c8y-plugin-list\n            class=\"m-t-16\"\n            [emptyListText]=\"'No plugins available' | translate\"\n            [plugins$]=\"orphanedPlugins$\"\n            [selectable]=\"false\"\n            [hideSource]=\"true\"\n          ></c8y-plugin-list>\n        </c8y-li-collapse>\n      </c8y-li>\n    </c8y-list-group>\n\n    <c8y-list-group *ngIf=\"(newPlugins$ | async).length > 0\">\n      <c8y-li [collapsed]=\"false\">\n        <c8y-li-icon>\n          <span class=\"badge badge-success\">{{ (newPlugins$ | async).length }}</span>\n        </c8y-li-icon>\n        <c8y-li-body>\n          <div translate>New plugins added</div>\n        </c8y-li-body>\n        <c8y-li-footer translate>\n          This blueprint will add new plugins. Please choose which you want to install.\n        </c8y-li-footer>\n        <c8y-li-collapse>\n          <c8y-plugin-list\n            class=\"m-t-16\"\n            [emptyListText]=\"'No plugins available' | translate\"\n            [plugins$]=\"newPlugins$\"\n            [selectable]=\"true\"\n            [hideSource]=\"false\"\n          ></c8y-plugin-list>\n        </c8y-li-collapse>\n      </c8y-li>\n    </c8y-list-group>\n  </ng-container>\n\n  <ng-container c8y-modal-footer-custom>\n    <div\n      class=\"modal-footer\"\n      *ngIf=\"\n        (orphanedPlugins$ | async).length > 0 || (newPlugins$ | async).length > 0;\n        else updateProgressButtons\n      \"\n    >\n      <button\n        class=\"btn btn-default\"\n        title=\"{{ 'Close' | translate }}\"\n        (click)=\"close()\"\n        [disabled]=\"isUpdateOngoing\"\n      >\n        {{ 'Close' | translate }}\n      </button>\n      <button\n        class=\"btn btn-primary\"\n        title=\"{{ 'Continue' | translate }}\"\n        (click)=\"updateApplication()\"\n        *ngIf=\"(orphanedPlugins$ | async).length > 0 || (newPlugins$ | async).length > 0\"\n        [disabled]=\"isUpdateOngoing\"\n      >\n        {{ 'Continue' | translate }}\n      </button>\n    </div>\n  </ng-container>\n\n  <ng-template #updateProgressButtons>\n    <ng-container c8y-modal-footer-custom>\n      <div class=\"modal-footer\">\n        <button\n          class=\"btn btn-default\"\n          title=\"{{ 'Close' | translate }}\"\n          (click)=\"done()\"\n          [disabled]=\"isUpdateOngoing\"\n        >\n          {{ 'Close' | translate }}\n        </button>\n      </div>\n    </ng-container>\n  </ng-template>\n\n  <ng-template #updateProgress>\n    <c8y-loading\n      class=\"text-center d-block p-t-56 p-b-56 m-t-4 m-b-4\"\n      style=\"min-height: 180px\"\n      layout=\"application\"\n      *ngIf=\"isUpdateOngoing\"\n      [message]=\"'Updating\u2026' | translate\"\n    ></c8y-loading>\n\n    <c8y-operation-result\n      type=\"success\"\n      *ngIf=\"!isUpdateOngoing && !updateFailure\"\n      text=\"{{ 'Update completed' | translate }}\"\n      [size]=\"120\"\n      [vertical]=\"true\"\n    ></c8y-operation-result>\n    <c8y-operation-result\n      type=\"error\"\n      *ngIf=\"!isUpdateOngoing && updateFailure\"\n      text=\"{{ 'Failed to update application.' | translate }}\"\n      [size]=\"120\"\n      [vertical]=\"true\"\n    ></c8y-operation-result>\n  </ng-template>\n</c8y-modal>\n", dependencies: [{ kind: "component", type: ModalComponent, selector: "c8y-modal", inputs: ["disabled", "close", "dismiss", "title", "body", "customFooter", "headerClasses", "labels"], outputs: ["onDismiss", "onClose"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "component", type: ListGroupComponent, selector: "c8y-list-group" }, { kind: "component", type: ListItemComponent, selector: "c8y-list-item, c8y-li", inputs: ["active", "highlighted", "emptyActions", "dense", "collapsed", "selectable"], outputs: ["collapsedChange"] }, { kind: "component", type: ListItemIconComponent, selector: "c8y-list-item-icon, c8y-li-icon", inputs: ["icon", "status"] }, { kind: "component", type: ListItemBodyComponent, selector: "c8y-list-item-body, c8y-li-body", inputs: ["body"] }, { kind: "component", type: ListItemFooterComponent, selector: "c8y-list-item-footer, c8y-li-footer", inputs: ["footer"] }, { kind: "component", type: ListItemCollapseComponent, selector: "c8y-list-item-collapse, c8y-li-collapse", inputs: ["collapseWay"] }, { kind: "component", type: PluginListComponent, selector: "c8y-plugin-list", inputs: ["plugins$", "emptyListText", "selectable", "hideSource", "installable", "package", "selectedPlugin"], outputs: ["selectedItems", "showOverview"] }, { kind: "component", type: LoadingComponent, selector: "c8y-loading", inputs: ["layout", "progress", "message"] }, { kind: "component", type: OperationResultComponent, selector: "c8y-operation-result", inputs: ["text", "vertical", "size", "type"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }, { kind: "pipe", type: AsyncPipe, name: "async" }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: UpdateApplicationModalComponent, decorators: [{
            type: Component,
            args: [{ selector: 'c8y-update-application-modal', imports: [
                        ModalComponent,
                        NgIf,
                        C8yTranslateDirective,
                        ListGroupComponent,
                        ListItemComponent,
                        ListItemIconComponent,
                        ListItemBodyComponent,
                        ListItemFooterComponent,
                        ListItemCollapseComponent,
                        PluginListComponent,
                        LoadingComponent,
                        OperationResultComponent,
                        C8yTranslatePipe,
                        AsyncPipe
                    ], template: "<c8y-modal\n  [title]=\"'Update application' | translate\"\n  [headerClasses]=\"'dialog-header'\"\n  [customFooter]=\"true\"\n  #modal\n>\n  <ng-container c8y-modal-title>\n    <span class=\"dlt-c8y-icon-installing-updates\"></span>\n  </ng-container>\n\n  <ng-container\n    *ngIf=\"\n      (orphanedPlugins$ | async).length > 0 || (newPlugins$ | async).length > 0;\n      else updateProgress\n    \"\n  >\n    <p\n      class=\"text-center text-break-word p-24 text-14\"\n      translate\n    >\n      Updating this blueprint will change the default plugins. Review the plugin changes before\n      proceeding.\n    </p>\n    <c8y-list-group *ngIf=\"(orphanedPlugins$ | async).length > 0\">\n      <c8y-li [collapsed]=\"true\">\n        <c8y-li-icon>\n          <span class=\"badge badge-danger\">{{ (orphanedPlugins$ | async).length }}</span>\n        </c8y-li-icon>\n        <c8y-li-body>\n          <div translate>Orphaned plugins</div>\n        </c8y-li-body>\n        <c8y-li-footer translate>\n          Some plugins are not contained in the new version of this blueprint and will therefore get\n          removed.\n        </c8y-li-footer>\n        <c8y-li-collapse>\n          <c8y-plugin-list\n            class=\"m-t-16\"\n            [emptyListText]=\"'No plugins available' | translate\"\n            [plugins$]=\"orphanedPlugins$\"\n            [selectable]=\"false\"\n            [hideSource]=\"true\"\n          ></c8y-plugin-list>\n        </c8y-li-collapse>\n      </c8y-li>\n    </c8y-list-group>\n\n    <c8y-list-group *ngIf=\"(newPlugins$ | async).length > 0\">\n      <c8y-li [collapsed]=\"false\">\n        <c8y-li-icon>\n          <span class=\"badge badge-success\">{{ (newPlugins$ | async).length }}</span>\n        </c8y-li-icon>\n        <c8y-li-body>\n          <div translate>New plugins added</div>\n        </c8y-li-body>\n        <c8y-li-footer translate>\n          This blueprint will add new plugins. Please choose which you want to install.\n        </c8y-li-footer>\n        <c8y-li-collapse>\n          <c8y-plugin-list\n            class=\"m-t-16\"\n            [emptyListText]=\"'No plugins available' | translate\"\n            [plugins$]=\"newPlugins$\"\n            [selectable]=\"true\"\n            [hideSource]=\"false\"\n          ></c8y-plugin-list>\n        </c8y-li-collapse>\n      </c8y-li>\n    </c8y-list-group>\n  </ng-container>\n\n  <ng-container c8y-modal-footer-custom>\n    <div\n      class=\"modal-footer\"\n      *ngIf=\"\n        (orphanedPlugins$ | async).length > 0 || (newPlugins$ | async).length > 0;\n        else updateProgressButtons\n      \"\n    >\n      <button\n        class=\"btn btn-default\"\n        title=\"{{ 'Close' | translate }}\"\n        (click)=\"close()\"\n        [disabled]=\"isUpdateOngoing\"\n      >\n        {{ 'Close' | translate }}\n      </button>\n      <button\n        class=\"btn btn-primary\"\n        title=\"{{ 'Continue' | translate }}\"\n        (click)=\"updateApplication()\"\n        *ngIf=\"(orphanedPlugins$ | async).length > 0 || (newPlugins$ | async).length > 0\"\n        [disabled]=\"isUpdateOngoing\"\n      >\n        {{ 'Continue' | translate }}\n      </button>\n    </div>\n  </ng-container>\n\n  <ng-template #updateProgressButtons>\n    <ng-container c8y-modal-footer-custom>\n      <div class=\"modal-footer\">\n        <button\n          class=\"btn btn-default\"\n          title=\"{{ 'Close' | translate }}\"\n          (click)=\"done()\"\n          [disabled]=\"isUpdateOngoing\"\n        >\n          {{ 'Close' | translate }}\n        </button>\n      </div>\n    </ng-container>\n  </ng-template>\n\n  <ng-template #updateProgress>\n    <c8y-loading\n      class=\"text-center d-block p-t-56 p-b-56 m-t-4 m-b-4\"\n      style=\"min-height: 180px\"\n      layout=\"application\"\n      *ngIf=\"isUpdateOngoing\"\n      [message]=\"'Updating\u2026' | translate\"\n    ></c8y-loading>\n\n    <c8y-operation-result\n      type=\"success\"\n      *ngIf=\"!isUpdateOngoing && !updateFailure\"\n      text=\"{{ 'Update completed' | translate }}\"\n      [size]=\"120\"\n      [vertical]=\"true\"\n    ></c8y-operation-result>\n    <c8y-operation-result\n      type=\"error\"\n      *ngIf=\"!isUpdateOngoing && updateFailure\"\n      text=\"{{ 'Failed to update application.' | translate }}\"\n      [size]=\"120\"\n      [vertical]=\"true\"\n    ></c8y-operation-result>\n  </ng-template>\n</c8y-modal>\n" }]
        }], ctorParameters: () => [{ type: i4.InventoryService }, { type: i1.EcosystemService }, { type: i2.PluginsService }], propDecorators: { modal: [{
                type: ViewChild,
                args: ['modal', { static: false }]
            }] } });

const MICROSERVICES_BASE_PATH = '/ecosystem/microservice/microservices';
const APPLICATIONS_BASE_PATH = '/ecosystem/application/applications';
class ApplicationPropertiesComponent {
    constructor(activatedRoute, ecosystemService, router, formBuilder, applicationService, alertService, inventoryService, permissions, modalService, translate, bsModalService, gainsightService) {
        this.activatedRoute = activatedRoute;
        this.ecosystemService = ecosystemService;
        this.router = router;
        this.formBuilder = formBuilder;
        this.applicationService = applicationService;
        this.alertService = alertService;
        this.inventoryService = inventoryService;
        this.permissions = permissions;
        this.modalService = modalService;
        this.translate = translate;
        this.bsModalService = bsModalService;
        this.gainsightService = gainsightService;
        this.CURRENT_LOCATION = location.href;
        this.singleTenant = false;
        this.subscription = false;
        this.iconMap = {
            HOSTED: 'cloud',
            EXTERNAL: 'external-link-square',
            MICROSERVICE: 'microchip'
        };
        this.isLoading = true;
        this.hasAdminPermissions = false;
        this.noDescriptionLabel = gettext('No description available.');
        this.packageProperties = [...packageProperties];
        this.isUpdateAvailable = false;
    }
    async ngOnInit() {
        this.hasAdminPermissions = this.permissions.hasRole(Permissions.ROLE_APPLICATION_MANAGEMENT_ADMIN);
        await this.refresh();
    }
    async refresh() {
        await this.load();
        this.isUnpacked = this.ecosystemService.isUnpacked(this.application);
        this.isPackage = this.ecosystemService.isPackage(this.application);
        this.isFeature = this.ecosystemService.isFeature(this.application);
        this.isExternal = this.ecosystemService.isExternal(this.application);
        this.isMicroservice = this.ecosystemService.isMicroservice(this.application);
        this.appState = this.ecosystemService.getAppState(this.application);
        if (this.isUnpacked) {
            await this.resolveSourcePackageDetails();
        }
        this.setBreadcrumbConfig();
        if (this.isCustomMicroservice) {
            this.loadBinaryMo();
        }
    }
    async load() {
        this.isLoading = true;
        this.initForm();
        await this.loadApplication();
        this.isLoading = false;
    }
    onApplication(app) {
        if (app.manifest) {
            this.singleTenant = app.manifest.isolation === Isolation.PER_TENANT;
            this.subscription = app.manifest.billingMode === BillingMode.SUBSCRIPTION;
        }
    }
    cancel() {
        if (this.application.type === ApplicationType.MICROSERVICE) {
            this.router.navigateByUrl(MICROSERVICES_BASE_PATH);
        }
        else {
            this.router.navigateByUrl(APPLICATIONS_BASE_PATH);
        }
    }
    openApp(app) {
        this.ecosystemService.openApp(app);
    }
    getPackage(entityOrId) {
        return this.applicationService.detail(entityOrId);
    }
    async delete() {
        try {
            await this.ecosystemService.deleteApp(this.application);
            if (this.application.type === ApplicationType.MICROSERVICE) {
                this.router.navigateByUrl(MICROSERVICES_BASE_PATH);
            }
            else {
                this.router.navigateByUrl(APPLICATIONS_BASE_PATH);
            }
        }
        catch (ex) {
            if (ex) {
                this.alertService.addServerFailure(ex);
            }
        }
    }
    async subscribe() {
        const initialState = { application: this.application, isSubscribed: false };
        await this.confirmSubscriptionChange(initialState);
        this.loadApplication();
    }
    async unsubscribe() {
        const initialState = { application: this.application, isSubscribed: true };
        await this.confirmSubscriptionChange(initialState);
        this.loadApplication();
    }
    async loadApplication() {
        const { id } = this.activatedRoute.snapshot.parent.data.contextData;
        this.application = await this.ecosystemService.getApplication(id);
        if (this.application.type === ApplicationType.MICROSERVICE) {
            this.formGroup.get('name').disable();
        }
        const updatedApplication = {
            ...this.application,
            description: this.getDescription(this.application),
            icon: this.application.config?.icon?.class || this.application.manifest?.icon?.class
        };
        this.formGroup.patchValue(updatedApplication);
        this.canOpenInBrowser = this.ecosystemService.canOpenAppInBrowser(this.application);
        this.disableOpenInBrowser =
            this.canOpenInBrowser &&
                (await this.ecosystemService.isOverwrittenByCustomApp(this.application));
        this.canDelete = await this.ecosystemService.canDeleteApp(this.application);
        this.isOwner = this.ecosystemService.isOwner(this.application);
        this.isActivityLogSupported = this.isActivityLogSupportedByApp(this.application);
        this.isCustomMicroservice = this.ecosystemService.isCustomMicroservice(this.application);
        this.isSubscribed = await this.ecosystemService.checkIfSubscribed(this.application);
        this.onApplication(this.application);
    }
    async save(app) {
        const icon = this.formGroup.controls['icon'].value;
        const name = this.formGroup.controls['name'].value;
        if (icon) {
            app = {
                ...app,
                config: { ...this.application.config, icon: { class: icon }, appTitle: name }
            };
        }
        else if (this.application.config) {
            app = {
                ...app,
                config: { ...this.application.config, appTitle: name }
            };
        }
        app.id = this.application.id;
        try {
            const { data } = await this.ecosystemService.updateApp(app);
            this.formGroup.reset();
            this.loadApplication();
            if (data) {
                this.alertService.success(gettext('Application saved.'));
            }
        }
        catch (ex) {
            // do nothing
        }
    }
    onNewArchive() {
        this.loadBinaryMo();
    }
    async updateToLatestVersion() {
        this.gainsightService.triggerEvent(PRODUCT_EXPERIENCE_ECOSYSTEM.APPLICATIONS.EVENTS.APPLICATION_PROPERTIES, {
            component: PRODUCT_EXPERIENCE_ECOSYSTEM.APPLICATIONS.COMPONENTS.APPLICATION_PROPERTIES,
            action: PRODUCT_EXPERIENCE_ECOSYSTEM.APPLICATIONS.ACTIONS.UPDATE_AVAILABLE,
            url: this.CURRENT_LOCATION
        });
        try {
            const translatedBody = this.translate.instant(gettext(`You're using the version {{ currentVersion }} of the {{ packageName }} package, the latest version available is {{ latestVersion }}, do you want to update? You can always revert to a previous version in the Activity log panel.`), {
                currentVersion: this.application.manifest?.version,
                latestVersion: this.blueprintApplicationVersion,
                packageName: this.sourcePackage.name
            });
            await this.modalService.confirm(gettext('Update application'), translatedBody, 'warning', {
                ok: gettext('Update'),
                cancel: gettext('Cancel')
            });
        }
        catch {
            // modal canceled
            return;
        }
        try {
            await this.bsModalService.show(UpdateApplicationModalComponent, {
                ariaDescribedby: 'modal-body',
                ariaLabelledBy: 'modal-title',
                class: 'modal-sm',
                ignoreBackdropClick: true,
                initialState: {
                    sourcePackage: this.sourcePackage,
                    application: this.application
                }
            }).content.result;
        }
        catch {
            // modal canceled
            return;
        }
        await this.refresh();
        this.alertService.success(gettext('Application updated.'));
    }
    getDescription(application) {
        if (!application) {
            return;
        }
        return application.description || application.manifest?.description;
    }
    async confirmSubscriptionChange(initialState) {
        await this.bsModalService.show(SubscriptionModalComponent, {
            class: 'modal-sm',
            ariaDescribedby: 'modal-body',
            ariaLabelledBy: 'modal-title',
            initialState,
            ignoreBackdropClick: true
        }).content.result;
    }
    async resolveSourcePackageDetails() {
        try {
            this.sourcePackage = (await this.getPackage(this.application.manifest?.source)).data;
            if (this.sourcePackage) {
                this.packageProperties.push({
                    label: gettext('Source package'),
                    value: this.sourcePackage.name,
                    type: 'link',
                    action: () => this.router.navigateByUrl(ViewContext.Extension.replace(':id', this.sourcePackage.id.toString()))
                });
            }
        }
        catch {
            this.alertService.warning(gettext('Unable to resolve source package.'));
            return;
        }
        await this.extractVersionInformation(this.application);
    }
    initForm() {
        this.formGroup = this.formBuilder.group({
            id: [{ value: '' }],
            name: [Validators.required, Validators.maxLength(120)],
            key: [Validators.required, Validators.maxLength(120)],
            contextPath: [Validators.required, Validators.maxLength(120)],
            description: ['', Validators.maxLength(200)],
            username: [Validators.required],
            password: [Validators.required],
            externalUrl: [Validators.required],
            icon: [undefined, [Validators.minLength(1)]]
        });
        if (!this.hasAdminPermissions) {
            this.formGroup.disable();
        }
    }
    isActivityLogSupportedByApp(app) {
        return (this.ecosystemService.isOwner(app) &&
            app.type !== ApplicationType.MICROSERVICE &&
            app.type !== ApplicationType.EXTERNAL);
    }
    setBreadcrumbConfig() {
        this.breadcrumbConfig = {
            icon: this.isMicroservice ? 'microchip' : this.isFeature ? 'tab' : 'c8y-modules',
            label: this.isMicroservice
                ? gettext('Microservices')
                : this.isFeature
                    ? gettext('Features')
                    : gettext('Applications'),
            path: this.isMicroservice
                ? '/ecosystem/microservice/microservices'
                : this.isFeature
                    ? 'ecosystem/application/features'
                    : 'ecosystem/application/applications'
        };
    }
    async loadBinaryMo() {
        this.binaryMo = (await this.inventoryService.detail(this.application.activeVersionId)).data;
    }
    async extractVersionInformation(application) {
        if (!application.manifest.isPackage && !application.manifest.source) {
            return;
        }
        const blueprintApplicationId = application.manifest?.source;
        const currentVersion = application.manifest?.version;
        try {
            const { data: blueprintApplicationVersions } = await this.applicationService.listVersions(blueprintApplicationId);
            const blueprintLatestVersion = this.ecosystemService.getApplicationVersionObjectByTag(blueprintApplicationVersions, 'latest');
            this.blueprintApplicationVersion = blueprintLatestVersion.version;
            this.isUpdateAvailable = this.ecosystemService.shouldUpgradePackage(currentVersion, blueprintLatestVersion);
        }
        catch {
            this.alertService.warning(gettext('Unable to resolve versions of source package.'));
        }
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: ApplicationPropertiesComponent, deps: [{ token: i1$2.ActivatedRoute }, { token: i1.EcosystemService }, { token: i1$2.Router }, { token: i3.FormBuilder }, { token: i4.ApplicationService }, { token: i2.AlertService }, { token: i4.InventoryService }, { token: i2.Permissions }, { token: i2.ModalService }, { token: i6.TranslateService }, { token: i1$1.BsModalService }, { token: i2.GainsightService }], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.14", type: ApplicationPropertiesComponent, isStandalone: true, selector: "c8y-application-properties", ngImport: i0, template: "<c8y-title>{{ application | humanizeAppName | async }}</c8y-title>\n\n<c8y-breadcrumb *ngIf=\"!isMicroservice\">\n  <c8y-breadcrumb-item\n    [icon]=\"'c8y-atom'\"\n    [label]=\"'Ecosystem' | translate\"\n  ></c8y-breadcrumb-item>\n  <c8y-breadcrumb-item\n    [icon]=\"'c8y-modules'\"\n    [label]=\"'Applications' | translate\"\n    [path]=\"'ecosystem/application/applications'\"\n  ></c8y-breadcrumb-item>\n  <c8y-breadcrumb-item\n    [icon]=\"breadcrumbConfig?.icon\"\n    *ngIf=\"isFeature\"\n    [label]=\"breadcrumbConfig?.label\"\n    [path]=\"breadcrumbConfig?.path\"\n  ></c8y-breadcrumb-item>\n  <c8y-breadcrumb-item [label]=\"application | humanizeAppName | async\"></c8y-breadcrumb-item>\n  <c8y-breadcrumb-item [label]=\"'Properties' | translate\"></c8y-breadcrumb-item>\n</c8y-breadcrumb>\n\n<c8y-breadcrumb *ngIf=\"isMicroservice\">\n  <c8y-breadcrumb-item\n    [icon]=\"'c8y-atom'\"\n    [label]=\"'Ecosystem' | translate\"\n  ></c8y-breadcrumb-item>\n  <c8y-breadcrumb-item\n    [icon]=\"breadcrumbConfig?.icon\"\n    [label]=\"breadcrumbConfig?.label\"\n    [path]=\"breadcrumbConfig?.path\"\n  ></c8y-breadcrumb-item>\n  <c8y-breadcrumb-item [label]=\"application | humanizeAppName | async\"></c8y-breadcrumb-item>\n  <c8y-breadcrumb-item [label]=\"'Properties' | translate\"></c8y-breadcrumb-item>\n</c8y-breadcrumb>\n\n<div class=\"row\">\n  <div [ngClass]=\"{ 'col-md-8': !isActivityLogSupported, 'col-md-12': isActivityLogSupported }\">\n    <div\n      class=\"card content-fullpage\"\n      *ngIf=\"application\"\n      [ngClass]=\"{ 'd-grid grid__col--7-5--md': isActivityLogSupported }\"\n    >\n      <form\n        class=\"d-flex d-col content-fullpage\"\n        (ngSubmit)=\"formGroup.valid && save(formGroup.value)\"\n        [formGroup]=\"formGroup\"\n        novalidate\n      >\n        <div\n          class=\"d-contents\"\n          *ngIf=\"!isLoading\"\n        >\n          <div class=\"card-block separator-bottom large-padding flex-no-shrink\">\n            <div class=\"d-flex-md a-i-start text-center text-left-md\">\n              <c8y-app-icon\n                class=\"icon-48\"\n                *ngIf=\"!isPackage && !isFeature && !isMicroservice && !isExternal\"\n                [app]=\"application\"\n                [contextPath]=\"application.contextPath\"\n                [name]=\"application.name\"\n              ></c8y-app-icon>\n              <i\n                class=\"icon-48\"\n                c8yIcon=\"big-parcel\"\n                *ngIf=\"isPackage\"\n              ></i>\n              <i\n                class=\"icon-48\"\n                c8yIcon=\"tab\"\n                *ngIf=\"isFeature\"\n              ></i>\n              <i\n                class=\"icon-48\"\n                c8yIcon=\"microchip\"\n                *ngIf=\"isMicroservice\"\n              ></i>\n              <i\n                class=\"icon-48\"\n                c8yIcon=\"globe1\"\n                *ngIf=\"isExternal\"\n              ></i>\n\n              <div class=\"p-t-md-16 p-l-md-16 p-r-md-32 flex-grow\">\n                <p class=\"h4 text-medium m-b-8\">{{ application | humanizeAppName | async }}</p>\n                <p *ngIf=\"!isOwner\">\n                  <em class=\"text-muted\">\n                    {{\n                      formGroup?.controls?.description?.value || (noDescriptionLabel | translate)\n                    }}\n                  </em>\n                </p>\n                <div\n                  class=\"form-group m-b-0\"\n                  *ngIf=\"isOwner\"\n                >\n                  <label\n                    class=\"editable\"\n                    [ngClass]=\"{ updated: formGroup?.controls?.description?.dirty }\"\n                  >\n                    <textarea\n                      class=\"form-control no-resize\"\n                      placeholder=\"{{ noDescriptionLabel | translate }}\"\n                      name=\"description\"\n                      c8y-textarea-autoresize\n                      formControlName=\"description\"\n                    ></textarea>\n                  </label>\n                </div>\n              </div>\n              <div class=\"text-right-md m-t-4\">\n                <span\n                  class=\"label\"\n                  [ngClass]=\"appState?.class\"\n                >\n                  {{ appState?.label | translate }}\n                </span>\n                <div\n                  class=\"fit-w m-t-2\"\n                  *ngIf=\"application.manifest?.version\"\n                  data-cy=\"application-detail--version\"\n                >\n                  <label\n                    class=\"text-label-small\"\n                    translate\n                  >\n                    Version:\n                  </label>\n                  <small class=\"p-l-4 text-bold\">{{ application.manifest?.version }}</small>\n                </div>\n                <div\n                  class=\"fit-w m-t-2\"\n                  *ngIf=\"!isUnpacked\"\n                >\n                  <label\n                    class=\"text-label-small\"\n                    translate\n                  >\n                    Creation time:\n                  </label>\n                  <small class=\"p-l-4 text-bold\">\n                    {{ (binaryMo?.creationTime | c8yDate) || '---' }}\n                  </small>\n                </div>\n                <div class=\"m-t-8\">\n                  <button\n                    class=\"btn btn-default btn-sm\"\n                    [attr.aria-label]=\"\n                      'There\\'s a newer version available, click to update' | translate\n                    \"\n                    tooltip=\"{{\n                      'There\\'s a newer version available, click to update' | translate\n                    }}\"\n                    placement=\"top\"\n                    type=\"button\"\n                    *ngIf=\"isUpdateAvailable\"\n                    (click)=\"updateToLatestVersion()\"\n                    [delay]=\"300\"\n                  >\n                    <i [c8yIcon]=\"'installing-updates'\"></i>\n                    {{ 'Update available' | translate }}\n                  </button>\n                  <button\n                    class=\"btn btn-default btn-sm\"\n                    title=\"{{ 'Open' | translate }}\"\n                    type=\"button\"\n                    (click)=\"openApp(application)\"\n                    [disabled]=\"disableOpenInBrowser\"\n                    *ngIf=\"canOpenInBrowser\"\n                  >\n                    <i [c8yIcon]=\"'external-link'\"></i>\n                    {{ 'Open' | translate }}\n                  </button>\n                  <div *ngIf=\"canOpenInBrowser && disableOpenInBrowser\">\n                    <small\n                      class=\"text-muted\"\n                      translate\n                    >\n                      The application is overwritten by a custom application sharing the same path\n                    </small>\n                  </div>\n                  <span *ngIf=\"isCustomMicroservice\">\n                    <button\n                      class=\"btn btn-default btn-sm\"\n                      title=\"{{ 'Subscribe' | translate }}\"\n                      type=\"button\"\n                      (click)=\"subscribe()\"\n                      *ngIf=\"!isSubscribed\"\n                    >\n                      <i [c8yIcon]=\"'check-circle-o'\"></i>\n                      {{ 'Subscribe' | translate }}\n                    </button>\n                    <button\n                      class=\"btn btn-default btn-sm\"\n                      title=\"{{ 'Unsubscribe' | translate }}\"\n                      type=\"button\"\n                      (click)=\"unsubscribe()\"\n                      *ngIf=\"isSubscribed\"\n                    >\n                      <i [c8yIcon]=\"'minus-circle'\"></i>\n                      {{ 'Unsubscribe' | translate }}\n                    </button>\n                  </span>\n                </div>\n              </div>\n            </div>\n          </div>\n          <div class=\"inner-scroll bg-level-0 flex-grow\">\n            <div class=\"card-block large-padding\">\n              <div\n                class=\"row p-16\"\n                *ngIf=\"isPackage\"\n              >\n                <c8y-properties-list\n                  icon=\"info\"\n                  [title]=\"'Package details' | translate\"\n                  [data]=\"application.manifest\"\n                  [properties]=\"packageProperties\"\n                  [emptyLabel]=\"'---'\"\n                ></c8y-properties-list>\n              </div>\n              <div\n                class=\"row p-16\"\n                *ngIf=\"sourcePackage\"\n              >\n                <c8y-properties-list\n                  icon=\"info\"\n                  [title]=\"'Source package information' | translate\"\n                  [data]=\"sourcePackage.manifest\"\n                  [properties]=\"packageProperties\"\n                  [emptyLabel]=\"'---'\"\n                ></c8y-properties-list>\n              </div>\n              <div class=\"row\">\n                <div class=\"col-sm-5\">\n                  <c8y-form-group>\n                    <label for=\"appId\">ID</label>\n                    <input\n                      class=\"form-control\"\n                      id=\"appId\"\n                      name=\"id\"\n                      type=\"text\"\n                      autocomplete=\"off\"\n                      [readonly]=\"true\"\n                      formControlName=\"id\"\n                    />\n                  </c8y-form-group>\n                </div>\n                <div class=\"col-sm-7\">\n                  <c8y-form-group>\n                    <label>{{ 'Name' | translate }}</label>\n                    <input\n                      class=\"form-control\"\n                      placeholder=\"{{ 'e.g. My application' | translate }}\"\n                      name=\"name\"\n                      type=\"text\"\n                      required\n                      [readonly]=\"!isOwner\"\n                      formControlName=\"name\"\n                    />\n                  </c8y-form-group>\n                </div>\n              </div>\n\n              <div class=\"row\">\n                <div class=\"col-sm-5\">\n                  <c8y-form-group>\n                    <label>{{ 'Application key' | translate }}</label>\n                    <input\n                      class=\"form-control\"\n                      placeholder=\"{{ 'e.g. my-application-key' | translate }}\"\n                      name=\"key\"\n                      type=\"text\"\n                      required\n                      [readonly]=\"application.id || !isOwner\"\n                      formControlName=\"key\"\n                    />\n                  </c8y-form-group>\n                </div>\n\n                <div class=\"col-sm-7\" data-cy=\"application-detail--type\">\n                  <c8y-form-group>\n                    <label>{{ 'Type' | translate }}</label>\n                    <div>\n                      <div *ngIf=\"application.id\">\n                        <p class=\"form-control-static\">\n                          <i [c8yIcon]=\"iconMap[application.type]\"></i>\n                          <span>\n                            {{ application.type | translate }}\n                          </span>\n                        </p>\n                      </div>\n                    </div>\n                  </c8y-form-group>\n                </div>\n              </div>\n\n              <div [ngSwitch]=\"application.type\">\n                <div *ngSwitchCase=\"'HOSTED'\">\n                  <c8y-form-group>\n                    <label>{{ 'Path' | translate }}</label>\n                    <div class=\"input-group\">\n                      <span class=\"input-group-addon\">/apps/</span>\n                      <input\n                        class=\"form-control\"\n                        placeholder=\"{{ 'e.g. my-application`used in URL`' | translate }}\"\n                        name=\"contextPath\"\n                        type=\"text\"\n                        required\n                        [readOnly]=\"application.id || !isOwner\"\n                        formControlName=\"contextPath\"\n                      />\n                    </div>\n                  </c8y-form-group>\n                </div>\n\n                <div *ngSwitchCase=\"'MICROSERVICE'\">\n                  <c8y-form-group>\n                    <label>{{ 'Path' | translate }}</label>\n                    <div class=\"input-group\">\n                      <span class=\"input-group-addon\">/service/</span>\n                      <input\n                        class=\"form-control\"\n                        placeholder=\"{{ 'e.g. my-microservice`used in URL`' | translate }}\"\n                        name=\"contextPath\"\n                        type=\"text\"\n                        required\n                        [readOnly]=\"application.id || !isOwner\"\n                        formControlName=\"contextPath\"\n                      />\n                    </div>\n                  </c8y-form-group>\n                  <div class=\"row\">\n                    <div\n                      class=\"col-sm-4 m-b-16 flex-auto\"\n                      *ngIf=\"application.manifest.version\"\n                      data-cy=\"application-detail--version\"\n                    >\n                      <label>{{ 'Version' | translate }}</label>\n                      <p class=\"form-control-static\">\n                        {{ application.manifest.version }}\n                      </p>\n                    </div>\n                    <div\n                      class=\"col-sm-4 m-b-16 flex-auto\"\n                      *ngIf=\"application.manifest.isolation\"\n                      data-cy=\"application-detail--isolation\"\n                    >\n                      <label>{{ 'Isolation' | translate }}</label>\n                      <p class=\"form-control-static\">\n                        <span *ngIf=\"singleTenant\">\n                          <i\n                            class=\"c8y-icon-duocolor h4\"\n                            [c8yIcon]=\"'c8y-enterprise'\"\n                          ></i>\n                          {{ 'Single tenant' | translate }}\n                        </span>\n                        <span *ngIf=\"!singleTenant\">\n                          <i\n                            class=\"c8y-icon-duocolor icon-32\"\n                            [c8yIcon]=\"'c8y-sub-tenants'\"\n                          ></i>\n                          {{ 'Multi tenant' | translate }}\n                        </span>\n                      </p>\n                    </div>\n                    <div\n                      class=\"col-sm-4 m-b-16 flex-auto\"\n                      *ngIf=\"application.manifest.isolation\"\n                      data-cy=\"application-detail--billing-mode\"\n                    >\n                      <label>{{ 'Billing mode' | translate }}</label>\n                      <p class=\"form-control-static\">\n                        <span\n                          [tooltip]=\"'Resources usage assigned to: Owner' | translate\"\n                          *ngIf=\"subscription\"\n                        >\n                          {{ 'Subscription' | translate }}\n                        </span>\n                        <span\n                          [tooltip]=\"'Resources usage assigned to: Subscriber | translate'\"\n                          *ngIf=\"!subscription && singleTenant\"\n                        >\n                          {{ 'Resources' | translate }}\n                        </span>\n                        <span\n                          [tooltip]=\"'Resources usage assigned to: Owner' | translate\"\n                          *ngIf=\"!subscription && !singleTenant\"\n                        >\n                          {{ 'Resources' | translate }}\n                        </span>\n                      </p>\n                    </div>\n                  </div>\n\n                  <div\n                    class=\"legend form-block m-t-40\"\n                    *ngIf=\"application.manifest.provider\"\n                  >\n                    {{ 'Provider' | translate }}\n                  </div>\n                  <div\n                    class=\"list-inline\"\n                    *ngIf=\"application.manifest.provider\"\n                    data-cy=\"application-detail--provider\"\n                  >\n                    <div *ngIf=\"application.manifest.provider.name\">\n                      <div class=\"col-sm-4 m-b-16\">\n                        <label>{{ 'Name' | translate }}</label>\n                        <p class=\"form-control-static\">\n                          {{ application.manifest.provider.name }}\n                        </p>\n                      </div>\n                    </div>\n                    <div *ngIf=\"application.manifest.provider.domain\">\n                      <div class=\"col-sm-4 m-b-16\">\n                        <label>{{ 'Domain' | translate }}</label>\n                        <p class=\"form-control-static\">\n                          {{ application.manifest.provider.domain }}\n                        </p>\n                      </div>\n                    </div>\n                    <div *ngIf=\"application.manifest.provider.support\">\n                      <div class=\"col-sm-4 m-b-16\">\n                        <label>{{ 'Support' | translate }}</label>\n                        <p class=\"form-control-static\">\n                          {{ application.manifest.provider.support }}\n                        </p>\n                      </div>\n                    </div>\n                  </div>\n                </div>\n\n                <div *ngSwitchCase=\"'EXTERNAL'\">\n                  <c8y-form-group>\n                    <label>{{ 'External URL' | translate }}</label>\n                    <input\n                      class=\"form-control\"\n                      placeholder=\"{{ 'e.g.' | translate }} http://www.example.com/\"\n                      name=\"externalUrl\"\n                      type=\"url\"\n                      required\n                      [pattern]=\"'^(?!javascript:).+'\"\n                      [readOnly]=\"!isOwner\"\n                      formControlName=\"externalUrl\"\n                    />\n                    <c8y-messages>\n                      <c8y-message\n                        [name]=\"'pattern'\"\n                        [text]=\"'Valid URL required.' | translate\"\n                      ></c8y-message>\n                    </c8y-messages>\n                  </c8y-form-group>\n                </div>\n\n                <div *ngIf=\"isOwner && !isCustomMicroservice\">\n                  <label>{{ 'Select icon' | translate }}</label>\n                  <c8y-icon-selector-wrapper\n                    name=\"icon\"\n                    formControlName=\"icon\"\n                  ></c8y-icon-selector-wrapper>\n                </div>\n              </div>\n            </div>\n          </div>\n          <ng-container *ngIf=\"isCustomMicroservice\">\n            <div\n              class=\"d-contents\"\n              *ngIf=\"!isLoading\"\n            >\n              <c8y-upload-archive\n                [(application)]=\"application\"\n                (refresh)=\"onNewArchive()\"\n              ></c8y-upload-archive>\n            </div>\n          </ng-container>\n          <div\n            class=\"card-footer separator\"\n            *ngIf=\"application && !!isOwner && hasAdminPermissions\"\n          >\n            <button\n              class=\"btn btn-default\"\n              title=\"{{ 'Cancel' | translate }}\"\n              type=\"button\"\n              (click)=\"cancel()\"\n            >\n              {{ 'Cancel' | translate }}\n            </button>\n            <button\n              class=\"btn btn-danger\"\n              title=\"{{ 'Delete' | translate }}\"\n              type=\"button\"\n              (click)=\"delete()\"\n              *ngIf=\"canDelete\"\n            >\n              {{ 'Delete' | translate }}\n            </button>\n            <button\n              class=\"btn btn-primary btn-form\"\n              title=\"{{ 'Save' | translate }}\"\n              type=\"submit\"\n              [disabled]=\"!application.type || formGroup.invalid || formGroup.pristine\"\n            >\n              {{ 'Save' | translate }}\n            </button>\n          </div>\n        </div>\n      </form>\n\n      <div\n        class=\"content-fullpage d-flex d-col bg-level-1\"\n        *ngIf=\"isActivityLogSupported\"\n      >\n        <div class=\"card-header separator\">\n          <div\n            class=\"card-title\"\n            translate\n          >\n            Activity log\n          </div>\n          <div class=\"m-l-auto\">\n            <button\n              class=\"btn btn-link btn-sm\"\n              title=\"{{ 'Reload' | translate }}\"\n              type=\"button\"\n              (click)=\"load()\"\n            >\n              <i\n                c8yIcon=\"refresh\"\n                [ngClass]=\"{ 'icon-spin': isLoading }\"\n              ></i>\n              {{ 'Reload' | translate }}\n            </button>\n          </div>\n        </div>\n        <div\n          class=\"p-16 text-center\"\n          *ngIf=\"isLoading\"\n        >\n          <c8y-loading></c8y-loading>\n        </div>\n        <c8y-activity-log\n          class=\"d-contents\"\n          *ngIf=\"!isLoading\"\n          [hasAdminPermissions]=\"hasAdminPermissions\"\n          [application]=\"application\"\n        ></c8y-activity-log>\n      </div>\n    </div>\n  </div>\n</div>\n", dependencies: [{ kind: "component", type: TitleComponent, selector: "c8y-title", inputs: ["pageTitleUpdate"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: BreadcrumbComponent, selector: "c8y-breadcrumb" }, { kind: "component", type: BreadcrumbItemComponent, selector: "c8y-breadcrumb-item", inputs: ["icon", "translate", "label", "path", "injector"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i3.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i3.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: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i3.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i3.PatternValidator, selector: "[pattern][formControlName],[pattern][formControl],[pattern][ngModel]", inputs: ["pattern"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i3.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i3.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: AppIconComponent, selector: "c8y-app-icon", inputs: ["contextPath", "name", "app"] }, { kind: "directive", type: IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "directive", type: TextareaAutoresizeDirective, selector: "[c8y-textarea-autoresize]" }, { kind: "directive", type: C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "directive", type: TooltipDirective, selector: "[tooltip], [tooltipHtml]", inputs: ["adaptivePosition", "tooltip", "placement", "triggers", "container", "containerClass", "boundariesElement", "isOpen", "isDisabled", "delay", "tooltipHtml", "tooltipPlacement", "tooltipIsOpen", "tooltipEnable", "tooltipAppendToBody", "tooltipAnimation", "tooltipClass", "tooltipContext", "tooltipPopupDelay", "tooltipFadeDuration", "tooltipTrigger"], outputs: ["tooltipChange", "onShown", "onHidden", "tooltipStateChanged"], exportAs: ["bs-tooltip"] }, { kind: "component", type: PropertiesListComponent, selector: "c8y-properties-list", inputs: ["properties", "title", "icon", "data", "groups", "noParse", "emptyLabel"] }, { kind: "component", type: FormGroupComponent, selector: "c8y-form-group", inputs: ["hasError", "hasWarning", "hasSuccess", "novalidation", "status"] }, { kind: "directive", type: RequiredInputPlaceholderDirective, selector: "input[required], input[formControlName]" }, { kind: "directive", type: NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "component", type: MessagesComponent, selector: "c8y-messages", inputs: ["show", "defaults", "helpMessage"] }, { kind: "directive", type: MessageDirective, selector: "c8y-message", inputs: ["name", "text"] }, { kind: "component", type: IconSelectorWrapperComponent, selector: "c8y-icon-selector-wrapper", inputs: ["canRemoveIcon", "selectedIcon", "iconSize"], outputs: ["onSelect"] }, { kind: "component", type: UploadArchiveComponent, selector: "c8y-upload-archive", inputs: ["application", "uploadNewVersion", "preUploadCallback"], outputs: ["applicationChange", "refresh"] }, { kind: "component", type: LoadingComponent, selector: "c8y-loading", inputs: ["layout", "progress", "message"] }, { kind: "component", type: ActivityLogComponent, selector: "c8y-activity-log", inputs: ["application", "hasAdminPermissions"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "pipe", type: HumanizeAppNamePipe, name: "humanizeAppName" }, { kind: "pipe", type: DatePipe, name: "c8yDate" }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: ApplicationPropertiesComponent, decorators: [{
            type: Component,
            args: [{ selector: 'c8y-application-properties', imports: [
                        TitleComponent,
                        NgIf,
                        BreadcrumbComponent,
                        BreadcrumbItemComponent,
                        NgClass,
                        FormsModule,
                        ReactiveFormsModule,
                        AppIconComponent,
                        IconDirective,
                        TextareaAutoresizeDirective,
                        C8yTranslateDirective,
                        TooltipDirective,
                        PropertiesListComponent,
                        FormGroupComponent,
                        RequiredInputPlaceholderDirective,
                        NgSwitch,
                        NgSwitchCase,
                        MessagesComponent,
                        MessageDirective,
                        IconSelectorWrapperComponent,
                        UploadArchiveComponent,
                        LoadingComponent,
                        ActivityLogComponent,
                        C8yTranslatePipe,
                        AsyncPipe,
                        HumanizeAppNamePipe,
                        DatePipe
                    ], template: "<c8y-title>{{ application | humanizeAppName | async }}</c8y-title>\n\n<c8y-breadcrumb *ngIf=\"!isMicroservice\">\n  <c8y-breadcrumb-item\n    [icon]=\"'c8y-atom'\"\n    [label]=\"'Ecosystem' | translate\"\n  ></c8y-breadcrumb-item>\n  <c8y-breadcrumb-item\n    [icon]=\"'c8y-modules'\"\n    [label]=\"'Applications' | translate\"\n    [path]=\"'ecosystem/application/applications'\"\n  ></c8y-breadcrumb-item>\n  <c8y-breadcrumb-item\n    [icon]=\"breadcrumbConfig?.icon\"\n    *ngIf=\"isFeature\"\n    [label]=\"breadcrumbConfig?.label\"\n    [path]=\"breadcrumbConfig?.path\"\n  ></c8y-breadcrumb-item>\n  <c8y-breadcrumb-item [label]=\"application | humanizeAppName | async\"></c8y-breadcrumb-item>\n  <c8y-breadcrumb-item [label]=\"'Properties' | translate\"></c8y-breadcrumb-item>\n</c8y-breadcrumb>\n\n<c8y-breadcrumb *ngIf=\"isMicroservice\">\n  <c8y-breadcrumb-item\n    [icon]=\"'c8y-atom'\"\n    [label]=\"'Ecosystem' | translate\"\n  ></c8y-breadcrumb-item>\n  <c8y-breadcrumb-item\n    [icon]=\"breadcrumbConfig?.icon\"\n    [label]=\"breadcrumbConfig?.label\"\n    [path]=\"breadcrumbConfig?.path\"\n  ></c8y-breadcrumb-item>\n  <c8y-breadcrumb-item [label]=\"application | humanizeAppName | async\"></c8y-breadcrumb-item>\n  <c8y-breadcrumb-item [label]=\"'Properties' | translate\"></c8y-breadcrumb-item>\n</c8y-breadcrumb>\n\n<div class=\"row\">\n  <div [ngClass]=\"{ 'col-md-8': !isActivityLogSupported, 'col-md-12': isActivityLogSupported }\">\n    <div\n      class=\"card content-fullpage\"\n      *ngIf=\"application\"\n      [ngClass]=\"{ 'd-grid grid__col--7-5--md': isActivityLogSupported }\"\n    >\n      <form\n        class=\"d-flex d-col content-fullpage\"\n        (ngSubmit)=\"formGroup.valid && save(formGroup.value)\"\n        [formGroup]=\"formGroup\"\n        novalidate\n      >\n        <div\n          class=\"d-contents\"\n          *ngIf=\"!isLoading\"\n        >\n          <div class=\"card-block separator-bottom large-padding flex-no-shrink\">\n            <div class=\"d-flex-md a-i-start text-center text-left-md\">\n              <c8y-app-icon\n                class=\"icon-48\"\n                *ngIf=\"!isPackage && !isFeature && !isMicroservice && !isExternal\"\n                [app]=\"application\"\n                [contextPath]=\"application.contextPath\"\n                [name]=\"application.name\"\n              ></c8y-app-icon>\n              <i\n                class=\"icon-48\"\n                c8yIcon=\"big-parcel\"\n                *ngIf=\"isPackage\"\n              ></i>\n              <i\n                class=\"icon-48\"\n                c8yIcon=\"tab\"\n                *ngIf=\"isFeature\"\n              ></i>\n              <i\n                class=\"icon-48\"\n                c8yIcon=\"microchip\"\n                *ngIf=\"isMicroservice\"\n              ></i>\n              <i\n                class=\"icon-48\"\n                c8yIcon=\"globe1\"\n                *ngIf=\"isExternal\"\n              ></i>\n\n              <div class=\"p-t-md-16 p-l-md-16 p-r-md-32 flex-grow\">\n                <p class=\"h4 text-medium m-b-8\">{{ application | humanizeAppName | async }}</p>\n                <p *ngIf=\"!isOwner\">\n                  <em class=\"text-muted\">\n                    {{\n                      formGroup?.controls?.description?.value || (noDescriptionLabel | translate)\n                    }}\n                  </em>\n                </p>\n                <div\n                  class=\"form-group m-b-0\"\n                  *ngIf=\"isOwner\"\n                >\n                  <label\n                    class=\"editable\"\n                    [ngClass]=\"{ updated: formGroup?.controls?.description?.dirty }\"\n                  >\n                    <textarea\n                      class=\"form-control no-resize\"\n                      placeholder=\"{{ noDescriptionLabel | translate }}\"\n                      name=\"description\"\n                      c8y-textarea-autoresize\n                      formControlName=\"description\"\n                    ></textarea>\n                  </label>\n                </div>\n              </div>\n              <div class=\"text-right-md m-t-4\">\n                <span\n                  class=\"label\"\n                  [ngClass]=\"appState?.class\"\n                >\n                  {{ appState?.label | translate }}\n                </span>\n                <div\n                  class=\"fit-w m-t-2\"\n                  *ngIf=\"application.manifest?.version\"\n                  data-cy=\"application-detail--version\"\n                >\n                  <label\n                    class=\"text-label-small\"\n                    translate\n                  >\n                    Version:\n                  </label>\n                  <small class=\"p-l-4 text-bold\">{{ application.manifest?.version }}</small>\n                </div>\n                <div\n                  class=\"fit-w m-t-2\"\n                  *ngIf=\"!isUnpacked\"\n                >\n                  <label\n                    class=\"text-label-small\"\n                    translate\n                  >\n                    Creation time:\n                  </label>\n                  <small class=\"p-l-4 text-bold\">\n                    {{ (binaryMo?.creationTime | c8yDate) || '---' }}\n                  </small>\n                </div>\n                <div class=\"m-t-8\">\n                  <button\n                    class=\"btn btn-default btn-sm\"\n                    [attr.aria-label]=\"\n                      'There\\'s a newer version available, click to update' | translate\n                    \"\n                    tooltip=\"{{\n                      'There\\'s a newer version available, click to update' | translate\n                    }}\"\n                    placement=\"top\"\n                    type=\"button\"\n                    *ngIf=\"isUpdateAvailable\"\n                    (click)=\"updateToLatestVersion()\"\n                    [delay]=\"300\"\n                  >\n                    <i [c8yIcon]=\"'installing-updates'\"></i>\n                    {{ 'Update available' | translate }}\n                  </button>\n                  <button\n                    class=\"btn btn-default btn-sm\"\n                    title=\"{{ 'Open' | translate }}\"\n                    type=\"button\"\n                    (click)=\"openApp(application)\"\n                    [disabled]=\"disableOpenInBrowser\"\n                    *ngIf=\"canOpenInBrowser\"\n                  >\n                    <i [c8yIcon]=\"'external-link'\"></i>\n                    {{ 'Open' | translate }}\n                  </button>\n                  <div *ngIf=\"canOpenInBrowser && disableOpenInBrowser\">\n                    <small\n                      class=\"text-muted\"\n                      translate\n                    >\n                      The application is overwritten by a custom application sharing the same path\n                    </small>\n                  </div>\n                  <span *ngIf=\"isCustomMicroservice\">\n                    <button\n                      class=\"btn btn-default btn-sm\"\n                      title=\"{{ 'Subscribe' | translate }}\"\n                      type=\"button\"\n                      (click)=\"subscribe()\"\n                      *ngIf=\"!isSubscribed\"\n                    >\n                      <i [c8yIcon]=\"'check-circle-o'\"></i>\n                      {{ 'Subscribe' | translate }}\n                    </button>\n                    <button\n                      class=\"btn btn-default btn-sm\"\n                      title=\"{{ 'Unsubscribe' | translate }}\"\n                      type=\"button\"\n                      (click)=\"unsubscribe()\"\n                      *ngIf=\"isSubscribed\"\n                    >\n                      <i [c8yIcon]=\"'minus-circle'\"></i>\n                      {{ 'Unsubscribe' | translate }}\n                    </button>\n                  </span>\n                </div>\n              </div>\n            </div>\n          </div>\n          <div class=\"inner-scroll bg-level-0 flex-grow\">\n            <div class=\"card-block large-padding\">\n              <div\n                class=\"row p-16\"\n                *ngIf=\"isPackage\"\n              >\n                <c8y-properties-list\n                  icon=\"info\"\n                  [title]=\"'Package details' | translate\"\n                  [data]=\"application.manifest\"\n                  [properties]=\"packageProperties\"\n                  [emptyLabel]=\"'---'\"\n                ></c8y-properties-list>\n              </div>\n              <div\n                class=\"row p-16\"\n                *ngIf=\"sourcePackage\"\n              >\n                <c8y-properties-list\n                  icon=\"info\"\n                  [title]=\"'Source package information' | translate\"\n                  [data]=\"sourcePackage.manifest\"\n                  [properties]=\"packageProperties\"\n                  [emptyLabel]=\"'---'\"\n                ></c8y-properties-list>\n              </div>\n              <div class=\"row\">\n                <div class=\"col-sm-5\">\n                  <c8y-form-group>\n                    <label for=\"appId\">ID</label>\n                    <input\n                      class=\"form-control\"\n                      id=\"appId\"\n                      name=\"id\"\n                      type=\"text\"\n                      autocomplete=\"off\"\n                      [readonly]=\"true\"\n                      formControlName=\"id\"\n                    />\n                  </c8y-form-group>\n                </div>\n                <div class=\"col-sm-7\">\n                  <c8y-form-group>\n                    <label>{{ 'Name' | translate }}</label>\n                    <input\n                      class=\"form-control\"\n                      placeholder=\"{{ 'e.g. My application' | translate }}\"\n                      name=\"name\"\n                      type=\"text\"\n                      required\n                      [readonly]=\"!isOwner\"\n                      formControlName=\"name\"\n                    />\n                  </c8y-form-group>\n                </div>\n              </div>\n\n              <div class=\"row\">\n                <div class=\"col-sm-5\">\n                  <c8y-form-group>\n                    <label>{{ 'Application key' | translate }}</label>\n                    <input\n                      class=\"form-control\"\n                      placeholder=\"{{ 'e.g. my-application-key' | translate }}\"\n                      name=\"key\"\n                      type=\"text\"\n                      required\n                      [readonly]=\"application.id || !isOwner\"\n                      formControlName=\"key\"\n                    />\n                  </c8y-form-group>\n                </div>\n\n                <div class=\"col-sm-7\" data-cy=\"application-detail--type\">\n                  <c8y-form-group>\n                    <label>{{ 'Type' | translate }}</label>\n                    <div>\n                      <div *ngIf=\"application.id\">\n                        <p class=\"form-control-static\">\n                          <i [c8yIcon]=\"iconMap[application.type]\"></i>\n                          <span>\n                            {{ application.type | translate }}\n                          </span>\n                        </p>\n                      </div>\n                    </div>\n                  </c8y-form-group>\n                </div>\n              </div>\n\n              <div [ngSwitch]=\"application.type\">\n                <div *ngSwitchCase=\"'HOSTED'\">\n                  <c8y-form-group>\n                    <label>{{ 'Path' | translate }}</label>\n                    <div class=\"input-group\">\n                      <span class=\"input-group-addon\">/apps/</span>\n                      <input\n                        class=\"form-control\"\n                        placeholder=\"{{ 'e.g. my-application`used in URL`' | translate }}\"\n                        name=\"contextPath\"\n                        type=\"text\"\n                        required\n                        [readOnly]=\"application.id || !isOwner\"\n                        formControlName=\"contextPath\"\n                      />\n                    </div>\n                  </c8y-form-group>\n                </div>\n\n                <div *ngSwitchCase=\"'MICROSERVICE'\">\n                  <c8y-form-group>\n                    <label>{{ 'Path' | translate }}</label>\n                    <div class=\"input-group\">\n                      <span class=\"input-group-addon\">/service/</span>\n                      <input\n                        class=\"form-control\"\n                        placeholder=\"{{ 'e.g. my-microservice`used in URL`' | translate }}\"\n                        name=\"contextPath\"\n                        type=\"text\"\n                        required\n                        [readOnly]=\"application.id || !isOwner\"\n                        formControlName=\"contextPath\"\n                      />\n                    </div>\n                  </c8y-form-group>\n                  <div class=\"row\">\n                    <div\n                      class=\"col-sm-4 m-b-16 flex-auto\"\n                      *ngIf=\"application.manifest.version\"\n                      data-cy=\"application-detail--version\"\n                    >\n                      <label>{{ 'Version' | translate }}</label>\n                      <p class=\"form-control-static\">\n                        {{ application.manifest.version }}\n                      </p>\n                    </div>\n                    <div\n                      class=\"col-sm-4 m-b-16 flex-auto\"\n                      *ngIf=\"application.manifest.isolation\"\n                      data-cy=\"application-detail--isolation\"\n                    >\n                      <label>{{ 'Isolation' | translate }}</label>\n                      <p class=\"form-control-static\">\n                        <span *ngIf=\"singleTenant\">\n                          <i\n                            class=\"c8y-icon-duocolor h4\"\n                            [c8yIcon]=\"'c8y-enterprise'\"\n                          ></i>\n                          {{ 'Single tenant' | translate }}\n                        </span>\n                        <span *ngIf=\"!singleTenant\">\n                          <i\n                            class=\"c8y-icon-duocolor icon-32\"\n                            [c8yIcon]=\"'c8y-sub-tenants'\"\n                          ></i>\n                          {{ 'Multi tenant' | translate }}\n                        </span>\n                      </p>\n                    </div>\n                    <div\n                      class=\"col-sm-4 m-b-16 flex-auto\"\n                      *ngIf=\"application.manifest.isolation\"\n                      data-cy=\"application-detail--billing-mode\"\n                    >\n                      <label>{{ 'Billing mode' | translate }}</label>\n                      <p class=\"form-control-static\">\n                        <span\n                          [tooltip]=\"'Resources usage assigned to: Owner' | translate\"\n                          *ngIf=\"subscription\"\n                        >\n                          {{ 'Subscription' | translate }}\n                        </span>\n                        <span\n                          [tooltip]=\"'Resources usage assigned to: Subscriber | translate'\"\n                          *ngIf=\"!subscription && singleTenant\"\n                        >\n                          {{ 'Resources' | translate }}\n                        </span>\n                        <span\n                          [tooltip]=\"'Resources usage assigned to: Owner' | translate\"\n                          *ngIf=\"!subscription && !singleTenant\"\n                        >\n                          {{ 'Resources' | translate }}\n                        </span>\n                      </p>\n                    </div>\n                  </div>\n\n                  <div\n                    class=\"legend form-block m-t-40\"\n                    *ngIf=\"application.manifest.provider\"\n                  >\n                    {{ 'Provider' | translate }}\n                  </div>\n                  <div\n                    class=\"list-inline\"\n                    *ngIf=\"application.manifest.provider\"\n                    data-cy=\"application-detail--provider\"\n                  >\n                    <div *ngIf=\"application.manifest.provider.name\">\n                      <div class=\"col-sm-4 m-b-16\">\n                        <label>{{ 'Name' | translate }}</label>\n                        <p class=\"form-control-static\">\n                          {{ application.manifest.provider.name }}\n                        </p>\n                      </div>\n                    </div>\n                    <div *ngIf=\"application.manifest.provider.domain\">\n                      <div class=\"col-sm-4 m-b-16\">\n                        <label>{{ 'Domain' | translate }}</label>\n                        <p class=\"form-control-static\">\n                          {{ application.manifest.provider.domain }}\n                        </p>\n                      </div>\n                    </div>\n                    <div *ngIf=\"application.manifest.provider.support\">\n                      <div class=\"col-sm-4 m-b-16\">\n                        <label>{{ 'Support' | translate }}</label>\n                        <p class=\"form-control-static\">\n                          {{ application.manifest.provider.support }}\n                        </p>\n                      </div>\n                    </div>\n                  </div>\n                </div>\n\n                <div *ngSwitchCase=\"'EXTERNAL'\">\n                  <c8y-form-group>\n                    <label>{{ 'External URL' | translate }}</label>\n                    <input\n                      class=\"form-control\"\n                      placeholder=\"{{ 'e.g.' | translate }} http://www.example.com/\"\n                      name=\"externalUrl\"\n                      type=\"url\"\n                      required\n                      [pattern]=\"'^(?!javascript:).+'\"\n                      [readOnly]=\"!isOwner\"\n                      formControlName=\"externalUrl\"\n                    />\n                    <c8y-messages>\n                      <c8y-message\n                        [name]=\"'pattern'\"\n                        [text]=\"'Valid URL required.' | translate\"\n                      ></c8y-message>\n                    </c8y-messages>\n                  </c8y-form-group>\n                </div>\n\n                <div *ngIf=\"isOwner && !isCustomMicroservice\">\n                  <label>{{ 'Select icon' | translate }}</label>\n                  <c8y-icon-selector-wrapper\n                    name=\"icon\"\n                    formControlName=\"icon\"\n                  ></c8y-icon-selector-wrapper>\n                </div>\n              </div>\n            </div>\n          </div>\n          <ng-container *ngIf=\"isCustomMicroservice\">\n            <div\n              class=\"d-contents\"\n              *ngIf=\"!isLoading\"\n            >\n              <c8y-upload-archive\n                [(application)]=\"application\"\n                (refresh)=\"onNewArchive()\"\n              ></c8y-upload-archive>\n            </div>\n          </ng-container>\n          <div\n            class=\"card-footer separator\"\n            *ngIf=\"application && !!isOwner && hasAdminPermissions\"\n          >\n            <button\n              class=\"btn btn-default\"\n              title=\"{{ 'Cancel' | translate }}\"\n              type=\"button\"\n              (click)=\"cancel()\"\n            >\n              {{ 'Cancel' | translate }}\n            </button>\n            <button\n              class=\"btn btn-danger\"\n              title=\"{{ 'Delete' | translate }}\"\n              type=\"button\"\n              (click)=\"delete()\"\n              *ngIf=\"canDelete\"\n            >\n              {{ 'Delete' | translate }}\n            </button>\n            <button\n              class=\"btn btn-primary btn-form\"\n              title=\"{{ 'Save' | translate }}\"\n              type=\"submit\"\n              [disabled]=\"!application.type || formGroup.invalid || formGroup.pristine\"\n            >\n              {{ 'Save' | translate }}\n            </button>\n          </div>\n        </div>\n      </form>\n\n      <div\n        class=\"content-fullpage d-flex d-col bg-level-1\"\n        *ngIf=\"isActivityLogSupported\"\n      >\n        <div class=\"card-header separator\">\n          <div\n            class=\"card-title\"\n            translate\n          >\n            Activity log\n          </div>\n          <div class=\"m-l-auto\">\n            <button\n              class=\"btn btn-link btn-sm\"\n              title=\"{{ 'Reload' | translate }}\"\n              type=\"button\"\n              (click)=\"load()\"\n            >\n              <i\n                c8yIcon=\"refresh\"\n                [ngClass]=\"{ 'icon-spin': isLoading }\"\n              ></i>\n              {{ 'Reload' | translate }}\n            </button>\n          </div>\n        </div>\n        <div\n          class=\"p-16 text-center\"\n          *ngIf=\"isLoading\"\n        >\n          <c8y-loading></c8y-loading>\n        </div>\n        <c8y-activity-log\n          class=\"d-contents\"\n          *ngIf=\"!isLoading\"\n          [hasAdminPermissions]=\"hasAdminPermissions\"\n          [application]=\"application\"\n        ></c8y-activity-log>\n      </div>\n    </div>\n  </div>\n</div>\n" }]
        }], ctorParameters: () => [{ type: i1$2.ActivatedRoute }, { type: i1.EcosystemService }, { type: i1$2.Router }, { type: i3.FormBuilder }, { type: i4.ApplicationService }, { type: i2.AlertService }, { type: i4.InventoryService }, { type: i2.Permissions }, { type: i2.ModalService }, { type: i6.TranslateService }, { type: i1$1.BsModalService }, { type: i2.GainsightService }] });

class ApplicationPropertiesGuard {
    constructor(ecosystemService) {
        this.ecosystemService = ecosystemService;
    }
    canActivate(route) {
        const app = route.data.contextData || route.parent.data.contextData;
        if (!app) {
            return false;
        }
        return !this.ecosystemService.isPackage(app);
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: ApplicationPropertiesGuard, deps: [{ token: i1.EcosystemService }], target: i0.ɵɵFactoryTarget.Injectable }); }
    static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: ApplicationPropertiesGuard }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: ApplicationPropertiesGuard, decorators: [{
            type: Injectable
        }], ctorParameters: () => [{ type: i1.EcosystemService }] });

class AddExternalApplicationComponent {
    constructor(applicationService, formBuilder, alertService, wizardComponent) {
        this.applicationService = applicationService;
        this.formBuilder = formBuilder;
        this.alertService = alertService;
        this.wizardComponent = wizardComponent;
    }
    ngOnInit() {
        this.initForm();
    }
    back() {
        this.wizardComponent.reset();
    }
    cancel() {
        this.wizardComponent.close();
    }
    done() {
        this.wizardComponent.close();
    }
    async save(app) {
        const appToSave = {
            manifest: {},
            externalUrl: app.externalUrl,
            type: ApplicationType.EXTERNAL,
            name: app.name,
            key: app.key
        };
        try {
            this.createdApp = await this.applicationService.create(appToSave);
        }
        catch (ex) {
            this.alertService.addServerFailure(ex);
        }
    }
    initForm() {
        this.formGroup = this.formBuilder.group({
            name: ['', [Validators.required, Validators.maxLength(120)]],
            key: ['', [Validators.required, Validators.maxLength(120)]],
            externalUrl: ['', Validators.required]
        });
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: AddExternalApplicationComponent, deps: [{ token: i4.ApplicationService }, { token: i3.FormBuilder }, { token: i2.AlertService }, { token: i2.WizardComponent }], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.14", type: AddExternalApplicationComponent, isStandalone: true, selector: "c8y-add-external-application", ngImport: i0, template: "<form *ngIf=\"!createdApp; else appCreated\" [formGroup]=\"formGroup\" novalidate>\n  <c8y-wizard-header>\n    <i [c8yIcon]=\"'cloud-link'\"></i>\n    <h4 translate id=\"modal-title\">Add external application</h4>\n  </c8y-wizard-header>\n\n  <c8y-wizard-body>\n    <p class=\"p-16 text-medium text-center bg-level-0 separator-bottom sticky-top\">\n      {{ 'Provide external application details' | translate }}\n    </p>\n    <div class=\"modal-body p-t-8\" id=\"modal-body\">\n      <c8y-form-group>\n        <label style=\"text-align: left\">{{ 'Name' | translate }}</label>\n        <input\n          class=\"form-control\"\n          formControlName=\"name\"\n          name=\"name\"\n          placeholder=\"{{ 'e.g. My application' | translate }}\"\n          required\n          type=\"text\"\n        />\n      </c8y-form-group>\n\n      <c8y-form-group>\n        <label style=\"text-align: left\">{{ 'Application key' | translate }}</label>\n        <input\n          class=\"form-control\"\n          formControlName=\"key\"\n          name=\"key\"\n          placeholder=\"{{ 'e.g. my-external-application-key' | translate }}\"\n          required\n          type=\"text\"\n        />\n      </c8y-form-group>\n\n      <c8y-form-group>\n        <label style=\"text-align: left\">{{ 'External URL' | translate }}</label>\n        <input\n          [pattern]=\"'^(?!javascript:).+'\"\n          class=\"form-control\"\n          formControlName=\"externalUrl\"\n          name=\"externalUrl\"\n          placeholder=\"{{ 'e.g.' | translate }} https://www.example.com\"\n          required\n          type=\"url\"\n        />\n      </c8y-form-group>\n    </div>\n  </c8y-wizard-body>\n\n  <c8y-wizard-footer>\n    <button\n      (click)=\"back()\"\n      class=\"btn btn-default\"\n      title=\"{{ 'Back' | translate }}\"\n      translate\n      type=\"button\"\n    >\n      Back\n    </button>\n    <button (click)=\"cancel()\" class=\"btn btn-default\" title=\"{{ 'Cancel' | translate }}\" translate>\n      Cancel\n    </button>\n    <button\n      (click)=\"save(formGroup.value)\"\n      [disabled]=\"formGroup.invalid || formGroup.pristine\"\n      class=\"btn btn-primary btn-form\"\n      title=\"{{ 'Add application' | translate }}\"\n      type=\"button\"\n    >\n      {{ 'Add application' | translate }}\n    </button>\n  </c8y-wizard-footer>\n</form>\n<ng-template #appCreated>\n  <c8y-wizard-body>\n    <div class=\"d-flex d-col j-c-center a-i-center\" style=\"min-height: 324px\">\n      <c8y-operation-result\n        text=\"{{ 'Application created' | translate }}\"\n        [size]=\"84\"\n        [vertical]=\"true\"\n        type=\"success\"\n        class=\"lead\"\n      ></c8y-operation-result>\n    </div>\n  </c8y-wizard-body>\n  <c8y-wizard-footer>\n    <button (click)=\"done()\" class=\"btn btn-default\" title=\"{{ 'Done' | translate }}\" translate>\n      Done\n    </button>\n    <a\n      (click)=\"$event.stopPropagation()\"\n      [href]=\"formGroup.value.externalUrl\"\n      target=\"_blank\"\n      rel=\"noopener noreferrer\"\n      class=\"btn btn-primary\"\n      title=\"{{ 'Open' | translate }}\"\n    >\n      <i c8yIcon=\"external-link\" class=\"m-r-4\"></i>\n      {{ 'Open' | translate }}\n    </a>\n  </c8y-wizard-footer>\n</ng-template>\n", dependencies: [{ kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i3.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i3.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: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i3.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i3.PatternValidator, selector: "[pattern][formControlName],[pattern][formControl],[pattern][ngModel]", inputs: ["pattern"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i3.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i3.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: WizardHeaderComponent, selector: "c8y-wizard-header" }, { kind: "directive", type: IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "directive", type: C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "component", type: WizardBodyComponent, selector: "c8y-wizard-body" }, { kind: "component", type: FormGroupComponent, selector: "c8y-form-group", inputs: ["hasError", "hasWarning", "hasSuccess", "novalidation", "status"] }, { kind: "directive", type: RequiredInputPlaceholderDirective, selector: "input[required], input[formControlName]" }, { kind: "component", type: WizardFooterComponent, selector: "c8y-wizard-footer" }, { kind: "component", type: OperationResultComponent, selector: "c8y-operation-result", inputs: ["text", "vertical", "size", "type"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: AddExternalApplicationComponent, decorators: [{
            type: Component,
            args: [{ selector: 'c8y-add-external-application', imports: [
                        NgIf,
                        FormsModule,
                        ReactiveFormsModule,
                        WizardHeaderComponent,
                        IconDirective,
                        C8yTranslateDirective,
                        WizardBodyComponent,
                        FormGroupComponent,
                        RequiredInputPlaceholderDirective,
                        WizardFooterComponent,
                        OperationResultComponent,
                        C8yTranslatePipe
                    ], template: "<form *ngIf=\"!createdApp; else appCreated\" [formGroup]=\"formGroup\" novalidate>\n  <c8y-wizard-header>\n    <i [c8yIcon]=\"'cloud-link'\"></i>\n    <h4 translate id=\"modal-title\">Add external application</h4>\n  </c8y-wizard-header>\n\n  <c8y-wizard-body>\n    <p class=\"p-16 text-medium text-center bg-level-0 separator-bottom sticky-top\">\n      {{ 'Provide external application details' | translate }}\n    </p>\n    <div class=\"modal-body p-t-8\" id=\"modal-body\">\n      <c8y-form-group>\n        <label style=\"text-align: left\">{{ 'Name' | translate }}</label>\n        <input\n          class=\"form-control\"\n          formControlName=\"name\"\n          name=\"name\"\n          placeholder=\"{{ 'e.g. My application' | translate }}\"\n          required\n          type=\"text\"\n        />\n      </c8y-form-group>\n\n      <c8y-form-group>\n        <label style=\"text-align: left\">{{ 'Application key' | translate }}</label>\n        <input\n          class=\"form-control\"\n          formControlName=\"key\"\n          name=\"key\"\n          placeholder=\"{{ 'e.g. my-external-application-key' | translate }}\"\n          required\n          type=\"text\"\n        />\n      </c8y-form-group>\n\n      <c8y-form-group>\n        <label style=\"text-align: left\">{{ 'External URL' | translate }}</label>\n        <input\n          [pattern]=\"'^(?!javascript:).+'\"\n          class=\"form-control\"\n          formControlName=\"externalUrl\"\n          name=\"externalUrl\"\n          placeholder=\"{{ 'e.g.' | translate }} https://www.example.com\"\n          required\n          type=\"url\"\n        />\n      </c8y-form-group>\n    </div>\n  </c8y-wizard-body>\n\n  <c8y-wizard-footer>\n    <button\n      (click)=\"back()\"\n      class=\"btn btn-default\"\n      title=\"{{ 'Back' | translate }}\"\n      translate\n      type=\"button\"\n    >\n      Back\n    </button>\n    <button (click)=\"cancel()\" class=\"btn btn-default\" title=\"{{ 'Cancel' | translate }}\" translate>\n      Cancel\n    </button>\n    <button\n      (click)=\"save(formGroup.value)\"\n      [disabled]=\"formGroup.invalid || formGroup.pristine\"\n      class=\"btn btn-primary btn-form\"\n      title=\"{{ 'Add application' | translate }}\"\n      type=\"button\"\n    >\n      {{ 'Add application' | translate }}\n    </button>\n  </c8y-wizard-footer>\n</form>\n<ng-template #appCreated>\n  <c8y-wizard-body>\n    <div class=\"d-flex d-col j-c-center a-i-center\" style=\"min-height: 324px\">\n      <c8y-operation-result\n        text=\"{{ 'Application created' | translate }}\"\n        [size]=\"84\"\n        [vertical]=\"true\"\n        type=\"success\"\n        class=\"lead\"\n      ></c8y-operation-result>\n    </div>\n  </c8y-wizard-body>\n  <c8y-wizard-footer>\n    <button (click)=\"done()\" class=\"btn btn-default\" title=\"{{ 'Done' | translate }}\" translate>\n      Done\n    </button>\n    <a\n      (click)=\"$event.stopPropagation()\"\n      [href]=\"formGroup.value.externalUrl\"\n      target=\"_blank\"\n      rel=\"noopener noreferrer\"\n      class=\"btn btn-primary\"\n      title=\"{{ 'Open' | translate }}\"\n    >\n      <i c8yIcon=\"external-link\" class=\"m-r-4\"></i>\n      {{ 'Open' | translate }}\n    </a>\n  </c8y-wizard-footer>\n</ng-template>\n" }]
        }], ctorParameters: () => [{ type: i4.ApplicationService }, { type: i3.FormBuilder }, { type: i2.AlertService }, { type: i2.WizardComponent }] });

class AddWebApplicationComponent {
    constructor(ecosystemService) {
        this.ecosystemService = ecosystemService;
        this.headerText = gettext('Upload web application');
        this.successText = gettext('Application created');
        this.createApplicationHandler = (f) => this.createApplication(f);
        this.uploadApplicationHandler = (f, app) => this.uploadApplication(f, app);
    }
    async createApplication(file) {
        await this.ecosystemService.isValidAppType(file, ApplicationType.HOSTED);
        return this.ecosystemService.createAppForArchive(file);
    }
    async uploadApplication(file, app) {
        return this.ecosystemService.uploadArchiveToApp(file, app);
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: AddWebApplicationComponent, deps: [{ token: i1.EcosystemService }], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.14", type: AddWebApplicationComponent, isStandalone: true, selector: "c8y-add-web-application", ngImport: i0, template: `<c8y-add-application
    [headerIcon]="'upload'"
    [headerText]="headerText"
    [successText]="successText"
    [createApplicationHandler]="createApplicationHandler"
    [uploadApplicationHandler]="uploadApplicationHandler"
    [canGoBack]="true"
  ></c8y-add-application>`, isInline: true, dependencies: [{ kind: "component", type: AddApplicationComponent, selector: "c8y-add-application", inputs: ["headerText", "headerIcon", "successText", "createApplicationHandler", "uploadApplicationHandler", "canGoBack", "applicationType"] }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: AddWebApplicationComponent, decorators: [{
            type: Component,
            args: [{
                    selector: 'c8y-add-web-application',
                    template: `<c8y-add-application
    [headerIcon]="'upload'"
    [headerText]="headerText"
    [successText]="successText"
    [createApplicationHandler]="createApplicationHandler"
    [uploadApplicationHandler]="uploadApplicationHandler"
    [canGoBack]="true"
  ></c8y-add-application>`,
                    imports: [AddApplicationComponent]
                }]
        }], ctorParameters: () => [{ type: i1.EcosystemService }] });

class ApplicationListComponent {
    constructor(ecosystemService, wizardModalService) {
        this.ecosystemService = ecosystemService;
        this.wizardModalService = wizardModalService;
        this.reloading = false;
        this.reload$ = new BehaviorSubject(null);
        this.apps$ = this.reload$.pipe(tap(() => (this.reloading = true)), switchMap(() => this.ecosystemService.getWebApplications()), tap(apps => {
            apps.forEach(app => {
                app.filterProps = this.ecosystemService.getAppFilterProps(app);
            });
        }), tap(() => (this.reloading = false)), shareReplay());
        this.packageAvailabilities = defaultPackageAvailabilities;
        this.destroy$ = new Subject();
    }
    ngOnInit() {
        this.loadApplications();
    }
    loadApplications() {
        this.reload$.next();
    }
    addApplication() {
        const wizardConfig = {
            headerText: 'Add Application',
            headerIcon: 'c8y-atom'
        };
        const initialState = {
            wizardConfig,
            id: EcosystemWizards.APPLICATION_UPLOAD
        };
        const modalOptions = { initialState };
        const modalRef = this.wizardModalService.show(modalOptions);
        modalRef.content.onClose.pipe(takeUntil(this.destroy$)).subscribe(() => {
            this.loadApplications();
        });
    }
    ngOnDestroy() {
        this.destroy$.next();
        this.destroy$.complete();
    }
    setFilterPipe(pipe) {
        this.filteredApps$ = this.apps$.pipe(src => pipe(src));
    }
    resetFilters() {
        this.filtersComponent.resetAllFilters();
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: ApplicationListComponent, deps: [{ token: i1.EcosystemService }, { token: i2.WizardModalService }], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.14", type: ApplicationListComponent, isStandalone: true, selector: "c8y-application-list", viewQueries: [{ propertyName: "filtersComponent", first: true, predicate: ListFiltersComponent, descendants: true }], ngImport: i0, template: "<c8y-title>{{ 'Applications' | translate }}</c8y-title>\n\n<c8y-breadcrumb>\n  <c8y-breadcrumb-item\n    [icon]=\"'c8y-atom'\"\n    [label]=\"'Ecosystem' | translate\"\n  ></c8y-breadcrumb-item>\n  <c8y-breadcrumb-item\n    [icon]=\"'c8y-modules'\"\n    [label]=\"'Applications' | translate\"\n    [path]=\"'ecosystem/application/applications'\"\n  ></c8y-breadcrumb-item>\n</c8y-breadcrumb>\n\n<c8y-action-bar-item\n  [placement]=\"'right'\"\n  *c8yIfAllowed=\"['ROLE_APPLICATION_MANAGEMENT_ADMIN']\"\n>\n  <button\n    class=\"btn btn-link\"\n    title=\"{{ 'Add application' | translate }}\"\n    (click)=\"addApplication()\"\n  >\n    <i c8yIcon=\"plus-circle\"></i>\n    {{ 'Add application' | translate }}\n  </button>\n</c8y-action-bar-item>\n\n<c8y-action-bar-item [placement]=\"'right'\">\n  <button\n    class=\"btn btn-link\"\n    title=\"{{ 'Reload' | translate }}\"\n    (click)=\"loadApplications()\"\n  >\n    <i\n      c8yIcon=\"refresh\"\n      [ngClass]=\"{ 'icon-spin': reloading }\"\n    ></i>\n    {{ 'Reload' | translate }}\n  </button>\n</c8y-action-bar-item>\n\n<c8y-action-bar-item [placement]=\"'left'\">\n  <c8y-list-filters\n    *ngIf=\"apps$ | async\"\n    (filterPipeChange)=\"setFilterPipe($event)\"\n    [packageAvailabilities]=\"packageAvailabilities\"\n  ></c8y-list-filters>\n</c8y-action-bar-item>\n\n<c8y-action-bar-item\n  [placement]=\"'left'\"\n  itemClass=\"navbar-form hidden-xs\"\n>\n  <c8y-list-display-switch\n    (onListClassChange)=\"listClass = $event\"\n    [listLength]=\"(apps$ | async)?.length\"\n  ></c8y-list-display-switch>\n</c8y-action-bar-item>\n\n<c8y-help src=\"/docs/standard-tenant/ecosystem/#managing-applications\"></c8y-help>\n\n<div\n  class=\"c8y-empty-state text-center\"\n  *ngIf=\"(apps$ | async)?.length === 0\"\n>\n  <h1 class=\"c8y-icon c8y-icon-modules c8y-icon-duocolor\"></h1>\n  <h3 translate>No applications to display.</h3>\n  <p translate>Add your first application by clicking below.</p>\n  <p>\n    <button\n      class=\"btn btn-primary\"\n      title=\"{{ 'Add application' | translate }}\"\n      (click)=\"addApplication()\"\n    >\n      {{ 'Add application' | translate }}\n    </button>\n  </p>\n</div>\n\n<div\n  class=\"card-group\"\n  [ngClass]=\"listClass\"\n>\n  <div\n    class=\"page-sticky-header hidden-xs d-flex\"\n    *ngIf=\"(apps$ | async)?.length > 0\"\n  >\n    <div class=\"card-block card-column-40\">\n      <div class=\"card-appicon p-l-32 p-r-16 m-r-0 m-l-4\"></div>\n      {{ 'Application' | translate }}\n    </div>\n    <div class=\"card-block p-0 card-column-80 m-r-40\">\n      <div class=\"card-block card-column-80\">{{ 'Description' | translate }}</div>\n      <div class=\"card-block card-column-20\">{{ 'Type' | translate }}</div>\n      <div class=\"card-block card-column-20\"></div>\n    </div>\n  </div>\n  <div\n    class=\"col-xs-12 col-sm-4 col-md-3\"\n    *ngFor=\"let app of filteredApps$ | async\"\n  >\n    <c8y-application-card\n      class=\"d-contents\"\n      (onAppDeleted)=\"loadApplications()\"\n      (onAppCloned)=\"loadApplications()\"\n      [app]=\"app\"\n    ></c8y-application-card>\n  </div>\n</div>\n\n<c8y-ui-empty-state\n  [icon]=\"'search'\"\n  [title]=\"'No matching applications.' | translate\"\n  [subtitle]=\"'Refine your search terms and/or the filters' | translate\"\n  *ngIf=\"(apps$ | async)?.length > 0 && (filteredApps$ | async)?.length === 0\"\n>\n  <button\n    class=\"btn btn-primary\"\n    title=\"{{ 'Reset filters' | translate }}\"\n    type=\"button\"\n    (click)=\"resetFilters()\"\n  >\n    {{ 'Reset filters' | translate }}\n  </button>\n</c8y-ui-empty-state>\n", dependencies: [{ kind: "component", type: TitleComponent, selector: "c8y-title", inputs: ["pageTitleUpdate"] }, { kind: "component", type: BreadcrumbComponent, selector: "c8y-breadcrumb" }, { kind: "component", type: BreadcrumbItemComponent, selector: "c8y-breadcrumb-item", inputs: ["icon", "translate", "label", "path", "injector"] }, { kind: "directive", type: IfAllowedDirective, selector: "[c8yIfAllowed]", inputs: ["c8yIfAllowed", "c8yIfAllowedAllowAny"] }, { kind: "component", type: ActionBarItemComponent, selector: "c8y-action-bar-item", inputs: ["placement", "priority", "itemClass", "injector", "groupId", "inGroupPriority"] }, { kind: "directive", type: IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: ListFiltersComponent, selector: "c8y-list-filters", inputs: ["packageTypes", "packageAvailabilities", "packageContents"], outputs: ["filterPipeChange"] }, { kind: "component", type: ListDisplaySwitchComponent, selector: "c8y-list-display-switch", inputs: ["listKey", "listLength", "filterPipe"], outputs: ["onListClassChange"] }, { kind: "component", type: HelpComponent, selector: "c8y-help", inputs: ["src", "isCollapsed", "priority", "icon"] }, { kind: "directive", type: C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "directive", type: NgFor, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "component", type: ApplicationCardComponent, selector: "c8y-application-card", inputs: ["app", "canEdit"], outputs: ["onAppDeleted", "onAppCloned"] }, { kind: "component", type: EmptyStateComponent, selector: "c8y-ui-empty-state", inputs: ["icon", "title", "subtitle", "horizontal"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }, { kind: "pipe", type: AsyncPipe, name: "async" }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: ApplicationListComponent, decorators: [{
            type: Component,
            args: [{ selector: 'c8y-application-list', imports: [
                        TitleComponent,
                        BreadcrumbComponent,
                        BreadcrumbItemComponent,
                        IfAllowedDirective,
                        ActionBarItemComponent,
                        IconDirective,
                        NgClass,
                        NgIf,
                        ListFiltersComponent,
                        ListDisplaySwitchComponent,
                        HelpComponent,
                        C8yTranslateDirective,
                        NgFor,
                        ApplicationCardComponent,
                        EmptyStateComponent,
                        C8yTranslatePipe,
                        AsyncPipe
                    ], template: "<c8y-title>{{ 'Applications' | translate }}</c8y-title>\n\n<c8y-breadcrumb>\n  <c8y-breadcrumb-item\n    [icon]=\"'c8y-atom'\"\n    [label]=\"'Ecosystem' | translate\"\n  ></c8y-breadcrumb-item>\n  <c8y-breadcrumb-item\n    [icon]=\"'c8y-modules'\"\n    [label]=\"'Applications' | translate\"\n    [path]=\"'ecosystem/application/applications'\"\n  ></c8y-breadcrumb-item>\n</c8y-breadcrumb>\n\n<c8y-action-bar-item\n  [placement]=\"'right'\"\n  *c8yIfAllowed=\"['ROLE_APPLICATION_MANAGEMENT_ADMIN']\"\n>\n  <button\n    class=\"btn btn-link\"\n    title=\"{{ 'Add application' | translate }}\"\n    (click)=\"addApplication()\"\n  >\n    <i c8yIcon=\"plus-circle\"></i>\n    {{ 'Add application' | translate }}\n  </button>\n</c8y-action-bar-item>\n\n<c8y-action-bar-item [placement]=\"'right'\">\n  <button\n    class=\"btn btn-link\"\n    title=\"{{ 'Reload' | translate }}\"\n    (click)=\"loadApplications()\"\n  >\n    <i\n      c8yIcon=\"refresh\"\n      [ngClass]=\"{ 'icon-spin': reloading }\"\n    ></i>\n    {{ 'Reload' | translate }}\n  </button>\n</c8y-action-bar-item>\n\n<c8y-action-bar-item [placement]=\"'left'\">\n  <c8y-list-filters\n    *ngIf=\"apps$ | async\"\n    (filterPipeChange)=\"setFilterPipe($event)\"\n    [packageAvailabilities]=\"packageAvailabilities\"\n  ></c8y-list-filters>\n</c8y-action-bar-item>\n\n<c8y-action-bar-item\n  [placement]=\"'left'\"\n  itemClass=\"navbar-form hidden-xs\"\n>\n  <c8y-list-display-switch\n    (onListClassChange)=\"listClass = $event\"\n    [listLength]=\"(apps$ | async)?.length\"\n  ></c8y-list-display-switch>\n</c8y-action-bar-item>\n\n<c8y-help src=\"/docs/standard-tenant/ecosystem/#managing-applications\"></c8y-help>\n\n<div\n  class=\"c8y-empty-state text-center\"\n  *ngIf=\"(apps$ | async)?.length === 0\"\n>\n  <h1 class=\"c8y-icon c8y-icon-modules c8y-icon-duocolor\"></h1>\n  <h3 translate>No applications to display.</h3>\n  <p translate>Add your first application by clicking below.</p>\n  <p>\n    <button\n      class=\"btn btn-primary\"\n      title=\"{{ 'Add application' | translate }}\"\n      (click)=\"addApplication()\"\n    >\n      {{ 'Add application' | translate }}\n    </button>\n  </p>\n</div>\n\n<div\n  class=\"card-group\"\n  [ngClass]=\"listClass\"\n>\n  <div\n    class=\"page-sticky-header hidden-xs d-flex\"\n    *ngIf=\"(apps$ | async)?.length > 0\"\n  >\n    <div class=\"card-block card-column-40\">\n      <div class=\"card-appicon p-l-32 p-r-16 m-r-0 m-l-4\"></div>\n      {{ 'Application' | translate }}\n    </div>\n    <div class=\"card-block p-0 card-column-80 m-r-40\">\n      <div class=\"card-block card-column-80\">{{ 'Description' | translate }}</div>\n      <div class=\"card-block card-column-20\">{{ 'Type' | translate }}</div>\n      <div class=\"card-block card-column-20\"></div>\n    </div>\n  </div>\n  <div\n    class=\"col-xs-12 col-sm-4 col-md-3\"\n    *ngFor=\"let app of filteredApps$ | async\"\n  >\n    <c8y-application-card\n      class=\"d-contents\"\n      (onAppDeleted)=\"loadApplications()\"\n      (onAppCloned)=\"loadApplications()\"\n      [app]=\"app\"\n    ></c8y-application-card>\n  </div>\n</div>\n\n<c8y-ui-empty-state\n  [icon]=\"'search'\"\n  [title]=\"'No matching applications.' | translate\"\n  [subtitle]=\"'Refine your search terms and/or the filters' | translate\"\n  *ngIf=\"(apps$ | async)?.length > 0 && (filteredApps$ | async)?.length === 0\"\n>\n  <button\n    class=\"btn btn-primary\"\n    title=\"{{ 'Reset filters' | translate }}\"\n    type=\"button\"\n    (click)=\"resetFilters()\"\n  >\n    {{ 'Reset filters' | translate }}\n  </button>\n</c8y-ui-empty-state>\n" }]
        }], ctorParameters: () => [{ type: i1.EcosystemService }, { type: i2.WizardModalService }], propDecorators: { filtersComponent: [{
                type: ViewChild,
                args: [ListFiltersComponent]
            }] } });

class InstallFromPackageComponent {
    constructor(ecosystemService, applicationService, wizardComponent, pluginsService) {
        this.ecosystemService = ecosystemService;
        this.applicationService = applicationService;
        this.wizardComponent = wizardComponent;
        this.pluginsService = pluginsService;
        this.deployedWithSuccess = false;
        this.isDeployed = false;
        this.model = {
            selected: undefined,
            binary: {
                id: undefined
            }
        };
        this.canDeploy = false;
        this.onInput = new BehaviorSubject('');
    }
    async ngOnInit() {
        this.loadPackages();
    }
    back() {
        this.wizardComponent.reset();
    }
    clean() {
        this.selectedPackage = undefined;
        this.versions$ = undefined;
        this.model = {
            selected: undefined,
            binary: {
                id: undefined
            }
        };
    }
    cancel() {
        this.wizardComponent.close();
    }
    async deployApp() {
        this.inProgress = true;
        const formGroupValue = this.applicationPropertiesForm.formGroup.getRawValue();
        const { contextPath, license, name } = this.selectedPackage;
        const type = this.pluginsService.getPackageType(this.selectedPackage);
        const licensedApp = {
            contextPath,
            license,
            name,
            type,
            version: this.model.selected.version
        };
        const isArchived = await this.ecosystemService.verifyArchived([licensedApp]);
        if (!isArchived) {
            this.cancel();
            return;
        }
        const licensesVerifiedByUser = await this.ecosystemService.verifyLicenses([licensedApp]);
        if (!licensesVerifiedByUser) {
            this.cancel();
            return;
        }
        // Verify if selected package version is compatible with current platform versions.
        this.selectedPackage.manifest.version = this.model.selected.version;
        const verifyVersionCompatibility = await this.ecosystemService.verifyBlueprintVersionsCompatibility(this.selectedPackage.manifest);
        if (!verifyVersionCompatibility) {
            this.cancel();
            return;
        }
        try {
            await this.ecosystemService.deployApp(this.selectedPackage, formGroupValue, this.model);
            this.deployedWithSuccess = true;
        }
        catch (error) {
            this.ecosystemService.alertError(error);
        }
        finally {
            this.markAsDeployed();
        }
    }
    onAppVersionSelect(appVersion) {
        Object.assign(this.model, {
            selected: appVersion
        });
        this.canDeploy = true;
    }
    async selectPackage(selectedPackage) {
        const apps = await this.ecosystemService.getHostedAndPackageApplications();
        this.newAppConfig = this.ecosystemService.getUniqueAppConfig(selectedPackage, apps);
        this.selectedPackage = selectedPackage;
        this.loadSelectedPackageVersions();
    }
    loadSelectedPackageVersions() {
        this.versions$ = combineLatest([
            this.getAppVersions(this.selectPackage),
            this.onInput.asObservable()
        ]).pipe(map(([resultList, filterStr]) => {
            this.canDeploy = false;
            const versionsFilteredByStr = this.filterAppVersions(resultList.data, filterStr);
            const sortedAppVersions = this.pluginsService.sortVersions({
                list: versionsFilteredByStr,
                path: ['version']
            }, 'desc');
            this.setInitialValueForInput(sortedAppVersions);
            return { data: sortedAppVersions, res: resultList.res };
        }));
    }
    getAppVersions(mo) {
        const versions = mo?.applicationVersions;
        return versions && versions.length > 0
            ? of({ data: versions, res: undefined })
            : from(this.applicationService.listVersions(this.selectedPackage.id));
    }
    setInitialValueForInput(versions) {
        if (!this.model.selected && versions.length > 0) {
            const latest = versions.find(v => v.tags.includes('latest'));
            this.model.selected = latest || versions[0];
            this.canDeploy = true;
        }
    }
    filterAppVersions(appVersions, filterStr) {
        return filterStr === ''
            ? appVersions
            : appVersions.filter(appVersion => appVersion.version.includes(filterStr));
    }
    markAsDeployed() {
        this.isDeployed = true;
        this.inProgress = false;
    }
    async loadPackages() {
        const applications = await this.ecosystemService.getPackageApplications();
        this.packages = applications.filter(app => this.ecosystemService.isPackageBlueprint(app));
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: InstallFromPackageComponent, deps: [{ token: i1.EcosystemService }, { token: i4.ApplicationService }, { token: i2.WizardComponent }, { token: i2.PluginsService }], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.14", type: InstallFromPackageComponent, isStandalone: true, selector: "c8y-install-from-package", viewQueries: [{ propertyName: "applicationPropertiesForm", first: true, predicate: ApplicationPropertiesFormComponent, descendants: true }], ngImport: i0, template: "<c8y-wizard-header>\n  <i [c8yIcon]=\"'big-parcel'\"></i>\n  <h4\n    id=\"modal-title\"\n    translate\n  >\n    Install from extension package\n  </h4>\n</c8y-wizard-header>\n<c8y-wizard-body>\n  <ng-container *ngIf=\"!selectedPackage\">\n    <div\n      class=\"modal-inner-scroll\"\n      id=\"modal-body\"\n    >\n      <p class=\"p-16 text-medium text-center separator-bottom sticky-top bg-level-0\">\n        {{ 'Select from available extension packages' | translate }}\n      </p>\n\n      <c8y-ui-empty-state\n        [icon]=\"'big-parcel'\"\n        [title]=\"'No extension packages to display.' | translate\"\n        *ngIf=\"!packages?.length\"\n        [horizontal]=\"true\"\n      ></c8y-ui-empty-state>\n\n      <div\n        class=\"c8y-wizard-list-nav\"\n        style=\"min-height: 257px\"\n        *ngIf=\"packages?.length\"\n      >\n        <button\n          class=\"list-group-item text-truncate bg-component\"\n          title=\"{{ package.name }}\"\n          type=\"button\"\n          *ngFor=\"let package of packages\"\n          (click)=\"selectPackage(package)\"\n        >\n          <i\n            class=\"list-group-icon\"\n            c8yIcon=\"big-parcel\"\n          ></i>\n          <span [innerText]=\"package.name\"></span>\n        </button>\n      </div>\n    </div>\n  </ng-container>\n  <ng-container *ngIf=\"!isDeployed && selectedPackage\">\n    <p class=\"p-16 text-center text-medium separator-bottom sticky-top bg-level-0\">\n      {{ 'Provide application details' | translate }}\n    </p>\n    <div\n      class=\"d-flex d-col a-i-center j-c-center\"\n      style=\"min-height: 257px\"\n    >\n      <c8y-application-properties-form\n        class=\"d-block fit-w\"\n        *ngIf=\"!inProgress\"\n        [application]=\"newAppConfig\"\n      ></c8y-application-properties-form>\n\n      <ng-container *ngIf=\"!inProgress\">\n        <div\n          class=\"d-block fit-w bg-gray-white\"\n          [ngStyle]=\"{ padding: '0 16px' }\"\n        >\n          <label\n            for=\"packageVersion\"\n            translate\n          >\n            Use extension package version\n          </label>\n          <c8y-form-group>\n            <c8y-typeahead\n              placeholder=\"{{ 'Select or enter' | translate }}\"\n              name=\"packageVersion\"\n              [(ngModel)]=\"model.selected\"\n              (onSearch)=\"onInput.next($event)\"\n              [displayProperty]=\"'version'\"\n              [required]=\"true\"\n              [hideNew]=\"true\"\n              [container]=\"'body'\"\n            >\n              <c8y-li\n                class=\"p-l-8 p-r-8 c8y-list__item--link\"\n                *c8yFor=\"let version of versions$; loadMore: 'auto'; notFound: notFoundTemplate\"\n                (click)=\"onAppVersionSelect(version)\"\n                [active]=\"model.selected === version\"\n              >\n                <c8y-li-icon icon=\"big-parcel\"></c8y-li-icon>\n                <span\n                  [ngStyle]=\"{\n                    display: 'flex',\n                    'flex-direction': 'row',\n                    'align-content': 'center',\n                    'justify-content': 'space-between',\n                    'align-items': 'center'\n                  }\"\n                >\n                  <c8y-highlight\n                    [text]=\"version.version || '--'\"\n                    [pattern]=\"onInput | async\"\n                  ></c8y-highlight>\n\n                  <span>\n                    <span\n                      class=\"label label-info m-l-4\"\n                      *ngFor=\"let tag of version.tags\"\n                    >\n                      {{ tag }}\n                    </span>\n                  </span>\n                </span>\n              </c8y-li>\n              <ng-template #notFoundTemplate>\n                <c8y-li\n                  class=\"bg-gray-lighter p-8\"\n                  *ngIf=\"(onInput | async)?.length > 0 && (versions$ | async)?.data?.length === 0\"\n                >\n                  <span translate>No match found.</span>\n                </c8y-li>\n              </ng-template>\n            </c8y-typeahead>\n          </c8y-form-group>\n        </div>\n      </ng-container>\n\n      <c8y-loading\n        class=\"text-center d-block\"\n        [message]=\"'Installing\u2026' | translate\"\n        *ngIf=\"inProgress\"\n        layout=\"application\"\n      ></c8y-loading>\n    </div>\n  </ng-container>\n\n  <ng-container *ngIf=\"isDeployed\">\n    <div\n      class=\"d-flex a-i-center j-c-center\"\n      style=\"min-height: 257px\"\n      *ngIf=\"deployedWithSuccess; else failedDeploy\"\n    >\n      <c8y-operation-result\n        class=\"lead\"\n        type=\"success\"\n        text=\"{{ 'Application created' | translate }}\"\n        [size]=\"84\"\n        [vertical]=\"true\"\n      ></c8y-operation-result>\n    </div>\n    <ng-template #failedDeploy>\n      <div\n        class=\"d-flex a-i-center j-c-center\"\n        style=\"min-height: 257px\"\n      >\n        <c8y-operation-result\n          class=\"lead\"\n          type=\"error\"\n          text=\"{{ 'Application creation failed' | translate }}\"\n          [size]=\"84\"\n          [vertical]=\"true\"\n        ></c8y-operation-result>\n      </div>\n    </ng-template>\n  </ng-container>\n</c8y-wizard-body>\n\n<c8y-wizard-footer>\n  <button\n    class=\"btn btn-default\"\n    title=\"{{ 'Back' | translate }}\"\n    type=\"button\"\n    *ngIf=\"!isDeployed\"\n    (click)=\"selectedPackage ? clean() : back()\"\n    [disabled]=\"inProgress\"\n  >\n    {{ 'Back' | translate }}\n  </button>\n  <button\n    class=\"btn btn-default\"\n    title=\"{{ isDeployed && deployedWithSuccess ? ('Close' | translate) : ('Cancel' | translate) }}\"\n    type=\"button\"\n    (click)=\"cancel()\"\n  >\n    {{ isDeployed && deployedWithSuccess ? ('Close' | translate) : ('Cancel' | translate) }}\n  </button>\n\n  <button\n    class=\"btn btn-primary\"\n    title=\"{{ 'Install' | translate }}\"\n    type=\"button\"\n    (click)=\"deployApp()\"\n    [disabled]=\"inProgress || !packages?.length\"\n    *ngIf=\"!isDeployed\"\n  >\n    {{ 'Install' | translate }}\n  </button>\n</c8y-wizard-footer>\n", dependencies: [{ kind: "component", type: WizardHeaderComponent, selector: "c8y-wizard-header" }, { kind: "directive", type: IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "directive", type: C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "component", type: WizardBodyComponent, selector: "c8y-wizard-body" }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: EmptyStateComponent, selector: "c8y-ui-empty-state", inputs: ["icon", "title", "subtitle", "horizontal"] }, { kind: "directive", type: NgFor, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "component", type: ApplicationPropertiesFormComponent, selector: "c8y-application-properties-form", inputs: ["application", "disabled"] }, { kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: FormGroupComponent, selector: "c8y-form-group", inputs: ["hasError", "hasWarning", "hasSuccess", "novalidation", "status"] }, { kind: "component", type: TypeaheadComponent, selector: "c8y-typeahead", inputs: ["required", "maxlength", "disabled", "allowFreeEntries", "placeholder", "displayProperty", "icon", "name", "autoClose", "hideNew", "container", "selected", "highlightFirstItem"], outputs: ["onSearch", "onIconClick"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: ForOfDirective, selector: "[c8yFor]", inputs: ["c8yForOf", "c8yForLoadMore", "c8yForPipe", "c8yForNotFound", "c8yForMaxIterations", "c8yForLoadingTemplate", "c8yForLoadNextLabel", "c8yForLoadingLabel", "c8yForRealtime", "c8yForRealtimeOptions", "c8yForComparator", "c8yForEnableVirtualScroll", "c8yForVirtualScrollElementSize", "c8yForVirtualScrollStrategy", "c8yForVirtualScrollContainerHeight"], outputs: ["c8yForCount", "c8yForChange", "c8yForLoadMoreComponent"] }, { kind: "component", type: ListItemComponent, selector: "c8y-list-item, c8y-li", inputs: ["active", "highlighted", "emptyActions", "dense", "collapsed", "selectable"], outputs: ["collapsedChange"] }, { kind: "component", type: ListItemIconComponent, selector: "c8y-list-item-icon, c8y-li-icon", inputs: ["icon", "status"] }, { kind: "component", type: HighlightComponent, selector: "c8y-highlight", inputs: ["pattern", "text", "elementClass", "shouldTrimPattern"] }, { kind: "component", type: LoadingComponent, selector: "c8y-loading", inputs: ["layout", "progress", "message"] }, { kind: "component", type: OperationResultComponent, selector: "c8y-operation-result", inputs: ["text", "vertical", "size", "type"] }, { kind: "component", type: WizardFooterComponent, selector: "c8y-wizard-footer" }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }, { kind: "pipe", type: AsyncPipe, name: "async" }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: InstallFromPackageComponent, decorators: [{
            type: Component,
            args: [{ selector: 'c8y-install-from-package', imports: [
                        WizardHeaderComponent,
                        IconDirective,
                        C8yTranslateDirective,
                        WizardBodyComponent,
                        NgIf,
                        EmptyStateComponent,
                        NgFor,
                        ApplicationPropertiesFormComponent,
                        NgStyle,
                        FormGroupComponent,
                        TypeaheadComponent,
                        FormsModule,
                        ForOfDirective,
                        ListItemComponent,
                        ListItemIconComponent,
                        HighlightComponent,
                        LoadingComponent,
                        OperationResultComponent,
                        WizardFooterComponent,
                        C8yTranslatePipe,
                        AsyncPipe
                    ], template: "<c8y-wizard-header>\n  <i [c8yIcon]=\"'big-parcel'\"></i>\n  <h4\n    id=\"modal-title\"\n    translate\n  >\n    Install from extension package\n  </h4>\n</c8y-wizard-header>\n<c8y-wizard-body>\n  <ng-container *ngIf=\"!selectedPackage\">\n    <div\n      class=\"modal-inner-scroll\"\n      id=\"modal-body\"\n    >\n      <p class=\"p-16 text-medium text-center separator-bottom sticky-top bg-level-0\">\n        {{ 'Select from available extension packages' | translate }}\n      </p>\n\n      <c8y-ui-empty-state\n        [icon]=\"'big-parcel'\"\n        [title]=\"'No extension packages to display.' | translate\"\n        *ngIf=\"!packages?.length\"\n        [horizontal]=\"true\"\n      ></c8y-ui-empty-state>\n\n      <div\n        class=\"c8y-wizard-list-nav\"\n        style=\"min-height: 257px\"\n        *ngIf=\"packages?.length\"\n      >\n        <button\n          class=\"list-group-item text-truncate bg-component\"\n          title=\"{{ package.name }}\"\n          type=\"button\"\n          *ngFor=\"let package of packages\"\n          (click)=\"selectPackage(package)\"\n        >\n          <i\n            class=\"list-group-icon\"\n            c8yIcon=\"big-parcel\"\n          ></i>\n          <span [innerText]=\"package.name\"></span>\n        </button>\n      </div>\n    </div>\n  </ng-container>\n  <ng-container *ngIf=\"!isDeployed && selectedPackage\">\n    <p class=\"p-16 text-center text-medium separator-bottom sticky-top bg-level-0\">\n      {{ 'Provide application details' | translate }}\n    </p>\n    <div\n      class=\"d-flex d-col a-i-center j-c-center\"\n      style=\"min-height: 257px\"\n    >\n      <c8y-application-properties-form\n        class=\"d-block fit-w\"\n        *ngIf=\"!inProgress\"\n        [application]=\"newAppConfig\"\n      ></c8y-application-properties-form>\n\n      <ng-container *ngIf=\"!inProgress\">\n        <div\n          class=\"d-block fit-w bg-gray-white\"\n          [ngStyle]=\"{ padding: '0 16px' }\"\n        >\n          <label\n            for=\"packageVersion\"\n            translate\n          >\n            Use extension package version\n          </label>\n          <c8y-form-group>\n            <c8y-typeahead\n              placeholder=\"{{ 'Select or enter' | translate }}\"\n              name=\"packageVersion\"\n              [(ngModel)]=\"model.selected\"\n              (onSearch)=\"onInput.next($event)\"\n              [displayProperty]=\"'version'\"\n              [required]=\"true\"\n              [hideNew]=\"true\"\n              [container]=\"'body'\"\n            >\n              <c8y-li\n                class=\"p-l-8 p-r-8 c8y-list__item--link\"\n                *c8yFor=\"let version of versions$; loadMore: 'auto'; notFound: notFoundTemplate\"\n                (click)=\"onAppVersionSelect(version)\"\n                [active]=\"model.selected === version\"\n              >\n                <c8y-li-icon icon=\"big-parcel\"></c8y-li-icon>\n                <span\n                  [ngStyle]=\"{\n                    display: 'flex',\n                    'flex-direction': 'row',\n                    'align-content': 'center',\n                    'justify-content': 'space-between',\n                    'align-items': 'center'\n                  }\"\n                >\n                  <c8y-highlight\n                    [text]=\"version.version || '--'\"\n                    [pattern]=\"onInput | async\"\n                  ></c8y-highlight>\n\n                  <span>\n                    <span\n                      class=\"label label-info m-l-4\"\n                      *ngFor=\"let tag of version.tags\"\n                    >\n                      {{ tag }}\n                    </span>\n                  </span>\n                </span>\n              </c8y-li>\n              <ng-template #notFoundTemplate>\n                <c8y-li\n                  class=\"bg-gray-lighter p-8\"\n                  *ngIf=\"(onInput | async)?.length > 0 && (versions$ | async)?.data?.length === 0\"\n                >\n                  <span translate>No match found.</span>\n                </c8y-li>\n              </ng-template>\n            </c8y-typeahead>\n          </c8y-form-group>\n        </div>\n      </ng-container>\n\n      <c8y-loading\n        class=\"text-center d-block\"\n        [message]=\"'Installing\u2026' | translate\"\n        *ngIf=\"inProgress\"\n        layout=\"application\"\n      ></c8y-loading>\n    </div>\n  </ng-container>\n\n  <ng-container *ngIf=\"isDeployed\">\n    <div\n      class=\"d-flex a-i-center j-c-center\"\n      style=\"min-height: 257px\"\n      *ngIf=\"deployedWithSuccess; else failedDeploy\"\n    >\n      <c8y-operation-result\n        class=\"lead\"\n        type=\"success\"\n        text=\"{{ 'Application created' | translate }}\"\n        [size]=\"84\"\n        [vertical]=\"true\"\n      ></c8y-operation-result>\n    </div>\n    <ng-template #failedDeploy>\n      <div\n        class=\"d-flex a-i-center j-c-center\"\n        style=\"min-height: 257px\"\n      >\n        <c8y-operation-result\n          class=\"lead\"\n          type=\"error\"\n          text=\"{{ 'Application creation failed' | translate }}\"\n          [size]=\"84\"\n          [vertical]=\"true\"\n        ></c8y-operation-result>\n      </div>\n    </ng-template>\n  </ng-container>\n</c8y-wizard-body>\n\n<c8y-wizard-footer>\n  <button\n    class=\"btn btn-default\"\n    title=\"{{ 'Back' | translate }}\"\n    type=\"button\"\n    *ngIf=\"!isDeployed\"\n    (click)=\"selectedPackage ? clean() : back()\"\n    [disabled]=\"inProgress\"\n  >\n    {{ 'Back' | translate }}\n  </button>\n  <button\n    class=\"btn btn-default\"\n    title=\"{{ isDeployed && deployedWithSuccess ? ('Close' | translate) : ('Cancel' | translate) }}\"\n    type=\"button\"\n    (click)=\"cancel()\"\n  >\n    {{ isDeployed && deployedWithSuccess ? ('Close' | translate) : ('Cancel' | translate) }}\n  </button>\n\n  <button\n    class=\"btn btn-primary\"\n    title=\"{{ 'Install' | translate }}\"\n    type=\"button\"\n    (click)=\"deployApp()\"\n    [disabled]=\"inProgress || !packages?.length\"\n    *ngIf=\"!isDeployed\"\n  >\n    {{ 'Install' | translate }}\n  </button>\n</c8y-wizard-footer>\n" }]
        }], ctorParameters: () => [{ type: i1.EcosystemService }, { type: i4.ApplicationService }, { type: i2.WizardComponent }, { type: i2.PluginsService }], propDecorators: { applicationPropertiesForm: [{
                type: ViewChild,
                args: [ApplicationPropertiesFormComponent]
            }] } });

class EcosystemTabs {
    constructor(router) {
        this.router = router;
        this.ecosystemTabs = [
            {
                icon: 'c8y-modules',
                priority: 1000,
                label: gettext('Applications'),
                path: 'ecosystem/application/applications'
            },
            {
                icon: 'tab',
                priority: 998,
                label: gettext('Features'),
                path: 'ecosystem/application/features'
            }
        ];
    }
    get() {
        if (this.router.url === '/ecosystem/application/applications' ||
            this.router.url === '/ecosystem/application/features') {
            return this.ecosystemTabs;
        }
        return [];
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: EcosystemTabs, deps: [{ token: i1$2.Router }], target: i0.ɵɵFactoryTarget.Injectable }); }
    static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: EcosystemTabs }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: EcosystemTabs, decorators: [{
            type: Injectable
        }], ctorParameters: () => [{ type: i1$2.Router }] });

class FeatureListComponent {
    constructor(ecosystemService) {
        this.ecosystemService = ecosystemService;
        this.reloading = false;
        this.reload$ = new BehaviorSubject(null);
        this.features$ = this.reload$.pipe(tap(() => (this.reloading = true)), switchMap(() => this.ecosystemService.getFeatureApplications()), tap(() => (this.reloading = false)), shareReplay());
    }
    ngOnInit() {
        this.loadFeatures();
    }
    loadFeatures() {
        this.reload$.next();
    }
    setFilterPipe(pipe) {
        this.filteredFeatures$ = this.features$.pipe(src => pipe(src));
    }
    resetFilters() {
        this.filtersComponent?.resetAllFilters();
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: FeatureListComponent, deps: [{ token: i1.EcosystemService }], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.14", type: FeatureListComponent, isStandalone: true, selector: "c8y-feature-list", viewQueries: [{ propertyName: "filtersComponent", first: true, predicate: ListFiltersComponent, descendants: true }], ngImport: i0, template: "<c8y-title>{{ 'Features' | translate }}</c8y-title>\n\n<c8y-breadcrumb>\n  <c8y-breadcrumb-item [icon]=\"'c8y-atom'\" [label]=\"'Ecosystem' | translate\"></c8y-breadcrumb-item>\n  <c8y-breadcrumb-item\n    [icon]=\"'c8y-modules'\"\n    [label]=\"'Applications' | translate\"\n    [path]=\"'ecosystem/application/applications'\"\n  ></c8y-breadcrumb-item>\n  <c8y-breadcrumb-item [icon]=\"'tab'\" [label]=\"'Features' | translate\"></c8y-breadcrumb-item>\n</c8y-breadcrumb>\n\n<c8y-action-bar-item [placement]=\"'right'\">\n  <button (click)=\"reload$.next()\" class=\"btn btn-link\" title=\"{{ 'Reload' | translate }}\">\n    <i [ngClass]=\"{ 'icon-spin': reloading }\" c8yIcon=\"refresh\"></i>\n    {{ 'Reload' | translate }}\n  </button>\n</c8y-action-bar-item>\n\n<c8y-action-bar-item [placement]=\"'left'\">\n  <c8y-list-filters\n    *ngIf=\"features$ | async\"\n    (filterPipeChange)=\"setFilterPipe($event)\"\n  ></c8y-list-filters>\n</c8y-action-bar-item>\n\n<c8y-action-bar-item [placement]=\"'left'\" itemClass=\"navbar-form hidden-xs\">\n  <c8y-list-display-switch\n    (onListClassChange)=\"listClass = $event\"\n    [listLength]=\"(features$ | async)?.length\"\n  ></c8y-list-display-switch>\n</c8y-action-bar-item>\n\n<div *ngIf=\"(features$ | async)?.length === 0\" class=\"c8y-empty-state text-center\">\n  <h1 class=\"c8y-icon c8y-icon-modules c8y-icon-duocolor\"></h1>\n  <h3 translate>No features to display.</h3>\n  <p translate>No additional features are subscribed to the tenant.</p>\n</div>\n\n<div [ngClass]=\"listClass\" class=\"card-group\">\n  <div class=\"page-sticky-header hidden-xs d-flex\" *ngIf=\"(features$ | async)?.length > 0\">\n    <div class=\"card-block card-column-40\">\n      <div class=\"card-appicon p-l-32 p-r-16 m-r-0 m-l-4\"></div>\n      {{ 'Feature' | translate }}\n    </div>\n    <div class=\"card-block p-0 card-column-80\">\n      <div class=\"card-block card-column-80\">{{ 'Description' | translate }}</div>\n      <div class=\"card-block card-column-20\">{{ 'Type' | translate }}</div>\n    </div>\n  </div>\n  <div *ngFor=\"let feature of filteredFeatures$ | async\" class=\"col-xs-12 col-sm-4 col-md-3\">\n    <c8y-application-card\n      [app]=\"feature\"\n      [canEdit]=\"false\"\n      class=\"d-contents\"\n    ></c8y-application-card>\n  </div>\n</div>\n\n<c8y-ui-empty-state\n  *ngIf=\"(features$ | async)?.length > 0 && (filteredFeatures$ | async)?.length === 0\"\n  [icon]=\"'search'\"\n  [title]=\"'No matching features.' | translate\"\n  [subtitle]=\"'Refine your search terms and/or the filters' | translate\"\n>\n  <button\n    class=\"btn btn-primary\"\n    type=\"button\"\n    title=\"{{ 'Reset filters' | translate }}\"\n    (click)=\"resetFilters()\"\n  >\n    {{ 'Reset filters' | translate }}\n  </button>\n</c8y-ui-empty-state>\n", dependencies: [{ kind: "component", type: TitleComponent, selector: "c8y-title", inputs: ["pageTitleUpdate"] }, { kind: "component", type: BreadcrumbComponent, selector: "c8y-breadcrumb" }, { kind: "component", type: BreadcrumbItemComponent, selector: "c8y-breadcrumb-item", inputs: ["icon", "translate", "label", "path", "injector"] }, { kind: "component", type: ActionBarItemComponent, selector: "c8y-action-bar-item", inputs: ["placement", "priority", "itemClass", "injector", "groupId", "inGroupPriority"] }, { kind: "directive", type: IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: ListFiltersComponent, selector: "c8y-list-filters", inputs: ["packageTypes", "packageAvailabilities", "packageContents"], outputs: ["filterPipeChange"] }, { kind: "component", type: ListDisplaySwitchComponent, selector: "c8y-list-display-switch", inputs: ["listKey", "listLength", "filterPipe"], outputs: ["onListClassChange"] }, { kind: "directive", type: C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "directive", type: NgFor, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "component", type: ApplicationCardComponent, selector: "c8y-application-card", inputs: ["app", "canEdit"], outputs: ["onAppDeleted", "onAppCloned"] }, { kind: "component", type: EmptyStateComponent, selector: "c8y-ui-empty-state", inputs: ["icon", "title", "subtitle", "horizontal"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }, { kind: "pipe", type: AsyncPipe, name: "async" }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: FeatureListComponent, decorators: [{
            type: Component,
            args: [{ selector: 'c8y-feature-list', imports: [
                        TitleComponent,
                        BreadcrumbComponent,
                        BreadcrumbItemComponent,
                        ActionBarItemComponent,
                        IconDirective,
                        NgClass,
                        NgIf,
                        ListFiltersComponent,
                        ListDisplaySwitchComponent,
                        C8yTranslateDirective,
                        NgFor,
                        ApplicationCardComponent,
                        EmptyStateComponent,
                        C8yTranslatePipe,
                        AsyncPipe
                    ], template: "<c8y-title>{{ 'Features' | translate }}</c8y-title>\n\n<c8y-breadcrumb>\n  <c8y-breadcrumb-item [icon]=\"'c8y-atom'\" [label]=\"'Ecosystem' | translate\"></c8y-breadcrumb-item>\n  <c8y-breadcrumb-item\n    [icon]=\"'c8y-modules'\"\n    [label]=\"'Applications' | translate\"\n    [path]=\"'ecosystem/application/applications'\"\n  ></c8y-breadcrumb-item>\n  <c8y-breadcrumb-item [icon]=\"'tab'\" [label]=\"'Features' | translate\"></c8y-breadcrumb-item>\n</c8y-breadcrumb>\n\n<c8y-action-bar-item [placement]=\"'right'\">\n  <button (click)=\"reload$.next()\" class=\"btn btn-link\" title=\"{{ 'Reload' | translate }}\">\n    <i [ngClass]=\"{ 'icon-spin': reloading }\" c8yIcon=\"refresh\"></i>\n    {{ 'Reload' | translate }}\n  </button>\n</c8y-action-bar-item>\n\n<c8y-action-bar-item [placement]=\"'left'\">\n  <c8y-list-filters\n    *ngIf=\"features$ | async\"\n    (filterPipeChange)=\"setFilterPipe($event)\"\n  ></c8y-list-filters>\n</c8y-action-bar-item>\n\n<c8y-action-bar-item [placement]=\"'left'\" itemClass=\"navbar-form hidden-xs\">\n  <c8y-list-display-switch\n    (onListClassChange)=\"listClass = $event\"\n    [listLength]=\"(features$ | async)?.length\"\n  ></c8y-list-display-switch>\n</c8y-action-bar-item>\n\n<div *ngIf=\"(features$ | async)?.length === 0\" class=\"c8y-empty-state text-center\">\n  <h1 class=\"c8y-icon c8y-icon-modules c8y-icon-duocolor\"></h1>\n  <h3 translate>No features to display.</h3>\n  <p translate>No additional features are subscribed to the tenant.</p>\n</div>\n\n<div [ngClass]=\"listClass\" class=\"card-group\">\n  <div class=\"page-sticky-header hidden-xs d-flex\" *ngIf=\"(features$ | async)?.length > 0\">\n    <div class=\"card-block card-column-40\">\n      <div class=\"card-appicon p-l-32 p-r-16 m-r-0 m-l-4\"></div>\n      {{ 'Feature' | translate }}\n    </div>\n    <div class=\"card-block p-0 card-column-80\">\n      <div class=\"card-block card-column-80\">{{ 'Description' | translate }}</div>\n      <div class=\"card-block card-column-20\">{{ 'Type' | translate }}</div>\n    </div>\n  </div>\n  <div *ngFor=\"let feature of filteredFeatures$ | async\" class=\"col-xs-12 col-sm-4 col-md-3\">\n    <c8y-application-card\n      [app]=\"feature\"\n      [canEdit]=\"false\"\n      class=\"d-contents\"\n    ></c8y-application-card>\n  </div>\n</div>\n\n<c8y-ui-empty-state\n  *ngIf=\"(features$ | async)?.length > 0 && (filteredFeatures$ | async)?.length === 0\"\n  [icon]=\"'search'\"\n  [title]=\"'No matching features.' | translate\"\n  [subtitle]=\"'Refine your search terms and/or the filters' | translate\"\n>\n  <button\n    class=\"btn btn-primary\"\n    type=\"button\"\n    title=\"{{ 'Reset filters' | translate }}\"\n    (click)=\"resetFilters()\"\n  >\n    {{ 'Reset filters' | translate }}\n  </button>\n</c8y-ui-empty-state>\n" }]
        }], ctorParameters: () => [{ type: i1.EcosystemService }], propDecorators: { filtersComponent: [{
                type: ViewChild,
                args: [ListFiltersComponent]
            }] } });

class AddMicroserviceComponent {
    constructor(ecosystemService, modal, tenantService, docs) {
        this.ecosystemService = ecosystemService;
        this.modal = modal;
        this.tenantService = tenantService;
        this.docs = docs;
        this.slaHref = this.docs.getUserGuideLink('docs/service-terms/service-level/#microservices-sla');
        this.headerText = gettext('Add microservice');
        this.successText = gettext('Microservice created');
        this.createMicroserviceApplicationHandler = (f) => this.createMicroserviceApplication(f);
        this.uploadMicroserviceHandler = (f, app) => this.uploadMicroservice(f, app);
    }
    async createMicroserviceApplication(file) {
        await this.ecosystemService.isValidAppType(file, ApplicationType.MICROSERVICE);
        return this.ecosystemService.createAppForArchive(file);
    }
    async uploadMicroservice(file, microservice) {
        const subscribeToCurrentTenant = await this.askIfActivationAfterUploadNeeded();
        await this.ecosystemService.uploadArchiveToApp(file, microservice);
        await this.subscribeMicroservice(microservice, subscribeToCurrentTenant);
    }
    async askIfActivationAfterUploadNeeded() {
        try {
            await this.modal.confirm(gettext('Subscribe to microservice'), gettext('You are about to subscribe to the microservice after upload. Do you want to subscribe to it?'), Status.INFO, { ok: gettext('Subscribe'), cancel: gettext("Don't subscribe") });
            return true;
        }
        catch (ex) {
            return false;
        }
    }
    async subscribeMicroservice(app, subscribeToCurrentTenant) {
        const tenant = (await this.tenantService.current()).data;
        const applications = tenant.applications.references;
        const isSubscribed = applications.some(({ application }) => application.id === app.id);
        if (!isSubscribed && subscribeToCurrentTenant) {
            try {
                return await this.tenantService.subscribeApplication(tenant, app);
            }
            catch (res) {
                if (res.status === 409) {
                    throw Error(ERROR_TYPE.ALREADY_SUBSCRIBED);
                }
            }
        }
        else if (isSubscribed && !subscribeToCurrentTenant) {
            return this.tenantService.unsubscribeApplication(tenant, app);
        }
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: AddMicroserviceComponent, deps: [{ token: i1.EcosystemService }, { token: i2.ModalService }, { token: i4.TenantService }, { token: i2.DocsService }], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.14", type: AddMicroserviceComponent, isStandalone: true, selector: "c8y-add-microservice", ngImport: i0, template: `<div class="p-16" translate [translateParams]="{ slaHref: slaHref }" ngNonBindable>
      By uploading a microservice, you agree to the
      <a href="{{ slaHref }}" target="_blank" rel="noopener noreferrer"
        >Microservice Deployment SLA</a
      >
      which outlines our microservices hosting terms, conditions, and performance standards.
    </div>
    <c8y-add-application
      [headerIcon]="'microchip'"
      [headerText]="headerText"
      [successText]="successText"
      [createApplicationHandler]="createMicroserviceApplicationHandler"
      [uploadApplicationHandler]="uploadMicroserviceHandler"
    ></c8y-add-application>`, isInline: true, dependencies: [{ kind: "directive", type: C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "component", type: AddApplicationComponent, selector: "c8y-add-application", inputs: ["headerText", "headerIcon", "successText", "createApplicationHandler", "uploadApplicationHandler", "canGoBack", "applicationType"] }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: AddMicroserviceComponent, decorators: [{
            type: Component,
            args: [{
                    selector: 'c8y-add-microservice',
                    template: `<div class="p-16" translate [translateParams]="{ slaHref: slaHref }" ngNonBindable>
      By uploading a microservice, you agree to the
      <a href="{{ slaHref }}" target="_blank" rel="noopener noreferrer"
        >Microservice Deployment SLA</a
      >
      which outlines our microservices hosting terms, conditions, and performance standards.
    </div>
    <c8y-add-application
      [headerIcon]="'microchip'"
      [headerText]="headerText"
      [successText]="successText"
      [createApplicationHandler]="createMicroserviceApplicationHandler"
      [uploadApplicationHandler]="uploadMicroserviceHandler"
    ></c8y-add-application>`,
                    imports: [C8yTranslateDirective, AddApplicationComponent]
                }]
        }], ctorParameters: () => [{ type: i1.EcosystemService }, { type: i2.ModalService }, { type: i4.TenantService }, { type: i2.DocsService }] });

class MicroserviceListComponent {
    constructor(ecosystemService, wizardModalService, cd) {
        this.ecosystemService = ecosystemService;
        this.wizardModalService = wizardModalService;
        this.cd = cd;
        this.reloading = false;
        this.reload$ = new BehaviorSubject(null);
        this.microservices$ = this.reload$.pipe(tap(() => (this.reloading = true)), switchMap(() => this.ecosystemService.getMicroservices()), tap(microservices => {
            microservices.forEach(microservice => {
                microservice.filterProps = this.ecosystemService.getAppFilterProps(microservice);
            });
        }), tap(() => (this.reloading = false)), shareReplay());
        this.isMicroserviceHostingAllowed$ = this.reload$.pipe(switchMap(() => this.ecosystemService.isMicroserviceHostingAllowed()), shareReplay());
        this.packageAvailabilities = [
            APP_STATE.SUBSCRIBED.label,
            APP_STATE.CUSTOM.label
        ];
    }
    ngOnInit() {
        this.loadMicroservices();
        // manually trigger detection to not have ExpressionChangedAfterItHasBeenChecked error in spec file
        this.cd.detectChanges();
    }
    loadMicroservices() {
        this.reload$.next();
    }
    addMicroservice() {
        const initialState = {
            id: EcosystemWizards.MICROSERVICE_UPLOAD
        };
        const modalOptions = { initialState };
        const modalRef = this.wizardModalService.show(modalOptions);
        modalRef.content.onClose.subscribe(() => {
            this.loadMicroservices();
        });
    }
    setFilterPipe(pipe) {
        this.filteredMicroservices$ = this.microservices$.pipe(src => pipe(src));
    }
    resetFilters() {
        this.filtersComponent?.resetAllFilters();
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: MicroserviceListComponent, deps: [{ token: i1.EcosystemService }, { token: i2.WizardModalService }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.14", type: MicroserviceListComponent, isStandalone: true, selector: "c8y-microservice-list", viewQueries: [{ propertyName: "filtersComponent", first: true, predicate: ListFiltersComponent, descendants: true }], ngImport: i0, template: "<c8y-title>{{ 'Microservices' | translate }}</c8y-title>\n\n<c8y-breadcrumb>\n  <c8y-breadcrumb-item\n    [icon]=\"'c8y-atom'\"\n    [label]=\"'Ecosystem' | translate\"\n  ></c8y-breadcrumb-item>\n  <c8y-breadcrumb-item\n    [icon]=\"'microchip'\"\n    [label]=\"'Microservices' | translate\"\n    [path]=\"'ecosystem/microservice/microservices'\"\n  ></c8y-breadcrumb-item>\n</c8y-breadcrumb>\n\n<ng-container *c8yIfAllowed=\"['ROLE_APPLICATION_MANAGEMENT_ADMIN']\">\n  <c8y-action-bar-item\n    [placement]=\"'right'\"\n    [priority]=\"100\"\n    *ngIf=\"isMicroserviceHostingAllowed$ | async\"\n  >\n    <button\n      class=\"btn btn-link\"\n      title=\"{{ 'Add microservice' | translate }}\"\n      (click)=\"addMicroservice()\"\n    >\n      <i c8yIcon=\"plus-circle\"></i>\n      {{ 'Add microservice' | translate }}\n    </button>\n  </c8y-action-bar-item>\n</ng-container>\n\n<c8y-help src=\"/docs/standard-tenant/ecosystem/#managing-microservices\"></c8y-help>\n\n<c8y-action-bar-item [placement]=\"'right'\">\n  <button\n    class=\"btn btn-link\"\n    title=\"{{ 'Reload' | translate }}\"\n    (click)=\"reload$.next()\"\n  >\n    <i\n      c8yIcon=\"refresh\"\n      [ngClass]=\"{ 'icon-spin': reloading }\"\n    ></i>\n    {{ 'Reload' | translate }}\n  </button>\n</c8y-action-bar-item>\n\n<c8y-action-bar-item [placement]=\"'left'\">\n  <c8y-list-filters\n    *ngIf=\"microservices$ | async\"\n    (filterPipeChange)=\"setFilterPipe($event)\"\n    [packageAvailabilities]=\"packageAvailabilities\"\n  ></c8y-list-filters>\n</c8y-action-bar-item>\n\n<c8y-action-bar-item\n  [placement]=\"'left'\"\n  itemClass=\"navbar-form hidden-xs\"\n>\n  <c8y-list-display-switch\n    (onListClassChange)=\"listClass = $event\"\n    [listLength]=\"(microservices$ | async)?.length\"\n  ></c8y-list-display-switch>\n</c8y-action-bar-item>\n\n<div\n  class=\"c8y-empty-state text-center\"\n  *ngIf=\"(microservices$ | async)?.length === 0\"\n>\n  <h1 class=\"c8y-icon c8y-icon-modules c8y-icon-duocolor\"></h1>\n  <h3 translate>No microservices to display.</h3>\n  <p translate>Add your first microservice by clicking below.</p>\n  <p>\n    <button\n      class=\"btn btn-primary\"\n      title=\"{{ 'Add microservice' | translate }}\"\n      (click)=\"addMicroservice()\"\n    >\n      {{ 'Add microservice' | translate }}\n    </button>\n  </p>\n</div>\n\n<div\n  class=\"card-group\"\n  [ngClass]=\"listClass\"\n>\n  <div\n    class=\"page-sticky-header hidden-xs d-flex\"\n    *ngIf=\"(microservices$ | async)?.length > 0\"\n  >\n    <div class=\"card-block card-column-40\">\n      <div class=\"card-appicon p-l-32 p-r-16 m-r-0 m-l-4\"></div>\n      {{ 'Microservice' | translate }}\n    </div>\n    <div class=\"card-block p-0 card-column-80 m-r-40\">\n      <div class=\"card-block card-column-80\">{{ 'Description' | translate }}</div>\n      <div class=\"card-block card-column-20\">{{ 'Type' | translate }}</div>\n      <div class=\"card-block card-column-20\"></div>\n    </div>\n  </div>\n  <div\n    class=\"col-xs-12 col-sm-4 col-md-3\"\n    *ngFor=\"let microservice of filteredMicroservices$ | async\"\n  >\n    <c8y-application-card\n      class=\"d-contents\"\n      (onAppDeleted)=\"loadMicroservices()\"\n      [app]=\"microservice\"\n    ></c8y-application-card>\n  </div>\n</div>\n\n<c8y-ui-empty-state\n  [icon]=\"'search'\"\n  [title]=\"'No matching microservices.' | translate\"\n  [subtitle]=\"'Refine your search terms and/or the filters' | translate\"\n  *ngIf=\"(microservices$ | async)?.length > 0 && (filteredMicroservices$ | async)?.length === 0\"\n>\n  <button\n    class=\"btn btn-primary\"\n    title=\"{{ 'Reset filters' | translate }}\"\n    type=\"button\"\n    (click)=\"resetFilters()\"\n  >\n    {{ 'Reset filters' | translate }}\n  </button>\n</c8y-ui-empty-state>\n", dependencies: [{ kind: "component", type: TitleComponent, selector: "c8y-title", inputs: ["pageTitleUpdate"] }, { kind: "component", type: BreadcrumbComponent, selector: "c8y-breadcrumb" }, { kind: "component", type: BreadcrumbItemComponent, selector: "c8y-breadcrumb-item", inputs: ["icon", "translate", "label", "path", "injector"] }, { kind: "directive", type: IfAllowedDirective, selector: "[c8yIfAllowed]", inputs: ["c8yIfAllowed", "c8yIfAllowedAllowAny"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: ActionBarItemComponent, selector: "c8y-action-bar-item", inputs: ["placement", "priority", "itemClass", "injector", "groupId", "inGroupPriority"] }, { kind: "directive", type: IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "component", type: HelpComponent, selector: "c8y-help", inputs: ["src", "isCollapsed", "priority", "icon"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: ListFiltersComponent, selector: "c8y-list-filters", inputs: ["packageTypes", "packageAvailabilities", "packageContents"], outputs: ["filterPipeChange"] }, { kind: "component", type: ListDisplaySwitchComponent, selector: "c8y-list-display-switch", inputs: ["listKey", "listLength", "filterPipe"], outputs: ["onListClassChange"] }, { kind: "directive", type: C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "directive", type: NgFor, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "component", type: ApplicationCardComponent, selector: "c8y-application-card", inputs: ["app", "canEdit"], outputs: ["onAppDeleted", "onAppCloned"] }, { kind: "component", type: EmptyStateComponent, selector: "c8y-ui-empty-state", inputs: ["icon", "title", "subtitle", "horizontal"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }, { kind: "pipe", type: AsyncPipe, name: "async" }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: MicroserviceListComponent, decorators: [{
            type: Component,
            args: [{ selector: 'c8y-microservice-list', imports: [
                        TitleComponent,
                        BreadcrumbComponent,
                        BreadcrumbItemComponent,
                        IfAllowedDirective,
                        NgIf,
                        ActionBarItemComponent,
                        IconDirective,
                        HelpComponent,
                        NgClass,
                        ListFiltersComponent,
                        ListDisplaySwitchComponent,
                        C8yTranslateDirective,
                        NgFor,
                        ApplicationCardComponent,
                        EmptyStateComponent,
                        C8yTranslatePipe,
                        AsyncPipe
                    ], template: "<c8y-title>{{ 'Microservices' | translate }}</c8y-title>\n\n<c8y-breadcrumb>\n  <c8y-breadcrumb-item\n    [icon]=\"'c8y-atom'\"\n    [label]=\"'Ecosystem' | translate\"\n  ></c8y-breadcrumb-item>\n  <c8y-breadcrumb-item\n    [icon]=\"'microchip'\"\n    [label]=\"'Microservices' | translate\"\n    [path]=\"'ecosystem/microservice/microservices'\"\n  ></c8y-breadcrumb-item>\n</c8y-breadcrumb>\n\n<ng-container *c8yIfAllowed=\"['ROLE_APPLICATION_MANAGEMENT_ADMIN']\">\n  <c8y-action-bar-item\n    [placement]=\"'right'\"\n    [priority]=\"100\"\n    *ngIf=\"isMicroserviceHostingAllowed$ | async\"\n  >\n    <button\n      class=\"btn btn-link\"\n      title=\"{{ 'Add microservice' | translate }}\"\n      (click)=\"addMicroservice()\"\n    >\n      <i c8yIcon=\"plus-circle\"></i>\n      {{ 'Add microservice' | translate }}\n    </button>\n  </c8y-action-bar-item>\n</ng-container>\n\n<c8y-help src=\"/docs/standard-tenant/ecosystem/#managing-microservices\"></c8y-help>\n\n<c8y-action-bar-item [placement]=\"'right'\">\n  <button\n    class=\"btn btn-link\"\n    title=\"{{ 'Reload' | translate }}\"\n    (click)=\"reload$.next()\"\n  >\n    <i\n      c8yIcon=\"refresh\"\n      [ngClass]=\"{ 'icon-spin': reloading }\"\n    ></i>\n    {{ 'Reload' | translate }}\n  </button>\n</c8y-action-bar-item>\n\n<c8y-action-bar-item [placement]=\"'left'\">\n  <c8y-list-filters\n    *ngIf=\"microservices$ | async\"\n    (filterPipeChange)=\"setFilterPipe($event)\"\n    [packageAvailabilities]=\"packageAvailabilities\"\n  ></c8y-list-filters>\n</c8y-action-bar-item>\n\n<c8y-action-bar-item\n  [placement]=\"'left'\"\n  itemClass=\"navbar-form hidden-xs\"\n>\n  <c8y-list-display-switch\n    (onListClassChange)=\"listClass = $event\"\n    [listLength]=\"(microservices$ | async)?.length\"\n  ></c8y-list-display-switch>\n</c8y-action-bar-item>\n\n<div\n  class=\"c8y-empty-state text-center\"\n  *ngIf=\"(microservices$ | async)?.length === 0\"\n>\n  <h1 class=\"c8y-icon c8y-icon-modules c8y-icon-duocolor\"></h1>\n  <h3 translate>No microservices to display.</h3>\n  <p translate>Add your first microservice by clicking below.</p>\n  <p>\n    <button\n      class=\"btn btn-primary\"\n      title=\"{{ 'Add microservice' | translate }}\"\n      (click)=\"addMicroservice()\"\n    >\n      {{ 'Add microservice' | translate }}\n    </button>\n  </p>\n</div>\n\n<div\n  class=\"card-group\"\n  [ngClass]=\"listClass\"\n>\n  <div\n    class=\"page-sticky-header hidden-xs d-flex\"\n    *ngIf=\"(microservices$ | async)?.length > 0\"\n  >\n    <div class=\"card-block card-column-40\">\n      <div class=\"card-appicon p-l-32 p-r-16 m-r-0 m-l-4\"></div>\n      {{ 'Microservice' | translate }}\n    </div>\n    <div class=\"card-block p-0 card-column-80 m-r-40\">\n      <div class=\"card-block card-column-80\">{{ 'Description' | translate }}</div>\n      <div class=\"card-block card-column-20\">{{ 'Type' | translate }}</div>\n      <div class=\"card-block card-column-20\"></div>\n    </div>\n  </div>\n  <div\n    class=\"col-xs-12 col-sm-4 col-md-3\"\n    *ngFor=\"let microservice of filteredMicroservices$ | async\"\n  >\n    <c8y-application-card\n      class=\"d-contents\"\n      (onAppDeleted)=\"loadMicroservices()\"\n      [app]=\"microservice\"\n    ></c8y-application-card>\n  </div>\n</div>\n\n<c8y-ui-empty-state\n  [icon]=\"'search'\"\n  [title]=\"'No matching microservices.' | translate\"\n  [subtitle]=\"'Refine your search terms and/or the filters' | translate\"\n  *ngIf=\"(microservices$ | async)?.length > 0 && (filteredMicroservices$ | async)?.length === 0\"\n>\n  <button\n    class=\"btn btn-primary\"\n    title=\"{{ 'Reset filters' | translate }}\"\n    type=\"button\"\n    (click)=\"resetFilters()\"\n  >\n    {{ 'Reset filters' | translate }}\n  </button>\n</c8y-ui-empty-state>\n" }]
        }], ctorParameters: () => [{ type: i1.EcosystemService }, { type: i2.WizardModalService }, { type: i0.ChangeDetectorRef }], propDecorators: { filtersComponent: [{
                type: ViewChild,
                args: [ListFiltersComponent]
            }] } });

class AddPackageComponent {
    constructor(ecosystemService) {
        this.ecosystemService = ecosystemService;
        this.headerText = gettext('Add extension package');
        this.successText = gettext('Extension package created');
        this.createPackageAppHandler = (f) => this.createPackageApp(f);
        this.uploadPackageHandler = (f, app) => this.uploadPackage(f, app);
    }
    async createPackageApp(file) {
        await this.ecosystemService.isValidAppType(file, ApplicationType.HOSTED);
        return await this.ecosystemService.createAppForArchive(file, true);
    }
    uploadPackage(file, pckg) {
        return this.ecosystemService.uploadArchiveToApp(file, pckg, true);
    }
    next() {
        this.stepper.next();
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: AddPackageComponent, deps: [{ token: i1.EcosystemService }], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.14", type: AddPackageComponent, isStandalone: true, selector: "c8y-add-package", viewQueries: [{ propertyName: "stepper", first: true, predicate: C8yStepper, descendants: true, static: true }], ngImport: i0, template: `<c8y-add-application
    [headerIcon]="'big-parcel'"
    [headerText]="headerText"
    [successText]="successText"
    [createApplicationHandler]="createPackageAppHandler"
    [uploadApplicationHandler]="uploadPackageHandler"
    [applicationType]="'package'"
  ></c8y-add-application>`, isInline: true, dependencies: [{ kind: "component", type: AddApplicationComponent, selector: "c8y-add-application", inputs: ["headerText", "headerIcon", "successText", "createApplicationHandler", "uploadApplicationHandler", "canGoBack", "applicationType"] }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: AddPackageComponent, decorators: [{
            type: Component,
            args: [{
                    selector: 'c8y-add-package',
                    template: `<c8y-add-application
    [headerIcon]="'big-parcel'"
    [headerText]="headerText"
    [successText]="successText"
    [createApplicationHandler]="createPackageAppHandler"
    [uploadApplicationHandler]="uploadPackageHandler"
    [applicationType]="'package'"
  ></c8y-add-application>`,
                    imports: [AddApplicationComponent]
                }]
        }], ctorParameters: () => [{ type: i1.EcosystemService }], propDecorators: { stepper: [{
                type: ViewChild,
                args: [C8yStepper, { static: true }]
            }] } });

class DeployApplicationComponent {
    constructor(ecosystemService, wizardComponent, translate, pluginService, gainsightService, router) {
        this.ecosystemService = ecosystemService;
        this.wizardComponent = wizardComponent;
        this.translate = translate;
        this.pluginService = pluginService;
        this.gainsightService = gainsightService;
        this.router = router;
        this.CURRENT_LOCATION = location.href;
        this.inProgress = true;
        this.isDeployed = false;
        this.deployedWithSuccess = false;
        this.model = {
            selected: undefined,
            binary: {
                id: undefined
            }
        };
        this.canDeploy = false;
        this.descriptionTemplate = gettext('Deploy application using "{{ packageName }}" package');
        this.successMessageTemplate = gettext('Application "{{ packageName }}" created');
        this.doneLabel = gettext('Done');
        this.cancelLabel = gettext('Cancel');
        this.package = this.wizardComponent.package;
    }
    async ngOnInit() {
        const apps = await this.ecosystemService.getHostedAndPackageApplications();
        this.newAppConfig = this.ecosystemService.getUniqueAppConfig(this.package, apps);
        this.headerText = this.getHeaderText();
        this.inProgress = false;
    }
    async deployApp() {
        this.inProgress = true;
        const formGroupValue = this.applicationPropertiesForm.formGroup.getRawValue();
        // Verify if selected package version is compatible with current platform versions.
        this.package.manifest.version = this.model.selected.version;
        const verifyVersionCompatibility = await this.ecosystemService.verifyBlueprintVersionsCompatibility(this.package.manifest);
        if (!verifyVersionCompatibility) {
            this.cancel();
            return;
        }
        const { contextPath, license, name, manifest } = this.package;
        const type = this.pluginService.getPackageType(this.package);
        const licensedApp = {
            contextPath,
            license: license || manifest.license,
            name,
            type,
            version: this.model.selected.version
        };
        const isArchived = await this.ecosystemService.verifyArchived([licensedApp]);
        if (!isArchived) {
            this.cancel();
            return;
        }
        const licensesVerifiedByUser = await this.ecosystemService.verifyLicenses([licensedApp]);
        if (!licensesVerifiedByUser) {
            this.cancel();
            return;
        }
        try {
            this.deployedApp = await this.ecosystemService.deployApp(this.package, formGroupValue, this.model);
            const applicationCustomEventInfo = pick(this.package, [
                'id',
                'name',
                'contextPath',
                'label',
                'key'
            ]);
            this.deployedWithSuccess = true;
            this.gainsightService.triggerEvent(PRODUCT_EXPERIENCE_ECOSYSTEM.APPLICATIONS.EVENTS.DEPLOY_APPLICATION, {
                component: PRODUCT_EXPERIENCE_ECOSYSTEM.APPLICATIONS.COMPONENTS.DEPLOY_APPLICATION,
                action: PRODUCT_EXPERIENCE_ECOSYSTEM.APPLICATIONS.ACTIONS.DEPLOY_APPLICATION,
                result: PRODUCT_EXPERIENCE_ECOSYSTEM.APPLICATIONS.RESULTS.DEPLOYED,
                url: this.CURRENT_LOCATION,
                ...applicationCustomEventInfo,
                package: this.deployedApp?.manifest?.package ?? null
            });
        }
        catch (error) {
            this.ecosystemService.alertError(error);
            this.gainsightService.triggerEvent(PRODUCT_EXPERIENCE_ECOSYSTEM.APPLICATIONS.EVENTS.DEPLOY_APPLICATION, {
                component: PRODUCT_EXPERIENCE_ECOSYSTEM.APPLICATIONS.COMPONENTS.DEPLOY_APPLICATION,
                action: PRODUCT_EXPERIENCE_ECOSYSTEM.APPLICATIONS.ACTIONS.DEPLOY_APPLICATION,
                result: PRODUCT_EXPERIENCE_ECOSYSTEM.APPLICATIONS.RESULTS.SERVER_FAILURE,
                url: this.CURRENT_LOCATION,
                error
            });
        }
        finally {
            this.markAsDeployed();
        }
    }
    cancel() {
        this.wizardComponent.close();
    }
    onAppVersionSelect(appVersion) {
        Object.assign(this.model, {
            selected: appVersion
        });
        this.canDeploy = true;
    }
    open() {
        this.router.navigateByUrl(ViewContext.Application.replace(':id', `${this.deployedApp.id}`));
        this.cancel();
    }
    markAsDeployed() {
        this.isDeployed = true;
        this.inProgress = false;
    }
    getHeaderText() {
        return this.translate.instant(this.descriptionTemplate, {
            packageName: this.package.name
        });
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DeployApplicationComponent, deps: [{ token: i1.EcosystemService }, { token: i2.WizardComponent }, { token: i6.TranslateService }, { token: i2.PluginsService }, { token: i2.GainsightService }, { token: i1$2.Router }], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.14", type: DeployApplicationComponent, isStandalone: true, selector: "c8y-deploy-application", viewQueries: [{ propertyName: "applicationPropertiesForm", first: true, predicate: ApplicationPropertiesFormComponent, descendants: true }], ngImport: i0, template: "<c8y-wizard-header>\n  <div class=\"modal-header dialog-header\">\n    <i c8yIcon=\"output\"></i>\n    <h4 id=\"modal-title\">{{ 'Deploy application' | translate }}</h4>\n  </div>\n</c8y-wizard-header>\n\n<c8y-wizard-body id=\"modal-body\">\n  <ng-container *ngIf=\"!isDeployed\">\n    <div class=\"fadeIn animated d-flex a-i-center j-c-center d-col\" style=\"min-height: 309px\">\n      <p\n        class=\"bg-level-0 fit-w p-16 text-center text-medium sticky-top bg-level-0 separator-bottom\"\n        *ngIf=\"!inProgress\"\n      >\n        {{ headerText | translate }}\n      </p>\n      <c8y-application-properties-form\n        *ngIf=\"!inProgress\"\n        [application]=\"newAppConfig\"\n        class=\"d-block fit-w bg-level-1\"\n      ></c8y-application-properties-form>\n\n      <ng-container *ngIf=\"!inProgress\">\n        <div [ngStyle]=\"{ padding: '0 16px' }\" class=\"d-block fit-w bg-gray-white\">\n          <c8y-package-version-select\n            [ngModel]=\"model.selected\"\n            (ngModelChange)=\"onAppVersionSelect($event)\"\n            [packageId]=\"package?.id\"\n            [label]=\"'Use extension package version' | translate\"\n          ></c8y-package-version-select>\n        </div>\n      </ng-container>\n\n      <c8y-loading\n        *ngIf=\"inProgress\"\n        [message]=\"'Deploying\u2026' | translate\"\n        class=\"text-center\"\n        layout=\"application\"\n      ></c8y-loading>\n    </div>\n  </ng-container>\n\n  <ng-container *ngIf=\"isDeployed\">\n    <div\n      *ngIf=\"deployedWithSuccess; else failedDeploy\"\n      class=\"modal-body fadeIn animated\"\n      style=\"min-height: 309px\"\n    >\n      <div class=\"d-flex a-i-center j-c-center d-col\">\n        <c8y-operation-result\n          type=\"success\"\n          [size]=\"84\"\n          [vertical]=\"true\"\n          [text]=\"successMessageTemplate | translate: { packageName: package.name }\"\n          class=\"lead d-block m-b-16\"\n        ></c8y-operation-result>\n      </div>\n    </div>\n    <ng-template #failedDeploy>\n      <div class=\"modal-body fadeIn animated text-center\" style=\"min-height: 257px\">\n        <c8y-operation-result\n          type=\"error\"\n          [size]=\"84\"\n          [vertical]=\"true\"\n          text=\"{{ 'Application creation failed' | translate }}\"\n          class=\"lead\"\n        ></c8y-operation-result>\n      </div>\n    </ng-template>\n  </ng-container>\n</c8y-wizard-body>\n\n<c8y-wizard-footer>\n  <button\n    (click)=\"cancel()\"\n    type=\"button\"\n    class=\"btn btn-default\"\n    data-cy=\"c8y-deploy-application--cancel-blueprint-button\"\n    title=\"{{ (isDeployed && deployedWithSuccess ? doneLabel : cancelLabel) | translate }}\"\n  >\n    {{ (isDeployed && deployedWithSuccess ? doneLabel : cancelLabel) | translate }}\n  </button>\n\n  <button\n    (click)=\"deployApp()\"\n    *ngIf=\"!isDeployed\"\n    [disabled]=\"inProgress || !canDeploy\"\n    [ngClass]=\"{ 'btn-pending': inProgress }\"\n    class=\"btn btn-primary\"\n    type=\"button\"\n    data-cy=\"c8y-deploy-application--deploy-blueprint-button\"\n    title=\"{{ 'Deploy' | translate }}\"\n  >\n    {{ 'Deploy' | translate }}\n  </button>\n\n  <button\n    (click)=\"open()\"\n    type=\"button\"\n    class=\"btn btn-primary\"\n    *ngIf=\"isDeployed && deployedWithSuccess\"\n    title=\"{{ 'Open the application details' | translate }}\"\n    translate\n  >\n    Open\n  </button>\n</c8y-wizard-footer>\n", dependencies: [{ kind: "component", type: WizardHeaderComponent, selector: "c8y-wizard-header" }, { kind: "directive", type: IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "component", type: WizardBodyComponent, selector: "c8y-wizard-body" }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: ApplicationPropertiesFormComponent, selector: "c8y-application-properties-form", inputs: ["application", "disabled"] }, { kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: PackageVersionSelectComponent, selector: "c8y-package-version-select", inputs: ["label", "packageContextPath", "packageId"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: LoadingComponent, selector: "c8y-loading", inputs: ["layout", "progress", "message"] }, { kind: "component", type: OperationResultComponent, selector: "c8y-operation-result", inputs: ["text", "vertical", "size", "type"] }, { kind: "component", type: WizardFooterComponent, selector: "c8y-wizard-footer" }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DeployApplicationComponent, decorators: [{
            type: Component,
            args: [{ selector: 'c8y-deploy-application', imports: [
                        WizardHeaderComponent,
                        IconDirective,
                        WizardBodyComponent,
                        NgIf,
                        ApplicationPropertiesFormComponent,
                        NgStyle,
                        PackageVersionSelectComponent,
                        FormsModule,
                        LoadingComponent,
                        OperationResultComponent,
                        WizardFooterComponent,
                        NgClass,
                        C8yTranslateDirective,
                        C8yTranslatePipe
                    ], template: "<c8y-wizard-header>\n  <div class=\"modal-header dialog-header\">\n    <i c8yIcon=\"output\"></i>\n    <h4 id=\"modal-title\">{{ 'Deploy application' | translate }}</h4>\n  </div>\n</c8y-wizard-header>\n\n<c8y-wizard-body id=\"modal-body\">\n  <ng-container *ngIf=\"!isDeployed\">\n    <div class=\"fadeIn animated d-flex a-i-center j-c-center d-col\" style=\"min-height: 309px\">\n      <p\n        class=\"bg-level-0 fit-w p-16 text-center text-medium sticky-top bg-level-0 separator-bottom\"\n        *ngIf=\"!inProgress\"\n      >\n        {{ headerText | translate }}\n      </p>\n      <c8y-application-properties-form\n        *ngIf=\"!inProgress\"\n        [application]=\"newAppConfig\"\n        class=\"d-block fit-w bg-level-1\"\n      ></c8y-application-properties-form>\n\n      <ng-container *ngIf=\"!inProgress\">\n        <div [ngStyle]=\"{ padding: '0 16px' }\" class=\"d-block fit-w bg-gray-white\">\n          <c8y-package-version-select\n            [ngModel]=\"model.selected\"\n            (ngModelChange)=\"onAppVersionSelect($event)\"\n            [packageId]=\"package?.id\"\n            [label]=\"'Use extension package version' | translate\"\n          ></c8y-package-version-select>\n        </div>\n      </ng-container>\n\n      <c8y-loading\n        *ngIf=\"inProgress\"\n        [message]=\"'Deploying\u2026' | translate\"\n        class=\"text-center\"\n        layout=\"application\"\n      ></c8y-loading>\n    </div>\n  </ng-container>\n\n  <ng-container *ngIf=\"isDeployed\">\n    <div\n      *ngIf=\"deployedWithSuccess; else failedDeploy\"\n      class=\"modal-body fadeIn animated\"\n      style=\"min-height: 309px\"\n    >\n      <div class=\"d-flex a-i-center j-c-center d-col\">\n        <c8y-operation-result\n          type=\"success\"\n          [size]=\"84\"\n          [vertical]=\"true\"\n          [text]=\"successMessageTemplate | translate: { packageName: package.name }\"\n          class=\"lead d-block m-b-16\"\n        ></c8y-operation-result>\n      </div>\n    </div>\n    <ng-template #failedDeploy>\n      <div class=\"modal-body fadeIn animated text-center\" style=\"min-height: 257px\">\n        <c8y-operation-result\n          type=\"error\"\n          [size]=\"84\"\n          [vertical]=\"true\"\n          text=\"{{ 'Application creation failed' | translate }}\"\n          class=\"lead\"\n        ></c8y-operation-result>\n      </div>\n    </ng-template>\n  </ng-container>\n</c8y-wizard-body>\n\n<c8y-wizard-footer>\n  <button\n    (click)=\"cancel()\"\n    type=\"button\"\n    class=\"btn btn-default\"\n    data-cy=\"c8y-deploy-application--cancel-blueprint-button\"\n    title=\"{{ (isDeployed && deployedWithSuccess ? doneLabel : cancelLabel) | translate }}\"\n  >\n    {{ (isDeployed && deployedWithSuccess ? doneLabel : cancelLabel) | translate }}\n  </button>\n\n  <button\n    (click)=\"deployApp()\"\n    *ngIf=\"!isDeployed\"\n    [disabled]=\"inProgress || !canDeploy\"\n    [ngClass]=\"{ 'btn-pending': inProgress }\"\n    class=\"btn btn-primary\"\n    type=\"button\"\n    data-cy=\"c8y-deploy-application--deploy-blueprint-button\"\n    title=\"{{ 'Deploy' | translate }}\"\n  >\n    {{ 'Deploy' | translate }}\n  </button>\n\n  <button\n    (click)=\"open()\"\n    type=\"button\"\n    class=\"btn btn-primary\"\n    *ngIf=\"isDeployed && deployedWithSuccess\"\n    title=\"{{ 'Open the application details' | translate }}\"\n    translate\n  >\n    Open\n  </button>\n</c8y-wizard-footer>\n" }]
        }], ctorParameters: () => [{ type: i1.EcosystemService }, { type: i2.WizardComponent }, { type: i6.TranslateService }, { type: i2.PluginsService }, { type: i2.GainsightService }, { type: i1$2.Router }], propDecorators: { applicationPropertiesForm: [{
                type: ViewChild,
                args: [ApplicationPropertiesFormComponent]
            }] } });

class PackageDetailsComponent {
    constructor(activatedRoute, wizardModalService, ecosystemService, contextRouteService, pluginsService, packageAvailabilityService, ui, gainsightService) {
        this.activatedRoute = activatedRoute;
        this.wizardModalService = wizardModalService;
        this.ecosystemService = ecosystemService;
        this.contextRouteService = contextRouteService;
        this.pluginsService = pluginsService;
        this.packageAvailabilityService = packageAvailabilityService;
        this.ui = ui;
        this.gainsightService = gainsightService;
        this.package = {};
        this.exportedPlugins$ = new BehaviorSubject([]);
        this.isChangingAvailability = false;
        this.isOwnedByCurrentTenant = false;
        this.isAllowedToCreateSubtenants = false;
        this.packageTypeLabels = PACKAGE_TYPE_LABELS;
        this.PACKAGE_TYPE = PackageType;
        this.packageProperties = packageProperties;
    }
    async ngOnInit() {
        this.isAllowedToCreateSubtenants = !!this.ui.currentTenant.value?.allowCreateTenants;
        await this.loadData();
    }
    deploy() {
        this.gainsightService.triggerEvent(PRODUCT_EXPERIENCE_ECOSYSTEM.APPLICATIONS.EVENTS.PACKAGE_PLUGINS, {
            component: PRODUCT_EXPERIENCE_ECOSYSTEM.APPLICATIONS.COMPONENTS.PACKAGE_DETAILS,
            action: PRODUCT_EXPERIENCE_ECOSYSTEM.APPLICATIONS.ACTIONS.DEPLOY_APPLICATION_INITIATED
        });
        const initialState = {
            wizardConfig: {},
            id: EcosystemWizards.BLUEPRINT_DEPLOYMENT,
            package: this.package
        };
        const modalOptions = { initialState };
        this.wizardModalService.show(modalOptions);
    }
    async togglePackageAvailability(pckg, newAvailability) {
        this.isChangingAvailability = true;
        pckg = await this.packageAvailabilityService.askIfAvailabilityShouldBeSetTo(pckg, newAvailability);
        const availabilityHasChanged = pckg.availability === newAvailability;
        if (availabilityHasChanged) {
            await this.loadData(pckg);
            this.contextRouteService.setContext(this.activatedRoute, pckg);
        }
        else {
            this.packageAvailability = this.package.availability;
        }
        this.isChangingAvailability = false;
    }
    async showPluginOverview(plugin) {
        this.selectedPlugin = plugin;
        const baseUrl = `/apps/${plugin.id}/`;
        this.pluginBaseUrl = baseUrl;
        this.pluginMarkdown = await this.pluginsService.getReadmeFileContent(baseUrl);
    }
    closeOverview() {
        this.selectedPlugin = null;
    }
    async loadData(pckg) {
        this.package = pckg
            ? pckg
            : this.contextRouteService.getContextData(this.activatedRoute)?.contextData;
        this.packageAvailability = this.package.availability;
        this.packageContentState = this.ecosystemService.getPackageContentState(this.package);
        this.packageType = this.pluginsService.getPackageType(this.package);
        this.name = this.package?.name;
        this.description = this.package?.manifest?.description;
        const baseUrl = `/apps/${this.package.contextPath}/`;
        this.markdown = await this.pluginsService.getReadmeFileContent(baseUrl);
        this.baseUrl = baseUrl;
        this.appState = this.ecosystemService.getAppState(this.package);
        this.isPackageBlueprint = this.ecosystemService.isPackageBlueprint(this.package);
        this.isOwnedByCurrentTenant =
            this.package?.owner?.tenant?.id === this.ui.currentTenant.value?.name;
        this.extractPackageMFExports();
    }
    extractPackageMFExports() {
        const exports = this.pluginsService.getMFExports(this.package);
        this.exportedPlugins$.next(exports);
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: PackageDetailsComponent, deps: [{ token: i1$2.ActivatedRoute }, { token: i2.WizardModalService }, { token: i1.EcosystemService }, { token: i2.ContextRouteService }, { token: i2.PluginsService }, { token: i1.PackageAvailabilityService }, { token: i2.AppStateService }, { token: i2.GainsightService }], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.14", type: PackageDetailsComponent, isStandalone: true, selector: "c8y-package-details", ngImport: i0, template: "<c8y-title>{{ name | humanizeAppName | async }}</c8y-title>\n\n<c8y-breadcrumb>\n  <c8y-breadcrumb-item\n    [icon]=\"'c8y-atom'\"\n    [label]=\"'Ecosystem' | translate\"\n  ></c8y-breadcrumb-item>\n  <c8y-breadcrumb-item\n    [icon]=\"'big-parcel'\"\n    [label]=\"'Extensions' | translate\"\n    [path]=\"'ecosystem/extension/extensions'\"\n  ></c8y-breadcrumb-item>\n  <c8y-breadcrumb-item [label]=\"name | humanizeAppName | async\"></c8y-breadcrumb-item>\n  <c8y-breadcrumb-item [label]=\"'Extension package' | translate\"></c8y-breadcrumb-item>\n</c8y-breadcrumb>\n\n<c8y-action-bar-item\n  placement=\"right\"\n  itemClass=\"navbar-form\"\n  *ngIf=\"isOwnedByCurrentTenant && isAllowedToCreateSubtenants\"\n>\n  <div class=\"d-flex a-i-center\">\n    <label\n      class=\"m-b-0 m-r-8\"\n      for=\"availability\"\n      translate\n    >\n      Availability`of package based on app state`\n    </label>\n    <div class=\"c8y-select-wrapper\">\n      <select\n        class=\"form-control\"\n        id=\"availability\"\n        [(ngModel)]=\"packageAvailability\"\n        [disabled]=\"isChangingAvailability\"\n        (ngModelChange)=\"togglePackageAvailability(package, $event)\"\n      >\n        <option\n          *ngFor=\"let availability of packageAvailabilityService.availabilities\"\n          [ngValue]=\"availability.value\"\n        >\n          {{ availability.label | translate }}\n        </option>\n      </select>\n    </div>\n  </div>\n</c8y-action-bar-item>\n\n<div\n  class=\"card content-fullpage d-grid grid__row--fit-auto\"\n  [ngClass]=\"{ 'grid__col--8-4-0': !selectedPlugin, 'grid__col--0-4-8': !!selectedPlugin }\"\n>\n  <div class=\"bg-level-1 grid__col--fullspan separator-bottom\">\n    <div class=\"card-block p-t-24 p-b-24 large-padding\">\n      <button\n        class=\"card__ribbon btn-clean\"\n        [attr.aria-label]=\"\n          (package.label || package.manifest.label | translatePackageLabel) +\n          ': ' +\n          (packageTypeLabels[packageType].tooltip | translate)\n        \"\n        tooltip=\"{{ packageTypeLabels[packageType].tooltip | translate }}\"\n        placement=\"bottom\"\n        type=\"button\"\n        *ngIf=\"packageType !== PACKAGE_TYPE.CUSTOM\"\n        [delay]=\"500\"\n      >\n        <span\n          [ngClass]=\"{\n            'bg-info': packageType === PACKAGE_TYPE.COMMUNITY,\n            'bg-primary': packageType === PACKAGE_TYPE.OFFICIAL,\n            'bg-warning': packageType === PACKAGE_TYPE.ARCHIVED\n          }\"\n        >\n          {{ package.label || package.manifest.label | translatePackageLabel }}\n        </span>\n      </button>\n      <div class=\"content-flex-70\">\n        <div class=\"text-center\">\n          <i\n            class=\"c8y-icon-duocolor icon-48\"\n            c8yIcon=\"big-parcel\"\n          ></i>\n          <button\n            class=\"btn-clean\"\n            [attr.aria-label]=\"\n              (appState?.label | translate) + ': ' + (appState?.tooltip | translate)\n            \"\n            [tooltip]=\"appState?.tooltip | translate\"\n            placement=\"top\"\n            type=\"button\"\n            [delay]=\"500\"\n          >\n            <span\n              class=\"label\"\n              [ngClass]=\"appState?.class\"\n            >\n              {{ appState?.label | translate }}\n            </span>\n          </button>\n          <button\n            class=\"btn-clean\"\n            [attr.aria-label]=\"\n              (packageContentState?.label | translate) +\n              ': ' +\n              (packageContentState?.tooltip | translate)\n            \"\n            [tooltip]=\"packageContentState?.tooltip | translate\"\n            placement=\"bottom\"\n            type=\"button\"\n            [delay]=\"500\"\n          >\n            <span\n              class=\"label\"\n              [ngClass]=\"packageContentState?.class\"\n            >\n              {{ packageContentState?.label | translate }}\n            </span>\n          </button>\n        </div>\n\n        <div class=\"flex-grow col-10\">\n          <div class=\"content-flex-80\">\n            <div class=\"col-8\">\n              <div class=\"card-title h4 m-b-8\">{{ name | humanizeAppName | async }}</div>\n              <p *ngIf=\"description\">{{ description }}</p>\n              <p\n                class=\"text-muted\"\n                *ngIf=\"!description\"\n              >\n                <em>{{ 'No description available.' | translate }}</em>\n              </p>\n            </div>\n            <div\n              class=\"col-3 text-right-md p-r-md-40\"\n              *ngIf=\"isPackageBlueprint\"\n            >\n              <button\n                class=\"btn btn-primary btn-sm\"\n                (click)=\"deploy()\"\n                data-cy=\"c8y-package-details--deploy-application-button\"\n              >\n                <i\n                  class=\"m-r-4\"\n                  c8yIcon=\"output\"\n                ></i>\n                {{ 'Deploy application' | translate }}\n              </button>\n            </div>\n            <div class=\"flex-grow\">\n              <c8y-properties-list\n                [data]=\"package.manifest\"\n                [properties]=\"packageProperties\"\n              ></c8y-properties-list>\n            </div>\n          </div>\n        </div>\n      </div>\n    </div>\n  </div>\n  <div class=\"inner-scroll\">\n    <div class=\"card-header separator sticky-top\">\n      <div class=\"card-title\">{{ 'Extension package overview' | translate }}</div>\n    </div>\n    <div class=\"card-block p-l-16 p-r-16\">\n      <div\n        class=\"alert alert-warning m-b-16\"\n        style=\"margin: auto\"\n        *ngIf=\"packageType === PACKAGE_TYPE.ARCHIVED\"\n        translate\n      >\n        The package was archived by the owner marking it as out of maintenance. It is not\n        recommended to install the package.\n      </div>\n      <c8y-ui-empty-state\n        [icon]=\"'user-manual'\"\n        [title]=\"'No README.md found' | translate\"\n        [subtitle]=\"\n          'To view the contents of &quot;README&quot;, add the file &quot;README.md&quot; to the package.'\n            | translate\n        \"\n        *ngIf=\"!markdown\"\n        [horizontal]=\"true\"\n      ></c8y-ui-empty-state>\n      <div\n        class=\"markdown-content\"\n        [innerHTML]=\"markdown | markdownToHtml: { baseUrl } | async\"\n      ></div>\n    </div>\n    <div class=\"separator-bottom visible-sm visible-xs\"></div>\n  </div>\n\n  <div\n    class=\"inner-scroll d-flex d-col bg-level-1 split-view__list\"\n    [ngClass]=\"{ 'border-right': !!selectedPlugin }\"\n  >\n    <div class=\"card-header separator sticky-top\">\n      <div class=\"card-title\">{{ 'Package plugins' | translate }}</div>\n    </div>\n    <div class=\"border-left flex-grow\">\n      <!-- empty state -->\n      <div\n        class=\"p-16\"\n        *ngIf=\"(exportedPlugins$ | async).length === 0\"\n      >\n        <c8y-ui-empty-state\n          [icon]=\"'plugin'\"\n          [title]=\"'No plugins to display.' | translate\"\n          [subtitle]=\"'This package doesn\\'t contain plugins.' | translate\"\n          [horizontal]=\"true\"\n        ></c8y-ui-empty-state>\n      </div>\n      <c8y-plugin-list\n        [plugins$]=\"exportedPlugins$\"\n        [selectable]=\"false\"\n        [installable]=\"true\"\n        [package]=\"package\"\n        [selectedPlugin]=\"selectedPlugin\"\n        (showOverview)=\"showPluginOverview($event)\"\n      ></c8y-plugin-list>\n    </div>\n  </div>\n\n  <div class=\"inner-scroll split-view__detail\"\n    [ngClass]=\"{ 'split-view__detail--selected': selectedPlugin }\">\n    <div\n      class=\"card-header separator sticky-top\"\n      *ngIf=\"selectedPlugin\"\n    >\n      <button\n        class=\"btn-clean\"\n        (click)=\"closeOverview()\"\n      >\n        <i c8yIcon=\"caret-back\"></i>\n        {{ 'Back to package overview ' | translate }}\n      </button>\n    </div>\n    <div\n      class=\"card-block p-l-16 p-r-16 overflow-visible\"\n      *ngIf=\"selectedPlugin\"\n    >\n      <div\n        class=\"markdown-content\"\n        *ngIf=\"pluginMarkdown\"\n        [innerHTML]=\"pluginMarkdown | markdownToHtml: { baseUrl: pluginBaseUrl } | async\"\n      ></div>\n      <c8y-ui-empty-state\n        [icon]=\"'user-manual'\"\n        [title]=\"'No README.md found for plugin' | translate\"\n        [subtitle]=\"\n          'To view the contents of &quot;README&quot;, add the file &quot;README.md&quot; to the plugin.'\n            | translate\n        \"\n        *ngIf=\"!pluginMarkdown\"\n        [horizontal]=\"true\"\n      ></c8y-ui-empty-state>\n    </div>\n  </div>\n</div>\n", dependencies: [{ kind: "component", type: TitleComponent, selector: "c8y-title", inputs: ["pageTitleUpdate"] }, { kind: "component", type: BreadcrumbComponent, selector: "c8y-breadcrumb" }, { kind: "component", type: BreadcrumbItemComponent, selector: "c8y-breadcrumb-item", inputs: ["icon", "translate", "label", "path", "injector"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: ActionBarItemComponent, selector: "c8y-action-bar-item", inputs: ["placement", "priority", "itemClass", "injector", "groupId", "inGroupPriority"] }, { kind: "directive", type: C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i3.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i3.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i3.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: NgFor, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: 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: IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "component", type: PropertiesListComponent, selector: "c8y-properties-list", inputs: ["properties", "title", "icon", "data", "groups", "noParse", "emptyLabel"] }, { kind: "component", type: EmptyStateComponent, selector: "c8y-ui-empty-state", inputs: ["icon", "title", "subtitle", "horizontal"] }, { kind: "component", type: PluginListComponent, selector: "c8y-plugin-list", inputs: ["plugins$", "emptyListText", "selectable", "hideSource", "installable", "package", "selectedPlugin"], outputs: ["selectedItems", "showOverview"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "pipe", type: HumanizeAppNamePipe, name: "humanizeAppName" }, { kind: "pipe", type: MarkdownToHtmlPipe, name: "markdownToHtml" }, { kind: "pipe", type: TranslatePackageLabelPipe, name: "translatePackageLabel" }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: PackageDetailsComponent, decorators: [{
            type: Component,
            args: [{ selector: 'c8y-package-details', imports: [
                        TitleComponent,
                        BreadcrumbComponent,
                        BreadcrumbItemComponent,
                        NgIf,
                        ActionBarItemComponent,
                        C8yTranslateDirective,
                        FormsModule,
                        NgFor,
                        NgClass,
                        TooltipDirective,
                        IconDirective,
                        PropertiesListComponent,
                        EmptyStateComponent,
                        PluginListComponent,
                        C8yTranslatePipe,
                        AsyncPipe,
                        HumanizeAppNamePipe,
                        MarkdownToHtmlPipe,
                        TranslatePackageLabelPipe
                    ], template: "<c8y-title>{{ name | humanizeAppName | async }}</c8y-title>\n\n<c8y-breadcrumb>\n  <c8y-breadcrumb-item\n    [icon]=\"'c8y-atom'\"\n    [label]=\"'Ecosystem' | translate\"\n  ></c8y-breadcrumb-item>\n  <c8y-breadcrumb-item\n    [icon]=\"'big-parcel'\"\n    [label]=\"'Extensions' | translate\"\n    [path]=\"'ecosystem/extension/extensions'\"\n  ></c8y-breadcrumb-item>\n  <c8y-breadcrumb-item [label]=\"name | humanizeAppName | async\"></c8y-breadcrumb-item>\n  <c8y-breadcrumb-item [label]=\"'Extension package' | translate\"></c8y-breadcrumb-item>\n</c8y-breadcrumb>\n\n<c8y-action-bar-item\n  placement=\"right\"\n  itemClass=\"navbar-form\"\n  *ngIf=\"isOwnedByCurrentTenant && isAllowedToCreateSubtenants\"\n>\n  <div class=\"d-flex a-i-center\">\n    <label\n      class=\"m-b-0 m-r-8\"\n      for=\"availability\"\n      translate\n    >\n      Availability`of package based on app state`\n    </label>\n    <div class=\"c8y-select-wrapper\">\n      <select\n        class=\"form-control\"\n        id=\"availability\"\n        [(ngModel)]=\"packageAvailability\"\n        [disabled]=\"isChangingAvailability\"\n        (ngModelChange)=\"togglePackageAvailability(package, $event)\"\n      >\n        <option\n          *ngFor=\"let availability of packageAvailabilityService.availabilities\"\n          [ngValue]=\"availability.value\"\n        >\n          {{ availability.label | translate }}\n        </option>\n      </select>\n    </div>\n  </div>\n</c8y-action-bar-item>\n\n<div\n  class=\"card content-fullpage d-grid grid__row--fit-auto\"\n  [ngClass]=\"{ 'grid__col--8-4-0': !selectedPlugin, 'grid__col--0-4-8': !!selectedPlugin }\"\n>\n  <div class=\"bg-level-1 grid__col--fullspan separator-bottom\">\n    <div class=\"card-block p-t-24 p-b-24 large-padding\">\n      <button\n        class=\"card__ribbon btn-clean\"\n        [attr.aria-label]=\"\n          (package.label || package.manifest.label | translatePackageLabel) +\n          ': ' +\n          (packageTypeLabels[packageType].tooltip | translate)\n        \"\n        tooltip=\"{{ packageTypeLabels[packageType].tooltip | translate }}\"\n        placement=\"bottom\"\n        type=\"button\"\n        *ngIf=\"packageType !== PACKAGE_TYPE.CUSTOM\"\n        [delay]=\"500\"\n      >\n        <span\n          [ngClass]=\"{\n            'bg-info': packageType === PACKAGE_TYPE.COMMUNITY,\n            'bg-primary': packageType === PACKAGE_TYPE.OFFICIAL,\n            'bg-warning': packageType === PACKAGE_TYPE.ARCHIVED\n          }\"\n        >\n          {{ package.label || package.manifest.label | translatePackageLabel }}\n        </span>\n      </button>\n      <div class=\"content-flex-70\">\n        <div class=\"text-center\">\n          <i\n            class=\"c8y-icon-duocolor icon-48\"\n            c8yIcon=\"big-parcel\"\n          ></i>\n          <button\n            class=\"btn-clean\"\n            [attr.aria-label]=\"\n              (appState?.label | translate) + ': ' + (appState?.tooltip | translate)\n            \"\n            [tooltip]=\"appState?.tooltip | translate\"\n            placement=\"top\"\n            type=\"button\"\n            [delay]=\"500\"\n          >\n            <span\n              class=\"label\"\n              [ngClass]=\"appState?.class\"\n            >\n              {{ appState?.label | translate }}\n            </span>\n          </button>\n          <button\n            class=\"btn-clean\"\n            [attr.aria-label]=\"\n              (packageContentState?.label | translate) +\n              ': ' +\n              (packageContentState?.tooltip | translate)\n            \"\n            [tooltip]=\"packageContentState?.tooltip | translate\"\n            placement=\"bottom\"\n            type=\"button\"\n            [delay]=\"500\"\n          >\n            <span\n              class=\"label\"\n              [ngClass]=\"packageContentState?.class\"\n            >\n              {{ packageContentState?.label | translate }}\n            </span>\n          </button>\n        </div>\n\n        <div class=\"flex-grow col-10\">\n          <div class=\"content-flex-80\">\n            <div class=\"col-8\">\n              <div class=\"card-title h4 m-b-8\">{{ name | humanizeAppName | async }}</div>\n              <p *ngIf=\"description\">{{ description }}</p>\n              <p\n                class=\"text-muted\"\n                *ngIf=\"!description\"\n              >\n                <em>{{ 'No description available.' | translate }}</em>\n              </p>\n            </div>\n            <div\n              class=\"col-3 text-right-md p-r-md-40\"\n              *ngIf=\"isPackageBlueprint\"\n            >\n              <button\n                class=\"btn btn-primary btn-sm\"\n                (click)=\"deploy()\"\n                data-cy=\"c8y-package-details--deploy-application-button\"\n              >\n                <i\n                  class=\"m-r-4\"\n                  c8yIcon=\"output\"\n                ></i>\n                {{ 'Deploy application' | translate }}\n              </button>\n            </div>\n            <div class=\"flex-grow\">\n              <c8y-properties-list\n                [data]=\"package.manifest\"\n                [properties]=\"packageProperties\"\n              ></c8y-properties-list>\n            </div>\n          </div>\n        </div>\n      </div>\n    </div>\n  </div>\n  <div class=\"inner-scroll\">\n    <div class=\"card-header separator sticky-top\">\n      <div class=\"card-title\">{{ 'Extension package overview' | translate }}</div>\n    </div>\n    <div class=\"card-block p-l-16 p-r-16\">\n      <div\n        class=\"alert alert-warning m-b-16\"\n        style=\"margin: auto\"\n        *ngIf=\"packageType === PACKAGE_TYPE.ARCHIVED\"\n        translate\n      >\n        The package was archived by the owner marking it as out of maintenance. It is not\n        recommended to install the package.\n      </div>\n      <c8y-ui-empty-state\n        [icon]=\"'user-manual'\"\n        [title]=\"'No README.md found' | translate\"\n        [subtitle]=\"\n          'To view the contents of &quot;README&quot;, add the file &quot;README.md&quot; to the package.'\n            | translate\n        \"\n        *ngIf=\"!markdown\"\n        [horizontal]=\"true\"\n      ></c8y-ui-empty-state>\n      <div\n        class=\"markdown-content\"\n        [innerHTML]=\"markdown | markdownToHtml: { baseUrl } | async\"\n      ></div>\n    </div>\n    <div class=\"separator-bottom visible-sm visible-xs\"></div>\n  </div>\n\n  <div\n    class=\"inner-scroll d-flex d-col bg-level-1 split-view__list\"\n    [ngClass]=\"{ 'border-right': !!selectedPlugin }\"\n  >\n    <div class=\"card-header separator sticky-top\">\n      <div class=\"card-title\">{{ 'Package plugins' | translate }}</div>\n    </div>\n    <div class=\"border-left flex-grow\">\n      <!-- empty state -->\n      <div\n        class=\"p-16\"\n        *ngIf=\"(exportedPlugins$ | async).length === 0\"\n      >\n        <c8y-ui-empty-state\n          [icon]=\"'plugin'\"\n          [title]=\"'No plugins to display.' | translate\"\n          [subtitle]=\"'This package doesn\\'t contain plugins.' | translate\"\n          [horizontal]=\"true\"\n        ></c8y-ui-empty-state>\n      </div>\n      <c8y-plugin-list\n        [plugins$]=\"exportedPlugins$\"\n        [selectable]=\"false\"\n        [installable]=\"true\"\n        [package]=\"package\"\n        [selectedPlugin]=\"selectedPlugin\"\n        (showOverview)=\"showPluginOverview($event)\"\n      ></c8y-plugin-list>\n    </div>\n  </div>\n\n  <div class=\"inner-scroll split-view__detail\"\n    [ngClass]=\"{ 'split-view__detail--selected': selectedPlugin }\">\n    <div\n      class=\"card-header separator sticky-top\"\n      *ngIf=\"selectedPlugin\"\n    >\n      <button\n        class=\"btn-clean\"\n        (click)=\"closeOverview()\"\n      >\n        <i c8yIcon=\"caret-back\"></i>\n        {{ 'Back to package overview ' | translate }}\n      </button>\n    </div>\n    <div\n      class=\"card-block p-l-16 p-r-16 overflow-visible\"\n      *ngIf=\"selectedPlugin\"\n    >\n      <div\n        class=\"markdown-content\"\n        *ngIf=\"pluginMarkdown\"\n        [innerHTML]=\"pluginMarkdown | markdownToHtml: { baseUrl: pluginBaseUrl } | async\"\n      ></div>\n      <c8y-ui-empty-state\n        [icon]=\"'user-manual'\"\n        [title]=\"'No README.md found for plugin' | translate\"\n        [subtitle]=\"\n          'To view the contents of &quot;README&quot;, add the file &quot;README.md&quot; to the plugin.'\n            | translate\n        \"\n        *ngIf=\"!pluginMarkdown\"\n        [horizontal]=\"true\"\n      ></c8y-ui-empty-state>\n    </div>\n  </div>\n</div>\n" }]
        }], ctorParameters: () => [{ type: i1$2.ActivatedRoute }, { type: i2.WizardModalService }, { type: i1.EcosystemService }, { type: i2.ContextRouteService }, { type: i2.PluginsService }, { type: i1.PackageAvailabilityService }, { type: i2.AppStateService }, { type: i2.GainsightService }] });

class PackagesListComponent {
    constructor(ecosystemService, wizardModalService, permissions) {
        this.ecosystemService = ecosystemService;
        this.wizardModalService = wizardModalService;
        this.permissions = permissions;
        this.reloading = false;
        this.reload$ = new BehaviorSubject(null);
        this.hasAdminPermissions = false;
        this.emptyStateSubtitle = gettext('Add your first package by clicking below.');
        this.packageTypes = defaultPackageTypes;
        this.packageAvailabilities = [
            APP_STATE.SUBSCRIBED.label,
            APP_STATE.CUSTOM.label
        ];
        this.packageContents = defaultPackageContents;
        this.destroy$ = new Subject();
        this.packages$ = this.reload$.pipe(takeUntil(this.destroy$), tap(() => (this.reloading = true)), switchMap(() => this.ecosystemService.getPackageApplications()), tap(packages => {
            packages.forEach(pckg => {
                pckg.filterProps = this.ecosystemService.getAppFilterProps(pckg);
            });
        }), tap(() => (this.reloading = false)), shareReplay(1));
    }
    ngOnInit() {
        this.hasAdminPermissions = this.permissions.hasRole(Permissions.ROLE_APPLICATION_MANAGEMENT_ADMIN);
        this.loadPackages();
    }
    loadPackages() {
        this.reload$.next();
    }
    addPackage() {
        const initialState = {
            id: EcosystemWizards.PACKAGE_UPLOAD
        };
        const modalOptions = { initialState };
        const modalRef = this.wizardModalService.show(modalOptions);
        modalRef.content.onClose.subscribe(() => {
            this.loadPackages();
        });
    }
    ngOnDestroy() {
        this.destroy$.next(true);
        this.destroy$.complete();
    }
    setFilterPipe(pipe) {
        this.filteredPackages$ = this.packages$.pipe(src => pipe(src));
    }
    resetFilters() {
        this.filtersComponent?.resetAllFilters();
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: PackagesListComponent, deps: [{ token: i1.EcosystemService }, { token: i2.WizardModalService }, { token: i2.Permissions }], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.14", type: PackagesListComponent, isStandalone: true, selector: "c8y-packages-list", viewQueries: [{ propertyName: "filtersComponent", first: true, predicate: ListFiltersComponent, descendants: true }], ngImport: i0, template: "<c8y-title>{{ 'Extensions' | translate }}</c8y-title>\n\n<c8y-breadcrumb>\n  <c8y-breadcrumb-item\n    [icon]=\"'c8y-atom'\"\n    [label]=\"'Ecosystem' | translate\"\n  ></c8y-breadcrumb-item>\n  <c8y-breadcrumb-item\n    [icon]=\"'big-parcel'\"\n    [path]=\"'ecosystem/extension/extensions'\"\n    [label]=\"'Extensions' | translate\"\n  ></c8y-breadcrumb-item>\n</c8y-breadcrumb>\n\n<c8y-action-bar-item\n  [placement]=\"'right'\"\n  *ngIf=\"hasAdminPermissions\"\n>\n  <button\n    class=\"btn btn-link\"\n    title=\"{{ 'Add extension package' | translate }}\"\n    type=\"button\"\n    data-cy=\"packages-list--add-extension-package\"\n    (click)=\"addPackage()\"\n  >\n    <i c8yIcon=\"plus-circle\"></i>\n    {{ 'Add extension package' | translate }}\n  </button>\n</c8y-action-bar-item>\n\n<c8y-action-bar-item [placement]=\"'right'\">\n  <button\n    class=\"btn btn-link\"\n    title=\"{{ 'Reload' | translate }}\"\n    type=\"button\"\n    (click)=\"loadPackages()\"\n  >\n    <i\n      c8yIcon=\"refresh\"\n      [ngClass]=\"{ 'icon-spin': reloading }\"\n    ></i>\n    {{ 'Reload' | translate }}\n  </button>\n</c8y-action-bar-item>\n\n<c8y-action-bar-item\n  [placement]=\"'left'\"\n  itemClass=\"p-r-8 p-l-8\"\n>\n  <c8y-list-filters\n    *ngIf=\"packages$ | async\"\n    [packageTypes]=\"packageTypes\"\n    [packageAvailabilities]=\"packageAvailabilities\"\n    [packageContents]=\"packageContents\"\n    (filterPipeChange)=\"setFilterPipe($event)\"\n  >\n    <c8y-archived-filter></c8y-archived-filter>\n  </c8y-list-filters>\n</c8y-action-bar-item>\n\n<c8y-action-bar-item\n  [placement]=\"'left'\"\n  itemClass=\"navbar-form hidden-xs\"\n>\n  <c8y-list-display-switch\n    (onListClassChange)=\"listClass = $event\"\n    [listLength]=\"(packages$ | async)?.length\"\n  ></c8y-list-display-switch>\n</c8y-action-bar-item>\n\n<c8y-help src=\"/docs/standard-tenant/ecosystem/#extensions\"></c8y-help>\n\n<div\n  class=\"card-group\"\n  [ngClass]=\"listClass\"\n>\n  <div\n    class=\"page-sticky-header hidden-xs d-flex m-b-8\"\n    *ngIf=\"(filteredPackages$ | async)?.length > 0\"\n  >\n    <div class=\"card-block card-column-40\">\n      <div class=\"card-appicon p-l-32 p-r-16 m-r-0 m-l-4\"></div>\n      {{ 'Package' | translate }}\n    </div>\n    <div class=\"card-block p-0 card-column-80 m-r-40\">\n      <div class=\"card-block card-column-80\">{{ 'Description' | translate }}</div>\n      <div class=\"card-block card-column-20\">{{ 'Type' | translate }}</div>\n      <div class=\"card-block card-column-20\"></div>\n    </div>\n  </div>\n  <div\n    class=\"col-xs-12 col-sm-4 col-md-3\"\n    *ngFor=\"let app of filteredPackages$ | async\"\n  >\n    <c8y-application-card\n      class=\"d-contents\"\n      (onAppDeleted)=\"loadPackages()\"\n      (onAppCloned)=\"loadPackages()\"\n      [app]=\"app\"\n    ></c8y-application-card>\n  </div>\n</div>\n\n<c8y-ui-empty-state\n  [icon]=\"'big-parcel'\"\n  [title]=\"'No extensions to display.' | translate\"\n  [subtitle]=\"hasAdminPermissions ? (emptyStateSubtitle | translate) : ''\"\n  *ngIf=\"(packages$ | async)?.length === 0\"\n>\n  <div *ngIf=\"hasAdminPermissions\">\n    <button\n      class=\"btn btn-primary\"\n      title=\"{{ 'Add extension package' | translate }}\"\n      type=\"button\"\n      (click)=\"addPackage()\"\n    >\n      {{ 'Add extension package' | translate }}\n    </button>\n  </div>\n</c8y-ui-empty-state>\n\n<c8y-ui-empty-state\n  [icon]=\"'search'\"\n  [title]=\"'No matching extensions.' | translate\"\n  [subtitle]=\"'Refine your search terms and/or the filters' | translate\"\n  *ngIf=\"(packages$ | async)?.length > 0 && (filteredPackages$ | async)?.length === 0\"\n>\n  <button\n    class=\"btn btn-primary\"\n    title=\"{{ 'Reset filters' | translate }}\"\n    type=\"button\"\n    (click)=\"resetFilters()\"\n  >\n    {{ 'Reset filters' | translate }}\n  </button>\n</c8y-ui-empty-state>\n", dependencies: [{ kind: "component", type: TitleComponent, selector: "c8y-title", inputs: ["pageTitleUpdate"] }, { kind: "component", type: BreadcrumbComponent, selector: "c8y-breadcrumb" }, { kind: "component", type: BreadcrumbItemComponent, selector: "c8y-breadcrumb-item", inputs: ["icon", "translate", "label", "path", "injector"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: ActionBarItemComponent, selector: "c8y-action-bar-item", inputs: ["placement", "priority", "itemClass", "injector", "groupId", "inGroupPriority"] }, { kind: "directive", type: IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: ListFiltersComponent, selector: "c8y-list-filters", inputs: ["packageTypes", "packageAvailabilities", "packageContents"], outputs: ["filterPipeChange"] }, { kind: "component", type: ArchivedFilterComponent, selector: "c8y-archived-filter" }, { kind: "component", type: ListDisplaySwitchComponent, selector: "c8y-list-display-switch", inputs: ["listKey", "listLength", "filterPipe"], outputs: ["onListClassChange"] }, { kind: "component", type: HelpComponent, selector: "c8y-help", inputs: ["src", "isCollapsed", "priority", "icon"] }, { kind: "directive", type: NgFor, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "component", type: ApplicationCardComponent, selector: "c8y-application-card", inputs: ["app", "canEdit"], outputs: ["onAppDeleted", "onAppCloned"] }, { kind: "component", type: EmptyStateComponent, selector: "c8y-ui-empty-state", inputs: ["icon", "title", "subtitle", "horizontal"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }, { kind: "pipe", type: AsyncPipe, name: "async" }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: PackagesListComponent, decorators: [{
            type: Component,
            args: [{ selector: 'c8y-packages-list', imports: [
                        TitleComponent,
                        BreadcrumbComponent,
                        BreadcrumbItemComponent,
                        NgIf,
                        ActionBarItemComponent,
                        IconDirective,
                        NgClass,
                        ListFiltersComponent,
                        ArchivedFilterComponent,
                        ListDisplaySwitchComponent,
                        HelpComponent,
                        NgFor,
                        ApplicationCardComponent,
                        EmptyStateComponent,
                        C8yTranslatePipe,
                        AsyncPipe
                    ], template: "<c8y-title>{{ 'Extensions' | translate }}</c8y-title>\n\n<c8y-breadcrumb>\n  <c8y-breadcrumb-item\n    [icon]=\"'c8y-atom'\"\n    [label]=\"'Ecosystem' | translate\"\n  ></c8y-breadcrumb-item>\n  <c8y-breadcrumb-item\n    [icon]=\"'big-parcel'\"\n    [path]=\"'ecosystem/extension/extensions'\"\n    [label]=\"'Extensions' | translate\"\n  ></c8y-breadcrumb-item>\n</c8y-breadcrumb>\n\n<c8y-action-bar-item\n  [placement]=\"'right'\"\n  *ngIf=\"hasAdminPermissions\"\n>\n  <button\n    class=\"btn btn-link\"\n    title=\"{{ 'Add extension package' | translate }}\"\n    type=\"button\"\n    data-cy=\"packages-list--add-extension-package\"\n    (click)=\"addPackage()\"\n  >\n    <i c8yIcon=\"plus-circle\"></i>\n    {{ 'Add extension package' | translate }}\n  </button>\n</c8y-action-bar-item>\n\n<c8y-action-bar-item [placement]=\"'right'\">\n  <button\n    class=\"btn btn-link\"\n    title=\"{{ 'Reload' | translate }}\"\n    type=\"button\"\n    (click)=\"loadPackages()\"\n  >\n    <i\n      c8yIcon=\"refresh\"\n      [ngClass]=\"{ 'icon-spin': reloading }\"\n    ></i>\n    {{ 'Reload' | translate }}\n  </button>\n</c8y-action-bar-item>\n\n<c8y-action-bar-item\n  [placement]=\"'left'\"\n  itemClass=\"p-r-8 p-l-8\"\n>\n  <c8y-list-filters\n    *ngIf=\"packages$ | async\"\n    [packageTypes]=\"packageTypes\"\n    [packageAvailabilities]=\"packageAvailabilities\"\n    [packageContents]=\"packageContents\"\n    (filterPipeChange)=\"setFilterPipe($event)\"\n  >\n    <c8y-archived-filter></c8y-archived-filter>\n  </c8y-list-filters>\n</c8y-action-bar-item>\n\n<c8y-action-bar-item\n  [placement]=\"'left'\"\n  itemClass=\"navbar-form hidden-xs\"\n>\n  <c8y-list-display-switch\n    (onListClassChange)=\"listClass = $event\"\n    [listLength]=\"(packages$ | async)?.length\"\n  ></c8y-list-display-switch>\n</c8y-action-bar-item>\n\n<c8y-help src=\"/docs/standard-tenant/ecosystem/#extensions\"></c8y-help>\n\n<div\n  class=\"card-group\"\n  [ngClass]=\"listClass\"\n>\n  <div\n    class=\"page-sticky-header hidden-xs d-flex m-b-8\"\n    *ngIf=\"(filteredPackages$ | async)?.length > 0\"\n  >\n    <div class=\"card-block card-column-40\">\n      <div class=\"card-appicon p-l-32 p-r-16 m-r-0 m-l-4\"></div>\n      {{ 'Package' | translate }}\n    </div>\n    <div class=\"card-block p-0 card-column-80 m-r-40\">\n      <div class=\"card-block card-column-80\">{{ 'Description' | translate }}</div>\n      <div class=\"card-block card-column-20\">{{ 'Type' | translate }}</div>\n      <div class=\"card-block card-column-20\"></div>\n    </div>\n  </div>\n  <div\n    class=\"col-xs-12 col-sm-4 col-md-3\"\n    *ngFor=\"let app of filteredPackages$ | async\"\n  >\n    <c8y-application-card\n      class=\"d-contents\"\n      (onAppDeleted)=\"loadPackages()\"\n      (onAppCloned)=\"loadPackages()\"\n      [app]=\"app\"\n    ></c8y-application-card>\n  </div>\n</div>\n\n<c8y-ui-empty-state\n  [icon]=\"'big-parcel'\"\n  [title]=\"'No extensions to display.' | translate\"\n  [subtitle]=\"hasAdminPermissions ? (emptyStateSubtitle | translate) : ''\"\n  *ngIf=\"(packages$ | async)?.length === 0\"\n>\n  <div *ngIf=\"hasAdminPermissions\">\n    <button\n      class=\"btn btn-primary\"\n      title=\"{{ 'Add extension package' | translate }}\"\n      type=\"button\"\n      (click)=\"addPackage()\"\n    >\n      {{ 'Add extension package' | translate }}\n    </button>\n  </div>\n</c8y-ui-empty-state>\n\n<c8y-ui-empty-state\n  [icon]=\"'search'\"\n  [title]=\"'No matching extensions.' | translate\"\n  [subtitle]=\"'Refine your search terms and/or the filters' | translate\"\n  *ngIf=\"(packages$ | async)?.length > 0 && (filteredPackages$ | async)?.length === 0\"\n>\n  <button\n    class=\"btn btn-primary\"\n    title=\"{{ 'Reset filters' | translate }}\"\n    type=\"button\"\n    (click)=\"resetFilters()\"\n  >\n    {{ 'Reset filters' | translate }}\n  </button>\n</c8y-ui-empty-state>\n" }]
        }], ctorParameters: () => [{ type: i1.EcosystemService }, { type: i2.WizardModalService }, { type: i2.Permissions }], propDecorators: { filtersComponent: [{
                type: ViewChild,
                args: [ListFiltersComponent]
            }] } });

class PackageVersionsGuard {
    canActivate(route) {
        const app = route.data.contextData || route.parent.data.contextData;
        return !!app?.applicationVersions?.length;
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: PackageVersionsGuard, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
    static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: PackageVersionsGuard }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: PackageVersionsGuard, decorators: [{
            type: Injectable
        }] });

class PackageVersionsAppsComponent {
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: PackageVersionsAppsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.14", type: PackageVersionsAppsComponent, isStandalone: true, selector: "c8y-contents-apps", inputs: { selectedVersionManifest: "selectedVersionManifest" }, ngImport: i0, template: "<p class=\"legend form-block\">\n  {{ 'Application' | translate }}\n</p>\n\n<div  *ngIf=\"selectedVersionManifest?.name; else emptyApp\">\n  <c8y-li>\n    <c8y-li-icon icon=\"big-parcel\"></c8y-li-icon>\n    <h5 class=\"text-medium text-16 p-b-8\">\n      {{ selectedVersionManifest?.name | humanizeAppName | async }}\n      <small class=\"m-l-8\" *ngIf=\"selectedVersionManifest?.requiredPlatformVersion\">\n        <em>{{ selectedVersionManifest?.requiredPlatformVersion }}</em>\n      </small>\n    </h5>\n    <p *ngIf=\"selectedVersionManifest?.description; else notAvailable\">\n      {{ selectedVersionManifest?.description }}\n    </p>\n  </c8y-li>\n</div>\n\n<ng-template #notAvailable>\n  <p class=\"text-muted\">\n    <em>{{ 'No description available.' | translate }}</em>\n  </p>\n</ng-template>\n\n<ng-template #emptyApp>\n  <c8y-ui-empty-state\n  [icon]=\"'big-parcel'\"\n  [horizontal]=\"true\"\n  [title]=\"'No application.' | translate\"\n  [subtitle]=\"'This package doesn\\'t contain an application.' | translate\"\n  ></c8y-ui-empty-state>\n</ng-template>", dependencies: [{ kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: ListItemComponent, selector: "c8y-list-item, c8y-li", inputs: ["active", "highlighted", "emptyActions", "dense", "collapsed", "selectable"], outputs: ["collapsedChange"] }, { kind: "component", type: ListItemIconComponent, selector: "c8y-list-item-icon, c8y-li-icon", inputs: ["icon", "status"] }, { kind: "component", type: EmptyStateComponent, selector: "c8y-ui-empty-state", inputs: ["icon", "title", "subtitle", "horizontal"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "pipe", type: HumanizeAppNamePipe, name: "humanizeAppName" }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: PackageVersionsAppsComponent, decorators: [{
            type: Component,
            args: [{ selector: 'c8y-contents-apps', imports: [
                        NgIf,
                        ListItemComponent,
                        ListItemIconComponent,
                        EmptyStateComponent,
                        C8yTranslatePipe,
                        AsyncPipe,
                        HumanizeAppNamePipe
                    ], template: "<p class=\"legend form-block\">\n  {{ 'Application' | translate }}\n</p>\n\n<div  *ngIf=\"selectedVersionManifest?.name; else emptyApp\">\n  <c8y-li>\n    <c8y-li-icon icon=\"big-parcel\"></c8y-li-icon>\n    <h5 class=\"text-medium text-16 p-b-8\">\n      {{ selectedVersionManifest?.name | humanizeAppName | async }}\n      <small class=\"m-l-8\" *ngIf=\"selectedVersionManifest?.requiredPlatformVersion\">\n        <em>{{ selectedVersionManifest?.requiredPlatformVersion }}</em>\n      </small>\n    </h5>\n    <p *ngIf=\"selectedVersionManifest?.description; else notAvailable\">\n      {{ selectedVersionManifest?.description }}\n    </p>\n  </c8y-li>\n</div>\n\n<ng-template #notAvailable>\n  <p class=\"text-muted\">\n    <em>{{ 'No description available.' | translate }}</em>\n  </p>\n</ng-template>\n\n<ng-template #emptyApp>\n  <c8y-ui-empty-state\n  [icon]=\"'big-parcel'\"\n  [horizontal]=\"true\"\n  [title]=\"'No application.' | translate\"\n  [subtitle]=\"'This package doesn\\'t contain an application.' | translate\"\n  ></c8y-ui-empty-state>\n</ng-template>" }]
        }], propDecorators: { selectedVersionManifest: [{
                type: Input,
                args: ['selectedVersionManifest']
            }] } });

class PackageVersionsPluginsComponent {
    constructor(activatedRoute) {
        this.activatedRoute = activatedRoute;
        this.showOverview = new EventEmitter();
        this.exportedPlugins$ = new BehaviorSubject([]);
        this.appParentData = this.activatedRoute.parent?.snapshot.data.contextData;
    }
    async ngOnChanges() {
        this.exportedPlugins$.next(this.getExportedPlugins());
    }
    showPluginOverview(plugin) {
        this.showOverview.emit(plugin);
    }
    getExportedPlugins() {
        if (!this.selectedVersionManifest?.exports) {
            return [];
        }
        const originApp = {
            label: this.appParentData?.label || this.appParentData?.manifest.label,
            owner: this.appParentData?.owner
        };
        return this.selectedVersionManifest.exports.map(plugin => ({
            ...plugin,
            id: PluginsService.createPluginId(this.selectedVersionManifest.contextPath, plugin, this.selectedVersionManifest.version, false),
            originApp
        }));
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: PackageVersionsPluginsComponent, deps: [{ token: i1$2.ActivatedRoute }], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.14", type: PackageVersionsPluginsComponent, isStandalone: true, selector: "c8y-contents-plugins", inputs: { selectedVersionManifest: "selectedVersionManifest", selectedPlugin: "selectedPlugin" }, outputs: { showOverview: "showOverview" }, usesOnChanges: true, ngImport: i0, template: "<p class=\"legend form-block\">\n  {{ 'Plugins' | translate }}\n</p>\n<!-- empty state -->\n<c8y-ui-empty-state\n  [icon]=\"'plugin'\"\n  [title]=\"'No plugins to display.' | translate\"\n  [subtitle]=\"'This package doesn\\'t contain plugins.' | translate\"\n  *ngIf=\"(exportedPlugins$ | async).length === 0\"\n  [horizontal]=\"true\"\n></c8y-ui-empty-state>\n\n<c8y-plugin-list\n  [plugins$]=\"exportedPlugins$\"\n  [selectable]=\"false\"\n  [selectedPlugin]=\"selectedPlugin\"\n  (showOverview)=\"showPluginOverview($event)\"\n></c8y-plugin-list>\n", dependencies: [{ kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: EmptyStateComponent, selector: "c8y-ui-empty-state", inputs: ["icon", "title", "subtitle", "horizontal"] }, { kind: "component", type: PluginListComponent, selector: "c8y-plugin-list", inputs: ["plugins$", "emptyListText", "selectable", "hideSource", "installable", "package", "selectedPlugin"], outputs: ["selectedItems", "showOverview"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }, { kind: "pipe", type: AsyncPipe, name: "async" }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: PackageVersionsPluginsComponent, decorators: [{
            type: Component,
            args: [{ selector: 'c8y-contents-plugins', imports: [NgIf, EmptyStateComponent, PluginListComponent, C8yTranslatePipe, AsyncPipe], template: "<p class=\"legend form-block\">\n  {{ 'Plugins' | translate }}\n</p>\n<!-- empty state -->\n<c8y-ui-empty-state\n  [icon]=\"'plugin'\"\n  [title]=\"'No plugins to display.' | translate\"\n  [subtitle]=\"'This package doesn\\'t contain plugins.' | translate\"\n  *ngIf=\"(exportedPlugins$ | async).length === 0\"\n  [horizontal]=\"true\"\n></c8y-ui-empty-state>\n\n<c8y-plugin-list\n  [plugins$]=\"exportedPlugins$\"\n  [selectable]=\"false\"\n  [selectedPlugin]=\"selectedPlugin\"\n  (showOverview)=\"showPluginOverview($event)\"\n></c8y-plugin-list>\n" }]
        }], ctorParameters: () => [{ type: i1$2.ActivatedRoute }], propDecorators: { selectedVersionManifest: [{
                type: Input,
                args: ['selectedVersionManifest']
            }], selectedPlugin: [{
                type: Input
            }], showOverview: [{
                type: Output
            }] } });

class PackageContentsComponent {
    constructor(activatedRoute, applicationService, alertService, contextRouteService) {
        this.activatedRoute = activatedRoute;
        this.applicationService = applicationService;
        this.alertService = alertService;
        this.contextRouteService = contextRouteService;
        this.showOverview = new EventEmitter();
        this.package = {};
        this.isLoading = false;
        this.packageVersionProperties = packageProperties;
    }
    showPluginOverview(plugin) {
        this.showOverview.emit(plugin);
    }
    async ngOnChanges(changes) {
        if (changes.selectedVersion?.currentValue) {
            this.loadManifest(this.selectedVersion);
            this.previousVersion = this.getPreviousVersion();
        }
    }
    async loadManifest(version) {
        this.package = this.contextRouteService.getContextData(this.activatedRoute)?.contextData;
        this.isLoading = true;
        this.selectedVersionManifest = await this.getManifest(version);
        this.isLoading = false;
    }
    async getManifest(version) {
        try {
            return await this.applicationService.getAppManifest(this.package, version);
        }
        catch (error) {
            this.alertService.addServerFailure(error);
        }
        return undefined;
    }
    getPreviousVersion() {
        if (this.package.applicationVersions.length === 1) {
            return null;
        }
        const selectedVersionIndex = this.package.applicationVersions.findIndex(version => version.version === this.selectedVersion);
        if (selectedVersionIndex === 0) {
            return null;
        }
        return this.package.applicationVersions[selectedVersionIndex - 1].version;
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: PackageContentsComponent, deps: [{ token: i1$2.ActivatedRoute }, { token: i4.ApplicationService }, { token: i2.AlertService }, { token: i2.ContextRouteService }], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.14", type: PackageContentsComponent, isStandalone: true, selector: "c8y-package-contents", inputs: { selectedVersion: "selectedVersion", selectedPlugin: "selectedPlugin" }, outputs: { showOverview: "showOverview" }, usesOnChanges: true, ngImport: i0, template: "<ng-container *ngIf=\"!selectedVersionManifest && !isLoading\">\n  <div class=\"p-16\">\n    <c8y-ui-empty-state\n      [icon]=\"'big-parcel'\"\n      [title]=\"'No package selected' | translate\"\n      [subtitle]=\"'Select a package from the list to display the package contents.' | translate\"\n      [horizontal]=\"true\"\n    ></c8y-ui-empty-state>\n  </div>\n</ng-container>\n\n<ng-container *ngIf=\"isLoading\">\n  <c8y-loading></c8y-loading>\n</ng-container>\n\n<ng-container *ngIf=\"selectedVersionManifest && !isLoading\">\n  <!-- DETAILS -->\n  <div class=\"card-block\">\n    <c8y-properties-list\n      [data]=\"selectedVersionManifest\"\n      [emptyLabel]=\"'--'\"\n      [properties]=\"packageVersionProperties\"\n    ></c8y-properties-list>\n\n    <!-- APPS -->\n    <c8y-contents-apps\n      class=\"p-t-16 d-block\"\n      [selectedVersionManifest]=\"selectedVersionManifest\"\n    ></c8y-contents-apps>\n\n    <!-- PLUGINS -->\n    <c8y-contents-plugins\n      class=\"p-t-16 d-block\"\n      [selectedVersionManifest]=\"selectedVersionManifest\"\n      [selectedPlugin]=\"selectedPlugin\"\n      (showOverview)=\"showPluginOverview($event)\"\n    ></c8y-contents-plugins>\n\n    <!-- CHANGELOG -->\n    <p class=\"legend form-block\">\n      {{ 'Change log' | translate }}\n    </p>\n\n    <c8y-contents-changelog\n      [package]=\"package\"\n      [selectedVersion]=\"selectedVersion\"\n      [previousVersion]=\"previousVersion\"\n    ></c8y-contents-changelog>\n  </div>\n</ng-container>\n", dependencies: [{ kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: EmptyStateComponent, selector: "c8y-ui-empty-state", inputs: ["icon", "title", "subtitle", "horizontal"] }, { kind: "component", type: LoadingComponent, selector: "c8y-loading", inputs: ["layout", "progress", "message"] }, { kind: "component", type: PropertiesListComponent, selector: "c8y-properties-list", inputs: ["properties", "title", "icon", "data", "groups", "noParse", "emptyLabel"] }, { kind: "component", type: PackageVersionsAppsComponent, selector: "c8y-contents-apps", inputs: ["selectedVersionManifest"] }, { kind: "component", type: PackageVersionsPluginsComponent, selector: "c8y-contents-plugins", inputs: ["selectedVersionManifest", "selectedPlugin"], outputs: ["showOverview"] }, { kind: "component", type: PackageChangelogComponent, selector: "c8y-contents-changelog", inputs: ["package", "selectedVersion", "previousVersion"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: PackageContentsComponent, decorators: [{
            type: Component,
            args: [{ selector: 'c8y-package-contents', imports: [
                        NgIf,
                        EmptyStateComponent,
                        LoadingComponent,
                        PropertiesListComponent,
                        PackageVersionsAppsComponent,
                        PackageVersionsPluginsComponent,
                        PackageChangelogComponent,
                        C8yTranslatePipe
                    ], template: "<ng-container *ngIf=\"!selectedVersionManifest && !isLoading\">\n  <div class=\"p-16\">\n    <c8y-ui-empty-state\n      [icon]=\"'big-parcel'\"\n      [title]=\"'No package selected' | translate\"\n      [subtitle]=\"'Select a package from the list to display the package contents.' | translate\"\n      [horizontal]=\"true\"\n    ></c8y-ui-empty-state>\n  </div>\n</ng-container>\n\n<ng-container *ngIf=\"isLoading\">\n  <c8y-loading></c8y-loading>\n</ng-container>\n\n<ng-container *ngIf=\"selectedVersionManifest && !isLoading\">\n  <!-- DETAILS -->\n  <div class=\"card-block\">\n    <c8y-properties-list\n      [data]=\"selectedVersionManifest\"\n      [emptyLabel]=\"'--'\"\n      [properties]=\"packageVersionProperties\"\n    ></c8y-properties-list>\n\n    <!-- APPS -->\n    <c8y-contents-apps\n      class=\"p-t-16 d-block\"\n      [selectedVersionManifest]=\"selectedVersionManifest\"\n    ></c8y-contents-apps>\n\n    <!-- PLUGINS -->\n    <c8y-contents-plugins\n      class=\"p-t-16 d-block\"\n      [selectedVersionManifest]=\"selectedVersionManifest\"\n      [selectedPlugin]=\"selectedPlugin\"\n      (showOverview)=\"showPluginOverview($event)\"\n    ></c8y-contents-plugins>\n\n    <!-- CHANGELOG -->\n    <p class=\"legend form-block\">\n      {{ 'Change log' | translate }}\n    </p>\n\n    <c8y-contents-changelog\n      [package]=\"package\"\n      [selectedVersion]=\"selectedVersion\"\n      [previousVersion]=\"previousVersion\"\n    ></c8y-contents-changelog>\n  </div>\n</ng-container>\n" }]
        }], ctorParameters: () => [{ type: i1$2.ActivatedRoute }, { type: i4.ApplicationService }, { type: i2.AlertService }, { type: i2.ContextRouteService }], propDecorators: { selectedVersion: [{
                type: Input
            }], selectedPlugin: [{
                type: Input
            }], showOverview: [{
                type: Output
            }] } });

const DEFAULT_VERSIONS_LIMIT = 20;
class PackageVersionsListComponent {
    constructor(activatedRoute, pluginsService, ecosystemService, translateService, modal, alertService, optionsService, permissions, gainsightService) {
        this.activatedRoute = activatedRoute;
        this.pluginsService = pluginsService;
        this.ecosystemService = ecosystemService;
        this.translateService = translateService;
        this.modal = modal;
        this.alertService = alertService;
        this.optionsService = optionsService;
        this.permissions = permissions;
        this.gainsightService = gainsightService;
        this.CURRENT_LOCATION = location.href;
        this.isLoading = false;
        this.hasAdminPermissions = false;
        this.isPackageOwnedByCurrentTenant = false;
        this.onVersionSelect = new EventEmitter();
    }
    async ngOnInit() {
        this.isLoading = true;
        this.hasAdminPermissions = this.permissions.hasRole(Permissions.ROLE_APPLICATION_MANAGEMENT_ADMIN);
        this.package = this.activatedRoute?.snapshot?.parent?.data?.contextData;
        this.isPackageOwnedByCurrentTenant = this.ecosystemService.isOwner(this.package);
        this.versionsLimit = (await this.optionsService.getSystemOption('application', 'versions.limit', DEFAULT_VERSIONS_LIMIT));
        this.sortVersions();
        this.isLoading = false;
    }
    async downloadArchive(appVersion) {
        this.gainsightService.triggerEvent(PRODUCT_EXPERIENCE_ECOSYSTEM.APPLICATIONS.EVENTS.PACKAGE_VERSIONS, {
            component: PRODUCT_EXPERIENCE_ECOSYSTEM.APPLICATIONS.COMPONENTS.PACKAGE_VERSIONS,
            action: PRODUCT_EXPERIENCE_ECOSYSTEM.APPLICATIONS.ACTIONS.DOWNLOAD,
            url: this.CURRENT_LOCATION
        });
        const archiveMO = await this.ecosystemService.getArchiveManagedObject(appVersion.binaryId);
        await this.ecosystemService.downloadArchive(this.package, {
            id: appVersion.binaryId,
            name: archiveMO.name
        });
    }
    packageVersionUploaded() {
        this.activatedRoute.snapshot.parent.data.contextData = this.package;
        this.sortVersions();
        this.setUploadedVersionAsLatest();
    }
    selectVersion(version) {
        this.selectedVersion = version;
        this.onVersionSelect.emit(version);
    }
    async removeVersionPackage(version) {
        try {
            await this.ecosystemService.deletePackageVersion(this.package, { version });
            this.alertService.success(this.translateService.instant(gettext('Package version {{version}} has been removed'), {
                version
            }));
            this.gainsightService.triggerEvent(PRODUCT_EXPERIENCE_ECOSYSTEM.APPLICATIONS.EVENTS.PACKAGE_VERSIONS, {
                component: PRODUCT_EXPERIENCE_ECOSYSTEM.APPLICATIONS.COMPONENTS.PACKAGE_VERSIONS,
                action: PRODUCT_EXPERIENCE_ECOSYSTEM.APPLICATIONS.ACTIONS.DELETE,
                result: PRODUCT_EXPERIENCE_ECOSYSTEM.APPLICATIONS.RESULTS.SUCCESS,
                url: this.CURRENT_LOCATION
            });
        }
        catch (e) {
            this.alertService.addServerFailure(e);
            this.gainsightService.triggerEvent(PRODUCT_EXPERIENCE_ECOSYSTEM.APPLICATIONS.EVENTS.PACKAGE_VERSIONS, {
                component: PRODUCT_EXPERIENCE_ECOSYSTEM.APPLICATIONS.COMPONENTS.PACKAGE_VERSIONS,
                action: PRODUCT_EXPERIENCE_ECOSYSTEM.APPLICATIONS.ACTIONS.DELETE,
                result: PRODUCT_EXPERIENCE_ECOSYSTEM.APPLICATIONS.RESULTS.SERVER_FAILURE,
                url: this.CURRENT_LOCATION
            });
        }
        if (version === this.selectedVersion) {
            this.selectVersion(null);
        }
        await this.refreshPackage();
    }
    async setVersionAsLatest(appVersion) {
        try {
            await this.ecosystemService.setPackageVersionTag(this.package, appVersion.version, [
                ...appVersion.tags,
                'latest'
            ]);
            // TODO added it due to: https://cumulocity.atlassian.net/browse/MTM-48553
            // Remove it when BE fixes issues with activeVersion.
            await this.ecosystemService.setAppActiveVersion(this.package, appVersion.binaryId);
            this.alertService.success(gettext('Tag has been set.'));
            this.gainsightService.triggerEvent(PRODUCT_EXPERIENCE_ECOSYSTEM.APPLICATIONS.EVENTS.PACKAGE_VERSIONS, {
                component: PRODUCT_EXPERIENCE_ECOSYSTEM.APPLICATIONS.COMPONENTS.PACKAGE_VERSIONS,
                action: PRODUCT_EXPERIENCE_ECOSYSTEM.APPLICATIONS.ACTIONS.SET_AS_LATEST,
                result: PRODUCT_EXPERIENCE_ECOSYSTEM.APPLICATIONS.RESULTS.SUCCESS,
                url: this.CURRENT_LOCATION
            });
        }
        catch (e) {
            this.alertService.addServerFailure(e);
            this.gainsightService.triggerEvent(PRODUCT_EXPERIENCE_ECOSYSTEM.APPLICATIONS.EVENTS.PACKAGE_VERSIONS, {
                component: PRODUCT_EXPERIENCE_ECOSYSTEM.APPLICATIONS.COMPONENTS.PACKAGE_VERSIONS,
                action: PRODUCT_EXPERIENCE_ECOSYSTEM.APPLICATIONS.ACTIONS.SET_AS_LATEST,
                result: PRODUCT_EXPERIENCE_ECOSYSTEM.APPLICATIONS.RESULTS.SERVER_FAILURE,
                url: this.CURRENT_LOCATION
            });
            return;
        }
        await this.refreshPackage();
    }
    async acknowledgeLimitReached() {
        await this.modal.acknowledge(gettext('Package limit exceeded'), this.translateService.instant(gettext('You have reached the maximum number of {{ versionsLimit }} package versions. To add another version, first delete one from the list.'), { versionsLimit: this.versionsLimit }), Status.INFO, gettext('Close'));
        throw undefined;
    }
    async refreshPackage() {
        this.isLoading = true;
        this.package = await this.ecosystemService.getApplication(this.package.id);
        this.activatedRoute.snapshot.parent.data.contextData = this.package;
        this.sortVersions();
        this.isLoading = false;
    }
    sortVersions() {
        this.sortedVersions = this.pluginsService.sortVersions({
            list: this.package.applicationVersions,
            path: ['version']
        }, 'desc');
        this.toggleUploadPossibility();
    }
    async setUploadedVersionAsLatest() {
        const uploadedVersion = this.package.applicationVersions[this.package.applicationVersions.length - 1];
        try {
            this.gainsightService.triggerEvent(PRODUCT_EXPERIENCE_ECOSYSTEM.APPLICATIONS.EVENTS.PACKAGE_VERSIONS, {
                component: PRODUCT_EXPERIENCE_ECOSYSTEM.APPLICATIONS.COMPONENTS.PACKAGE_VERSIONS,
                action: PRODUCT_EXPERIENCE_ECOSYSTEM.APPLICATIONS.ACTIONS.UPLOAD,
                result: PRODUCT_EXPERIENCE_ECOSYSTEM.APPLICATIONS.RESULTS.SUCCESS,
                url: this.CURRENT_LOCATION
            });
            await this.modal.confirm(gettext('Upload successful'), this.translateService.instant(gettext('Do you want to set version {{version}} as the latest? Deploying a new application will always use this version.'), { version: uploadedVersion.version }), Status.SUCCESS, {
                ok: gettext('Set as latest`version`'),
                cancel: gettext('Keep unchanged`version`')
            });
        }
        catch (e) {
            await this.refreshPackage();
            return;
        }
        await this.setVersionAsLatest(uploadedVersion);
    }
    toggleUploadPossibility() {
        this.preUploadCallback =
            this.sortedVersions.length < this.versionsLimit
                ? null
                : this.acknowledgeLimitReached.bind(this);
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: PackageVersionsListComponent, deps: [{ token: i1$2.ActivatedRoute }, { token: i2.PluginsService }, { token: i1.EcosystemService }, { token: i6.TranslateService }, { token: i2.ModalService }, { token: i2.AlertService }, { token: i2.OptionsService }, { token: i2.Permissions }, { token: i2.GainsightService }], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.14", type: PackageVersionsListComponent, isStandalone: true, selector: "c8y-package-versions-list", outputs: { onVersionSelect: "onVersionSelect" }, ngImport: i0, template: "<div class=\"inner-scroll split-view__list\">\n  <div class=\"card-header separator sticky-top bg-component\">\n    <div class=\"card-title\" translate>Versions</div>\n  </div>\n\n  <div class=\"bg-level-1 flex-grow\">\n    <div class=\"p-16\" *ngIf=\"isLoading\">\n      <c8y-loading></c8y-loading>\n    </div>\n    <ul class=\"nav c8y-nav-stacked\" *ngIf=\"!isLoading\">\n      <li\n        class=\"c8y-stacked-item p-t-0 p-b-0 p-r-4\"\n        [ngClass]=\"{ active: selectedVersion === applicationVersion.version }\"\n        *ngFor=\"let applicationVersion of sortedVersions\"\n      >\n        <div\n          class=\"flex-grow d-flex a-i-center gap-4 p-t-8 p-b-8\"\n          (click)=\"selectVersion(applicationVersion.version)\"\n        >\n          <i c8yIcon=\"big-parcel\" class=\"icon-20\"></i>\n          <span class=\"text-label-small\">\n            {{ 'Version' | translate }}\n          </span>\n          <span class=\"text-medium\">{{ applicationVersion.version }}</span>\n          <div class=\"text-truncate d-flex j-c-end flex-grow gap-4 flex-wrap m-l-auto\">\n            <span *ngFor=\"let tag of applicationVersion.tags\" class=\"label label-info\">\n              {{ tag }}\n            </span>\n          </div>\n        </div>\n        <div class=\"dropdown\" dropdown *ngIf=\"hasAdminPermissions && isPackageOwnedByCurrentTenant\">\n          <button\n            class=\"dropdown-toggle c8y-dropdown\"\n            type=\"button\"\n            title=\"{{ 'Settings' | translate }}\"\n            dropdownToggle\n          >\n            <i c8yIcon=\"ellipsis-v\"></i>\n          </button>\n          <ul *dropdownMenu class=\"dropdown-menu dropdown-menu-right\">\n            <li>\n              <button\n                type=\"button\"\n                title=\"{{ 'Set as latest`version`' | translate }}\"\n                (click)=\"setVersionAsLatest(applicationVersion)\"\n                [disabled]=\"applicationVersion.tags?.includes('latest')\"\n              >\n                <i c8yIcon=\"collect\" class=\"m-r-4\"></i>\n                {{ 'Set as latest`version`' | translate }}\n              </button>\n            </li>\n            <li>\n              <button\n                type=\"button\"\n                title=\"{{ 'Download' | translate }}\"\n                (click)=\"downloadArchive(applicationVersion)\"\n              >\n                <i c8yIcon=\"download\" class=\"m-r-4\"></i>\n                {{ 'Download' | translate }}\n              </button>\n            </li>\n            <li>\n              <button\n                type=\"button\"\n                title=\"{{ 'Delete' | translate }}\"\n                (click)=\"removeVersionPackage(applicationVersion.version)\"\n                [disabled]=\"applicationVersion.tags?.includes('latest')\"\n              >\n                <i c8yIcon=\"trash\" class=\"m-r-4\"></i>\n                {{ 'Delete' | translate }}\n              </button>\n            </li>\n          </ul>\n        </div>\n      </li>\n    </ul>\n  </div>\n\n  <div\n    class=\"card-footer separator sticky-bottom\"\n    *ngIf=\"!isLoading && isPackageOwnedByCurrentTenant\"\n  >\n    <div class=\"form-group m-b-0\">\n      <label translate>Upload a new version</label>\n      <c8y-upload-archive\n        [(application)]=\"package\"\n        [uploadNewVersion]=\"true\"\n        (refresh)=\"packageVersionUploaded()\"\n        [preUploadCallback]=\"preUploadCallback\"\n      ></c8y-upload-archive>\n    </div>\n  </div>\n</div>\n", dependencies: [{ kind: "directive", type: C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: LoadingComponent, selector: "c8y-loading", inputs: ["layout", "progress", "message"] }, { kind: "directive", type: NgFor, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "directive", type: BsDropdownDirective, selector: "[bsDropdown], [dropdown]", inputs: ["placement", "triggers", "container", "dropup", "autoClose", "isAnimated", "insideClick", "isDisabled", "isOpen"], outputs: ["isOpenChange", "onShown", "onHidden"], exportAs: ["bs-dropdown"] }, { kind: "directive", type: BsDropdownToggleDirective, selector: "[bsDropdownToggle],[dropdownToggle]", exportAs: ["bs-dropdown-toggle"] }, { kind: "directive", type: BsDropdownMenuDirective, selector: "[bsDropdownMenu],[dropdownMenu]", exportAs: ["bs-dropdown-menu"] }, { kind: "component", type: UploadArchiveComponent, selector: "c8y-upload-archive", inputs: ["application", "uploadNewVersion", "preUploadCallback"], outputs: ["applicationChange", "refresh"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: PackageVersionsListComponent, decorators: [{
            type: Component,
            args: [{ selector: 'c8y-package-versions-list', imports: [
                        C8yTranslateDirective,
                        NgIf,
                        LoadingComponent,
                        NgFor,
                        NgClass,
                        IconDirective,
                        BsDropdownDirective,
                        BsDropdownToggleDirective,
                        BsDropdownMenuDirective,
                        UploadArchiveComponent,
                        C8yTranslatePipe
                    ], template: "<div class=\"inner-scroll split-view__list\">\n  <div class=\"card-header separator sticky-top bg-component\">\n    <div class=\"card-title\" translate>Versions</div>\n  </div>\n\n  <div class=\"bg-level-1 flex-grow\">\n    <div class=\"p-16\" *ngIf=\"isLoading\">\n      <c8y-loading></c8y-loading>\n    </div>\n    <ul class=\"nav c8y-nav-stacked\" *ngIf=\"!isLoading\">\n      <li\n        class=\"c8y-stacked-item p-t-0 p-b-0 p-r-4\"\n        [ngClass]=\"{ active: selectedVersion === applicationVersion.version }\"\n        *ngFor=\"let applicationVersion of sortedVersions\"\n      >\n        <div\n          class=\"flex-grow d-flex a-i-center gap-4 p-t-8 p-b-8\"\n          (click)=\"selectVersion(applicationVersion.version)\"\n        >\n          <i c8yIcon=\"big-parcel\" class=\"icon-20\"></i>\n          <span class=\"text-label-small\">\n            {{ 'Version' | translate }}\n          </span>\n          <span class=\"text-medium\">{{ applicationVersion.version }}</span>\n          <div class=\"text-truncate d-flex j-c-end flex-grow gap-4 flex-wrap m-l-auto\">\n            <span *ngFor=\"let tag of applicationVersion.tags\" class=\"label label-info\">\n              {{ tag }}\n            </span>\n          </div>\n        </div>\n        <div class=\"dropdown\" dropdown *ngIf=\"hasAdminPermissions && isPackageOwnedByCurrentTenant\">\n          <button\n            class=\"dropdown-toggle c8y-dropdown\"\n            type=\"button\"\n            title=\"{{ 'Settings' | translate }}\"\n            dropdownToggle\n          >\n            <i c8yIcon=\"ellipsis-v\"></i>\n          </button>\n          <ul *dropdownMenu class=\"dropdown-menu dropdown-menu-right\">\n            <li>\n              <button\n                type=\"button\"\n                title=\"{{ 'Set as latest`version`' | translate }}\"\n                (click)=\"setVersionAsLatest(applicationVersion)\"\n                [disabled]=\"applicationVersion.tags?.includes('latest')\"\n              >\n                <i c8yIcon=\"collect\" class=\"m-r-4\"></i>\n                {{ 'Set as latest`version`' | translate }}\n              </button>\n            </li>\n            <li>\n              <button\n                type=\"button\"\n                title=\"{{ 'Download' | translate }}\"\n                (click)=\"downloadArchive(applicationVersion)\"\n              >\n                <i c8yIcon=\"download\" class=\"m-r-4\"></i>\n                {{ 'Download' | translate }}\n              </button>\n            </li>\n            <li>\n              <button\n                type=\"button\"\n                title=\"{{ 'Delete' | translate }}\"\n                (click)=\"removeVersionPackage(applicationVersion.version)\"\n                [disabled]=\"applicationVersion.tags?.includes('latest')\"\n              >\n                <i c8yIcon=\"trash\" class=\"m-r-4\"></i>\n                {{ 'Delete' | translate }}\n              </button>\n            </li>\n          </ul>\n        </div>\n      </li>\n    </ul>\n  </div>\n\n  <div\n    class=\"card-footer separator sticky-bottom\"\n    *ngIf=\"!isLoading && isPackageOwnedByCurrentTenant\"\n  >\n    <div class=\"form-group m-b-0\">\n      <label translate>Upload a new version</label>\n      <c8y-upload-archive\n        [(application)]=\"package\"\n        [uploadNewVersion]=\"true\"\n        (refresh)=\"packageVersionUploaded()\"\n        [preUploadCallback]=\"preUploadCallback\"\n      ></c8y-upload-archive>\n    </div>\n  </div>\n</div>\n" }]
        }], ctorParameters: () => [{ type: i1$2.ActivatedRoute }, { type: i2.PluginsService }, { type: i1.EcosystemService }, { type: i6.TranslateService }, { type: i2.ModalService }, { type: i2.AlertService }, { type: i2.OptionsService }, { type: i2.Permissions }, { type: i2.GainsightService }], propDecorators: { onVersionSelect: [{
                type: Output
            }] } });

class PackageVersionsComponent {
    constructor(activatedRoute, contextRouteService, pluginsService) {
        this.activatedRoute = activatedRoute;
        this.contextRouteService = contextRouteService;
        this.pluginsService = pluginsService;
        this.package = {};
        this.packageContentsTitle = gettext('Version {{ selectedVersion }} package contents');
    }
    async ngOnInit() {
        this.package = this.contextRouteService.getContextData(this.activatedRoute)?.contextData;
    }
    async showPluginOverview(plugin) {
        this.selectedPlugin = plugin;
        const baseUrl = `/apps/${plugin.id}/`;
        this.pluginBaseUrl = baseUrl;
        this.pluginMarkdown = await this.pluginsService.getReadmeFileContent(baseUrl);
    }
    closeOverview() {
        this.selectedPlugin = null;
    }
    clearSelectedVersion() {
        this.selectedVersion = null;
    }
    selectVersion(version) {
        if (this.selectedVersion !== version) {
            this.selectedVersion = version;
            this.closeOverview();
        }
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: PackageVersionsComponent, deps: [{ token: i1$2.ActivatedRoute }, { token: i2.ContextRouteService }, { token: i2.PluginsService }], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.14", type: PackageVersionsComponent, isStandalone: true, selector: "c8y-package-versions", ngImport: i0, template: "<c8y-title>{{ package?.name | humanizeAppName | async }}</c8y-title>\n\n<c8y-breadcrumb>\n  <c8y-breadcrumb-item\n    [icon]=\"'c8y-atom'\"\n    [label]=\"'Ecosystem' | translate\"\n  ></c8y-breadcrumb-item>\n  <c8y-breadcrumb-item\n    [icon]=\"'big-parcel'\"\n    [label]=\"'Extensions' | translate\"\n    [path]=\"'ecosystem/extension/extensions'\"\n  ></c8y-breadcrumb-item>\n  <c8y-breadcrumb-item [label]=\"package?.name | humanizeAppName | async\"></c8y-breadcrumb-item>\n  <c8y-breadcrumb-item [label]=\"'Versions' | translate\"></c8y-breadcrumb-item>\n</c8y-breadcrumb>\n\n<div\n  class=\"card content-fullpage d-grid\"\n  [ngClass]=\"{ 'grid__col--6-6-0': !selectedPlugin, 'grid__col--0-6-6': !!selectedPlugin }\"\n>\n  <c8y-package-versions-list\n    class=\"d-contents\"\n    (onVersionSelect)=\"selectVersion($event)\"\n  ></c8y-package-versions-list>\n\n  <!-- Package contents -->\n  <div\n    class=\"inner-scroll split-view__detail\"\n    [ngClass]=\"{ 'split-view__detail--selected': selectedVersion }\"\n  >\n    <div class=\"large-padding card-header separator visible-sm visible-xs fit-w sticky-top\">\n      <div class=\"d-flex a-i-center\">\n        <button\n          class=\"btn-clean text-primary m-r-8\"\n          title=\"{{ 'Back' | translate }}\"\n          (click)=\"clearSelectedVersion()\"\n        >\n          <i c8yIcon=\"chevron-left\"></i>\n          <span translate>Back</span>\n        </button>\n        <div class=\"card-title\">\n          {{ packageContentsTitle | translate: { selectedVersion } }}\n        </div>\n      </div>\n    </div>\n    <div class=\"card-header large-padding separator sticky-top visible-md visible-lg\">\n      <div class=\"card-title\">\n        <ng-container *ngIf=\"selectedVersion\">\n          {{ packageContentsTitle | translate: { selectedVersion } }}\n        </ng-container>\n      </div>\n    </div>\n    <div class=\"inner-scroll split-view__list\">\n      <c8y-package-contents\n        [selectedVersion]=\"selectedVersion\"\n        [selectedPlugin]=\"selectedPlugin\"\n        (showOverview)=\"showPluginOverview($event)\"\n      ></c8y-package-contents>\n    </div>\n  </div>\n\n  <!-- Plugin readme -->\n  <div\n    class=\"inner-scroll split-view__detail\"\n    [ngClass]=\"{ 'split-view__detail--selected': selectedPlugin }\"\n  >\n    <div\n      class=\"card-header separator sticky-top\"\n      *ngIf=\"selectedPlugin\"\n    >\n      <button\n        class=\"btn-clean\"\n        (click)=\"closeOverview()\"\n      >\n        <i c8yIcon=\"caret-back\"></i>\n        {{ 'Back to package versions overview ' | translate }}\n      </button>\n    </div>\n    <div\n      class=\"card-block p-l-16 p-r-16 overflow-visible\"\n      *ngIf=\"selectedPlugin\"\n    >\n      <div\n        class=\"markdown-content\"\n        *ngIf=\"pluginMarkdown\"\n        [innerHTML]=\"pluginMarkdown | markdownToHtml: { baseUrl: pluginBaseUrl } | async\"\n      ></div>\n      <c8y-ui-empty-state\n        [icon]=\"'user-manual'\"\n        [title]=\"'No README.md found for plugin' | translate\"\n        [subtitle]=\"\n          'To view the contents of &quot;README&quot;, add the file &quot;README.md&quot; to the plugin.'\n            | translate\n        \"\n        *ngIf=\"!pluginMarkdown\"\n        [horizontal]=\"true\"\n      ></c8y-ui-empty-state>\n    </div>\n  </div>\n</div>\n", dependencies: [{ kind: "component", type: TitleComponent, selector: "c8y-title", inputs: ["pageTitleUpdate"] }, { kind: "component", type: BreadcrumbComponent, selector: "c8y-breadcrumb" }, { kind: "component", type: BreadcrumbItemComponent, selector: "c8y-breadcrumb-item", inputs: ["icon", "translate", "label", "path", "injector"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: PackageVersionsListComponent, selector: "c8y-package-versions-list", outputs: ["onVersionSelect"] }, { kind: "directive", type: IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "directive", type: C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: PackageContentsComponent, selector: "c8y-package-contents", inputs: ["selectedVersion", "selectedPlugin"], outputs: ["showOverview"] }, { kind: "component", type: EmptyStateComponent, selector: "c8y-ui-empty-state", inputs: ["icon", "title", "subtitle", "horizontal"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "pipe", type: HumanizeAppNamePipe, name: "humanizeAppName" }, { kind: "pipe", type: MarkdownToHtmlPipe, name: "markdownToHtml" }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: PackageVersionsComponent, decorators: [{
            type: Component,
            args: [{ selector: 'c8y-package-versions', imports: [
                        TitleComponent,
                        BreadcrumbComponent,
                        BreadcrumbItemComponent,
                        NgClass,
                        PackageVersionsListComponent,
                        IconDirective,
                        C8yTranslateDirective,
                        NgIf,
                        PackageContentsComponent,
                        EmptyStateComponent,
                        C8yTranslatePipe,
                        AsyncPipe,
                        HumanizeAppNamePipe,
                        MarkdownToHtmlPipe
                    ], template: "<c8y-title>{{ package?.name | humanizeAppName | async }}</c8y-title>\n\n<c8y-breadcrumb>\n  <c8y-breadcrumb-item\n    [icon]=\"'c8y-atom'\"\n    [label]=\"'Ecosystem' | translate\"\n  ></c8y-breadcrumb-item>\n  <c8y-breadcrumb-item\n    [icon]=\"'big-parcel'\"\n    [label]=\"'Extensions' | translate\"\n    [path]=\"'ecosystem/extension/extensions'\"\n  ></c8y-breadcrumb-item>\n  <c8y-breadcrumb-item [label]=\"package?.name | humanizeAppName | async\"></c8y-breadcrumb-item>\n  <c8y-breadcrumb-item [label]=\"'Versions' | translate\"></c8y-breadcrumb-item>\n</c8y-breadcrumb>\n\n<div\n  class=\"card content-fullpage d-grid\"\n  [ngClass]=\"{ 'grid__col--6-6-0': !selectedPlugin, 'grid__col--0-6-6': !!selectedPlugin }\"\n>\n  <c8y-package-versions-list\n    class=\"d-contents\"\n    (onVersionSelect)=\"selectVersion($event)\"\n  ></c8y-package-versions-list>\n\n  <!-- Package contents -->\n  <div\n    class=\"inner-scroll split-view__detail\"\n    [ngClass]=\"{ 'split-view__detail--selected': selectedVersion }\"\n  >\n    <div class=\"large-padding card-header separator visible-sm visible-xs fit-w sticky-top\">\n      <div class=\"d-flex a-i-center\">\n        <button\n          class=\"btn-clean text-primary m-r-8\"\n          title=\"{{ 'Back' | translate }}\"\n          (click)=\"clearSelectedVersion()\"\n        >\n          <i c8yIcon=\"chevron-left\"></i>\n          <span translate>Back</span>\n        </button>\n        <div class=\"card-title\">\n          {{ packageContentsTitle | translate: { selectedVersion } }}\n        </div>\n      </div>\n    </div>\n    <div class=\"card-header large-padding separator sticky-top visible-md visible-lg\">\n      <div class=\"card-title\">\n        <ng-container *ngIf=\"selectedVersion\">\n          {{ packageContentsTitle | translate: { selectedVersion } }}\n        </ng-container>\n      </div>\n    </div>\n    <div class=\"inner-scroll split-view__list\">\n      <c8y-package-contents\n        [selectedVersion]=\"selectedVersion\"\n        [selectedPlugin]=\"selectedPlugin\"\n        (showOverview)=\"showPluginOverview($event)\"\n      ></c8y-package-contents>\n    </div>\n  </div>\n\n  <!-- Plugin readme -->\n  <div\n    class=\"inner-scroll split-view__detail\"\n    [ngClass]=\"{ 'split-view__detail--selected': selectedPlugin }\"\n  >\n    <div\n      class=\"card-header separator sticky-top\"\n      *ngIf=\"selectedPlugin\"\n    >\n      <button\n        class=\"btn-clean\"\n        (click)=\"closeOverview()\"\n      >\n        <i c8yIcon=\"caret-back\"></i>\n        {{ 'Back to package versions overview ' | translate }}\n      </button>\n    </div>\n    <div\n      class=\"card-block p-l-16 p-r-16 overflow-visible\"\n      *ngIf=\"selectedPlugin\"\n    >\n      <div\n        class=\"markdown-content\"\n        *ngIf=\"pluginMarkdown\"\n        [innerHTML]=\"pluginMarkdown | markdownToHtml: { baseUrl: pluginBaseUrl } | async\"\n      ></div>\n      <c8y-ui-empty-state\n        [icon]=\"'user-manual'\"\n        [title]=\"'No README.md found for plugin' | translate\"\n        [subtitle]=\"\n          'To view the contents of &quot;README&quot;, add the file &quot;README.md&quot; to the plugin.'\n            | translate\n        \"\n        *ngIf=\"!pluginMarkdown\"\n        [horizontal]=\"true\"\n      ></c8y-ui-empty-state>\n    </div>\n  </div>\n</div>\n" }]
        }], ctorParameters: () => [{ type: i1$2.ActivatedRoute }, { type: i2.ContextRouteService }, { type: i2.PluginsService }] });

class PackageGuard {
    constructor(ecosystemService) {
        this.ecosystemService = ecosystemService;
    }
    canActivate(route) {
        const app = route.data.contextData || route.parent.data.contextData;
        if (!app) {
            return false;
        }
        return this.ecosystemService.isPackage(app);
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: PackageGuard, deps: [{ token: i1.EcosystemService }], target: i0.ɵɵFactoryTarget.Injectable }); }
    static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: PackageGuard }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: PackageGuard, decorators: [{
            type: Injectable
        }], ctorParameters: () => [{ type: i1.EcosystemService }] });

class PackageChangelogTabComponent {
    constructor(activatedRoute, contextRouteService) {
        this.activatedRoute = activatedRoute;
        this.contextRouteService = contextRouteService;
        this.package = {};
    }
    async ngOnInit() {
        this.package = this.contextRouteService.getContextData(this.activatedRoute)?.contextData;
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: PackageChangelogTabComponent, deps: [{ token: i1$2.ActivatedRoute }, { token: i2.ContextRouteService }], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.14", type: PackageChangelogTabComponent, isStandalone: true, selector: "c8y-package-changelog-tab", ngImport: i0, template: "<c8y-title>{{ package?.name | humanizeAppName | async }}</c8y-title>\n\n<c8y-breadcrumb>\n  <c8y-breadcrumb-item\n    [icon]=\"'c8y-atom'\"\n    [label]=\"'Ecosystem' | translate\"\n  ></c8y-breadcrumb-item>\n  <c8y-breadcrumb-item\n    [icon]=\"'big-parcel'\"\n    [label]=\"'Extensions' | translate\"\n    [path]=\"'ecosystem/extension/extensions'\"\n  ></c8y-breadcrumb-item>\n  <c8y-breadcrumb-item [label]=\"package?.name | humanizeAppName | async\"></c8y-breadcrumb-item>\n  <c8y-breadcrumb-item [label]=\"'Change logs' | translate\"></c8y-breadcrumb-item>\n</c8y-breadcrumb>\n\n<c8y-contents-changelog [package]=\"package\"></c8y-contents-changelog>\n", dependencies: [{ kind: "component", type: PackageChangelogComponent, selector: "c8y-contents-changelog", inputs: ["package", "selectedVersion", "previousVersion"] }, { kind: "component", type: TitleComponent, selector: "c8y-title", inputs: ["pageTitleUpdate"] }, { kind: "pipe", type: HumanizeAppNamePipe, name: "humanizeAppName" }, { kind: "component", type: BreadcrumbComponent, selector: "c8y-breadcrumb" }, { kind: "component", type: BreadcrumbItemComponent, selector: "c8y-breadcrumb-item", inputs: ["icon", "translate", "label", "path", "injector"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }, { kind: "pipe", type: AsyncPipe, name: "async" }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: PackageChangelogTabComponent, decorators: [{
            type: Component,
            args: [{ selector: 'c8y-package-changelog-tab', standalone: true, imports: [
                        PackageChangelogComponent,
                        TitleComponent,
                        HumanizeAppNamePipe,
                        BreadcrumbComponent,
                        BreadcrumbItemComponent,
                        C8yTranslatePipe,
                        AsyncPipe
                    ], template: "<c8y-title>{{ package?.name | humanizeAppName | async }}</c8y-title>\n\n<c8y-breadcrumb>\n  <c8y-breadcrumb-item\n    [icon]=\"'c8y-atom'\"\n    [label]=\"'Ecosystem' | translate\"\n  ></c8y-breadcrumb-item>\n  <c8y-breadcrumb-item\n    [icon]=\"'big-parcel'\"\n    [label]=\"'Extensions' | translate\"\n    [path]=\"'ecosystem/extension/extensions'\"\n  ></c8y-breadcrumb-item>\n  <c8y-breadcrumb-item [label]=\"package?.name | humanizeAppName | async\"></c8y-breadcrumb-item>\n  <c8y-breadcrumb-item [label]=\"'Change logs' | translate\"></c8y-breadcrumb-item>\n</c8y-breadcrumb>\n\n<c8y-contents-changelog [package]=\"package\"></c8y-contents-changelog>\n" }]
        }], ctorParameters: () => [{ type: i1$2.ActivatedRoute }, { type: i2.ContextRouteService }] });

class PackageChangelogGuard {
    constructor() {
        this.pluginsService = inject(PluginsService);
        this.router = inject(Router);
    }
    async canActivate(route) {
        const app = route.data.contextData || route.parent.data.contextData;
        const packageChangelogUrl = `/apps/${app.contextPath}/`;
        const changelog = await this.pluginsService.getChangelogFileContent(packageChangelogUrl);
        return !!changelog;
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: PackageChangelogGuard, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
    static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: PackageChangelogGuard }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: PackageChangelogGuard, decorators: [{
            type: Injectable
        }] });

const ecosystemMainRoutes = [
    {
        path: 'ecosystem/application',
        redirectTo: 'ecosystem/application/applications',
        pathMatch: 'full'
    },
    {
        // keeps legacy links functional
        path: 'ecosystem/applications',
        redirectTo: 'ecosystem/application/applications',
        pathMatch: 'full'
    },
    {
        path: 'ecosystem/application/applications',
        component: ApplicationListComponent
    },
    {
        path: 'ecosystem/extension/extensions',
        component: PackagesListComponent
    },
    {
        path: 'ecosystem/application/features',
        component: FeatureListComponent
    },
    {
        path: 'ecosystem/microservice/microservices',
        component: MicroserviceListComponent
    }
];
const applicationDetailsRoutes = [
    {
        path: 'properties',
        component: ApplicationPropertiesComponent,
        icon: 'list',
        label: gettext('Properties'),
        context: ViewContext.Application,
        priority: 5,
        canActivate: [ApplicationPropertiesGuard]
    },
    {
        path: 'application-versions',
        component: PackageVersionsComponent,
        icon: 'c8y-modules',
        label: gettext('Versions'),
        context: ViewContext.Application,
        priority: 1,
        canActivate: [PackageVersionsGuard]
    },
    {
        path: 'properties',
        component: ApplicationPropertiesComponent,
        icon: 'list',
        label: gettext('Properties'),
        context: ViewContext.Feature,
        priority: 5,
        canActivate: [ApplicationPropertiesGuard]
    },
    {
        path: 'package-details',
        component: PackageDetailsComponent,
        icon: 'big-parcel',
        label: gettext('Extension package'),
        context: ViewContext.Extension,
        priority: 10,
        canActivate: [PackageGuard]
    },
    {
        path: 'package-versions',
        component: PackageVersionsComponent,
        icon: 'c8y-modules',
        label: gettext('Versions'),
        context: ViewContext.Extension,
        priority: 5,
        canActivate: [PackageGuard, PackageVersionsGuard]
    },
    {
        path: 'package-changelog',
        component: PackageChangelogTabComponent,
        icon: 'list',
        label: gettext('Change log'),
        context: ViewContext.Extension,
        priority: 1,
        canActivate: [PackageGuard, PackageChangelogGuard]
    },
    {
        path: 'properties',
        component: ApplicationPropertiesComponent,
        icon: 'list',
        label: gettext('Properties'),
        context: ViewContext.Microservice,
        priority: 5,
        canActivate: [ApplicationPropertiesGuard]
    }
];
class EcosystemModule {
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: EcosystemModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
    static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.2.14", ngImport: i0, type: EcosystemModule, imports: [CoreModule,
            BsDropdownModule,
            TooltipModule,
            FormsModule$1,
            ReactiveFormsModule, i1$2.RouterModule, PopoverModule,
            ApplicationPluginsModule,
            SharedEcosystemModule,
            LicenseConfirmModule,
            IconSelectorModule,
            A11yModule,
            ArchivedConfirmModule,
            PackageChangelogTabComponent,
            ApplicationListComponent,
            MicroserviceListComponent,
            ApplicationPropertiesComponent,
            AddMicroserviceComponent,
            ActivityLogComponent,
            AddWebApplicationComponent,
            AddExternalApplicationComponent,
            InstallFromPackageComponent,
            PackagesListComponent,
            PackageDetailsComponent,
            DeployApplicationComponent,
            AddPackageComponent,
            FeatureListComponent,
            PackageVersionsComponent,
            PackageVersionsPluginsComponent,
            PackageVersionsAppsComponent,
            PackageContentsComponent,
            PackageVersionsListComponent,
            SubscriptionModalComponent,
            UpdateApplicationModalComponent], exports: [ApplicationPropertiesComponent, UpdateApplicationModalComponent] }); }
    static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: EcosystemModule, providers: [
            hookTab(EcosystemTabs),
            hookRoute(applicationDetailsRoutes),
            PackageGuard,
            PackageVersionsGuard,
            PackageChangelogGuard,
            ApplicationPropertiesGuard,
            hookWizard({
                wizardId: EcosystemWizards.APPLICATION_UPLOAD,
                component: AddWebApplicationComponent,
                name: gettext('Upload web application'),
                c8yIcon: 'upload'
            }),
            hookWizard({
                name: undefined,
                wizardId: EcosystemWizards.PACKAGE_UPLOAD,
                component: AddPackageComponent
            }),
            hookWizard({
                wizardId: EcosystemWizards.APPLICATION_UPLOAD,
                component: AddExternalApplicationComponent,
                name: gettext('External application'),
                c8yIcon: 'cloud-link'
            }),
            hookWizard({
                wizardId: EcosystemWizards.BLUEPRINT_DEPLOYMENT,
                component: DeployApplicationComponent,
                name: gettext('Deploy package'),
                c8yIcon: 'big-parcel'
            }),
            hookWizard({
                wizardId: EcosystemWizards.APPLICATION_UPLOAD,
                component: InstallFromPackageComponent,
                name: gettext('Install from available extension packages'),
                c8yIcon: 'big-parcel'
            }),
            hookWizard({
                name: undefined,
                wizardId: EcosystemWizards.MICROSERVICE_UPLOAD,
                component: AddMicroserviceComponent
            })
        ], imports: [CoreModule,
            BsDropdownModule,
            TooltipModule,
            FormsModule$1,
            ReactiveFormsModule,
            RouterModule.forChild(ecosystemMainRoutes),
            PopoverModule,
            ApplicationPluginsModule,
            SharedEcosystemModule,
            LicenseConfirmModule,
            IconSelectorModule,
            A11yModule,
            ArchivedConfirmModule,
            PackageChangelogTabComponent,
            ApplicationListComponent,
            MicroserviceListComponent,
            ApplicationPropertiesComponent,
            AddMicroserviceComponent,
            ActivityLogComponent,
            AddWebApplicationComponent,
            AddExternalApplicationComponent,
            InstallFromPackageComponent,
            PackagesListComponent,
            PackageDetailsComponent,
            DeployApplicationComponent,
            AddPackageComponent,
            FeatureListComponent,
            PackageVersionsComponent,
            PackageVersionsPluginsComponent,
            PackageVersionsAppsComponent,
            PackageContentsComponent,
            PackageVersionsListComponent,
            SubscriptionModalComponent,
            UpdateApplicationModalComponent] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: EcosystemModule, decorators: [{
            type: NgModule,
            args: [{
                    imports: [
                        CoreModule,
                        BsDropdownModule,
                        TooltipModule,
                        FormsModule$1,
                        ReactiveFormsModule,
                        RouterModule.forChild(ecosystemMainRoutes),
                        PopoverModule,
                        ApplicationPluginsModule,
                        SharedEcosystemModule,
                        LicenseConfirmModule,
                        IconSelectorModule,
                        A11yModule,
                        ArchivedConfirmModule,
                        PackageChangelogTabComponent,
                        ApplicationListComponent,
                        MicroserviceListComponent,
                        ApplicationPropertiesComponent,
                        AddMicroserviceComponent,
                        ActivityLogComponent,
                        AddWebApplicationComponent,
                        AddExternalApplicationComponent,
                        InstallFromPackageComponent,
                        PackagesListComponent,
                        PackageDetailsComponent,
                        DeployApplicationComponent,
                        AddPackageComponent,
                        FeatureListComponent,
                        PackageVersionsComponent,
                        PackageVersionsPluginsComponent,
                        PackageVersionsAppsComponent,
                        PackageContentsComponent,
                        PackageVersionsListComponent,
                        SubscriptionModalComponent,
                        UpdateApplicationModalComponent
                    ],
                    exports: [ApplicationPropertiesComponent, UpdateApplicationModalComponent],
                    providers: [
                        hookTab(EcosystemTabs),
                        hookRoute(applicationDetailsRoutes),
                        PackageGuard,
                        PackageVersionsGuard,
                        PackageChangelogGuard,
                        ApplicationPropertiesGuard,
                        hookWizard({
                            wizardId: EcosystemWizards.APPLICATION_UPLOAD,
                            component: AddWebApplicationComponent,
                            name: gettext('Upload web application'),
                            c8yIcon: 'upload'
                        }),
                        hookWizard({
                            name: undefined,
                            wizardId: EcosystemWizards.PACKAGE_UPLOAD,
                            component: AddPackageComponent
                        }),
                        hookWizard({
                            wizardId: EcosystemWizards.APPLICATION_UPLOAD,
                            component: AddExternalApplicationComponent,
                            name: gettext('External application'),
                            c8yIcon: 'cloud-link'
                        }),
                        hookWizard({
                            wizardId: EcosystemWizards.BLUEPRINT_DEPLOYMENT,
                            component: DeployApplicationComponent,
                            name: gettext('Deploy package'),
                            c8yIcon: 'big-parcel'
                        }),
                        hookWizard({
                            wizardId: EcosystemWizards.APPLICATION_UPLOAD,
                            component: InstallFromPackageComponent,
                            name: gettext('Install from available extension packages'),
                            c8yIcon: 'big-parcel'
                        }),
                        hookWizard({
                            name: undefined,
                            wizardId: EcosystemWizards.MICROSERVICE_UPLOAD,
                            component: AddMicroserviceComponent
                        })
                    ]
                }]
        }] });

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

export { ActivityLogComponent, AddExternalApplicationComponent, AddMicroserviceComponent, AddPackageComponent, AddWebApplicationComponent, ApplicationListComponent, ApplicationPropertiesComponent, ApplicationPropertiesGuard, DeployApplicationComponent, EcosystemModule, EcosystemTabs, FeatureListComponent, InstallFromPackageComponent, MicroserviceListComponent, PackageDetailsComponent, PackageGuard, PackageVersionsComponent, PackageVersionsPluginsComponent, PackagesListComponent, UpdateApplicationModalComponent };
//# sourceMappingURL=c8y-ngx-components-ecosystem.mjs.map