@c8y/ngx-components 1017.0.31 → 1017.0.33

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/ecosystem/application-plugins/application-plugins.component.d.ts +54 -3
  2. package/ecosystem/application-plugins/plugin-list.component.d.ts +5 -3
  3. package/ecosystem/application-plugins/update-plugin-of-app/update-plugin-of-app.component.d.ts +4 -2
  4. package/ecosystem/application-properties/application-properties.component.d.ts +5 -3
  5. package/ecosystem/packages/deploy-application/deploy-application.component.d.ts +5 -4
  6. package/ecosystem/packages/package-availability.service.d.ts +4 -2
  7. package/ecosystem/packages/package-versions/package-versions-list/package-versions-list.component.d.ts +4 -2
  8. package/ecosystem/shared/application-card.component.d.ts +5 -3
  9. package/ecosystem/shared/duplicate-application/duplicate-application-properties/duplicate-application-properties.component.d.ts +4 -2
  10. package/ecosystem/shared/ecosystem.model.d.ts +49 -0
  11. package/esm2020/core/help/help.component.mjs +3 -3
  12. package/esm2020/ecosystem/application-plugins/application-plugins.component.mjs +32 -9
  13. package/esm2020/ecosystem/application-plugins/plugin-list.component.mjs +18 -6
  14. package/esm2020/ecosystem/application-plugins/update-plugin-of-app/update-plugin-of-app.component.mjs +20 -5
  15. package/esm2020/ecosystem/application-properties/application-properties.component.mjs +13 -6
  16. package/esm2020/ecosystem/packages/deploy-application/deploy-application.component.mjs +20 -7
  17. package/esm2020/ecosystem/packages/package-availability.service.mjs +18 -5
  18. package/esm2020/ecosystem/packages/package-versions/package-versions-list/package-versions-list.component.mjs +43 -6
  19. package/esm2020/ecosystem/shared/application-card.component.mjs +28 -5
  20. package/esm2020/ecosystem/shared/duplicate-application/duplicate-application-properties/duplicate-application-properties.component.mjs +21 -8
  21. package/esm2020/ecosystem/shared/ecosystem.model.mjs +50 -1
  22. package/esm2020/operations/operations-list/operations-list-item.component.mjs +3 -3
  23. package/fesm2015/c8y-ngx-components-ecosystem-application-plugins.mjs +61 -12
  24. package/fesm2015/c8y-ngx-components-ecosystem-application-plugins.mjs.map +1 -1
  25. package/fesm2015/c8y-ngx-components-ecosystem-shared.mjs +90 -7
  26. package/fesm2015/c8y-ngx-components-ecosystem-shared.mjs.map +1 -1
  27. package/fesm2015/c8y-ngx-components-ecosystem.mjs +143 -24
  28. package/fesm2015/c8y-ngx-components-ecosystem.mjs.map +1 -1
  29. package/fesm2015/c8y-ngx-components-operations-operations-list.mjs +2 -2
  30. package/fesm2015/c8y-ngx-components-operations-operations-list.mjs.map +1 -1
  31. package/fesm2015/c8y-ngx-components.mjs +2 -2
  32. package/fesm2015/c8y-ngx-components.mjs.map +1 -1
  33. package/fesm2020/c8y-ngx-components-ecosystem-application-plugins.mjs +61 -12
  34. package/fesm2020/c8y-ngx-components-ecosystem-application-plugins.mjs.map +1 -1
  35. package/fesm2020/c8y-ngx-components-ecosystem-shared.mjs +90 -7
  36. package/fesm2020/c8y-ngx-components-ecosystem-shared.mjs.map +1 -1
  37. package/fesm2020/c8y-ngx-components-ecosystem.mjs +143 -24
  38. package/fesm2020/c8y-ngx-components-ecosystem.mjs.map +1 -1
  39. package/fesm2020/c8y-ngx-components-operations-operations-list.mjs +2 -2
  40. package/fesm2020/c8y-ngx-components-operations-operations-list.mjs.map +1 -1
  41. package/fesm2020/c8y-ngx-components.mjs +2 -2
  42. package/fesm2020/c8y-ngx-components.mjs.map +1 -1
  43. package/package.json +2 -2
