UNPKG

@c8y/ngx-components

Version:

Angular modules for Cumulocity IoT applications

238 lines (232 loc) 23.7 kB
import { NgIf, NgForOf } from '@angular/common'; import * as i0 from '@angular/core'; import { Component, Optional, ViewChild } from '@angular/core'; import * as i3 from '@c8y/ngx-components'; import { C8yTranslatePipe, IconDirective, ModalModule, MessagesComponent, MessageDirective, C8yTranslateDirective, FormGroupComponent, BuiltInActionType, gettext as gettext$1, TitleComponent, DataGridModule, LoadingComponent, ActionBarItemComponent, HelpModule } from '@c8y/ngx-components'; import * as i1$1 from '@c8y/ngx-components/translation-editor/data'; import * as i1 from '@angular/forms'; import { FormsModule, Validators, ReactiveFormsModule } from '@angular/forms'; import * as i2 from 'ngx-bootstrap/modal'; import { gettext } from '@c8y/ngx-components/gettext'; class ManageTranslationCellRendererComponent { constructor(context, permissions, grid) { this.context = context; this.permissions = permissions; this.grid = grid; this.FOCUS_RENDER_WAIT_TIME_IN_MS = 100; this.isCellEditable = false; this.cellValue = ''; this.isCreateDisabled = false; } ngOnInit() { this.isCreateDisabled = !this.permissions.hasRole('ROLE_APPLICATION_MANAGEMENT_ADMIN'); } async save() { this.isCellEditable = false; const cellValueTrimed = this.cellValue.trim(); this.context.value = cellValueTrimed; this.context.item[this.context.property.path] = cellValueTrimed; this.grid?.valueChanged(); } cancel() { this.isCellEditable = false; } editCell() { this.cellValue = this.context.value; this.isCellEditable = true; // Focuses the input box after the input text box is visible setTimeout(() => { this.cellInput.nativeElement.focus(); }, this.FOCUS_RENDER_WAIT_TIME_IN_MS); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ManageTranslationCellRendererComponent, deps: [{ token: i3.CellRendererContext }, { token: i3.Permissions }, { token: TranslationEditorComponent, optional: true }], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: ManageTranslationCellRendererComponent, isStandalone: true, selector: "c8y-manage-translation-cell-renderer", viewQueries: [{ propertyName: "cellInput", first: true, predicate: ["cellInput"], descendants: true }], ngImport: i0, template: "<div\n class=\"text-truncate pointer d-flex\"\n title=\"{{ context.value }}\"\n data-cy=\"c8y-manage-translation-cell-renderer--edit\"\n (click)=\"!isCreateDisabled ? editCell() : ''\"\n *ngIf=\"!isCellEditable\"\n>\n <span\n class=\"text-truncate\"\n *ngIf=\"!isCellEditable && context.value !== ''\"\n >\n {{ context.value }}\n </span>\n <span\n class=\"text-truncate\"\n title=\"{{ 'Add translation' | translate }}\"\n *ngIf=\"!isCellEditable && context.value === ''\"\n >\n <em class=\"text-muted\">{{ 'Add translation' | translate }}</em>\n </span>\n <i\n class=\"showOnHover text-primary m-l-4\"\n c8yIcon=\"pencil\"\n title=\"{{ 'Edit translation' | translate }}\"\n *ngIf=\"!isCreateDisabled\"\n ></i>\n</div>\n\n<div\n class=\"input-group input-group-sm\"\n *ngIf=\"isCellEditable && !isCreateDisabled\"\n>\n <input\n class=\"form-control\"\n placeholder=\"{{ 'Add translation' | translate }}\"\n type=\"text\"\n #cellInput\n data-cy=\"c8y-manage-translation-cell-renderer--input\"\n [(ngModel)]=\"cellValue\"\n />\n <div class=\"input-group-btn\">\n <button\n class=\"btn btn-clean\"\n title=\"{{ 'Cancel' | translate }}\"\n type=\"button\"\n (click)=\"cancel()\"\n data-cy=\"c8y-manage-translation-cell-renderer--cancel\"\n >\n <i\n class=\"text-danger\"\n c8yIcon=\"times\"\n ></i>\n </button>\n <button\n class=\"btn btn-clean\"\n title=\"{{ 'Save' | translate }}\"\n type=\"button\"\n (click)=\"save()\"\n data-cy=\"c8y-manage-translation-cell-renderer--save\"\n >\n <i\n class=\"text-primary\"\n c8yIcon=\"check\"\n ></i>\n </button>\n </div>\n</div>\n", dependencies: [{ kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }, { kind: "directive", type: IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.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: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }] }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ManageTranslationCellRendererComponent, decorators: [{ type: Component, args: [{ selector: 'c8y-manage-translation-cell-renderer', standalone: true, imports: [NgIf, C8yTranslatePipe, IconDirective, FormsModule], template: "<div\n class=\"text-truncate pointer d-flex\"\n title=\"{{ context.value }}\"\n data-cy=\"c8y-manage-translation-cell-renderer--edit\"\n (click)=\"!isCreateDisabled ? editCell() : ''\"\n *ngIf=\"!isCellEditable\"\n>\n <span\n class=\"text-truncate\"\n *ngIf=\"!isCellEditable && context.value !== ''\"\n >\n {{ context.value }}\n </span>\n <span\n class=\"text-truncate\"\n title=\"{{ 'Add translation' | translate }}\"\n *ngIf=\"!isCellEditable && context.value === ''\"\n >\n <em class=\"text-muted\">{{ 'Add translation' | translate }}</em>\n </span>\n <i\n class=\"showOnHover text-primary m-l-4\"\n c8yIcon=\"pencil\"\n title=\"{{ 'Edit translation' | translate }}\"\n *ngIf=\"!isCreateDisabled\"\n ></i>\n</div>\n\n<div\n class=\"input-group input-group-sm\"\n *ngIf=\"isCellEditable && !isCreateDisabled\"\n>\n <input\n class=\"form-control\"\n placeholder=\"{{ 'Add translation' | translate }}\"\n type=\"text\"\n #cellInput\n data-cy=\"c8y-manage-translation-cell-renderer--input\"\n [(ngModel)]=\"cellValue\"\n />\n <div class=\"input-group-btn\">\n <button\n class=\"btn btn-clean\"\n title=\"{{ 'Cancel' | translate }}\"\n type=\"button\"\n (click)=\"cancel()\"\n data-cy=\"c8y-manage-translation-cell-renderer--cancel\"\n >\n <i\n class=\"text-danger\"\n c8yIcon=\"times\"\n ></i>\n </button>\n <button\n class=\"btn btn-clean\"\n title=\"{{ 'Save' | translate }}\"\n type=\"button\"\n (click)=\"save()\"\n data-cy=\"c8y-manage-translation-cell-renderer--save\"\n >\n <i\n class=\"text-primary\"\n c8yIcon=\"check\"\n ></i>\n </button>\n </div>\n</div>\n" }] }], ctorParameters: () => [{ type: i3.CellRendererContext }, { type: i3.Permissions }, { type: TranslationEditorComponent, decorators: [{ type: Optional }] }], propDecorators: { cellInput: [{ type: ViewChild, args: ['cellInput'] }] } }); class AddTranslationModalComponent { constructor(formBuilder) { this.formBuilder = formBuilder; this.title = gettext('Add translation'); this.result = new Promise((resolve, reject) => { this._resovle = resolve; this._reject = reject; }); this.alreadyTakenMsg = gettext('The provided translation key has already been defined.'); this.alreadyDefinedKeys = []; this.availableLangs = []; } ngOnInit() { this.form = this.initForm(); } initForm() { return this.formBuilder.group({ key: ['', [Validators.required, this.ensureNotExistingKey()]], ...this.availableLangs .map(language => { return { [language.lang]: [''] }; }) .reduceRight((acc, curr) => ({ ...curr, ...acc }), {}) }); } cancel() { this._reject(); } save() { this._resovle(this.form.value); } ensureNotExistingKey() { return (control) => { if (typeof control.value === 'string') { const keyAlreadyTaken = this.alreadyDefinedKeys.some(name => name === control.value); if (keyAlreadyTaken) { return { keyAlreadyTaken: {} }; } } return null; }; } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AddTranslationModalComponent, deps: [{ token: i1.FormBuilder }], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: AddTranslationModalComponent, isStandalone: true, selector: "c8y-add-translation-modal", ngImport: i0, template: "<c8y-modal\n [title]=\"title\"\n [headerClasses]=\"'dialog-header'\"\n (onDismiss)=\"cancel()\"\n (onClose)=\"save()\"\n [disabled]=\"form.invalid\"\n [labels]=\"{ cancel: 'Cancel', ok: 'Add' }\"\n>\n<ng-container c8y-modal-title>\n <span [c8yIcon]=\"'language1'\"></span>\n</ng-container>\n <div [formGroup]=\"form\" class=\"p-24\">\n <c8y-form-group>\n <label\n for=\"label\"\n translate\n >\n Translation key\n </label>\n <input\n class=\"form-control\"\n name=\"key\"\n id=\"key\"\n type=\"text\"\n formControlName=\"key\"\n placeholder=\"{{'e.g. {{ example }}' | translate : { example: 'Home' } }}\"\n />\n <c8y-messages>\n <c8y-message\n name=\"keyAlreadyTaken\"\n [text]=\"alreadyTakenMsg | translate\"\n ></c8y-message>\n </c8y-messages>\n </c8y-form-group>\n\n <c8y-form-group *ngFor=\"let language of availableLangs\">\n <label\n [for]=\"language.lang\"\n >\n {{ language.nativeLanguage }} ({{ language.lang }})\n </label>\n <input\n class=\"form-control\"\n [name]=\"language.lang\"\n [id]=\"language.lang\"\n type=\"text\"\n [formControlName]=\"language.lang\"\n />\n </c8y-form-group>\n </div>\n</c8y-modal>\n", dependencies: [{ kind: "ngmodule", type: ModalModule }, { kind: "component", type: i3.ModalComponent, selector: "c8y-modal", inputs: ["disabled", "close", "dismiss", "title", "body", "customFooter", "headerClasses", "labels"], outputs: ["onDismiss", "onClose"] }, { kind: "directive", type: IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "component", type: MessagesComponent, selector: "c8y-messages", inputs: ["show", "defaults", "helpMessage"] }, { kind: "directive", type: MessageDirective, selector: "c8y-message", inputs: ["name", "text"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }, { kind: "directive", type: C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.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: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "component", type: FormGroupComponent, selector: "c8y-form-group", inputs: ["hasError", "hasWarning", "hasSuccess", "novalidation", "status"] }] }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AddTranslationModalComponent, decorators: [{ type: Component, args: [{ selector: 'c8y-add-translation-modal', standalone: true, imports: [ ModalModule, IconDirective, MessagesComponent, MessageDirective, C8yTranslatePipe, C8yTranslateDirective, ReactiveFormsModule, NgForOf, FormGroupComponent ], template: "<c8y-modal\n [title]=\"title\"\n [headerClasses]=\"'dialog-header'\"\n (onDismiss)=\"cancel()\"\n (onClose)=\"save()\"\n [disabled]=\"form.invalid\"\n [labels]=\"{ cancel: 'Cancel', ok: 'Add' }\"\n>\n<ng-container c8y-modal-title>\n <span [c8yIcon]=\"'language1'\"></span>\n</ng-container>\n <div [formGroup]=\"form\" class=\"p-24\">\n <c8y-form-group>\n <label\n for=\"label\"\n translate\n >\n Translation key\n </label>\n <input\n class=\"form-control\"\n name=\"key\"\n id=\"key\"\n type=\"text\"\n formControlName=\"key\"\n placeholder=\"{{'e.g. {{ example }}' | translate : { example: 'Home' } }}\"\n />\n <c8y-messages>\n <c8y-message\n name=\"keyAlreadyTaken\"\n [text]=\"alreadyTakenMsg | translate\"\n ></c8y-message>\n </c8y-messages>\n </c8y-form-group>\n\n <c8y-form-group *ngFor=\"let language of availableLangs\">\n <label\n [for]=\"language.lang\"\n >\n {{ language.nativeLanguage }} ({{ language.lang }})\n </label>\n <input\n class=\"form-control\"\n [name]=\"language.lang\"\n [id]=\"language.lang\"\n type=\"text\"\n [formControlName]=\"language.lang\"\n />\n </c8y-form-group>\n </div>\n</c8y-modal>\n" }] }], ctorParameters: () => [{ type: i1.FormBuilder }] }); class TranslationEditorComponent { constructor(translationStore, modalService, alert, appState, translate) { this.translationStore = translationStore; this.modalService = modalService; this.alert = alert; this.appState = appState; this.translate = translate; this.pagination = { pageSize: 10, currentPage: 1 }; this.displayOptions = { bordered: false, striped: true, filter: true, gridHeader: true, hover: true }; this.actionControls = [ { type: BuiltInActionType.Delete, callback: item => { this.items = this.items.filter(i => i.key !== item.key); } } ]; this.columns = []; this.isLoading = true; this.items = new Array(); this.isHavingChanges = false; this.availableLangs = []; this.availableLangs = this.appState.state.langs .sort((a, b) => a.localeCompare(b)) .map(l => ({ lang: l, nativeLanguage: this.translate.getNativeLanguage(l) })); } async ngOnInit() { this.refresh(); } async refresh() { this.isLoading = true; this.refreshColumns(); const translations = await this.translationStore.getCombinedListOfTranslationsForPerKey(this.availableLangs.map(l => l.lang)); this.items = translations; this.isLoading = false; } async addEntry() { const currentKeys = this.items.map(item => item.key); const modalRef = this.modalService.show(AddTranslationModalComponent, { initialState: { alreadyDefinedKeys: currentKeys, availableLangs: this.availableLangs } }); try { const result = await modalRef.content.result; this.items = [...this.items, result]; } catch (e) { // do nothing, modal was closed. } } refreshColumns() { this.columns = this.getColumnsForLocales(); } valueChanged() { this.isHavingChanges = true; } async saveTranslations() { try { await this.translationStore.updateTranslations(this.items); await this.refresh(); this.alert.success(gettext$1('Translations saved')); } catch (e) { this.alert.danger(gettext$1('Failed to save translations')); this.alert.addServerFailure(e); } } getColumnsForLocales() { const columns = new Array(); columns.push({ name: 'key', header: gettext$1('Translation key'), path: 'key', filterable: true }); columns.push(...this.availableLangs.map((language, index) => ({ name: language.lang, header: `${language.nativeLanguage} (${language.lang})`, path: language.lang, filterable: false, visible: index < 5, cellRendererComponent: ManageTranslationCellRendererComponent }))); return columns; } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: TranslationEditorComponent, deps: [{ token: i1$1.TranslationStoreService }, { token: i2.BsModalService }, { token: i3.AlertService }, { token: i3.AppStateService }, { token: i3.TranslateService }], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: TranslationEditorComponent, isStandalone: true, selector: "c8y-translation-editor", ngImport: i0, template: "<c8y-title translate>Localization</c8y-title>\n\n<ng-container *ngIf=\"!isLoading; else loading\">\n <c8y-action-bar-item placement=\"right\">\n <button\n class=\"btn btn-link\"\n (click)=\"addEntry()\"\n data-cy=\"c8y-translation-editor--add-translation\"\n >\n <i c8yIcon=\"plus-circle\"></i>\n <span translate>Add translation</span>\n </button>\n </c8y-action-bar-item>\n\n <c8y-action-bar-item placement=\"right\">\n <button\n class=\"btn btn-link\"\n (click)=\"saveTranslations()\"\n data-cy=\"c8y-translation-editor--save-and-apply\"\n >\n <i c8yIcon=\"save\"></i>\n <span translate>Save & apply</span>\n </button>\n </c8y-action-bar-item>\n\n <c8y-help src=\"/docs/standard-tenant/changing-settings/#localization\"></c8y-help>\n\n <c8y-data-grid\n class=\"content-fullpage d-flex d-col\"\n [title]=\"'Translations' | translate\"\n [columns]=\"columns\"\n [actionControls]=\"actionControls\"\n [pagination]=\"pagination\"\n [displayOptions]=\"displayOptions\"\n (onReload)=\"refresh()\"\n [rows]=\"items\"\n ></c8y-data-grid>\n</ng-container>\n\n<ng-template #loading>\n <c8y-loading></c8y-loading>\n</ng-template>\n", dependencies: [{ kind: "component", type: TitleComponent, selector: "c8y-title", inputs: ["pageTitleUpdate"] }, { kind: "ngmodule", type: DataGridModule }, { kind: "component", type: i3.DataGridComponent, selector: "c8y-data-grid", inputs: ["title", "loadMoreItemsLabel", "loadingItemsLabel", "showSearch", "refresh", "columns", "rows", "pagination", "infiniteScroll", "serverSideDataCallback", "selectable", "singleSelection", "selectionPrimaryKey", "displayOptions", "actionControls", "bulkActionControls", "headerActionControls", "searchText", "configureColumnsEnabled", "showCounterWarning", "activeClassName", "expandableRows"], outputs: ["rowMouseOver", "rowMouseLeave", "rowClick", "onConfigChange", "onBeforeFilter", "onBeforeSearch", "onFilter", "itemsSelect", "onReload", "onAddCustomColumn", "onRemoveCustomColumn", "onColumnFilterReset", "onSort", "onPageSizeChange", "onColumnReordered", "onColumnVisibilityChange"] }, { kind: "component", type: LoadingComponent, selector: "c8y-loading", inputs: ["layout", "progress", "message"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }, { kind: "component", type: ActionBarItemComponent, selector: "c8y-action-bar-item", inputs: ["placement", "priority", "itemClass", "injector", "groupId", "inGroupPriority"] }, { kind: "directive", type: IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "directive", type: C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "ngmodule", type: HelpModule }, { kind: "component", type: i3.HelpComponent, selector: "c8y-help", inputs: ["src", "isCollapsed", "priority", "icon"] }] }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: TranslationEditorComponent, decorators: [{ type: Component, args: [{ selector: 'c8y-translation-editor', standalone: true, imports: [ TitleComponent, DataGridModule, LoadingComponent, NgIf, C8yTranslatePipe, ActionBarItemComponent, IconDirective, C8yTranslateDirective, HelpModule ], template: "<c8y-title translate>Localization</c8y-title>\n\n<ng-container *ngIf=\"!isLoading; else loading\">\n <c8y-action-bar-item placement=\"right\">\n <button\n class=\"btn btn-link\"\n (click)=\"addEntry()\"\n data-cy=\"c8y-translation-editor--add-translation\"\n >\n <i c8yIcon=\"plus-circle\"></i>\n <span translate>Add translation</span>\n </button>\n </c8y-action-bar-item>\n\n <c8y-action-bar-item placement=\"right\">\n <button\n class=\"btn btn-link\"\n (click)=\"saveTranslations()\"\n data-cy=\"c8y-translation-editor--save-and-apply\"\n >\n <i c8yIcon=\"save\"></i>\n <span translate>Save & apply</span>\n </button>\n </c8y-action-bar-item>\n\n <c8y-help src=\"/docs/standard-tenant/changing-settings/#localization\"></c8y-help>\n\n <c8y-data-grid\n class=\"content-fullpage d-flex d-col\"\n [title]=\"'Translations' | translate\"\n [columns]=\"columns\"\n [actionControls]=\"actionControls\"\n [pagination]=\"pagination\"\n [displayOptions]=\"displayOptions\"\n (onReload)=\"refresh()\"\n [rows]=\"items\"\n ></c8y-data-grid>\n</ng-container>\n\n<ng-template #loading>\n <c8y-loading></c8y-loading>\n</ng-template>\n" }] }], ctorParameters: () => [{ type: i1$1.TranslationStoreService }, { type: i2.BsModalService }, { type: i3.AlertService }, { type: i3.AppStateService }, { type: i3.TranslateService }] }); /** * Generated bundle index. Do not edit. */ export { TranslationEditorComponent }; //# sourceMappingURL=c8y-ngx-components-translation-editor-lazy.mjs.map