@c8y/ngx-components
Version:
Angular modules for Cumulocity IoT applications
474 lines (463 loc) • 44.7 kB
JavaScript
import * as i0 from '@angular/core';
import { InjectionToken, Directive, ViewChild, Input, Optional, Inject, Component, Injectable, HostListener, EventEmitter, Output, NgModule } from '@angular/core';
import { OperationBulkGeneralStatus } from '@c8y/client';
import { gettext } from '@c8y/ngx-components/gettext';
import * as i3 from '@c8y/ngx-components';
import { C8yTranslatePipe, IconDirective, ProductExperienceDirective, C8yTranslateDirective, Status, ListItemComponent, ListItemIconComponent, ListItemActionComponent, ListItemCollapseComponent, DatePipe, NumberPipe } from '@c8y/ngx-components';
import * as i1 from '@c8y/ngx-components/operations/bulk-operations-service';
import { BULK_OPERATION_EVENT } from '@c8y/ngx-components/operations/product-experience';
import { assign, values, find, cloneDeep } from 'lodash-es';
import * as i2 from 'ngx-bootstrap/modal';
import { Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
import { OperationSchedulerComponent } from '@c8y/ngx-components/operations/bulk-operation-scheduler';
import { OperationSummaryComponent } from '@c8y/ngx-components/operations/operation-summary';
import * as i4 from '@angular/forms';
import { FormsModule } from '@angular/forms';
import { NgClass, NgIf } from '@angular/common';
import { TooltipDirective } from 'ngx-bootstrap/tooltip';
import { PopoverDirective } from 'ngx-bootstrap/popover';
import { OperationDetailsTabsComponent } from '@c8y/ngx-components/operations/operations-list-item-details';
const BULK_OPERATION_STATUS_LABELS = {
SCHEDULED: gettext('Scheduled'),
EXECUTING: gettext('Executing'),
CANCELED: gettext('Canceled'),
FAILED: gettext('Completed with failures'),
SUCCESSFUL: gettext('Completed successfully'),
DELETED: gettext('Deleted')
};
const BULK_OPERATION_STATUS_OPTIONS = {
SCHEDULED: {
label: BULK_OPERATION_STATUS_LABELS.SCHEDULED,
generalStatuses: [OperationBulkGeneralStatus.SCHEDULED],
icon: 'calendar',
styleClass: 'text-info'
},
EXECUTING: {
label: BULK_OPERATION_STATUS_LABELS.EXECUTING,
generalStatuses: [
OperationBulkGeneralStatus.EXECUTING,
OperationBulkGeneralStatus.EXECUTING_WITH_ERROR
],
icon: 'refresh',
styleClass: 'text-primary'
},
DELETED: {
label: BULK_OPERATION_STATUS_LABELS.DELETED,
generalStatuses: [OperationBulkGeneralStatus.DELETED],
icon: 'delete-document',
styleClass: 'text-muted'
},
CANCELED: {
label: BULK_OPERATION_STATUS_LABELS.CANCELED,
generalStatuses: [OperationBulkGeneralStatus.CANCELED],
icon: 'ban',
styleClass: 'text-primary'
},
FAILED: {
label: BULK_OPERATION_STATUS_LABELS.FAILED,
generalStatuses: [OperationBulkGeneralStatus.FAILED],
icon: 'exclamation-circle',
styleClass: 'text-danger'
},
SUCCESSFUL: {
label: BULK_OPERATION_STATUS_LABELS.SUCCESSFUL,
generalStatuses: [OperationBulkGeneralStatus.SUCCESSFUL],
icon: 'check-circle',
styleClass: 'text-success'
}
};
const BULK_OPERATION_WRAPPER_MODAL_BODY_COMPONENT = new InjectionToken('BulkOperationWrapperModalBodyComponent');
class ModalBodyHostDirective {
constructor(viewContainerRef) {
this.viewContainerRef = viewContainerRef;
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: ModalBodyHostDirective, deps: [{ token: i0.ViewContainerRef }], target: i0.ɵɵFactoryTarget.Directive }); }
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.15", type: ModalBodyHostDirective, isStandalone: true, selector: "[modalBodyHost]", ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: ModalBodyHostDirective, decorators: [{
type: Directive,
args: [{ selector: '[modalBodyHost]' }]
}], ctorParameters: () => [{ type: i0.ViewContainerRef }] });
class BulkOperationWrapperComponent {
constructor(bulkOperationsService, modalRef, modalService, modalBodyConfig) {
this.bulkOperationsService = bulkOperationsService;
this.modalRef = modalRef;
this.modalService = modalService;
this.modalBodyConfig = modalBodyConfig;
this.destroyed$ = new Subject();
}
ngOnInit() {
if (this.modalBodyConfig) {
const componentRef = this.modalBodyHost.viewContainerRef.createComponent(this.modalBodyConfig.component);
assign(componentRef.instance, this.modalBodyConfig.config);
componentRef.instance.bulkOperation = this.bulkOperation;
componentRef.instance.showFailedOperation
.pipe(takeUntil(this.destroyed$))
.subscribe(event => this.openDetails(event));
}
}
ngOnDestroy() {
this.destroyed$.next();
this.destroyed$.complete();
}
// openDetails function needs to be defined in the both places (component and the service) to avoid circular dependency.
async openDetails(bulkOperationId) {
const bulkOperation = (await this.bulkOperationsService.getBulkOperationById(bulkOperationId)).data;
const initialState = { bulkOperation };
this.modalService.show(BulkOperationWrapperComponent, {
initialState,
class: 'modal-lg',
ariaDescribedby: 'modal-body',
ariaLabelledBy: 'modal-title'
});
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: BulkOperationWrapperComponent, deps: [{ token: i1.BulkOperationsService }, { token: i2.BsModalRef }, { token: i2.BsModalService }, { token: BULK_OPERATION_WRAPPER_MODAL_BODY_COMPONENT, optional: true }], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.15", type: BulkOperationWrapperComponent, isStandalone: true, selector: "c8y-bulk-operations-wrapper", inputs: { bulkOperation: "bulkOperation" }, viewQueries: [{ propertyName: "modalBodyHost", first: true, predicate: ModalBodyHostDirective, descendants: true, static: true }], ngImport: i0, template: "<div class=\"viewport-modal\">\n <div class=\"modal-header\">\n <h3 id=\"modal-title\">{{ 'Bulk operation details' | translate }}</h3>\n </div>\n\n <div class=\"modal-inner-scroll\" id=\"modal-body\">\n <ng-container modalBodyHost></ng-container>\n </div>\n\n <div class=\"modal-footer\">\n <button\n title=\"{{ 'Close' | translate }}\"\n type=\"button\"\n class=\"btn btn-default\"\n (click)=\"modalRef.hide()\"\n >\n {{ 'Close' | translate }}\n </button>\n </div>\n</div>\n", dependencies: [{ kind: "directive", type: ModalBodyHostDirective, selector: "[modalBodyHost]" }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: BulkOperationWrapperComponent, decorators: [{
type: Component,
args: [{ selector: 'c8y-bulk-operations-wrapper', imports: [ModalBodyHostDirective, C8yTranslatePipe], template: "<div class=\"viewport-modal\">\n <div class=\"modal-header\">\n <h3 id=\"modal-title\">{{ 'Bulk operation details' | translate }}</h3>\n </div>\n\n <div class=\"modal-inner-scroll\" id=\"modal-body\">\n <ng-container modalBodyHost></ng-container>\n </div>\n\n <div class=\"modal-footer\">\n <button\n title=\"{{ 'Close' | translate }}\"\n type=\"button\"\n class=\"btn btn-default\"\n (click)=\"modalRef.hide()\"\n >\n {{ 'Close' | translate }}\n </button>\n </div>\n</div>\n" }]
}], ctorParameters: () => [{ type: i1.BulkOperationsService }, { type: i2.BsModalRef }, { type: i2.BsModalService }, { type: undefined, decorators: [{
type: Optional
}, {
type: Inject,
args: [BULK_OPERATION_WRAPPER_MODAL_BODY_COMPONENT]
}] }], propDecorators: { bulkOperation: [{
type: Input
}], modalBodyHost: [{
type: ViewChild,
args: [ModalBodyHostDirective, { static: true }]
}] } });
class BulkOperationListItemService {
constructor(bulkOperationsService, modalService) {
this.bulkOperationsService = bulkOperationsService;
this.modalService = modalService;
}
async openDetails(bulkOperationId) {
const bulkOperation = (await this.bulkOperationsService.getBulkOperationById(bulkOperationId)).data;
const initialState = { bulkOperation };
this.modalService.show(BulkOperationWrapperComponent, {
initialState,
class: 'modal-lg',
ariaDescribedby: 'modal-body',
ariaLabelledBy: 'modal-title'
});
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: BulkOperationListItemService, deps: [{ token: i1.BulkOperationsService }, { token: i2.BsModalService }], target: i0.ɵɵFactoryTarget.Injectable }); }
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: BulkOperationListItemService, providedIn: 'root' }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: BulkOperationListItemService, decorators: [{
type: Injectable,
args: [{ providedIn: 'root' }]
}], ctorParameters: () => [{ type: i1.BulkOperationsService }, { type: i2.BsModalService }] });
class BulkOperationsRescheduleModalComponent {
constructor(bsModalRef, bulkOperationsService, alert, gainsightService) {
this.bsModalRef = bsModalRef;
this.bulkOperationsService = bulkOperationsService;
this.alert = alert;
this.gainsightService = gainsightService;
this.BULK_OPERATION_EVENT = BULK_OPERATION_EVENT;
this.closeSubject = new Subject();
this.CARRIAGE_RETURN_CODE = 'Escape';
}
onKeyUp(event) {
if (event.code === this.CARRIAGE_RETURN_CODE) {
this.gainsightService.triggerEvent('modalDialog', {
title: this.modalTitle,
result: 'Cancel'
});
}
}
ngOnInit() {
this.modalTitle = this.getTitle();
}
onDateAndDelaySelect($event) {
this.dateAndDelay = $event;
}
getTitle() {
return this.isRetryOperation ? gettext('Retry operation') : gettext('Edit schedule');
}
onCancel() {
this.bsModalRef.hide();
}
async onSave() {
let newBulkOperation;
this.bulkOperation.startDate = this.dateAndDelay.scheduledDate.toISOString();
this.bulkOperation.creationRamp = this.dateAndDelay.delayInSeconds;
if (this.isRetryOperation) {
try {
newBulkOperation = await this.bulkOperationsService.createBulkOperation(this.bulkOperation);
this.alert.success(gettext('Successfully rescheduled for a retry.'));
}
catch (er) {
this.alert.addServerFailure(er);
}
}
else {
try {
newBulkOperation = await this.bulkOperationsService.updateBulkOperation(this.bulkOperation);
this.alert.success(gettext('Successfully rescheduled.'));
}
catch (er) {
this.alert.addServerFailure(er);
}
}
// send back to component from which modal was called
this.closeSubject.next(newBulkOperation.data);
this.bsModalRef.hide();
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: BulkOperationsRescheduleModalComponent, deps: [{ token: i2.BsModalRef }, { token: i1.BulkOperationsService }, { token: i3.AlertService }, { token: i3.GainsightService }], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.15", type: BulkOperationsRescheduleModalComponent, isStandalone: true, selector: "c8y-bulk-operations-reschedule-modal", host: { listeners: { "window:keyup": "onKeyUp($event)" } }, ngImport: i0, template: "<div class=\"viewport-modal\">\n <div class=\"modal-header dialog-header\">\n <i c8yIcon=\"c8y-energy\"></i>\n <h4 id=\"modal-title\">{{ modalTitle | translate }}</h4>\n </div>\n <div class=\"modal-inner-scroll\" id=\"modal-body\">\n <div class=\"modal-body\">\n <div class=\"text-center\">\n <c8y-operation-summary\n [description]=\"bulkOperation.operationPrototype.description\"\n ></c8y-operation-summary>\n </div>\n <div class=\"p-t-16 center-block\" style=\"max-width: 300px\">\n <c8y-operation-scheduler\n [(ngModel)]=\"dateAndDelay\"\n #scheduler=\"ngModel\"\n ></c8y-operation-scheduler>\n </div>\n </div>\n </div>\n <div class=\"modal-footer\">\n <button\n (click)=\"onCancel()\"\n type=\"button\"\n class=\"btn btn-default\"\n title=\"{{ 'Cancel' | translate }}\"\n c8yProductExperience\n [actionName]=\"BULK_OPERATION_EVENT\"\n [actionData]=\"{ title: modalTitle, result: 'Cancel' }\"\n >\n <span translate>Cancel</span>\n </button>\n <button\n id=\"save-btn\"\n (click)=\"onSave()\"\n type=\"button\"\n class=\"btn btn-primary\"\n title=\"{{ 'Save' | translate }}\"\n [disabled]=\"scheduler?.control?.errors\"\n c8yProductExperience\n [actionName]=\"BULK_OPERATION_EVENT\"\n [actionData]=\"{ title: modalTitle, result: 'Save' }\"\n >\n <span translate>Save</span>\n </button>\n </div>\n</div>\n", dependencies: [{ kind: "directive", type: IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "component", type: OperationSummaryComponent, selector: "c8y-operation-summary", inputs: ["name", "description", "deviceQueryString"] }, { kind: "component", type: OperationSchedulerComponent, selector: "c8y-operation-scheduler", inputs: ["minutesAhead"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i4.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: ProductExperienceDirective, selector: "[c8yProductExperience]", inputs: ["actionName", "actionData", "inherit", "suppressDataOverriding"] }, { kind: "directive", type: C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: BulkOperationsRescheduleModalComponent, decorators: [{
type: Component,
args: [{ selector: 'c8y-bulk-operations-reschedule-modal', imports: [
IconDirective,
OperationSummaryComponent,
OperationSchedulerComponent,
FormsModule,
ProductExperienceDirective,
C8yTranslateDirective,
C8yTranslatePipe
], template: "<div class=\"viewport-modal\">\n <div class=\"modal-header dialog-header\">\n <i c8yIcon=\"c8y-energy\"></i>\n <h4 id=\"modal-title\">{{ modalTitle | translate }}</h4>\n </div>\n <div class=\"modal-inner-scroll\" id=\"modal-body\">\n <div class=\"modal-body\">\n <div class=\"text-center\">\n <c8y-operation-summary\n [description]=\"bulkOperation.operationPrototype.description\"\n ></c8y-operation-summary>\n </div>\n <div class=\"p-t-16 center-block\" style=\"max-width: 300px\">\n <c8y-operation-scheduler\n [(ngModel)]=\"dateAndDelay\"\n #scheduler=\"ngModel\"\n ></c8y-operation-scheduler>\n </div>\n </div>\n </div>\n <div class=\"modal-footer\">\n <button\n (click)=\"onCancel()\"\n type=\"button\"\n class=\"btn btn-default\"\n title=\"{{ 'Cancel' | translate }}\"\n c8yProductExperience\n [actionName]=\"BULK_OPERATION_EVENT\"\n [actionData]=\"{ title: modalTitle, result: 'Cancel' }\"\n >\n <span translate>Cancel</span>\n </button>\n <button\n id=\"save-btn\"\n (click)=\"onSave()\"\n type=\"button\"\n class=\"btn btn-primary\"\n title=\"{{ 'Save' | translate }}\"\n [disabled]=\"scheduler?.control?.errors\"\n c8yProductExperience\n [actionName]=\"BULK_OPERATION_EVENT\"\n [actionData]=\"{ title: modalTitle, result: 'Save' }\"\n >\n <span translate>Save</span>\n </button>\n </div>\n</div>\n" }]
}], ctorParameters: () => [{ type: i2.BsModalRef }, { type: i1.BulkOperationsService }, { type: i3.AlertService }, { type: i3.GainsightService }], propDecorators: { onKeyUp: [{
type: HostListener,
args: ['window:keyup', ['$event']]
}] } });
class BulkOperationListItemComponent {
constructor(bulkOperationListItemService, bulkOperationsService, modal, alert, bsModalService) {
this.bulkOperationListItemService = bulkOperationListItemService;
this.bulkOperationsService = bulkOperationsService;
this.modal = modal;
this.alert = alert;
this.bsModalService = bsModalService;
this.BULK_OPERATION_EVENT = BULK_OPERATION_EVENT;
this.detailsCollapsed = true;
this.readOnly = false;
this.showFailedOperation = new EventEmitter();
this.reload = new EventEmitter();
this.refreshLoading = false;
this.bulkOperationGeneralStatus = OperationBulkGeneralStatus;
this.BULK_OPERATION_STATUS_OPTIONS = BULK_OPERATION_STATUS_OPTIONS;
this.finishDatePopoverText = gettext('Approximate date, estimated based on the bulk operation settings.');
this.progressBarClass = 'progress';
this.progressBarStatus = 0;
}
ngOnInit() {
this.finishDate = this.calculateFinishDateMs();
this.setProgressBar();
}
getOperationStatusOptions() {
const statusOptions = values(BULK_OPERATION_STATUS_OPTIONS);
return find(statusOptions, options => options.generalStatuses.includes(this.bulkOperation.generalStatus));
}
ngOnChanges(changes) {
if (changes.bulkOperation && !changes.bulkOperation.firstChange) {
this.setProgressBar();
}
}
calculateFinishDateMs() {
const startDateMs = new Date(this.bulkOperation.startDate).getTime();
const creationRampMs = this.bulkOperation.creationRamp * 1000;
return startDateMs + creationRampMs * this.bulkOperation.progress.all;
}
progressBarProgressFn() {
return (((this.bulkOperation.progress.successful + this.bulkOperation.progress.failed) /
this.bulkOperation.progress.all) *
100);
}
setProgressBar() {
const staticContentOfClass = 'progress-bar progress-striped active progress-bar';
const progressBarState = {
EXECUTING: {
progressBarClass: 'progress progress-striped active',
progressBarColor: `${staticContentOfClass}-primary`,
progressBarStatus: this.progressBarProgressFn()
},
EXECUTING_WITH_ERROR: {
progressBarClass: 'progress progress-striped active',
progressBarColor: `${staticContentOfClass}-danger`,
progressBarStatus: this.progressBarProgressFn()
},
FAILED: {
progressBarClass: 'progress',
progressBarColor: `${staticContentOfClass}-danger`,
progressBarStatus: 100
},
SUCCESSFUL: {
progressBarClass: 'progress',
progressBarColor: `${staticContentOfClass}-success`,
progressBarStatus: 100
}
};
assign(this, progressBarState[this.bulkOperation.generalStatus]);
}
editSchedule() {
const rescheduledOperation = cloneDeep(this.bulkOperation);
const initialState = {
bulkOperation: rescheduledOperation
};
const modalOptions = {
initialState,
class: 'modal-sm',
ariaDescribedby: 'modal-body',
ariaLabelledBy: 'modal-title',
backdrop: 'static'
};
this.bsModalRef = this.bsModalService.show(BulkOperationsRescheduleModalComponent, modalOptions);
}
async cancelBulkOperation() {
try {
await this.modal.confirm(gettext('Cancel bulk operation'), gettext('You are about to cancel the bulk operation. Do you want to proceed?'), Status.DANGER, {}, {}, { eventName: BULK_OPERATION_EVENT });
await this.bulkOperationsService.deleteBulkOperation(this.bulkOperation.id);
this.reload.emit();
this.alert.success(gettext('Operation canceled.'));
}
catch (er) {
this.alert.addServerFailure(er);
}
}
retryFailedOperation() {
const clonedBulk = cloneDeep(this.bulkOperation);
// change the id to failedparentId similar to the logic in deviceBulkControl.service.js
delete clonedBulk.groupId;
clonedBulk.failedParentId = this.bulkOperation.id;
// show reschdedule modal:
const initialState = {
bulkOperation: clonedBulk,
isRetryOperation: true
};
const modalOptions = { initialState, class: 'modal-sm', backdrop: 'static' };
this.bsModalRef = this.bsModalService.show(BulkOperationsRescheduleModalComponent, modalOptions);
this.bsModalRef.content.closeSubject.subscribe(() => {
this.reload.emit();
});
}
async setToSuccessful() {
try {
await this.modal.confirm(gettext('Set manually bulk operation to SUCCESSFUL'), gettext('You are about to change the bulk operation status to SUCCESSFUL. Do you want to proceed?'), Status.DANGER, {}, {}, { eventName: BULK_OPERATION_EVENT });
await this.bulkOperationsService.updateBulkOperation({
id: this.bulkOperation.id,
generalStatus: OperationBulkGeneralStatus.SUCCESSFUL
});
this.reload.emit();
this.alert.success(gettext('Operation status changed to SUCCESSFUL.'));
}
catch (er) {
this.alert.addServerFailure(er);
}
}
openFailedOperation(failedParentId) {
this.showFailedOperation.emit(failedParentId);
}
isStatusScheduled() {
return this.bulkOperation.generalStatus === this.bulkOperationGeneralStatus.SCHEDULED;
}
isStatusExecutingOrExecutingWithError() {
return (this.bulkOperation.generalStatus === this.bulkOperationGeneralStatus.EXECUTING ||
this.bulkOperation.generalStatus === this.bulkOperationGeneralStatus.EXECUTING_WITH_ERROR);
}
allOperationsCreated() {
return (this.bulkOperation.progress.all ===
this.bulkOperation.progress.executing +
this.bulkOperation.progress.failed +
this.bulkOperation.progress.pending +
this.bulkOperation.progress.successful);
}
isStatusCanceled() {
return this.bulkOperation.generalStatus === this.bulkOperationGeneralStatus.CANCELED;
}
isStatusFailed() {
return this.bulkOperation.generalStatus === this.bulkOperationGeneralStatus.FAILED;
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: BulkOperationListItemComponent, deps: [{ token: BulkOperationListItemService }, { token: i1.BulkOperationsService }, { token: i3.ModalService }, { token: i3.AlertService }, { token: i2.BsModalService }], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.15", type: BulkOperationListItemComponent, isStandalone: true, selector: "c8y-bulk-operation-list-item", inputs: { bulkOperation: "bulkOperation", detailsCollapsed: "detailsCollapsed", readOnly: "readOnly" }, outputs: { showFailedOperation: "showFailedOperation", reload: "reload" }, viewQueries: [{ propertyName: "listItem", first: true, predicate: ["listItem"], descendants: true, static: true }], usesOnChanges: true, ngImport: i0, template: "<c8y-li\n class=\"c8y-list__item--double-actions\"\n [ngClass]=\"{ 'c8y-list__item--no-expand': !detailsCollapsed }\"\n [collapsed]=\"detailsCollapsed\"\n #listItem\n id=\"{{ bulkOperation.id }}\"\n>\n <c8y-li-icon>\n <i\n [c8yIcon]=\"getOperationStatusOptions().icon\"\n [ngClass]=\"getOperationStatusOptions().styleClass\"\n [tooltip]=\"getOperationStatusOptions().label | translate\"\n ></i>\n </c8y-li-icon>\n <div [ngClass]=\"{ 'content-flex-58': !readOnly, 'content-flex-50': readOnly }\">\n <div class=\"col-5\">\n <button\n class=\"btn-clean\"\n type=\"button\"\n title=\"{{ bulkOperation.id }} - {{\n bulkOperation.operationPrototype.description | translate\n }}\"\n (click)=\"listItem.toggleCollapsed()\"\n >\n <span class=\"text-truncate\">\n <strong class=\"text-muted m-r-4\">{{ bulkOperation.id }}</strong>\n {{ bulkOperation.operationPrototype.description | translate }}\n </span>\n </button>\n </div>\n <div class=\"flex-grow\">\n <div class=\"m-t-8 visible-xs\"></div>\n <hr *ngIf=\"isStatusCanceled(); else statusNotCanceled\" class=\"m-t-16 m-b-0 visible-xs\" />\n <ng-template #statusNotCanceled>\n <div\n [class]=\"progressBarClass\"\n title=\"{{ progressBarStatus | c8yNumber: 'floor':'1.0-0' }}%\"\n >\n <div\n [class]=\"progressBarColor\"\n role=\"progressbar\"\n [attr.aria-label]=\"'Progress' | translate\"\n aria-valuenow=\"0\"\n aria-valuemin=\"0\"\n aria-valuemax=\"100\"\n [style.width.%]=\"progressBarStatus\"\n >\n <span *ngIf=\"progressBarStatus !== 0\">\n {{ progressBarStatus | c8yNumber: 'floor':'1.0-0' }}%\n </span>\n </div>\n </div>\n </ng-template>\n </div>\n <div class=\"col-4\">\n <div class=\"p-t-8 visible-xs\"></div>\n <small *ngIf=\"bulkOperation.progress.successful > 0\" class=\"m-r-8 icon-flex\">\n <i c8yIcon=\"check-circle\" class=\"text-success m-r-4\"></i>\n <span\n ngNonBindable\n translate\n [translateParams]=\"{ bulkOperationsCountSuccessful: bulkOperation.progress.successful }\"\n >\n {{ bulkOperationsCountSuccessful }} successful\n </span>\n </small>\n <small *ngIf=\"bulkOperation.progress.failed > 0\" class=\"m-r-8 icon-flex\">\n <i c8yIcon=\"warning\" class=\"text-danger m-r-4\"></i>\n <span\n ngNonBindable\n translate\n [translateParams]=\"{ bulkOperationsCountFailed: bulkOperation.progress.failed }\"\n >\n {{ bulkOperationsCountFailed }} failed\n </span>\n </small>\n <small *ngIf=\"bulkOperation.progress.executing > 0\" class=\"m-r-8 icon-flex\">\n <i c8yIcon=\"refresh\" class=\"text-primary m-r-4\"></i>\n <span\n ngNonBindable\n translate\n [translateParams]=\"{ bulkOperationsCountExecuting: bulkOperation.progress.executing }\"\n >\n {{ bulkOperationsCountExecuting }} executing\n </span>\n </small>\n <small *ngIf=\"bulkOperation.progress.pending > 0\" class=\"m-r-8 icon-flex\">\n <i c8yIcon=\"clock-o\" class=\"text-primary m-r-4\"></i>\n <span\n ngNonBindable\n translate\n [translateParams]=\"{ bulkOperationsCountPending: bulkOperation.progress.pending }\"\n >\n {{ bulkOperationsCountPending }} pending\n </span>\n </small>\n </div>\n </div>\n <div class=\"c8y-list__item__footer\">\n <div class=\"m-r-16\">\n <span class=\"text-label-small m-r-4\" translate>Start</span>\n <small class=\"icon-flex\">\n <i c8yIcon=\"calendar\" class=\"m-r-4\"></i>\n <span>\n {{ bulkOperation.startDate | c8yDate }}\n </span>\n </small>\n </div>\n <div class=\"m-r-16\" *ngIf=\"bulkOperationGeneralStatus.CANCELED !== bulkOperation.generalStatus\">\n <span class=\"text-label-small m-r-4\" translate>Finish</span>\n\n <small class=\"icon-flex\">\n <i c8yIcon=\"calendar\" class=\"m-r-4\"></i>\n <span>{{ finishDate | c8yDate }}</span>\n </small>\n <button\n class=\"btn-help btn-help--sm\"\n type=\"button\"\n [attr.aria-label]=\"'Help' | translate\"\n popover=\"{{ finishDatePopoverText | translate }}\"\n placement=\"right\"\n triggers=\"focus\"\n container=\"body\"\n *ngIf=\"isStatusScheduled() || isStatusExecutingOrExecutingWithError()\"\n ></button>\n </div>\n </div>\n <ng-container *ngIf=\"!readOnly\">\n <c8y-li-action\n *ngIf=\"isStatusScheduled()\"\n label=\"{{ 'Edit schedule' | translate }}\"\n (click)=\"editSchedule()\"\n icon=\"pencil\"\n c8yProductExperience\n [actionName]=\"BULK_OPERATION_EVENT\"\n ></c8y-li-action>\n <c8y-li-action\n *ngIf=\"\n isStatusScheduled() || (isStatusExecutingOrExecutingWithError() && !allOperationsCreated())\n \"\n label=\"{{ 'Cancel bulk operation' | translate }}\"\n (click)=\"cancelBulkOperation()\"\n icon=\"remove\"\n c8yProductExperience\n [actionName]=\"BULK_OPERATION_EVENT\"\n ></c8y-li-action>\n <c8y-li-action\n *ngIf=\"isStatusFailed()\"\n label=\"{{ 'Retry failed operations' | translate }}\"\n (click)=\"retryFailedOperation()\"\n icon=\"repeat\"\n c8yProductExperience\n [actionName]=\"BULK_OPERATION_EVENT\"\n ></c8y-li-action>\n <c8y-li-action\n *ngIf=\"isStatusFailed()\"\n label=\"{{ 'Set operation to SUCCESSFUL' | translate }}\"\n (click)=\"setToSuccessful()\"\n icon=\"check-circle\"\n c8yProductExperience\n [actionName]=\"BULK_OPERATION_EVENT\"\n ></c8y-li-action>\n </ng-container>\n <c8y-li-collapse class=\"m-b-16\">\n <c8y-operation-details-tabs\n *ngIf=\"!listItem.collapsed\"\n [operation]=\"bulkOperation\"\n [readOnly]=\"readOnly\"\n (onRetryFailedOperations)=\"retryFailedOperation()\"\n (showFailedOperation)=\"openFailedOperation($event)\"\n [bulkOperationModalDetailsService]=\"bulkOperationListItemService\"\n ></c8y-operation-details-tabs>\n </c8y-li-collapse>\n</c8y-li>\n", dependencies: [{ kind: "component", type: ListItemComponent, selector: "c8y-list-item, c8y-li", inputs: ["active", "highlighted", "emptyActions", "dense", "collapsed", "selectable"], outputs: ["collapsedChange"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: ListItemIconComponent, selector: "c8y-list-item-icon, c8y-li-icon", inputs: ["icon", "status"] }, { kind: "directive", type: IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "directive", type: TooltipDirective, selector: "[tooltip], [tooltipHtml]", inputs: ["adaptivePosition", "tooltip", "placement", "triggers", "container", "containerClass", "boundariesElement", "isOpen", "isDisabled", "delay", "tooltipHtml", "tooltipPlacement", "tooltipIsOpen", "tooltipEnable", "tooltipAppendToBody", "tooltipAnimation", "tooltipClass", "tooltipContext", "tooltipPopupDelay", "tooltipFadeDuration", "tooltipTrigger"], outputs: ["tooltipChange", "onShown", "onHidden", "tooltipStateChanged"], exportAs: ["bs-tooltip"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "directive", type: PopoverDirective, selector: "[popover]", inputs: ["adaptivePosition", "boundariesElement", "popover", "popoverContext", "popoverTitle", "placement", "outsideClick", "triggers", "container", "containerClass", "isOpen", "delay"], outputs: ["onShown", "onHidden"], exportAs: ["bs-popover"] }, { kind: "component", type: ListItemActionComponent, selector: "c8y-list-item-action, c8y-li-action", inputs: ["label", "icon", "disabled"], outputs: ["click"] }, { kind: "directive", type: ProductExperienceDirective, selector: "[c8yProductExperience]", inputs: ["actionName", "actionData", "inherit", "suppressDataOverriding"] }, { kind: "component", type: ListItemCollapseComponent, selector: "c8y-list-item-collapse, c8y-li-collapse", inputs: ["collapseWay"] }, { kind: "component", type: OperationDetailsTabsComponent, selector: "c8y-operation-details-tabs", inputs: ["operation", "readOnly", "bulkOperationModalDetailsService"], outputs: ["onRetryFailedOperations", "showFailedOperation"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }, { kind: "pipe", type: DatePipe, name: "c8yDate" }, { kind: "pipe", type: NumberPipe, name: "c8yNumber" }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: BulkOperationListItemComponent, decorators: [{
type: Component,
args: [{ selector: 'c8y-bulk-operation-list-item', imports: [
ListItemComponent,
NgClass,
ListItemIconComponent,
IconDirective,
TooltipDirective,
NgIf,
C8yTranslateDirective,
PopoverDirective,
ListItemActionComponent,
ProductExperienceDirective,
ListItemCollapseComponent,
OperationDetailsTabsComponent,
C8yTranslatePipe,
DatePipe,
NumberPipe
], template: "<c8y-li\n class=\"c8y-list__item--double-actions\"\n [ngClass]=\"{ 'c8y-list__item--no-expand': !detailsCollapsed }\"\n [collapsed]=\"detailsCollapsed\"\n #listItem\n id=\"{{ bulkOperation.id }}\"\n>\n <c8y-li-icon>\n <i\n [c8yIcon]=\"getOperationStatusOptions().icon\"\n [ngClass]=\"getOperationStatusOptions().styleClass\"\n [tooltip]=\"getOperationStatusOptions().label | translate\"\n ></i>\n </c8y-li-icon>\n <div [ngClass]=\"{ 'content-flex-58': !readOnly, 'content-flex-50': readOnly }\">\n <div class=\"col-5\">\n <button\n class=\"btn-clean\"\n type=\"button\"\n title=\"{{ bulkOperation.id }} - {{\n bulkOperation.operationPrototype.description | translate\n }}\"\n (click)=\"listItem.toggleCollapsed()\"\n >\n <span class=\"text-truncate\">\n <strong class=\"text-muted m-r-4\">{{ bulkOperation.id }}</strong>\n {{ bulkOperation.operationPrototype.description | translate }}\n </span>\n </button>\n </div>\n <div class=\"flex-grow\">\n <div class=\"m-t-8 visible-xs\"></div>\n <hr *ngIf=\"isStatusCanceled(); else statusNotCanceled\" class=\"m-t-16 m-b-0 visible-xs\" />\n <ng-template #statusNotCanceled>\n <div\n [class]=\"progressBarClass\"\n title=\"{{ progressBarStatus | c8yNumber: 'floor':'1.0-0' }}%\"\n >\n <div\n [class]=\"progressBarColor\"\n role=\"progressbar\"\n [attr.aria-label]=\"'Progress' | translate\"\n aria-valuenow=\"0\"\n aria-valuemin=\"0\"\n aria-valuemax=\"100\"\n [style.width.%]=\"progressBarStatus\"\n >\n <span *ngIf=\"progressBarStatus !== 0\">\n {{ progressBarStatus | c8yNumber: 'floor':'1.0-0' }}%\n </span>\n </div>\n </div>\n </ng-template>\n </div>\n <div class=\"col-4\">\n <div class=\"p-t-8 visible-xs\"></div>\n <small *ngIf=\"bulkOperation.progress.successful > 0\" class=\"m-r-8 icon-flex\">\n <i c8yIcon=\"check-circle\" class=\"text-success m-r-4\"></i>\n <span\n ngNonBindable\n translate\n [translateParams]=\"{ bulkOperationsCountSuccessful: bulkOperation.progress.successful }\"\n >\n {{ bulkOperationsCountSuccessful }} successful\n </span>\n </small>\n <small *ngIf=\"bulkOperation.progress.failed > 0\" class=\"m-r-8 icon-flex\">\n <i c8yIcon=\"warning\" class=\"text-danger m-r-4\"></i>\n <span\n ngNonBindable\n translate\n [translateParams]=\"{ bulkOperationsCountFailed: bulkOperation.progress.failed }\"\n >\n {{ bulkOperationsCountFailed }} failed\n </span>\n </small>\n <small *ngIf=\"bulkOperation.progress.executing > 0\" class=\"m-r-8 icon-flex\">\n <i c8yIcon=\"refresh\" class=\"text-primary m-r-4\"></i>\n <span\n ngNonBindable\n translate\n [translateParams]=\"{ bulkOperationsCountExecuting: bulkOperation.progress.executing }\"\n >\n {{ bulkOperationsCountExecuting }} executing\n </span>\n </small>\n <small *ngIf=\"bulkOperation.progress.pending > 0\" class=\"m-r-8 icon-flex\">\n <i c8yIcon=\"clock-o\" class=\"text-primary m-r-4\"></i>\n <span\n ngNonBindable\n translate\n [translateParams]=\"{ bulkOperationsCountPending: bulkOperation.progress.pending }\"\n >\n {{ bulkOperationsCountPending }} pending\n </span>\n </small>\n </div>\n </div>\n <div class=\"c8y-list__item__footer\">\n <div class=\"m-r-16\">\n <span class=\"text-label-small m-r-4\" translate>Start</span>\n <small class=\"icon-flex\">\n <i c8yIcon=\"calendar\" class=\"m-r-4\"></i>\n <span>\n {{ bulkOperation.startDate | c8yDate }}\n </span>\n </small>\n </div>\n <div class=\"m-r-16\" *ngIf=\"bulkOperationGeneralStatus.CANCELED !== bulkOperation.generalStatus\">\n <span class=\"text-label-small m-r-4\" translate>Finish</span>\n\n <small class=\"icon-flex\">\n <i c8yIcon=\"calendar\" class=\"m-r-4\"></i>\n <span>{{ finishDate | c8yDate }}</span>\n </small>\n <button\n class=\"btn-help btn-help--sm\"\n type=\"button\"\n [attr.aria-label]=\"'Help' | translate\"\n popover=\"{{ finishDatePopoverText | translate }}\"\n placement=\"right\"\n triggers=\"focus\"\n container=\"body\"\n *ngIf=\"isStatusScheduled() || isStatusExecutingOrExecutingWithError()\"\n ></button>\n </div>\n </div>\n <ng-container *ngIf=\"!readOnly\">\n <c8y-li-action\n *ngIf=\"isStatusScheduled()\"\n label=\"{{ 'Edit schedule' | translate }}\"\n (click)=\"editSchedule()\"\n icon=\"pencil\"\n c8yProductExperience\n [actionName]=\"BULK_OPERATION_EVENT\"\n ></c8y-li-action>\n <c8y-li-action\n *ngIf=\"\n isStatusScheduled() || (isStatusExecutingOrExecutingWithError() && !allOperationsCreated())\n \"\n label=\"{{ 'Cancel bulk operation' | translate }}\"\n (click)=\"cancelBulkOperation()\"\n icon=\"remove\"\n c8yProductExperience\n [actionName]=\"BULK_OPERATION_EVENT\"\n ></c8y-li-action>\n <c8y-li-action\n *ngIf=\"isStatusFailed()\"\n label=\"{{ 'Retry failed operations' | translate }}\"\n (click)=\"retryFailedOperation()\"\n icon=\"repeat\"\n c8yProductExperience\n [actionName]=\"BULK_OPERATION_EVENT\"\n ></c8y-li-action>\n <c8y-li-action\n *ngIf=\"isStatusFailed()\"\n label=\"{{ 'Set operation to SUCCESSFUL' | translate }}\"\n (click)=\"setToSuccessful()\"\n icon=\"check-circle\"\n c8yProductExperience\n [actionName]=\"BULK_OPERATION_EVENT\"\n ></c8y-li-action>\n </ng-container>\n <c8y-li-collapse class=\"m-b-16\">\n <c8y-operation-details-tabs\n *ngIf=\"!listItem.collapsed\"\n [operation]=\"bulkOperation\"\n [readOnly]=\"readOnly\"\n (onRetryFailedOperations)=\"retryFailedOperation()\"\n (showFailedOperation)=\"openFailedOperation($event)\"\n [bulkOperationModalDetailsService]=\"bulkOperationListItemService\"\n ></c8y-operation-details-tabs>\n </c8y-li-collapse>\n</c8y-li>\n" }]
}], ctorParameters: () => [{ type: BulkOperationListItemService }, { type: i1.BulkOperationsService }, { type: i3.ModalService }, { type: i3.AlertService }, { type: i2.BsModalService }], propDecorators: { bulkOperation: [{
type: Input
}], detailsCollapsed: [{
type: Input
}], readOnly: [{
type: Input
}], showFailedOperation: [{
type: Output
}], reload: [{
type: Output
}], listItem: [{
type: ViewChild,
args: ['listItem', { static: true }]
}] } });
/**
* This module allows for displaying the list item of a bulk operation with its details.
*/
class BulkOperationListItemModule {
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: BulkOperationListItemModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.3.15", ngImport: i0, type: BulkOperationListItemModule, imports: [BulkOperationListItemComponent,
BulkOperationsRescheduleModalComponent,
BulkOperationWrapperComponent,
ModalBodyHostDirective], exports: [BulkOperationListItemComponent,
BulkOperationsRescheduleModalComponent,
BulkOperationWrapperComponent] }); }
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: BulkOperationListItemModule, providers: [
BulkOperationListItemService,
{
provide: BULK_OPERATION_WRAPPER_MODAL_BODY_COMPONENT,
useValue: {
component: BulkOperationListItemComponent,
config: { detailsCollapsed: false, readOnly: true }
}
}
], imports: [BulkOperationListItemComponent,
BulkOperationsRescheduleModalComponent] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: BulkOperationListItemModule, decorators: [{
type: NgModule,
args: [{
imports: [
BulkOperationListItemComponent,
BulkOperationsRescheduleModalComponent,
BulkOperationWrapperComponent,
ModalBodyHostDirective
],
providers: [
BulkOperationListItemService,
{
provide: BULK_OPERATION_WRAPPER_MODAL_BODY_COMPONENT,
useValue: {
component: BulkOperationListItemComponent,
config: { detailsCollapsed: false, readOnly: true }
}
}
],
exports: [
BulkOperationListItemComponent,
BulkOperationsRescheduleModalComponent,
BulkOperationWrapperComponent
]
}]
}] });
/**
* Generated bundle index. Do not edit.
*/
export { BULK_OPERATION_STATUS_LABELS, BULK_OPERATION_STATUS_OPTIONS, BulkOperationListItemComponent, BulkOperationListItemModule, BulkOperationListItemService, BulkOperationWrapperComponent, BulkOperationsRescheduleModalComponent };
//# sourceMappingURL=c8y-ngx-components-operations-bulk-operation-list-item.mjs.map