@@ -3,7 +3,7 @@ import { Component, Input, Injectable, ViewChild, Pipe, EventEmitter, Output, Ng
3
3
  import * as i2 from '@c8y/ngx-components';
4
4
  import { gettext, Status, ViewContext, ApplicationPluginStatus, DataGridComponent, CoreModule, hookRoute, FormsModule, hookTab, hookNavigator, hookWizard } from '@c8y/ngx-components';
5
5
  import * as i1 from '@c8y/ngx-components/ecosystem/shared';
6
- import { packageProperties, ApplicationPropertiesFormComponent, ERROR_TYPE, SharedEcosystemModule } from '@c8y/ngx-components/ecosystem/shared';
6
+ import { packageProperties, PRODUCT_EXPERIENCE, ApplicationPropertiesFormComponent, ERROR_TYPE, SharedEcosystemModule } from '@c8y/ngx-components/ecosystem/shared';
7
7
  import * as i3 from '@angular/common';
8
8
  import * as i3$1 from '@angular/forms';
9
9
  import { Validators, ReactiveFormsModule } from '@angular/forms';
@@ -190,7 +190,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.6", ngImpor
190
190
  const MICROSERVICES_BASE_PATH = '/microservices';
191
191
  const APPLICATIONS_BASE_PATH = '/ecosystem';
192
192
  class ApplicationPropertiesComponent {
193
- constructor(activatedRoute, ecosystemService, router, formBuilder, applicationService, alertService, inventoryService, permissions, modalService, translate, bsModalService) {
193
+ constructor(activatedRoute, ecosystemService, router, formBuilder, applicationService, alertService, inventoryService, permissions, modalService, translate, bsModalService, gainsightService) {
194
194
  this.activatedRoute = activatedRoute;
195
195
  this.ecosystemService = ecosystemService;
196
196
  this.router = router;
@@ -202,6 +202,8 @@ class ApplicationPropertiesComponent {
202
202
  this.modalService = modalService;
203
203
  this.translate = translate;
204
204
  this.bsModalService = bsModalService;
205
+ this.gainsightService = gainsightService;
206
+ this.CURRENT_LOCATION = location.href;
205
207
  this.singleTenant = false;
206
208
  this.subscription = false;
207
209
  this.iconMap = {
@@ -321,6 +323,11 @@ class ApplicationPropertiesComponent {
321
323
  this.loadBinaryMo();
322
324
  }
323
325
  async updateToLatestVersion() {
326
+ this.gainsightService.triggerEvent(PRODUCT_EXPERIENCE.APPLICATIONS.EVENTS.APPLICATION_PROPERTIES, {
327
+ component: PRODUCT_EXPERIENCE.APPLICATIONS.COMPONENTS.APPLICATION_PROPERTIES,
328
+ action: PRODUCT_EXPERIENCE.APPLICATIONS.ACTIONS.UPDATE_AVAILABLE,
329
+ url: this.CURRENT_LOCATION
330
+ });
324
331
  try {
325
332
  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.`), {
326
333
  currentVersion: this.application.manifest?.version,
@@ -457,12 +464,12 @@ class ApplicationPropertiesComponent {
457
464
  }
458
465
  }
459
466
  }
460
- ApplicationPropertiesComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.6", ngImport: i0, type: ApplicationPropertiesComponent, deps: [{ token: i1$2.ActivatedRoute }, { token: i1.EcosystemService }, { token: i1$2.Router }, { token: i3$1.FormBuilder }, { token: i2$1.ApplicationService }, { token: i2.AlertService }, { token: i2$1.InventoryService }, { token: i2.Permissions }, { token: i2.ModalService }, { token: i4.TranslateService }, { token: i1$1.BsModalService }], target: i0.ɵɵFactoryTarget.Component });
467
+ ApplicationPropertiesComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.6", ngImport: i0, type: ApplicationPropertiesComponent, deps: [{ token: i1$2.ActivatedRoute }, { token: i1.EcosystemService }, { token: i1$2.Router }, { token: i3$1.FormBuilder }, { token: i2$1.ApplicationService }, { token: i2.AlertService }, { token: i2$1.InventoryService }, { token: i2.Permissions }, { token: i2.ModalService }, { token: i4.TranslateService }, { token: i1$1.BsModalService }, { token: i2.GainsightService }], target: i0.ɵɵFactoryTarget.Component });
461
468
  ApplicationPropertiesComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.0.6", type: ApplicationPropertiesComponent, selector: "c8y-application-properties", ngImport: i0, template: "<c8y-title>{{ application | humanizeAppName | async }}</c8y-title>\n\n<c8y-breadcrumb *ngIf=\"!isMicroservice\">\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/applications'\"\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<c8y-breadcrumb *ngIf=\"isMicroservice\">\n <c8y-breadcrumb-item [icon]=\"'c8y-atom'\" [label]=\"'Ecosystem' | translate\"></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 *ngIf=\"application\"\n [ngClass]=\"{ 'd-grid grid__col--7-5--md': isActivityLogSupported }\"\n class=\"card content-fullpage\"\n >\n <form\n (ngSubmit)=\"formGroup.valid && save(formGroup.value)\"\n [formGroup]=\"formGroup\"\n class=\"d-flex d-col content-fullpage\"\n novalidate\n >\n <div *ngIf=\"!isLoading\" class=\"d-contents\">\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 *ngIf=\"!isPackage && !isFeature && !isMicroservice && !isExternal\"\n [app]=\"application\"\n [contextPath]=\"application.contextPath\"\n [name]=\"application.name\"\n class=\"icon-48\"\n ></c8y-app-icon>\n <i *ngIf=\"isPackage\" c8yIcon=\"big-parcel\" class=\"icon-48\"></i>\n <i *ngIf=\"isFeature\" c8yIcon=\"tab\" class=\"icon-48\"></i>\n <i *ngIf=\"isMicroservice\" c8yIcon=\"microchip\" class=\"icon-48\"></i>\n <i *ngIf=\"isExternal\" c8yIcon=\"globe1\" class=\"icon-48\"></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 {{ application.description || ('No description available.' | translate) }}\n </em>\n </p>\n <div *ngIf=\"isOwner\" class=\"form-group m-b-0\">\n <label\n [ngClass]=\"{ updated: formGroup?.controls?.description?.dirty }\"\n class=\"editable\"\n >\n <textarea\n c8y-textarea-autoresize\n class=\"form-control no-resize\"\n formControlName=\"description\"\n name=\"description\"\n placeholder=\"{{ 'No description available.' | translate }}\"\n ></textarea>\n </label>\n </div>\n </div>\n <div class=\"text-right-md m-t-4\">\n <span [ngClass]=\"appState?.class\" class=\"label\">\n {{ appState?.label | translate }}\n </span>\n <div class=\"fit-w m-t-2\" *ngIf=\"isPackage || isMicroservice\">\n <label class=\"text-label-small\" translate>Version:</label>\n <small class=\"p-l-4 text-bold\">{{ application.manifest?.version }}</small>\n </div>\n <div class=\"fit-w m-t-2\">\n <label class=\"text-label-small\" translate>Creation time:</label>\n <small class=\"p-l-4 text-bold\">{{ (binaryMo?.creationTime | c8yDate) || '---' }}</small>\n </div>\n <div class=\"m-t-8\">\n <button\n type=\"button\"\n *ngIf=\"isUpdateAvailable\"\n (click)=\"updateToLatestVersion()\"\n [ngClass]=\"{ 'btn-pending': isUpdateOngoing }\"\n class=\"btn btn-warning btn-sm\"\n >\n {{ 'Update available' | translate }}\n </button>\n <button\n (click)=\"openApp(application)\"\n [disabled]=\"disableOpenInBrowser\"\n *ngIf=\"canOpenInBrowser\"\n class=\"btn btn-default btn-sm\"\n title=\"{{ 'Open' | translate }}\"\n type=\"button\"\n >\n <i [c8yIcon]=\"'external-link'\"></i>\n {{ 'Open' | translate }}\n </button>\n <div *ngIf=\"canOpenInBrowser && disableOpenInBrowser\">\n <small class=\"text-muted\" translate>\n The application is overwritten by a custom application sharing the same path\n </small>\n </div>\n <span *ngIf=\"isCustomMicroservice\">\n <button\n (click)=\"subscribe()\"\n *ngIf=\"!isSubscribed\"\n class=\"btn btn-default btn-sm\"\n title=\"{{ 'Subscribe' | translate }}\"\n >\n <i [c8yIcon]=\"'check-circle-o'\"></i>\n {{ 'Subscribe' | translate }}\n </button>\n <button\n (click)=\"unsubscribe()\"\n *ngIf=\"isSubscribed\"\n class=\"btn btn-default btn-sm\"\n title=\"{{ 'Unsubscribe' | translate }}\"\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 *ngIf=\"isPackage\" class=\"row p-16\">\n <c8y-properties-list\n [data]=\"application.manifest\"\n [properties]=\"packageProperties\"\n [title]=\"'Package details' | translate\"\n [emptyLabel]=\"'---'\"\n icon=\"info\"\n ></c8y-properties-list>\n </div>\n <div *ngIf=\"sourcePackage\" class=\"row p-16\">\n <c8y-properties-list\n [data]=\"sourcePackage.manifest\"\n [properties]=\"packageProperties\"\n [title]=\"'Source package information' | translate\"\n [emptyLabel]=\"'---'\"\n icon=\"info\"\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 [readonly]=\"true\"\n autocomplete=\"off\"\n class=\"form-control\"\n formControlName=\"id\"\n name=\"id\"\n id=\"appId\"\n type=\"text\"\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 [readonly]=\"!isOwner\"\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 </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 [readonly]=\"application.id || !isOwner\"\n class=\"form-control\"\n name=\"key\"\n formControlName=\"key\"\n placeholder=\"{{ 'e.g. my-application-key' | translate }}\"\n required\n type=\"text\"\n />\n </c8y-form-group>\n </div>\n\n <div class=\"col-sm-7\">\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 [readOnly]=\"application.id || !isOwner\"\n class=\"form-control\"\n name=\"contextPath\"\n placeholder=\"{{ 'e.g. my-application`used in URL`' | translate }}\"\n required\n type=\"text\"\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 [readOnly]=\"application.id || !isOwner\"\n class=\"form-control\"\n name=\"contextPath\"\n placeholder=\"{{ 'e.g. my-microservice`used in URL`' | translate }}\"\n required\n type=\"text\"\n formControlName=\"contextPath\"\n />\n </div>\n </c8y-form-group>\n <div class=\"row\">\n <div *ngIf=\"application.manifest.version\" class=\"col-sm-4 m-b-16 flex-auto\">\n <label>{{ 'Version' | translate }}</label>\n <p class=\"form-control-static\">\n {{ application.manifest.version }}\n </p>\n </div>\n <div *ngIf=\"application.manifest.isolation\" class=\"col-sm-4 m-b-16 flex-auto\">\n <label>{{ 'Isolation' | translate }}</label>\n <p class=\"form-control-static\">\n <span *ngIf=\"singleTenant\">\n <i [c8yIcon]=\"'c8y-enterprise'\" class=\"c8y-icon-duocolor h4\"></i>\n {{ 'Single tenant' | translate }}\n </span>\n <span *ngIf=\"!singleTenant\">\n <i [c8yIcon]=\"'c8y-sub-tenants'\" class=\"c8y-icon-duocolor icon-32\"></i>\n {{ 'Multi tenant' | translate }}\n </span>\n </p>\n </div>\n <div *ngIf=\"application.manifest.isolation\" class=\"col-sm-4 m-b-16 flex-auto\">\n <label>{{ 'Billing mode' | translate }}</label>\n <p class=\"form-control-static\">\n <span\n *ngIf=\"subscription\"\n [tooltip]=\"'Resources usage assigned to: Owner' | translate\"\n >\n {{ 'Subscription' | translate }}\n </span>\n <span\n *ngIf=\"!subscription && singleTenant\"\n [tooltip]=\"'Resources usage assigned to: Subscriber | translate'\"\n >\n {{ 'Resources' | translate }}\n </span>\n <span\n *ngIf=\"!subscription && !singleTenant\"\n [tooltip]=\"'Resources usage assigned to: Owner' | translate\"\n >\n {{ 'Resources' | translate }}\n </span>\n </p>\n </div>\n </div>\n\n <div *ngIf=\"application.manifest.provider\" class=\"legend form-block m-t-40\">\n {{ 'Provider' | translate }}\n </div>\n <div class=\"list-inline\" *ngIf=\"application.manifest.provider\">\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=\"'REPOSITORY'\">\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 [readOnly]=\"application.id || !isOwner\"\n class=\"form-control\"\n formControlName=\"contextPath\"\n name=\"contextPath\"\n placeholder=\"{{ 'e.g. my-application`used in URL`' | translate }}\"\n required\n type=\"text\"\n />\n </div>\n </c8y-form-group>\n\n <c8y-form-group>\n <label>{{ 'Server URL' | translate }}</label>\n <input\n class=\"form-control\"\n name=\"resourcesUrl\"\n formControlName=\"resourcesUrl\"\n placeholder=\"{{ 'e.g. my-application`used in URL`' | translate }}\"\n required\n type=\"url\"\n />\n </c8y-form-group>\n\n <div class=\"form-group\">\n <label>{{ 'Username' | translate }}</label>\n <input\n class=\"form-control\"\n formControlName=\"username\"\n name=\"username\"\n type=\"text\"\n />\n </div>\n\n <div class=\"form-group\">\n <label>{{ 'Password' | translate }}</label>\n <input\n class=\"form-control\"\n formControlName=\"password\"\n name=\"password\"\n type=\"text\"\n />\n </div>\n </div>\n\n <div *ngSwitchCase=\"'EXTERNAL'\">\n <c8y-form-group>\n <label>{{ 'External URL' | translate }}</label>\n <input\n [pattern]=\"'^(?!javascript:).+'\"\n [readOnly]=\"!isOwner\"\n class=\"form-control\"\n formControlName=\"externalUrl\"\n name=\"externalUrl\"\n placeholder=\"{{ 'e.g.' | translate }} http://www.example.com/\"\n required\n type=\"url\"\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 </div>\n </div>\n </div>\n <ng-container *ngIf=\"isCustomMicroservice\">\n <div *ngIf=\"!isLoading\" class=\"d-contents\">\n <c8y-upload-archive\n [(application)]=\"application\"\n (refresh)=\"onNewArchive()\"\n ></c8y-upload-archive>\n </div>\n </ng-container>\n <div\n *ngIf=\"application && !!isOwner && hasAdminPermissions\"\n class=\"card-footer separator\"\n >\n <button\n (click)=\"cancel()\"\n class=\"btn btn-default\"\n title=\"{{ 'Cancel' | translate }}\"\n type=\"button\"\n >\n {{ 'Cancel' | translate }}\n </button>\n <button\n (click)=\"delete()\"\n *ngIf=\"canDelete\"\n class=\"btn btn-danger\"\n title=\"{{ 'Delete' | translate }}\"\n type=\"button\"\n >\n {{ 'Delete' | translate }}\n </button>\n <button\n [disabled]=\"!application.type || formGroup.invalid || formGroup.pristine\"\n class=\"btn btn-primary btn-form\"\n title=\"{{ 'Save' | translate }}\"\n type=\"submit\"\n >\n {{ 'Save' | translate }}\n </button>\n </div>\n </div>\n </form>\n\n <div *ngIf=\"isActivityLogSupported\" class=\"content-fullpage d-flex d-col bg-level-1\">\n <div class=\"card-header separator\">\n <div class=\"card-title\" translate>Activity log</div>\n <div class=\"m-l-auto\">\n <button\n (click)=\"load()\"\n class=\"btn btn-link btn-sm\"\n title=\"{{ 'Reload' | translate }}\"\n type=\"button\"\n >\n <i [ngClass]=\"{ 'icon-spin': isLoading }\" c8yIcon=\"refresh\"></i>\n {{ 'Reload' | translate }}\n </button>\n </div>\n </div>\n <div *ngIf=\"isLoading\" class=\"p-16 text-center\">\n <c8y-loading></c8y-loading>\n </div>\n <c8y-activity-log\n *ngIf=\"!isLoading\"\n [hasAdminPermissions]=\"hasAdminPermissions\"\n [application]=\"application\"\n class=\"d-contents\"\n ></c8y-activity-log>\n </div>\n </div>\n </div>\n</div>\n", dependencies: [{ kind: "component", type: i2.BreadcrumbComponent, selector: "c8y-breadcrumb" }, { kind: "component", type: i2.BreadcrumbItemComponent, selector: "c8y-breadcrumb-item", inputs: ["icon", "translate", "label", "path", "injector"] }, { kind: "directive", type: i2.IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "directive", type: i2.C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "directive", type: i3.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: i3.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "component", type: i2.LoadingComponent, selector: "c8y-loading" }, { kind: "directive", type: i2.TextareaAutoresizeDirective, selector: "[c8y-textarea-autoresize]" }, { kind: "component", type: i2.TitleComponent, selector: "c8y-title", inputs: ["pageTitleUpdate"] }, { kind: "component", type: i2.AppIconComponent, selector: "c8y-app-icon", inputs: ["contextPath", "name", "app"] }, { kind: "directive", type: i3$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i3$1.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$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i3$1.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i3$1.PatternValidator, selector: "[pattern][formControlName],[pattern][formControl],[pattern][ngModel]", inputs: ["pattern"] }, { kind: "component", type: i2.FormGroupComponent, selector: "c8y-form-group", inputs: ["hasError", "hasWarning", "hasSuccess", "novalidation", "status"] }, { kind: "directive", type: i2.MessageDirective, selector: "c8y-message", inputs: ["name", "text"] }, { kind: "component", type: i2.MessagesComponent, selector: "c8y-messages", inputs: ["show", "defaults"] }, { kind: "directive", type: i2.RequiredInputPlaceholderDirective, selector: "input[required], input[formControlName]" }, { kind: "directive", type: i3$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i3$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: i2.PropertiesListComponent, selector: "c8y-properties-list", inputs: ["properties", "title", "icon", "data", "groups", "noParse", "emptyLabel"] }, { kind: "directive", type: i9.TooltipDirective, selector: "[tooltip], [tooltipHtml]", inputs: ["adaptivePosition", "tooltip", "placement", "triggers", "container", "containerClass", "boundariesElement", "isOpen", "isDisabled", "delay", "tooltipHtml", "tooltipPlacement", "tooltipIsOpen", "tooltipEnable", "tooltipAppendToBody", "tooltipAnimation", "tooltipClass", "tooltipContext", "tooltipPopupDelay", "tooltipFadeDuration", "tooltipTrigger"], outputs: ["tooltipChange", "onShown", "onHidden", "tooltipStateChanged"], exportAs: ["bs-tooltip"] }, { kind: "component", type: i1.UploadArchiveComponent, selector: "c8y-upload-archive", inputs: ["application", "uploadNewVersion", "preUploadCallback"], outputs: ["applicationChange", "refresh"] }, { kind: "component", type: ActivityLogComponent, selector: "c8y-activity-log", inputs: ["application", "hasAdminPermissions"] }, { kind: "pipe", type: i2.C8yTranslatePipe, name: "translate" }, { kind: "pipe", type: i3.AsyncPipe, name: "async" }, { kind: "pipe", type: i2.HumanizeAppNamePipe, name: "humanizeAppName" }, { kind: "pipe", type: i2.DatePipe, name: "c8yDate" }] });
462
469
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.6", ngImport: i0, type: ApplicationPropertiesComponent, decorators: [{
463
470
  type: Component,
464
471
  args: [{ selector: 'c8y-application-properties', template: "<c8y-title>{{ application | humanizeAppName | async }}</c8y-title>\n\n<c8y-breadcrumb *ngIf=\"!isMicroservice\">\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/applications'\"\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<c8y-breadcrumb *ngIf=\"isMicroservice\">\n <c8y-breadcrumb-item [icon]=\"'c8y-atom'\" [label]=\"'Ecosystem' | translate\"></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 *ngIf=\"application\"\n [ngClass]=\"{ 'd-grid grid__col--7-5--md': isActivityLogSupported }\"\n class=\"card content-fullpage\"\n >\n <form\n (ngSubmit)=\"formGroup.valid && save(formGroup.value)\"\n [formGroup]=\"formGroup\"\n class=\"d-flex d-col content-fullpage\"\n novalidate\n >\n <div *ngIf=\"!isLoading\" class=\"d-contents\">\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 *ngIf=\"!isPackage && !isFeature && !isMicroservice && !isExternal\"\n [app]=\"application\"\n [contextPath]=\"application.contextPath\"\n [name]=\"application.name\"\n class=\"icon-48\"\n ></c8y-app-icon>\n <i *ngIf=\"isPackage\" c8yIcon=\"big-parcel\" class=\"icon-48\"></i>\n <i *ngIf=\"isFeature\" c8yIcon=\"tab\" class=\"icon-48\"></i>\n <i *ngIf=\"isMicroservice\" c8yIcon=\"microchip\" class=\"icon-48\"></i>\n <i *ngIf=\"isExternal\" c8yIcon=\"globe1\" class=\"icon-48\"></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 {{ application.description || ('No description available.' | translate) }}\n </em>\n </p>\n <div *ngIf=\"isOwner\" class=\"form-group m-b-0\">\n <label\n [ngClass]=\"{ updated: formGroup?.controls?.description?.dirty }\"\n class=\"editable\"\n >\n <textarea\n c8y-textarea-autoresize\n class=\"form-control no-resize\"\n formControlName=\"description\"\n name=\"description\"\n placeholder=\"{{ 'No description available.' | translate }}\"\n ></textarea>\n </label>\n </div>\n </div>\n <div class=\"text-right-md m-t-4\">\n <span [ngClass]=\"appState?.class\" class=\"label\">\n {{ appState?.label | translate }}\n </span>\n <div class=\"fit-w m-t-2\" *ngIf=\"isPackage || isMicroservice\">\n <label class=\"text-label-small\" translate>Version:</label>\n <small class=\"p-l-4 text-bold\">{{ application.manifest?.version }}</small>\n </div>\n <div class=\"fit-w m-t-2\">\n <label class=\"text-label-small\" translate>Creation time:</label>\n <small class=\"p-l-4 text-bold\">{{ (binaryMo?.creationTime | c8yDate) || '---' }}</small>\n </div>\n <div class=\"m-t-8\">\n <button\n type=\"button\"\n *ngIf=\"isUpdateAvailable\"\n (click)=\"updateToLatestVersion()\"\n [ngClass]=\"{ 'btn-pending': isUpdateOngoing }\"\n class=\"btn btn-warning btn-sm\"\n >\n {{ 'Update available' | translate }}\n </button>\n <button\n (click)=\"openApp(application)\"\n [disabled]=\"disableOpenInBrowser\"\n *ngIf=\"canOpenInBrowser\"\n class=\"btn btn-default btn-sm\"\n title=\"{{ 'Open' | translate }}\"\n type=\"button\"\n >\n <i [c8yIcon]=\"'external-link'\"></i>\n {{ 'Open' | translate }}\n </button>\n <div *ngIf=\"canOpenInBrowser && disableOpenInBrowser\">\n <small class=\"text-muted\" translate>\n The application is overwritten by a custom application sharing the same path\n </small>\n </div>\n <span *ngIf=\"isCustomMicroservice\">\n <button\n (click)=\"subscribe()\"\n *ngIf=\"!isSubscribed\"\n class=\"btn btn-default btn-sm\"\n title=\"{{ 'Subscribe' | translate }}\"\n >\n <i [c8yIcon]=\"'check-circle-o'\"></i>\n {{ 'Subscribe' | translate }}\n </button>\n <button\n (click)=\"unsubscribe()\"\n *ngIf=\"isSubscribed\"\n class=\"btn btn-default btn-sm\"\n title=\"{{ 'Unsubscribe' | translate }}\"\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 *ngIf=\"isPackage\" class=\"row p-16\">\n <c8y-properties-list\n [data]=\"application.manifest\"\n [properties]=\"packageProperties\"\n [title]=\"'Package details' | translate\"\n [emptyLabel]=\"'---'\"\n icon=\"info\"\n ></c8y-properties-list>\n </div>\n <div *ngIf=\"sourcePackage\" class=\"row p-16\">\n <c8y-properties-list\n [data]=\"sourcePackage.manifest\"\n [properties]=\"packageProperties\"\n [title]=\"'Source package information' | translate\"\n [emptyLabel]=\"'---'\"\n icon=\"info\"\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 [readonly]=\"true\"\n autocomplete=\"off\"\n class=\"form-control\"\n formControlName=\"id\"\n name=\"id\"\n id=\"appId\"\n type=\"text\"\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 [readonly]=\"!isOwner\"\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 </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 [readonly]=\"application.id || !isOwner\"\n class=\"form-control\"\n name=\"key\"\n formControlName=\"key\"\n placeholder=\"{{ 'e.g. my-application-key' | translate }}\"\n required\n type=\"text\"\n />\n </c8y-form-group>\n </div>\n\n <div class=\"col-sm-7\">\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 [readOnly]=\"application.id || !isOwner\"\n class=\"form-control\"\n name=\"contextPath\"\n placeholder=\"{{ 'e.g. my-application`used in URL`' | translate }}\"\n required\n type=\"text\"\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 [readOnly]=\"application.id || !isOwner\"\n class=\"form-control\"\n name=\"contextPath\"\n placeholder=\"{{ 'e.g. my-microservice`used in URL`' | translate }}\"\n required\n type=\"text\"\n formControlName=\"contextPath\"\n />\n </div>\n </c8y-form-group>\n <div class=\"row\">\n <div *ngIf=\"application.manifest.version\" class=\"col-sm-4 m-b-16 flex-auto\">\n <label>{{ 'Version' | translate }}</label>\n <p class=\"form-control-static\">\n {{ application.manifest.version }}\n </p>\n </div>\n <div *ngIf=\"application.manifest.isolation\" class=\"col-sm-4 m-b-16 flex-auto\">\n <label>{{ 'Isolation' | translate }}</label>\n <p class=\"form-control-static\">\n <span *ngIf=\"singleTenant\">\n <i [c8yIcon]=\"'c8y-enterprise'\" class=\"c8y-icon-duocolor h4\"></i>\n {{ 'Single tenant' | translate }}\n </span>\n <span *ngIf=\"!singleTenant\">\n <i [c8yIcon]=\"'c8y-sub-tenants'\" class=\"c8y-icon-duocolor icon-32\"></i>\n {{ 'Multi tenant' | translate }}\n </span>\n </p>\n </div>\n <div *ngIf=\"application.manifest.isolation\" class=\"col-sm-4 m-b-16 flex-auto\">\n <label>{{ 'Billing mode' | translate }}</label>\n <p class=\"form-control-static\">\n <span\n *ngIf=\"subscription\"\n [tooltip]=\"'Resources usage assigned to: Owner' | translate\"\n >\n {{ 'Subscription' | translate }}\n </span>\n <span\n *ngIf=\"!subscription && singleTenant\"\n [tooltip]=\"'Resources usage assigned to: Subscriber | translate'\"\n >\n {{ 'Resources' | translate }}\n </span>\n <span\n *ngIf=\"!subscription && !singleTenant\"\n [tooltip]=\"'Resources usage assigned to: Owner' | translate\"\n >\n {{ 'Resources' | translate }}\n </span>\n </p>\n </div>\n </div>\n\n <div *ngIf=\"application.manifest.provider\" class=\"legend form-block m-t-40\">\n {{ 'Provider' | translate }}\n </div>\n <div class=\"list-inline\" *ngIf=\"application.manifest.provider\">\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=\"'REPOSITORY'\">\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 [readOnly]=\"application.id || !isOwner\"\n class=\"form-control\"\n formControlName=\"contextPath\"\n name=\"contextPath\"\n placeholder=\"{{ 'e.g. my-application`used in URL`' | translate }}\"\n required\n type=\"text\"\n />\n </div>\n </c8y-form-group>\n\n <c8y-form-group>\n <label>{{ 'Server URL' | translate }}</label>\n <input\n class=\"form-control\"\n name=\"resourcesUrl\"\n formControlName=\"resourcesUrl\"\n placeholder=\"{{ 'e.g. my-application`used in URL`' | translate }}\"\n required\n type=\"url\"\n />\n </c8y-form-group>\n\n <div class=\"form-group\">\n <label>{{ 'Username' | translate }}</label>\n <input\n class=\"form-control\"\n formControlName=\"username\"\n name=\"username\"\n type=\"text\"\n />\n </div>\n\n <div class=\"form-group\">\n <label>{{ 'Password' | translate }}</label>\n <input\n class=\"form-control\"\n formControlName=\"password\"\n name=\"password\"\n type=\"text\"\n />\n </div>\n </div>\n\n <div *ngSwitchCase=\"'EXTERNAL'\">\n <c8y-form-group>\n <label>{{ 'External URL' | translate }}</label>\n <input\n [pattern]=\"'^(?!javascript:).+'\"\n [readOnly]=\"!isOwner\"\n class=\"form-control\"\n formControlName=\"externalUrl\"\n name=\"externalUrl\"\n placeholder=\"{{ 'e.g.' | translate }} http://www.example.com/\"\n required\n type=\"url\"\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 </div>\n </div>\n </div>\n <ng-container *ngIf=\"isCustomMicroservice\">\n <div *ngIf=\"!isLoading\" class=\"d-contents\">\n <c8y-upload-archive\n [(application)]=\"application\"\n (refresh)=\"onNewArchive()\"\n ></c8y-upload-archive>\n </div>\n </ng-container>\n <div\n *ngIf=\"application && !!isOwner && hasAdminPermissions\"\n class=\"card-footer separator\"\n >\n <button\n (click)=\"cancel()\"\n class=\"btn btn-default\"\n title=\"{{ 'Cancel' | translate }}\"\n type=\"button\"\n >\n {{ 'Cancel' | translate }}\n </button>\n <button\n (click)=\"delete()\"\n *ngIf=\"canDelete\"\n class=\"btn btn-danger\"\n title=\"{{ 'Delete' | translate }}\"\n type=\"button\"\n >\n {{ 'Delete' | translate }}\n </button>\n <button\n [disabled]=\"!application.type || formGroup.invalid || formGroup.pristine\"\n class=\"btn btn-primary btn-form\"\n title=\"{{ 'Save' | translate }}\"\n type=\"submit\"\n >\n {{ 'Save' | translate }}\n </button>\n </div>\n </div>\n </form>\n\n <div *ngIf=\"isActivityLogSupported\" class=\"content-fullpage d-flex d-col bg-level-1\">\n <div class=\"card-header separator\">\n <div class=\"card-title\" translate>Activity log</div>\n <div class=\"m-l-auto\">\n <button\n (click)=\"load()\"\n class=\"btn btn-link btn-sm\"\n title=\"{{ 'Reload' | translate }}\"\n type=\"button\"\n >\n <i [ngClass]=\"{ 'icon-spin': isLoading }\" c8yIcon=\"refresh\"></i>\n {{ 'Reload' | translate }}\n </button>\n </div>\n </div>\n <div *ngIf=\"isLoading\" class=\"p-16 text-center\">\n <c8y-loading></c8y-loading>\n </div>\n <c8y-activity-log\n *ngIf=\"!isLoading\"\n [hasAdminPermissions]=\"hasAdminPermissions\"\n [application]=\"application\"\n class=\"d-contents\"\n ></c8y-activity-log>\n </div>\n </div>\n </div>\n</div>\n" }]
465
- }], ctorParameters: function () { return [{ type: i1$2.ActivatedRoute }, { type: i1.EcosystemService }, { type: i1$2.Router }, { type: i3$1.FormBuilder }, { type: i2$1.ApplicationService }, { type: i2.AlertService }, { type: i2$1.InventoryService }, { type: i2.Permissions }, { type: i2.ModalService }, { type: i4.TranslateService }, { type: i1$1.BsModalService }]; } });
472
+ }], ctorParameters: function () { return [{ type: i1$2.ActivatedRoute }, { type: i1.EcosystemService }, { type: i1$2.Router }, { type: i3$1.FormBuilder }, { type: i2$1.ApplicationService }, { type: i2.AlertService }, { type: i2$1.InventoryService }, { type: i2.Permissions }, { type: i2.ModalService }, { type: i4.TranslateService }, { type: i1$1.BsModalService }, { type: i2.GainsightService }]; } });
466
473
 
467
474
  class ApplicationPropertiesGuard {
468
475
  constructor(ecosystemService) {
@@ -999,11 +1006,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.6", ngImpor
999
1006
  }], ctorParameters: function () { return [{ type: i1.EcosystemService }, { type: i2.WizardModalService }]; } });
1000
1007
 
1001
1008
  class PackageAvailabilityService {
1002
- constructor(appState, alert, modal, application) {
1009
+ constructor(appState, alert, modal, application, gainsightService) {
1003
1010
  this.appState = appState;
1004
1011
  this.alert = alert;
1005
1012
  this.modal = modal;
1006
1013
  this.application = application;
1014
+ this.gainsightService = gainsightService;
1015
+ this.CURRENT_LOCATION = location.href;
1007
1016
  }
1008
1017
  async askIfAvailabilityShouldBeSetTo(applicationPackage, availability) {
1009
1018
  // availability does not matter for tenant that do not have or can create subtenants
@@ -1020,11 +1029,21 @@ class PackageAvailabilityService {
1020
1029
  try {
1021
1030
  const { data: app } = await this.application.updateApplicationAvailability(applicationPackage, availability);
1022
1031
  this.alert.success(gettext('Updated package availability.'));
1032
+ this.gainsightService.triggerEvent(PRODUCT_EXPERIENCE.APPLICATIONS.EVENTS.AVAILABILITY, {
1033
+ action: PRODUCT_EXPERIENCE.APPLICATIONS.ACTIONS.AVAILABILITY_CHANGE,
1034
+ result: availability.toString().toLocaleLowerCase(),
1035
+ url: this.CURRENT_LOCATION
1036
+ });
1023
1037
  return app;
1024
1038
  }
1025
1039
  catch (e) {
1026
1040
  this.alert.warning(gettext('Failed to set package availability.'));
1027
1041
  this.alert.addServerFailure(e);
1042
+ this.gainsightService.triggerEvent(PRODUCT_EXPERIENCE.APPLICATIONS.EVENTS.AVAILABILITY, {
1043
+ action: PRODUCT_EXPERIENCE.APPLICATIONS.ACTIONS.AVAILABILITY_CHANGE,
1044
+ result: PRODUCT_EXPERIENCE.APPLICATIONS.RESULTS.SERVER_FAILURE,
1045
+ url: this.CURRENT_LOCATION
1046
+ });
1028
1047
  return applicationPackage;
1029
1048
  }
1030
1049
  }
@@ -1048,12 +1067,12 @@ class PackageAvailabilityService {
1048
1067
  }
1049
1068
  }
1050
1069
  }
1051
- PackageAvailabilityService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.6", ngImport: i0, type: PackageAvailabilityService, deps: [{ token: i2.AppStateService }, { token: i2.AlertService }, { token: i2.ModalService }, { token: i2$1.ApplicationService }], target: i0.ɵɵFactoryTarget.Injectable });
1070
+ PackageAvailabilityService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.6", ngImport: i0, type: PackageAvailabilityService, deps: [{ token: i2.AppStateService }, { token: i2.AlertService }, { token: i2.ModalService }, { token: i2$1.ApplicationService }, { token: i2.GainsightService }], target: i0.ɵɵFactoryTarget.Injectable });
1052
1071
  PackageAvailabilityService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.0.6", ngImport: i0, type: PackageAvailabilityService, providedIn: 'root' });
1053
1072
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.6", ngImport: i0, type: PackageAvailabilityService, decorators: [{
1054
1073
  type: Injectable,
1055
1074
  args: [{ providedIn: 'root' }]
1056
- }], ctorParameters: function () { return [{ type: i2.AppStateService }, { type: i2.AlertService }, { type: i2.ModalService }, { type: i2$1.ApplicationService }]; } });
1075
+ }], ctorParameters: function () { return [{ type: i2.AppStateService }, { type: i2.AlertService }, { type: i2.ModalService }, { type: i2$1.ApplicationService }, { type: i2.GainsightService }]; } });
1057
1076
 
1058
1077
  class AddPackageComponent {
1059
1078
  constructor(ecosystemService, appState, packageAvailability) {
@@ -1097,12 +1116,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.6", ngImpor
1097
1116
  }], ctorParameters: function () { return [{ type: i1.EcosystemService }, { type: i2.AppStateService }, { type: PackageAvailabilityService }]; } });
1098
1117
 
1099
1118
  class DeployApplicationComponent {
1100
- constructor(ecosystemService, applicationService, wizardComponent, translate, inventoryService) {
1119
+ constructor(ecosystemService, applicationService, wizardComponent, translate, inventoryService, gainsightService) {
1101
1120
  this.ecosystemService = ecosystemService;
1102
1121
  this.applicationService = applicationService;
1103
1122
  this.wizardComponent = wizardComponent;
1104
1123
  this.translate = translate;
1105
1124
  this.inventoryService = inventoryService;
1125
+ this.gainsightService = gainsightService;
1126
+ this.CURRENT_LOCATION = location.href;
1106
1127
  this.inProgress = true;
1107
1128
  this.isDeployed = false;
1108
1129
  this.deployedWithSuccess = false;
@@ -1159,11 +1180,23 @@ class DeployApplicationComponent {
1159
1180
  // Update manifest
1160
1181
  await this.ecosystemService.updateAppManifest(newApp, this.package);
1161
1182
  this.deployedWithSuccess = true;
1183
+ this.gainsightService.triggerEvent(PRODUCT_EXPERIENCE.APPLICATIONS.EVENTS.DEPLOY_APPLICATION, {
1184
+ component: PRODUCT_EXPERIENCE.APPLICATIONS.COMPONENTS.DEPLOY_APPLICATION,
1185
+ action: PRODUCT_EXPERIENCE.APPLICATIONS.ACTIONS.DEPLOY_APPLICATION,
1186
+ result: PRODUCT_EXPERIENCE.APPLICATIONS.RESULTS.DEPLOYED,
1187
+ url: this.CURRENT_LOCATION
1188
+ });
1162
1189
  }
1163
1190
  catch (error) {
1164
1191
  if (error?.res?.status === 404) {
1165
1192
  await this.applicationService.delete(newApp.id);
1166
1193
  await this.fallbackToCloneLatest(config);
1194
+ this.gainsightService.triggerEvent(PRODUCT_EXPERIENCE.APPLICATIONS.EVENTS.DEPLOY_APPLICATION, {
1195
+ component: PRODUCT_EXPERIENCE.APPLICATIONS.COMPONENTS.DEPLOY_APPLICATION,
1196
+ action: PRODUCT_EXPERIENCE.APPLICATIONS.ACTIONS.DEPLOY_APPLICATION,
1197
+ result: PRODUCT_EXPERIENCE.APPLICATIONS.RESULTS.SERVER_FAILURE,
1198
+ url: this.CURRENT_LOCATION
1199
+ });
1167
1200
  }
1168
1201
  }
1169
1202
  finally {
@@ -1217,12 +1250,12 @@ class DeployApplicationComponent {
1217
1250
  });
1218
1251
  }
1219
1252
  }
1220
- DeployApplicationComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.6", ngImport: i0, type: DeployApplicationComponent, deps: [{ token: i1.EcosystemService }, { token: i2$1.ApplicationService }, { token: i2.WizardComponent }, { token: i4.TranslateService }, { token: i2$1.InventoryService }], target: i0.ɵɵFactoryTarget.Component });
1253
+ DeployApplicationComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.6", ngImport: i0, type: DeployApplicationComponent, deps: [{ token: i1.EcosystemService }, { token: i2$1.ApplicationService }, { token: i2.WizardComponent }, { token: i4.TranslateService }, { token: i2$1.InventoryService }, { token: i2.GainsightService }], target: i0.ɵɵFactoryTarget.Component });
1221
1254
  DeployApplicationComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.0.6", type: DeployApplicationComponent, 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 [ngModel]=\"model.selected\" (ngModelChange)=\"onAppVersionSelect($event)\" [packageId]=\"package?.id\" [label]=\"'Use package version' | translate\"></c8y-package-version-select>\n </div>\n </ng-container>\n\n <c8y-progress-bar\n *ngIf=\"inProgress\"\n [message]=\"'Deploying\u2026' | translate\"\n class=\"text-center\"\n ></c8y-progress-bar>\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 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 title=\"{{ 'Deploy' | translate }}\"\n >\n {{ 'Deploy' | translate }}\n </button>\n</c8y-wizard-footer>\n", dependencies: [{ kind: "directive", type: i2.IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "directive", type: i3.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: i2.ProgressBarComponent, selector: "c8y-progress-bar", inputs: ["message", "progress"] }, { kind: "component", type: i2.OperationResultComponent, selector: "c8y-operation-result", inputs: ["text", "vertical", "size", "type"] }, { kind: "directive", type: i3$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i2.WizardHeaderComponent, selector: "c8y-wizard-header" }, { kind: "component", type: i2.WizardBodyComponent, selector: "c8y-wizard-body" }, { kind: "component", type: i2.WizardFooterComponent, selector: "c8y-wizard-footer" }, { kind: "component", type: i1.ApplicationPropertiesFormComponent, selector: "c8y-application-properties-form", inputs: ["application", "disabled"] }, { kind: "component", type: i1.PackageVersionSelectComponent, selector: "c8y-package-version-select", inputs: ["label", "packageContextPath", "packageId"] }, { kind: "pipe", type: i2.C8yTranslatePipe, name: "translate" }] });
1222
1255
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.6", ngImport: i0, type: DeployApplicationComponent, decorators: [{
1223
1256
  type: Component,
1224
1257
  args: [{ selector: 'c8y-deploy-application', 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 [ngModel]=\"model.selected\" (ngModelChange)=\"onAppVersionSelect($event)\" [packageId]=\"package?.id\" [label]=\"'Use package version' | translate\"></c8y-package-version-select>\n </div>\n </ng-container>\n\n <c8y-progress-bar\n *ngIf=\"inProgress\"\n [message]=\"'Deploying\u2026' | translate\"\n class=\"text-center\"\n ></c8y-progress-bar>\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 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 title=\"{{ 'Deploy' | translate }}\"\n >\n {{ 'Deploy' | translate }}\n </button>\n</c8y-wizard-footer>\n" }]
1225
- }], ctorParameters: function () { return [{ type: i1.EcosystemService }, { type: i2$1.ApplicationService }, { type: i2.WizardComponent }, { type: i4.TranslateService }, { type: i2$1.InventoryService }]; }, propDecorators: { applicationPropertiesForm: [{
1258
+ }], ctorParameters: function () { return [{ type: i1.EcosystemService }, { type: i2$1.ApplicationService }, { type: i2.WizardComponent }, { type: i4.TranslateService }, { type: i2$1.InventoryService }, { type: i2.GainsightService }]; }, propDecorators: { applicationPropertiesForm: [{
1226
1259
  type: ViewChild,
1227
1260
  args: [ApplicationPropertiesFormComponent]
1228
1261
  }] } });
@@ -1301,12 +1334,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.6", ngImpor
1301
1334
  }] } });
1302
1335
 
1303
1336
  class PluginListComponent {
1304
- constructor(ecosystemService, bsModalService, pluginsService, alertService, translateService) {
1337
+ constructor(ecosystemService, bsModalService, pluginsService, alertService, translateService, gainsightService) {
1305
1338
  this.ecosystemService = ecosystemService;
1306
1339
  this.bsModalService = bsModalService;
1307
1340
  this.pluginsService = pluginsService;
1308
1341
  this.alertService = alertService;
1309
1342
  this.translateService = translateService;
1343
+ this.gainsightService = gainsightService;
1344
+ this.CURRENT_LOCATION = location.href;
1310
1345
  this.emptyListText = '';
1311
1346
  /**
1312
1347
  * Shows the install button for each plugin separately. Currently used in package-details view.
@@ -1349,9 +1384,19 @@ class PluginListComponent {
1349
1384
  await this.handleRemotesInstallation(app, plugin);
1350
1385
  const successText = this.translateService.instant(gettext('Plugin installed successfully to app "{{ appName }}".'), { appName: app.name });
1351
1386
  this.alertService.success(successText);
1387
+ this.gainsightService.triggerEvent(PRODUCT_EXPERIENCE.APPLICATIONS.EVENTS.PACKAGE_PLUGINS, {
1388
+ component: PRODUCT_EXPERIENCE.APPLICATIONS.COMPONENTS.PLUGIN_LIST,
1389
+ result: PRODUCT_EXPERIENCE.APPLICATIONS.RESULTS.PLUGIN_INSTALLED,
1390
+ url: this.CURRENT_LOCATION
1391
+ });
1352
1392
  }
1353
1393
  catch {
1354
1394
  // nothing to do
1395
+ this.gainsightService.triggerEvent(PRODUCT_EXPERIENCE.APPLICATIONS.EVENTS.PACKAGE_PLUGINS, {
1396
+ component: PRODUCT_EXPERIENCE.APPLICATIONS.COMPONENTS.PLUGIN_LIST,
1397
+ result: PRODUCT_EXPERIENCE.APPLICATIONS.RESULTS.SERVER_FAILURE,
1398
+ url: this.CURRENT_LOCATION
1399
+ });
1355
1400
  }
1356
1401
  }
1357
1402
  this.installingPluginId = '';
@@ -1397,12 +1442,12 @@ class PluginListComponent {
1397
1442
  }
1398
1443
  }
1399
1444
  }
1400
- PluginListComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.6", ngImport: i0, type: PluginListComponent, deps: [{ token: i1.EcosystemService }, { token: i1$1.BsModalService }, { token: i2.PluginsService }, { token: i2.AlertService }, { token: i4.TranslateService }], target: i0.ɵɵFactoryTarget.Component });
1445
+ PluginListComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.6", ngImport: i0, type: PluginListComponent, deps: [{ token: i1.EcosystemService }, { token: i1$1.BsModalService }, { token: i2.PluginsService }, { token: i2.AlertService }, { token: i4.TranslateService }, { token: i2.GainsightService }], target: i0.ɵɵFactoryTarget.Component });
1401
1446
  PluginListComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.0.6", type: PluginListComponent, selector: "c8y-plugin-list", inputs: { plugins$: "plugins$", emptyListText: "emptyListText", selectable: "selectable", installable: "installable", package: "package" }, outputs: { selectedItems: "selectedItems" }, ngImport: i0, template: "<c8y-list-group class=\"bg-inherit\">\n <ng-container *ngIf=\"(plugins$ | async)?.length !== 0; else emptyList\">\n <ng-container *ngFor=\"let plugin of plugins$ | async\">\n <c8y-li [ngClass]=\"{ disabled: plugin.installed }\" class=\"bg-inherit\">\n <c8y-plugin-list-item\n (isItemSelected)=\"updateSelectedItems($event, plugin?.id)\"\n [plugin]=\"plugin\"\n [selectable]=\"selectable\"\n class=\"d-flex\"\n ></c8y-plugin-list-item>\n <div class=\"p-l-40 m-t-4\">\n <button\n *ngIf=\"installable\"\n (click)=\"installPlugin(plugin)\"\n [ngClass]=\"{ 'btn-pending': plugin.id === installingPluginId }\"\n [disabled]=\"installingPluginId && plugin.id !== installingPluginId\"\n class=\"btn btn-default btn-sm m-l-4\"\n title=\"{{ 'Install plugin' | translate }}\"\n translate\n >\n Install plugin\n </button>\n </div>\n </c8y-li>\n </ng-container>\n </ng-container>\n</c8y-list-group>\n<ng-template #emptyList>\n <div class=\"c8y-empty-state text-left\" *ngIf=\"emptyListText\">\n <h1 c8yIcon=\"plugin\"></h1>\n <p>\n {{ emptyListText | translate }}\n </p>\n </div>\n</ng-template>\n", dependencies: [{ kind: "directive", type: i2.IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "directive", type: i2.C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "directive", type: i3.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i2.ListGroupComponent, selector: "c8y-list-group" }, { kind: "component", type: i2.ListItemComponent, selector: "c8y-list-item, c8y-li", inputs: ["active", "emptyActions", "collapsed", "selectable"], outputs: ["collapsedChange"] }, { kind: "component", type: PluginListItemComponent, selector: "c8y-plugin-list-item", inputs: ["plugin", "selectable"], outputs: ["isItemSelected"] }, { kind: "pipe", type: i2.C8yTranslatePipe, name: "translate" }, { kind: "pipe", type: i3.AsyncPipe, name: "async" }] });
1402
1447
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.6", ngImport: i0, type: PluginListComponent, decorators: [{
1403
1448
  type: Component,
1404
1449
  args: [{ selector: 'c8y-plugin-list', template: "<c8y-list-group class=\"bg-inherit\">\n <ng-container *ngIf=\"(plugins$ | async)?.length !== 0; else emptyList\">\n <ng-container *ngFor=\"let plugin of plugins$ | async\">\n <c8y-li [ngClass]=\"{ disabled: plugin.installed }\" class=\"bg-inherit\">\n <c8y-plugin-list-item\n (isItemSelected)=\"updateSelectedItems($event, plugin?.id)\"\n [plugin]=\"plugin\"\n [selectable]=\"selectable\"\n class=\"d-flex\"\n ></c8y-plugin-list-item>\n <div class=\"p-l-40 m-t-4\">\n <button\n *ngIf=\"installable\"\n (click)=\"installPlugin(plugin)\"\n [ngClass]=\"{ 'btn-pending': plugin.id === installingPluginId }\"\n [disabled]=\"installingPluginId && plugin.id !== installingPluginId\"\n class=\"btn btn-default btn-sm m-l-4\"\n title=\"{{ 'Install plugin' | translate }}\"\n translate\n >\n Install plugin\n </button>\n </div>\n </c8y-li>\n </ng-container>\n </ng-container>\n</c8y-list-group>\n<ng-template #emptyList>\n <div class=\"c8y-empty-state text-left\" *ngIf=\"emptyListText\">\n <h1 c8yIcon=\"plugin\"></h1>\n <p>\n {{ emptyListText | translate }}\n </p>\n </div>\n</ng-template>\n" }]
1405
- }], ctorParameters: function () { return [{ type: i1.EcosystemService }, { type: i1$1.BsModalService }, { type: i2.PluginsService }, { type: i2.AlertService }, { type: i4.TranslateService }]; }, propDecorators: { plugins$: [{
1450
+ }], ctorParameters: function () { return [{ type: i1.EcosystemService }, { type: i1$1.BsModalService }, { type: i2.PluginsService }, { type: i2.AlertService }, { type: i4.TranslateService }, { type: i2.GainsightService }]; }, propDecorators: { plugins$: [{
1406
1451
  type: Input
1407
1452
  }], emptyListText: [{
1408
1453
  type: Input
@@ -1625,7 +1670,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.6", ngImpor
1625
1670
 
1626
1671
  const DEFAULT_VERSIONS_LIMIT = 20;
1627
1672
  class PackageVersionsListComponent {
1628
- constructor(activatedRoute, pluginsService, ecosystemService, translateService, modal, alertService, optionsService, permissions) {
1673
+ constructor(activatedRoute, pluginsService, ecosystemService, translateService, modal, alertService, optionsService, permissions, gainsightService) {
1629
1674
  this.activatedRoute = activatedRoute;
1630
1675
  this.pluginsService = pluginsService;
1631
1676
  this.ecosystemService = ecosystemService;
@@ -1634,6 +1679,8 @@ class PackageVersionsListComponent {
1634
1679
  this.alertService = alertService;
1635
1680
  this.optionsService = optionsService;
1636
1681
  this.permissions = permissions;
1682
+ this.gainsightService = gainsightService;
1683
+ this.CURRENT_LOCATION = location.href;
1637
1684
  this.isLoading = false;
1638
1685
  this.hasAdminPermissions = false;
1639
1686
  this.isPackageOwnedByCurrentTenant = false;
@@ -1649,6 +1696,11 @@ class PackageVersionsListComponent {
1649
1696
  this.isLoading = false;
1650
1697
  }
1651
1698
  async downloadArchive(appVersion) {
1699
+ this.gainsightService.triggerEvent(PRODUCT_EXPERIENCE.APPLICATIONS.EVENTS.PACKAGE_VERSIONS, {
1700
+ component: PRODUCT_EXPERIENCE.APPLICATIONS.COMPONENTS.PACKAGE_VERSIONS,
1701
+ action: PRODUCT_EXPERIENCE.APPLICATIONS.ACTIONS.DOWNLOAD,
1702
+ url: this.CURRENT_LOCATION
1703
+ });
1652
1704
  const archiveMO = await this.ecosystemService.getArchiveManagedObject(appVersion.binaryId);
1653
1705
  await this.ecosystemService.downloadArchive(this.package, {
1654
1706
  id: appVersion.binaryId,
@@ -1670,9 +1722,21 @@ class PackageVersionsListComponent {
1670
1722
  this.alertService.success(this.translateService.instant(gettext('Package version {{version}} has been removed'), {
1671
1723
  version
1672
1724
  }));
1725
+ this.gainsightService.triggerEvent(PRODUCT_EXPERIENCE.APPLICATIONS.EVENTS.PACKAGE_VERSIONS, {
1726
+ component: PRODUCT_EXPERIENCE.APPLICATIONS.COMPONENTS.PACKAGE_VERSIONS,
1727
+ action: PRODUCT_EXPERIENCE.APPLICATIONS.ACTIONS.DELETE,
1728
+ result: PRODUCT_EXPERIENCE.APPLICATIONS.RESULTS.SUCCESS,
1729
+ url: this.CURRENT_LOCATION
1730
+ });
1673
1731
  }
1674
1732
  catch (e) {
1675
1733
  this.alertService.addServerFailure(e);
1734
+ this.gainsightService.triggerEvent(PRODUCT_EXPERIENCE.APPLICATIONS.EVENTS.PACKAGE_VERSIONS, {
1735
+ component: PRODUCT_EXPERIENCE.APPLICATIONS.COMPONENTS.PACKAGE_VERSIONS,
1736
+ action: PRODUCT_EXPERIENCE.APPLICATIONS.ACTIONS.DELETE,
1737
+ result: PRODUCT_EXPERIENCE.APPLICATIONS.RESULTS.SERVER_FAILURE,
1738
+ url: this.CURRENT_LOCATION
1739
+ });
1676
1740
  }
1677
1741
  if (version === this.selectedVersion) {
1678
1742
  this.selectVersion(null);
@@ -1689,9 +1753,21 @@ class PackageVersionsListComponent {
1689
1753
  // Remove it when BE fixes issues with activeVersion.
1690
1754
  await this.ecosystemService.setAppActiveVersion(this.package, appVersion.binaryId);
1691
1755
  this.alertService.success(gettext('Tag has been set.'));
1756
+ this.gainsightService.triggerEvent(PRODUCT_EXPERIENCE.APPLICATIONS.EVENTS.PACKAGE_VERSIONS, {
1757
+ component: PRODUCT_EXPERIENCE.APPLICATIONS.COMPONENTS.PACKAGE_VERSIONS,
1758
+ action: PRODUCT_EXPERIENCE.APPLICATIONS.ACTIONS.SET_AS_LATEST,
1759
+ result: PRODUCT_EXPERIENCE.APPLICATIONS.RESULTS.SUCCESS,
1760
+ url: this.CURRENT_LOCATION
1761
+ });
1692
1762
  }
1693
1763
  catch (e) {
1694
1764
  this.alertService.addServerFailure(e);
1765
+ this.gainsightService.triggerEvent(PRODUCT_EXPERIENCE.APPLICATIONS.EVENTS.PACKAGE_VERSIONS, {
1766
+ component: PRODUCT_EXPERIENCE.APPLICATIONS.COMPONENTS.PACKAGE_VERSIONS,
1767
+ action: PRODUCT_EXPERIENCE.APPLICATIONS.ACTIONS.SET_AS_LATEST,
1768
+ result: PRODUCT_EXPERIENCE.APPLICATIONS.RESULTS.SERVER_FAILURE,
1769
+ url: this.CURRENT_LOCATION
1770
+ });
1695
1771
  return;
1696
1772
  }
1697
1773
  await this.refreshPackage();
@@ -1717,6 +1793,12 @@ class PackageVersionsListComponent {
1717
1793
  async setUploadedVersionAsLatest() {
1718
1794
  const uploadedVersion = this.package.applicationVersions[this.package.applicationVersions.length - 1];
1719
1795
  try {
1796
+ this.gainsightService.triggerEvent(PRODUCT_EXPERIENCE.APPLICATIONS.EVENTS.PACKAGE_VERSIONS, {
1797
+ component: PRODUCT_EXPERIENCE.APPLICATIONS.COMPONENTS.PACKAGE_VERSIONS,
1798
+ action: PRODUCT_EXPERIENCE.APPLICATIONS.ACTIONS.UPLOAD,
1799
+ result: PRODUCT_EXPERIENCE.APPLICATIONS.RESULTS.SUCCESS,
1800
+ url: this.CURRENT_LOCATION
1801
+ });
1720
1802
  await this.modal.confirm(gettext('Upload successful'), this.translateService.instant(gettext('Do you want to set version {{version}} as the latest? Deploying a new app will always use this version.'), { version: uploadedVersion.version }), Status.SUCCESS, {
1721
1803
  ok: gettext('Set as latest`version`'),
1722
1804
  cancel: gettext('Keep unchanged`version`')
@@ -1735,12 +1817,12 @@ class PackageVersionsListComponent {
1735
1817
  : this.acknowledgeLimitReached.bind(this);
1736
1818
  }
1737
1819
  }
1738
- PackageVersionsListComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.6", ngImport: i0, type: PackageVersionsListComponent, deps: [{ token: i1$2.ActivatedRoute }, { token: i2.PluginsService }, { token: i1.EcosystemService }, { token: i4.TranslateService }, { token: i2.ModalService }, { token: i2.AlertService }, { token: i2.OptionsService }, { token: i2.Permissions }], target: i0.ɵɵFactoryTarget.Component });
1820
+ PackageVersionsListComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.6", ngImport: i0, type: PackageVersionsListComponent, deps: [{ token: i1$2.ActivatedRoute }, { token: i2.PluginsService }, { token: i1.EcosystemService }, { token: i4.TranslateService }, { token: i2.ModalService }, { token: i2.AlertService }, { token: i2.OptionsService }, { token: i2.Permissions }, { token: i2.GainsightService }], target: i0.ɵɵFactoryTarget.Component });
1739
1821
  PackageVersionsListComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.0.6", type: PackageVersionsListComponent, 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 dropdownToggle\n title=\"{{ 'Settings' | translate }}\"\n >\n <i c8yIcon=\"ellipsis-v\"></i>\n </button>\n <ul *dropdownMenu class=\"dropdown-menu dropdown-menu-right\">\n <li>\n <button\n (click)=\"setVersionAsLatest(applicationVersion)\"\n [disabled]=\"applicationVersion.tags?.includes('latest')\"\n title=\"{{ 'Set as latest`version`' | translate }}\"\n type=\"button\"\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 (click)=\"downloadArchive(applicationVersion)\"\n title=\"{{ 'Download' | translate }}\"\n type=\"button\"\n >\n <i c8yIcon=\"download\" class=\"m-r-4\"></i>\n {{ 'Download' | translate }}\n </button>\n </li>\n <li>\n <button\n (click)=\"removeVersionPackage(applicationVersion.version)\"\n [disabled]=\"applicationVersion.tags?.includes('latest')\"\n title=\"{{ 'Delete' | translate }}\"\n type=\"button\"\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: i2.IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "directive", type: i2.C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "directive", type: i3.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i2.LoadingComponent, selector: "c8y-loading" }, { kind: "directive", type: i6.BsDropdownMenuDirective, selector: "[bsDropdownMenu],[dropdownMenu]", exportAs: ["bs-dropdown-menu"] }, { kind: "directive", type: i6.BsDropdownToggleDirective, selector: "[bsDropdownToggle],[dropdownToggle]", exportAs: ["bs-dropdown-toggle"] }, { kind: "directive", type: i6.BsDropdownDirective, selector: "[bsDropdown], [dropdown]", inputs: ["placement", "triggers", "container", "dropup", "autoClose", "isAnimated", "insideClick", "isDisabled", "isOpen"], outputs: ["isOpenChange", "onShown", "onHidden"], exportAs: ["bs-dropdown"] }, { kind: "component", type: i1.UploadArchiveComponent, selector: "c8y-upload-archive", inputs: ["application", "uploadNewVersion", "preUploadCallback"], outputs: ["applicationChange", "refresh"] }, { kind: "pipe", type: i2.C8yTranslatePipe, name: "translate" }] });
1740
1822
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.6", ngImport: i0, type: PackageVersionsListComponent, decorators: [{
1741
1823
  type: Component,
1742
1824
  args: [{ selector: 'c8y-package-versions-list', 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 dropdownToggle\n title=\"{{ 'Settings' | translate }}\"\n >\n <i c8yIcon=\"ellipsis-v\"></i>\n </button>\n <ul *dropdownMenu class=\"dropdown-menu dropdown-menu-right\">\n <li>\n <button\n (click)=\"setVersionAsLatest(applicationVersion)\"\n [disabled]=\"applicationVersion.tags?.includes('latest')\"\n title=\"{{ 'Set as latest`version`' | translate }}\"\n type=\"button\"\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 (click)=\"downloadArchive(applicationVersion)\"\n title=\"{{ 'Download' | translate }}\"\n type=\"button\"\n >\n <i c8yIcon=\"download\" class=\"m-r-4\"></i>\n {{ 'Download' | translate }}\n </button>\n </li>\n <li>\n <button\n (click)=\"removeVersionPackage(applicationVersion.version)\"\n [disabled]=\"applicationVersion.tags?.includes('latest')\"\n title=\"{{ 'Delete' | translate }}\"\n type=\"button\"\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" }]
1743
- }], ctorParameters: function () { return [{ type: i1$2.ActivatedRoute }, { type: i2.PluginsService }, { type: i1.EcosystemService }, { type: i4.TranslateService }, { type: i2.ModalService }, { type: i2.AlertService }, { type: i2.OptionsService }, { type: i2.Permissions }]; }, propDecorators: { onVersionSelect: [{
1825
+ }], ctorParameters: function () { return [{ type: i1$2.ActivatedRoute }, { type: i2.PluginsService }, { type: i1.EcosystemService }, { type: i4.TranslateService }, { type: i2.ModalService }, { type: i2.AlertService }, { type: i2.OptionsService }, { type: i2.Permissions }, { type: i2.GainsightService }]; }, propDecorators: { onVersionSelect: [{
1744
1826
  type: Output
1745
1827
  }] } });
1746
1828
 
@@ -1910,10 +1992,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.6", ngImpor
1910
1992
  }], ctorParameters: function () { return [{ type: i2.CellRendererContext }]; } });
1911
1993
 
1912
1994
  class UpdatePluginOfAppComponent {
1913
- constructor(bsModalRef, pluginsService, alert) {
1995
+ constructor(bsModalRef, pluginsService, alert, gainsightService) {
1914
1996
  this.bsModalRef = bsModalRef;
1915
1997
  this.pluginsService = pluginsService;
1916
1998
  this.alert = alert;
1999
+ this.gainsightService = gainsightService;
2000
+ this.CURRENT_LOCATION = location.href;
1917
2001
  this.result = new Promise((resolve, reject) => {
1918
2002
  this._install = resolve;
1919
2003
  this._cancel = reject;
@@ -1963,9 +2047,21 @@ class UpdatePluginOfAppComponent {
1963
2047
  try {
1964
2048
  await this.pluginsService.updateRemotesInAppConfig(this.app, newRemotes);
1965
2049
  this.alert.success(gettext(`Switched the version of plugin.`));
2050
+ this.gainsightService.triggerEvent(PRODUCT_EXPERIENCE.APPLICATIONS.EVENTS.INSTALLED_PLUGINS, {
2051
+ component: PRODUCT_EXPERIENCE.APPLICATIONS.COMPONENTS.UPDATE_PLUGIN_OF_APP,
2052
+ action: PRODUCT_EXPERIENCE.APPLICATIONS.ACTIONS.CHANGE_PLUGIN_VERSION,
2053
+ result: PRODUCT_EXPERIENCE.APPLICATIONS.RESULTS.PLUGIN_VERSION_CHANGED,
2054
+ url: this.CURRENT_LOCATION
2055
+ });
1966
2056
  }
1967
2057
  catch (e) {
1968
2058
  this.alert.addServerFailure(e);
2059
+ this.gainsightService.triggerEvent(PRODUCT_EXPERIENCE.APPLICATIONS.EVENTS.INSTALLED_PLUGINS, {
2060
+ component: PRODUCT_EXPERIENCE.APPLICATIONS.COMPONENTS.UPDATE_PLUGIN_OF_APP,
2061
+ action: PRODUCT_EXPERIENCE.APPLICATIONS.ACTIONS.CHANGE_PLUGIN_VERSION,
2062
+ result: PRODUCT_EXPERIENCE.APPLICATIONS.RESULTS.SERVER_FAILURE,
2063
+ url: this.CURRENT_LOCATION
2064
+ });
1969
2065
  }
1970
2066
  this.bsModalRef.hide();
1971
2067
  this._install();
@@ -1975,15 +2071,15 @@ class UpdatePluginOfAppComponent {
1975
2071
  this._cancel();
1976
2072
  }
1977
2073
  }
1978
- UpdatePluginOfAppComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.6", ngImport: i0, type: UpdatePluginOfAppComponent, deps: [{ token: i1$1.BsModalRef }, { token: i2.PluginsService }, { token: i2.AlertService }], target: i0.ɵɵFactoryTarget.Component });
2074
+ UpdatePluginOfAppComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.6", ngImport: i0, type: UpdatePluginOfAppComponent, deps: [{ token: i1$1.BsModalRef }, { token: i2.PluginsService }, { token: i2.AlertService }, { token: i2.GainsightService }], target: i0.ɵɵFactoryTarget.Component });
1979
2075
  UpdatePluginOfAppComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.0.6", type: UpdatePluginOfAppComponent, selector: "c8y-update-plugin-of-app", ngImport: i0, template: "<div class=\"viewport-modal\">\n <div class=\"modal-header dialog-header\">\n <i [c8yIcon]=\"'c8y-modules'\"></i>\n <h4 *ngIf=\"!downgrade\" id=\"modal-title\" translate>Update plugin</h4>\n <h4 *ngIf=\"downgrade\" id=\"modal-title\" translate>Downgrade plugin</h4>\n </div>\n <div class=\"inner-scroll\" id=\"modal-body\">\n <div class=\"p-16\">\n <div class=\"d-block fit-w bg-gray-white\">\n <c8y-package-version-select\n [packageContextPath]=\"plugin?.contextPath\"\n [(ngModel)]=\"applicationVersion\"\n ></c8y-package-version-select>\n <div\n *ngIf=\"plugin?.version && plugin.version === applicationVersion?.version\"\n class=\"alert alert-info\"\n role=\"alert\"\n >\n <span translate ngNonBindable [translateParams]=\"applicationVersion\">\n Select another version, as {{ version }} is currently used.\n </span>\n </div>\n </div>\n\n <div class=\"form-group\">\n <label class=\"c8y-checkbox\">\n <input [(ngModel)]=\"updateAll\" type=\"checkbox\" />\n <span></span>\n <span translate ngNonBindable [translateParams]=\"plugin\">\n Set version for all plugins using the same context path \"{{ contextPath }}\".\n </span>\n </label>\n </div>\n </div>\n </div>\n <div class=\"modal-footer\">\n <button\n class=\"btn btn-default\"\n title=\"{{ 'Cancel' | translate }}\"\n type=\"button\"\n (click)=\"cancel()\"\n >\n {{ 'Cancel' | translate }}\n </button>\n <button\n class=\"btn btn-primary\"\n title=\"{{ 'Set version' | translate }}\"\n [disabled]=\"!applicationVersion || plugin?.version === applicationVersion?.version\"\n (click)=\"update()\"\n >\n {{ 'Set version' | translate }}\n </button>\n </div>\n</div>\n", dependencies: [{ kind: "directive", type: i2.IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "directive", type: i2.C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3$1.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i3$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i1.PackageVersionSelectComponent, selector: "c8y-package-version-select", inputs: ["label", "packageContextPath", "packageId"] }, { kind: "pipe", type: i2.C8yTranslatePipe, name: "translate" }] });
1980
2076
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.6", ngImport: i0, type: UpdatePluginOfAppComponent, decorators: [{
1981
2077
  type: Component,
1982
2078
  args: [{ selector: 'c8y-update-plugin-of-app', template: "<div class=\"viewport-modal\">\n <div class=\"modal-header dialog-header\">\n <i [c8yIcon]=\"'c8y-modules'\"></i>\n <h4 *ngIf=\"!downgrade\" id=\"modal-title\" translate>Update plugin</h4>\n <h4 *ngIf=\"downgrade\" id=\"modal-title\" translate>Downgrade plugin</h4>\n </div>\n <div class=\"inner-scroll\" id=\"modal-body\">\n <div class=\"p-16\">\n <div class=\"d-block fit-w bg-gray-white\">\n <c8y-package-version-select\n [packageContextPath]=\"plugin?.contextPath\"\n [(ngModel)]=\"applicationVersion\"\n ></c8y-package-version-select>\n <div\n *ngIf=\"plugin?.version && plugin.version === applicationVersion?.version\"\n class=\"alert alert-info\"\n role=\"alert\"\n >\n <span translate ngNonBindable [translateParams]=\"applicationVersion\">\n Select another version, as {{ version }} is currently used.\n </span>\n </div>\n </div>\n\n <div class=\"form-group\">\n <label class=\"c8y-checkbox\">\n <input [(ngModel)]=\"updateAll\" type=\"checkbox\" />\n <span></span>\n <span translate ngNonBindable [translateParams]=\"plugin\">\n Set version for all plugins using the same context path \"{{ contextPath }}\".\n </span>\n </label>\n </div>\n </div>\n </div>\n <div class=\"modal-footer\">\n <button\n class=\"btn btn-default\"\n title=\"{{ 'Cancel' | translate }}\"\n type=\"button\"\n (click)=\"cancel()\"\n >\n {{ 'Cancel' | translate }}\n </button>\n <button\n class=\"btn btn-primary\"\n title=\"{{ 'Set version' | translate }}\"\n [disabled]=\"!applicationVersion || plugin?.version === applicationVersion?.version\"\n (click)=\"update()\"\n >\n {{ 'Set version' | translate }}\n </button>\n </div>\n</div>\n" }]
1983
- }], ctorParameters: function () { return [{ type: i1$1.BsModalRef }, { type: i2.PluginsService }, { type: i2.AlertService }]; } });
2079
+ }], ctorParameters: function () { return [{ type: i1$1.BsModalRef }, { type: i2.PluginsService }, { type: i2.AlertService }, { type: i2.GainsightService }]; } });
1984
2080
 
1985
2081
  class ApplicationPluginsComponent {
1986
- constructor(activatedRoute, ecosystemService, bsModalService, modal, translateService, pluginsService, alertService) {
2082
+ constructor(activatedRoute, ecosystemService, bsModalService, modal, translateService, pluginsService, alertService, gainsightService) {
1987
2083
  this.activatedRoute = activatedRoute;
1988
2084
  this.ecosystemService = ecosystemService;
1989
2085
  this.bsModalService = bsModalService;
@@ -1991,6 +2087,9 @@ class ApplicationPluginsComponent {
1991
2087
  this.translateService = translateService;
1992
2088
  this.pluginsService = pluginsService;
1993
2089
  this.alertService = alertService;
2090
+ this.gainsightService = gainsightService;
2091
+ this.PRODUCT_EXPERIENCE = PRODUCT_EXPERIENCE;
2092
+ this.CURRENT_LOCATION = location.href;
1994
2093
  this.exportedPlugins$ = new BehaviorSubject([]);
1995
2094
  this.remotePlugins$ = new BehaviorSubject({});
1996
2095
  this.allAvailablePlugins$ = new BehaviorSubject([]);
@@ -2076,10 +2175,20 @@ class ApplicationPluginsComponent {
2076
2175
  this.isLoading = true;
2077
2176
  await this.handleRemotesInstallation(pluginsToAdd);
2078
2177
  this.alertService.success(gettext('Plugins installed.'));
2178
+ this.gainsightService.triggerEvent(PRODUCT_EXPERIENCE.APPLICATIONS.EVENTS.INSTALLED_PLUGINS, {
2179
+ component: PRODUCT_EXPERIENCE.APPLICATIONS.COMPONENTS.APPLICATION_PLUGINS,
2180
+ result: PRODUCT_EXPERIENCE.APPLICATIONS.RESULTS.PLUGIN_INSTALLED,
2181
+ url: this.CURRENT_LOCATION
2182
+ });
2079
2183
  }
2080
2184
  catch (ex) {
2081
2185
  if (ex) {
2082
2186
  this.alertService.addServerFailure(ex);
2187
+ this.gainsightService.triggerEvent(PRODUCT_EXPERIENCE.APPLICATIONS.EVENTS.INSTALLED_PLUGINS, {
2188
+ component: PRODUCT_EXPERIENCE.APPLICATIONS.COMPONENTS.APPLICATION_PLUGINS,
2189
+ result: PRODUCT_EXPERIENCE.APPLICATIONS.RESULTS.SERVER_FAILURE,
2190
+ url: this.CURRENT_LOCATION
2191
+ });
2083
2192
  }
2084
2193
  }
2085
2194
  finally {
@@ -2094,10 +2203,20 @@ class ApplicationPluginsComponent {
2094
2203
  this.isLoading = false;
2095
2204
  this.dataGrid.cancel();
2096
2205
  this.alertService.success(gettext('Plugins removed.'));
2206
+ this.gainsightService.triggerEvent(PRODUCT_EXPERIENCE.APPLICATIONS.EVENTS.INSTALLED_PLUGINS, {
2207
+ component: PRODUCT_EXPERIENCE.APPLICATIONS.COMPONENTS.APPLICATION_PLUGINS,
2208
+ result: PRODUCT_EXPERIENCE.APPLICATIONS.RESULTS.PLUGIN_REMOVED,
2209
+ url: this.CURRENT_LOCATION
2210
+ });
2097
2211
  }
2098
2212
  catch (ex) {
2099
2213
  if (ex) {
2100
2214
  this.alertService.addServerFailure(ex);
2215
+ this.gainsightService.triggerEvent(PRODUCT_EXPERIENCE.APPLICATIONS.EVENTS.INSTALLED_PLUGINS, {
2216
+ component: PRODUCT_EXPERIENCE.APPLICATIONS.COMPONENTS.APPLICATION_PLUGINS,
2217
+ result: PRODUCT_EXPERIENCE.APPLICATIONS.RESULTS.SERVER_FAILURE,
2218
+ url: this.CURRENT_LOCATION
2219
+ });
2101
2220
  }
2102
2221
  }
2103
2222
  finally {
@@ -2329,12 +2448,12 @@ class ApplicationPluginsComponent {
2329
2448
  return value.replace(/(@|\/)/g, '');
2330
2449
  }
2331
2450
  }
2332
- ApplicationPluginsComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.6", ngImport: i0, type: ApplicationPluginsComponent, deps: [{ token: i1$2.ActivatedRoute }, { token: i1.EcosystemService }, { token: i1$1.BsModalService }, { token: i2.ModalService }, { token: i4.TranslateService }, { token: i2.PluginsService }, { token: i2.AlertService }], target: i0.ɵɵFactoryTarget.Component });
2333
- ApplicationPluginsComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.0.6", type: ApplicationPluginsComponent, selector: "c8y-app-plugins", inputs: { appId: "appId" }, viewQueries: [{ propertyName: "dataGrid", first: true, predicate: DataGridComponent, descendants: true }], ngImport: i0, template: "<c8y-title>{{ app | humanizeAppName | async }}</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/applications'\"\n ></c8y-breadcrumb-item>\n <c8y-breadcrumb-item\n [icon]=\"'c8y-modules'\"\n [label]=\"'All applications' | translate\"\n [path]=\"'ecosystem/applications'\"\n ></c8y-breadcrumb-item>\n <c8y-breadcrumb-item [label]=\"app | humanizeAppName | async\"></c8y-breadcrumb-item>\n <c8y-breadcrumb-item [label]=\"'Plugins' | translate\"></c8y-breadcrumb-item>\n</c8y-breadcrumb>\n\n<c8y-action-bar-item [placement]=\"'right'\">\n <button\n (click)=\"installPlugins()\"\n [ngClass]=\"{ 'btn-pending': isLoading }\"\n class=\"btn btn-link\"\n title=\"{{ 'Install plugins' | translate }}\"\n >\n <i c8yIcon=\"plus-circle\"></i>\n {{ 'Install plugins' | translate }}\n </button>\n</c8y-action-bar-item>\n\n<ng-container *ngIf=\"orphanedPlugins$ | async as orphanedPlugins\">\n <c8y-action-bar-item *ngIf=\"orphanedPlugins?.length\" [placement]=\"'right'\">\n <button\n (click)=\"cleanupOrphanedPlugins(orphanedPlugins)\"\n [ngClass]=\"{ 'btn-pending': isLoading }\"\n class=\"btn btn-link\"\n title=\"{{ 'Clean up orphaned plugins' | translate }}\"\n >\n <i c8yIcon=\"erase\"></i>\n {{ 'Clean up orphaned plugins' | translate }}\n </button>\n </c8y-action-bar-item>\n</ng-container>\n\n<div class=\"content-fullpage d-flex d-col border-top\">\n <c8y-data-grid\n [title]=\"title\"\n [loadMoreItemsLabel]=\"loadMoreItemsLabel\"\n [loadingItemsLabel]=\"loadingItemsLabel\"\n [displayOptions]=\"displayOptions\"\n [columns]=\"columns\"\n [rows]=\"installedPlugins$ | async\"\n [pagination]=\"pagination\"\n [selectable]=\"true\"\n [actionControls]=\"actionControls\"\n [bulkActionControls]=\"bulkActionControls\"\n [headerActionControls]=\"headerActionControls\"\n (onReload)=\"refresh()\"\n class=\"d-contents\"\n >\n <!-- No search/filtered results empty state -->\n <c8y-ui-empty-state\n *ngIf=\"(installedPlugins$ | async)?.length\"\n [icon]=\"'search'\"\n [title]=\"'No plugins to display.' | translate\"\n [subtitle]=\"'Refine your search terms or check your spelling.' | translate\"\n [horizontal]=\"true\"\n >\n </c8y-ui-empty-state>\n <!-- No installed plugins empty state -->\n <c8y-ui-empty-state\n *ngIf=\"!(installedPlugins$ | async)?.length && !isLoading\"\n [icon]=\"'plugin'\"\n [title]=\"'No plugins installed.' | translate\"\n [subtitle]=\"'This application doesn\\'t have any plugin. Click below to install.' | translate\"\n [horizontal]=\"true\"\n >\n <div class=\"fit-w p-t-16\">\n <button\n (click)=\"installPlugins()\"\n [ngClass]=\"{ 'btn-pending': isLoading }\"\n class=\"btn btn-primary btn-sm\"\n title=\"{{ 'Install plugins' | translate }}\"\n translate\n >\n Install plugins\n </button>\n </div>\n </c8y-ui-empty-state>\n </c8y-data-grid>\n</div>\n", dependencies: [{ kind: "component", type: i2.ActionBarItemComponent, selector: "c8y-action-bar-item", inputs: ["placement", "priority", "itemClass", "injector", "groupId"] }, { kind: "component", type: i2.BreadcrumbComponent, selector: "c8y-breadcrumb" }, { kind: "component", type: i2.BreadcrumbItemComponent, selector: "c8y-breadcrumb-item", inputs: ["icon", "translate", "label", "path", "injector"] }, { kind: "component", type: i2.EmptyStateComponent, selector: "c8y-ui-empty-state", inputs: ["icon", "title", "subtitle", "horizontal"] }, { kind: "directive", type: i2.IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "directive", type: i2.C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "directive", type: i3.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i2.DataGridComponent, selector: "c8y-data-grid", inputs: ["title", "loadMoreItemsLabel", "loadingItemsLabel", "showSearch", "refresh", "columns", "rows", "pagination", "infiniteScroll", "serverSideDataCallback", "selectable", "selectionPrimaryKey", "displayOptions", "actionControls", "bulkActionControls", "headerActionControls", "searchText", "configureColumnsEnabled", "showCounterWarning"], outputs: ["rowMouseOver", "rowMouseLeave", "rowClick", "onConfigChange", "onBeforeFilter", "onBeforeSearch", "onFilter", "itemsSelect", "onReload", "onAddCustomColumn", "onRemoveCustomColumn", "onColumnFilterReset", "onSort", "onPageSizeChange", "onColumnReordered", "onColumnVisibilityChange"] }, { kind: "component", type: i2.TitleComponent, selector: "c8y-title", inputs: ["pageTitleUpdate"] }, { kind: "pipe", type: i2.C8yTranslatePipe, name: "translate" }, { kind: "pipe", type: i3.AsyncPipe, name: "async" }, { kind: "pipe", type: i2.HumanizeAppNamePipe, name: "humanizeAppName" }] });
2451
+ ApplicationPluginsComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.6", ngImport: i0, type: ApplicationPluginsComponent, deps: [{ token: i1$2.ActivatedRoute }, { token: i1.EcosystemService }, { token: i1$1.BsModalService }, { token: i2.ModalService }, { token: i4.TranslateService }, { token: i2.PluginsService }, { token: i2.AlertService }, { token: i2.GainsightService }], target: i0.ɵɵFactoryTarget.Component });
2452
+ ApplicationPluginsComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.0.6", type: ApplicationPluginsComponent, selector: "c8y-app-plugins", inputs: { appId: "appId" }, viewQueries: [{ propertyName: "dataGrid", first: true, predicate: DataGridComponent, descendants: true }], ngImport: i0, template: "<c8y-title>{{ app | humanizeAppName | async }}</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/applications'\"\n ></c8y-breadcrumb-item>\n <c8y-breadcrumb-item\n [icon]=\"'c8y-modules'\"\n [label]=\"'All applications' | translate\"\n [path]=\"'ecosystem/applications'\"\n ></c8y-breadcrumb-item>\n <c8y-breadcrumb-item [label]=\"app | humanizeAppName | async\"></c8y-breadcrumb-item>\n <c8y-breadcrumb-item [label]=\"'Plugins' | translate\"></c8y-breadcrumb-item>\n</c8y-breadcrumb>\n\n<c8y-action-bar-item [placement]=\"'right'\">\n <button\n (click)=\"installPlugins()\"\n [ngClass]=\"{ 'btn-pending': isLoading }\"\n class=\"btn btn-link\"\n title=\"{{ 'Install plugins' | translate }}\"\n >\n <i c8yIcon=\"plus-circle\"></i>\n {{ 'Install plugins' | translate }}\n </button>\n</c8y-action-bar-item>\n\n<ng-container *ngIf=\"orphanedPlugins$ | async as orphanedPlugins\">\n <c8y-action-bar-item *ngIf=\"orphanedPlugins?.length\" [placement]=\"'right'\">\n <button\n (click)=\"cleanupOrphanedPlugins(orphanedPlugins)\"\n [ngClass]=\"{ 'btn-pending': isLoading }\"\n class=\"btn btn-link\"\n title=\"{{ 'Clean up orphaned plugins' | translate }}\"\n >\n <i c8yIcon=\"erase\"></i>\n {{ 'Clean up orphaned plugins' | translate }}\n </button>\n </c8y-action-bar-item>\n</ng-container>\n\n<div class=\"content-fullpage d-flex d-col border-top\">\n <c8y-data-grid\n [title]=\"title\"\n [loadMoreItemsLabel]=\"loadMoreItemsLabel\"\n [loadingItemsLabel]=\"loadingItemsLabel\"\n [displayOptions]=\"displayOptions\"\n [columns]=\"columns\"\n [rows]=\"installedPlugins$ | async\"\n [pagination]=\"pagination\"\n [selectable]=\"true\"\n [actionControls]=\"actionControls\"\n [bulkActionControls]=\"bulkActionControls\"\n [headerActionControls]=\"headerActionControls\"\n (onReload)=\"refresh()\"\n class=\"d-contents\"\n >\n <!-- No search/filtered results empty state -->\n <c8y-ui-empty-state\n *ngIf=\"(installedPlugins$ | async)?.length\"\n [icon]=\"'search'\"\n [title]=\"'No plugins to display.' | translate\"\n [subtitle]=\"'Refine your search terms or check your spelling.' | translate\"\n [horizontal]=\"true\"\n >\n </c8y-ui-empty-state>\n <!-- No installed plugins empty state -->\n <c8y-ui-empty-state\n *ngIf=\"!(installedPlugins$ | async)?.length && !isLoading\"\n [icon]=\"'plugin'\"\n [title]=\"'No plugins installed.' | translate\"\n [subtitle]=\"'This application doesn\\'t have any plugin. Click below to install.' | translate\"\n [horizontal]=\"true\"\n >\n <div class=\"fit-w p-t-16\">\n <button\n c8yProductExperience\n [actionName]=\"PRODUCT_EXPERIENCE.APPLICATIONS.EVENTS.INSTALLED_PLUGINS\"\n [actionData]=\"{\n component: PRODUCT_EXPERIENCE.APPLICATIONS.COMPONENTS.APPLICATION_PLUGINS,\n action: PRODUCT_EXPERIENCE.APPLICATIONS.ACTIONS.INSTALL_PLUGINS,\n url: CURRENT_LOCATION\n }\"\n (click)=\"installPlugins()\"\n [ngClass]=\"{ 'btn-pending': isLoading }\"\n class=\"btn btn-primary btn-sm\"\n title=\"{{ 'Install plugins' | translate }}\"\n translate\n >\n Install plugins\n </button>\n </div>\n </c8y-ui-empty-state>\n </c8y-data-grid>\n</div>\n", dependencies: [{ kind: "component", type: i2.ActionBarItemComponent, selector: "c8y-action-bar-item", inputs: ["placement", "priority", "itemClass", "injector", "groupId"] }, { kind: "component", type: i2.BreadcrumbComponent, selector: "c8y-breadcrumb" }, { kind: "component", type: i2.BreadcrumbItemComponent, selector: "c8y-breadcrumb-item", inputs: ["icon", "translate", "label", "path", "injector"] }, { kind: "component", type: i2.EmptyStateComponent, selector: "c8y-ui-empty-state", inputs: ["icon", "title", "subtitle", "horizontal"] }, { kind: "directive", type: i2.IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "directive", type: i2.C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "directive", type: i3.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i2.DataGridComponent, selector: "c8y-data-grid", inputs: ["title", "loadMoreItemsLabel", "loadingItemsLabel", "showSearch", "refresh", "columns", "rows", "pagination", "infiniteScroll", "serverSideDataCallback", "selectable", "selectionPrimaryKey", "displayOptions", "actionControls", "bulkActionControls", "headerActionControls", "searchText", "configureColumnsEnabled", "showCounterWarning"], outputs: ["rowMouseOver", "rowMouseLeave", "rowClick", "onConfigChange", "onBeforeFilter", "onBeforeSearch", "onFilter", "itemsSelect", "onReload", "onAddCustomColumn", "onRemoveCustomColumn", "onColumnFilterReset", "onSort", "onPageSizeChange", "onColumnReordered", "onColumnVisibilityChange"] }, { kind: "component", type: i2.TitleComponent, selector: "c8y-title", inputs: ["pageTitleUpdate"] }, { kind: "directive", type: i2.ProductExperienceDirective, selector: "[c8yProductExperience]", inputs: ["actionName", "actionData", "inherit"] }, { kind: "pipe", type: i2.C8yTranslatePipe, name: "translate" }, { kind: "pipe", type: i3.AsyncPipe, name: "async" }, { kind: "pipe", type: i2.HumanizeAppNamePipe, name: "humanizeAppName" }] });
2334
2453
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.6", ngImport: i0, type: ApplicationPluginsComponent, decorators: [{
2335
2454
  type: Component,
2336
- args: [{ selector: 'c8y-app-plugins', template: "<c8y-title>{{ app | humanizeAppName | async }}</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/applications'\"\n ></c8y-breadcrumb-item>\n <c8y-breadcrumb-item\n [icon]=\"'c8y-modules'\"\n [label]=\"'All applications' | translate\"\n [path]=\"'ecosystem/applications'\"\n ></c8y-breadcrumb-item>\n <c8y-breadcrumb-item [label]=\"app | humanizeAppName | async\"></c8y-breadcrumb-item>\n <c8y-breadcrumb-item [label]=\"'Plugins' | translate\"></c8y-breadcrumb-item>\n</c8y-breadcrumb>\n\n<c8y-action-bar-item [placement]=\"'right'\">\n <button\n (click)=\"installPlugins()\"\n [ngClass]=\"{ 'btn-pending': isLoading }\"\n class=\"btn btn-link\"\n title=\"{{ 'Install plugins' | translate }}\"\n >\n <i c8yIcon=\"plus-circle\"></i>\n {{ 'Install plugins' | translate }}\n </button>\n</c8y-action-bar-item>\n\n<ng-container *ngIf=\"orphanedPlugins$ | async as orphanedPlugins\">\n <c8y-action-bar-item *ngIf=\"orphanedPlugins?.length\" [placement]=\"'right'\">\n <button\n (click)=\"cleanupOrphanedPlugins(orphanedPlugins)\"\n [ngClass]=\"{ 'btn-pending': isLoading }\"\n class=\"btn btn-link\"\n title=\"{{ 'Clean up orphaned plugins' | translate }}\"\n >\n <i c8yIcon=\"erase\"></i>\n {{ 'Clean up orphaned plugins' | translate }}\n </button>\n </c8y-action-bar-item>\n</ng-container>\n\n<div class=\"content-fullpage d-flex d-col border-top\">\n <c8y-data-grid\n [title]=\"title\"\n [loadMoreItemsLabel]=\"loadMoreItemsLabel\"\n [loadingItemsLabel]=\"loadingItemsLabel\"\n [displayOptions]=\"displayOptions\"\n [columns]=\"columns\"\n [rows]=\"installedPlugins$ | async\"\n [pagination]=\"pagination\"\n [selectable]=\"true\"\n [actionControls]=\"actionControls\"\n [bulkActionControls]=\"bulkActionControls\"\n [headerActionControls]=\"headerActionControls\"\n (onReload)=\"refresh()\"\n class=\"d-contents\"\n >\n <!-- No search/filtered results empty state -->\n <c8y-ui-empty-state\n *ngIf=\"(installedPlugins$ | async)?.length\"\n [icon]=\"'search'\"\n [title]=\"'No plugins to display.' | translate\"\n [subtitle]=\"'Refine your search terms or check your spelling.' | translate\"\n [horizontal]=\"true\"\n >\n </c8y-ui-empty-state>\n <!-- No installed plugins empty state -->\n <c8y-ui-empty-state\n *ngIf=\"!(installedPlugins$ | async)?.length && !isLoading\"\n [icon]=\"'plugin'\"\n [title]=\"'No plugins installed.' | translate\"\n [subtitle]=\"'This application doesn\\'t have any plugin. Click below to install.' | translate\"\n [horizontal]=\"true\"\n >\n <div class=\"fit-w p-t-16\">\n <button\n (click)=\"installPlugins()\"\n [ngClass]=\"{ 'btn-pending': isLoading }\"\n class=\"btn btn-primary btn-sm\"\n title=\"{{ 'Install plugins' | translate }}\"\n translate\n >\n Install plugins\n </button>\n </div>\n </c8y-ui-empty-state>\n </c8y-data-grid>\n</div>\n" }]
2337
- }], ctorParameters: function () { return [{ type: i1$2.ActivatedRoute }, { type: i1.EcosystemService }, { type: i1$1.BsModalService }, { type: i2.ModalService }, { type: i4.TranslateService }, { type: i2.PluginsService }, { type: i2.AlertService }]; }, propDecorators: { appId: [{
2455
+ args: [{ selector: 'c8y-app-plugins', template: "<c8y-title>{{ app | humanizeAppName | async }}</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/applications'\"\n ></c8y-breadcrumb-item>\n <c8y-breadcrumb-item\n [icon]=\"'c8y-modules'\"\n [label]=\"'All applications' | translate\"\n [path]=\"'ecosystem/applications'\"\n ></c8y-breadcrumb-item>\n <c8y-breadcrumb-item [label]=\"app | humanizeAppName | async\"></c8y-breadcrumb-item>\n <c8y-breadcrumb-item [label]=\"'Plugins' | translate\"></c8y-breadcrumb-item>\n</c8y-breadcrumb>\n\n<c8y-action-bar-item [placement]=\"'right'\">\n <button\n (click)=\"installPlugins()\"\n [ngClass]=\"{ 'btn-pending': isLoading }\"\n class=\"btn btn-link\"\n title=\"{{ 'Install plugins' | translate }}\"\n >\n <i c8yIcon=\"plus-circle\"></i>\n {{ 'Install plugins' | translate }}\n </button>\n</c8y-action-bar-item>\n\n<ng-container *ngIf=\"orphanedPlugins$ | async as orphanedPlugins\">\n <c8y-action-bar-item *ngIf=\"orphanedPlugins?.length\" [placement]=\"'right'\">\n <button\n (click)=\"cleanupOrphanedPlugins(orphanedPlugins)\"\n [ngClass]=\"{ 'btn-pending': isLoading }\"\n class=\"btn btn-link\"\n title=\"{{ 'Clean up orphaned plugins' | translate }}\"\n >\n <i c8yIcon=\"erase\"></i>\n {{ 'Clean up orphaned plugins' | translate }}\n </button>\n </c8y-action-bar-item>\n</ng-container>\n\n<div class=\"content-fullpage d-flex d-col border-top\">\n <c8y-data-grid\n [title]=\"title\"\n [loadMoreItemsLabel]=\"loadMoreItemsLabel\"\n [loadingItemsLabel]=\"loadingItemsLabel\"\n [displayOptions]=\"displayOptions\"\n [columns]=\"columns\"\n [rows]=\"installedPlugins$ | async\"\n [pagination]=\"pagination\"\n [selectable]=\"true\"\n [actionControls]=\"actionControls\"\n [bulkActionControls]=\"bulkActionControls\"\n [headerActionControls]=\"headerActionControls\"\n (onReload)=\"refresh()\"\n class=\"d-contents\"\n >\n <!-- No search/filtered results empty state -->\n <c8y-ui-empty-state\n *ngIf=\"(installedPlugins$ | async)?.length\"\n [icon]=\"'search'\"\n [title]=\"'No plugins to display.' | translate\"\n [subtitle]=\"'Refine your search terms or check your spelling.' | translate\"\n [horizontal]=\"true\"\n >\n </c8y-ui-empty-state>\n <!-- No installed plugins empty state -->\n <c8y-ui-empty-state\n *ngIf=\"!(installedPlugins$ | async)?.length && !isLoading\"\n [icon]=\"'plugin'\"\n [title]=\"'No plugins installed.' | translate\"\n [subtitle]=\"'This application doesn\\'t have any plugin. Click below to install.' | translate\"\n [horizontal]=\"true\"\n >\n <div class=\"fit-w p-t-16\">\n <button\n c8yProductExperience\n [actionName]=\"PRODUCT_EXPERIENCE.APPLICATIONS.EVENTS.INSTALLED_PLUGINS\"\n [actionData]=\"{\n component: PRODUCT_EXPERIENCE.APPLICATIONS.COMPONENTS.APPLICATION_PLUGINS,\n action: PRODUCT_EXPERIENCE.APPLICATIONS.ACTIONS.INSTALL_PLUGINS,\n url: CURRENT_LOCATION\n }\"\n (click)=\"installPlugins()\"\n [ngClass]=\"{ 'btn-pending': isLoading }\"\n class=\"btn btn-primary btn-sm\"\n title=\"{{ 'Install plugins' | translate }}\"\n translate\n >\n Install plugins\n </button>\n </div>\n </c8y-ui-empty-state>\n </c8y-data-grid>\n</div>\n" }]
2456
+ }], ctorParameters: function () { return [{ type: i1$2.ActivatedRoute }, { type: i1.EcosystemService }, { type: i1$1.BsModalService }, { type: i2.ModalService }, { type: i4.TranslateService }, { type: i2.PluginsService }, { type: i2.AlertService }, { type: i2.GainsightService }]; }, propDecorators: { appId: [{
2338
2457
  type: Input
2339
2458
  }], dataGrid: [{
2340
2459
  type: ViewChild,