UNPKG

@c8y/ngx-components

Version:

Angular modules for Cumulocity IoT applications

363 lines (356 loc) 33.7 kB
import { NgIf, NgForOf } from '@angular/common'; import * as i0 from '@angular/core'; import { ViewChild, Optional, Component, signal, computed } from '@angular/core'; import * as i1 from '@c8y/ngx-components'; import { C8yTranslatePipe, IconDirective, ModalModule, MessagesComponent, MessageDirective, C8yTranslateDirective, FormGroupComponent, BuiltInActionType, gettext as gettext$1, TitleComponent, DataGridModule, LoadingComponent, ActionBarItemComponent, HelpComponent } from '@c8y/ngx-components'; import * as i1$2 from '@c8y/ngx-components/translation-editor/data'; import * as i1$1 from '@angular/forms'; import { FormsModule, Validators, ReactiveFormsModule } from '@angular/forms'; import * as i2 from 'ngx-bootstrap/modal'; import { gettext } from '@c8y/ngx-components/gettext'; import { EditorComponent, MonacoEditorMarkerValidatorDirective } from '@c8y/ngx-components/editor'; import * as i3 from '@ngx-translate/core'; 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: "19.2.14", ngImport: i0, type: ManageTranslationCellRendererComponent, deps: [{ token: i1.CellRendererContext }, { token: i1.Permissions }, { token: TranslationEditorComponent, optional: true }], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.14", 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$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: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }] }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", 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: i1.CellRendererContext }, { type: i1.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: "19.2.14", ngImport: i0, type: AddTranslationModalComponent, deps: [{ token: i1$1.FormBuilder }], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.14", 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: i1.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$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: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.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: "19.2.14", 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$1.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: "19.2.14", ngImport: i0, type: TranslationEditorComponent, deps: [{ token: i1$2.TranslationStoreService }, { token: i2.BsModalService }, { token: i1.AlertService }, { token: i1.AppStateService }, { token: i1.TranslateService }], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.14", 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: i1.DataGridComponent, selector: "c8y-data-grid", inputs: ["title", "loadMoreItemsLabel", "loadingItemsLabel", "showSearch", "refresh", "columns", "rows", "pagination", "childNodePagination", "infiniteScroll", "serverSideDataCallback", "selectable", "singleSelection", "selectionPrimaryKey", "displayOptions", "actionControls", "bulkActionControls", "headerActionControls", "searchText", "configureColumnsEnabled", "showCounterWarning", "activeClassName", "expandableRows", "treeGrid", "hideReload", "childNodesProperty", "parentNodeLabelProperty"], outputs: ["rowMouseOver", "rowMouseLeave", "rowClick", "onConfigChange", "onBeforeFilter", "onBeforeSearch", "onFilter", "itemsSelect", "onReload", "onAddCustomColumn", "onRemoveCustomColumn", "onColumnFilterReset", "onSort", "onPageSizeChange", "onColumnReordered", "onColumnVisibilityChange"] }, { kind: "component", type: 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: "component", type: HelpComponent, selector: "c8y-help", inputs: ["src", "isCollapsed", "priority", "icon"] }] }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: TranslationEditorComponent, decorators: [{ type: Component, args: [{ selector: 'c8y-translation-editor', standalone: true, imports: [ TitleComponent, DataGridModule, LoadingComponent, NgIf, C8yTranslatePipe, ActionBarItemComponent, IconDirective, C8yTranslateDirective, HelpComponent ], 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$2.TranslationStoreService }, { type: i2.BsModalService }, { type: i1.AlertService }, { type: i1.AppStateService }, { type: i1.TranslateService }] }); class AdvancedTranslationEditorComponent { constructor(appState, translationStore, alert, translation) { this.appState = appState; this.translationStore = translationStore; this.alert = alert; this.translation = translation; this.valueString = signal(''); this.editorOptions = { language: 'json' }; this.isLoading = signal(false); this.isValidJSON = computed(() => { const data = this.valueString(); try { JSON.parse(data); return true; } catch (e) { return false; } }); this.availableLangs = []; this.availableLangs = this.appState.state.langs.sort((a, b) => a.localeCompare(b)); this.refresh(); } onValueChange(data) { this.valueString.set(data); } onEditorInit(_data) { this.editorComponent.monaco.languages.json.jsonDefaults.setDiagnosticsOptions({ validate: true, schemas: [{ schema: this.JSONSchema, fileMatch: ['*'], uri: 'translation' }], enableSchemaRequest: false, allowComments: false }); } async refresh() { this.isLoading.set(true); const translationProperties = this.availableLangs.reduceRight((acc, lang) => { acc[lang] = { type: 'string', description: this.translation.instant(gettext('Translation for "{{ languageCode }}" language.'), { languageCode: lang }) }; return acc; }, { key: { type: 'string', description: this.translation.instant(gettext('The key to be translated.')) } }); this.JSONSchema = { $schema: 'http://json-schema.org/draft-04/schema#', type: 'array', items: { type: 'object', properties: translationProperties, required: ['key'], minProperties: 2 } }; const translations = await this.translationStore.getCombinedListOfTranslationsForPerKey(this.availableLangs); this.valueString.set(JSON.stringify(translations, undefined, 2)); this.isLoading.set(false); } async importTranslationKeys() { try { this.alert.info(gettext('Importing translation from available Web SDK based applications. This may take a while...')); // since we are only interested in the keys, we only need to retrieve the translations for one (well supported) language // we assume that the keys are the same for all other languages, otherwise we would need to perform a lot more requests. const data = await this.translationStore.getAvailableTranslations(['de']); const valueString = this.valueString(); const values = JSON.parse(valueString); const previousNumberOfEntries = values.length; const retrievedKeys = Object.keys(data); for (const key of retrievedKeys) { const foundKey = values.find(value => value.key === key); if (!foundKey) { values.push({ key }); } } const newpreviousNumberOfEntries = values.length; this.valueString.set(JSON.stringify(values, undefined, 2)); this.alert.success(this.translation.instant(gettext('Retrieved {{ numberOfRetrievedKeys }} keys from available applications. {{ numberOfNewKeys }} new translation keys were added.'), { numberOfRetrievedKeys: retrievedKeys.length, numberOfNewKeys: newpreviousNumberOfEntries - previousNumberOfEntries })); } catch (e) { this.alert.danger(gettext('Failed to import translation keys')); this.alert.addServerFailure(e); } } async saveTranslations() { try { await this.translationStore.updateTranslations(JSON.parse(this.valueString())); await this.refresh(); this.alert.success(gettext('Translations saved')); } catch (e) { this.alert.danger(gettext('Failed to save translations')); this.alert.addServerFailure(e); } } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: AdvancedTranslationEditorComponent, deps: [{ token: i1.AppStateService }, { token: i1$2.TranslationStoreService }, { token: i1.AlertService }, { token: i3.TranslateService }], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.14", type: AdvancedTranslationEditorComponent, isStandalone: true, selector: "c8y-advanced-translation-editor", viewQueries: [{ propertyName: "editorComponent", first: true, predicate: EditorComponent, descendants: true }], 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 [disabled]=\"!isValidJSON()\"\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-action-bar-item placement=\"right\">\n <button\n class=\"btn btn-link\"\n [disabled]=\"!isValidJSON()\"\n (click)=\"importTranslationKeys()\"\n data-cy=\"c8y-translation-editor--import-translation-keys\"\n >\n <i [c8yIcon]=\"'import'\"></i>\n <span translate>Import translation keys from Apps</span>\n </button>\n </c8y-action-bar-item>\n\n <div class=\"card card--fullpage content-fullpage\">\n <c8y-editor\n class=\"flex-grow\"\n [editorOptions]=\"editorOptions\"\n [ngModel]=\"valueString()\"\n (ngModelChange)=\"onValueChange($event)\"\n (editorInit)=\"onEditorInit($event)\"\n monacoEditorMarkerValidator\n ></c8y-editor>\n </div>\n</ng-container>\n\n<ng-template #loading>\n <c8y-loading></c8y-loading>\n</ng-template>", dependencies: [{ kind: "component", type: EditorComponent, selector: "c8y-editor", inputs: ["editorOptions", "theme"], outputs: ["editorInit"] }, { kind: "directive", type: MonacoEditorMarkerValidatorDirective, selector: "c8y-editor [monacoEditorMarkerValidator]" }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: TitleComponent, selector: "c8y-title", inputs: ["pageTitleUpdate"] }, { kind: "component", type: LoadingComponent, selector: "c8y-loading", inputs: ["layout", "progress", "message"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: ActionBarItemComponent, selector: "c8y-action-bar-item", inputs: ["placement", "priority", "itemClass", "injector", "groupId", "inGroupPriority"] }, { kind: "directive", type: IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }] }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: AdvancedTranslationEditorComponent, decorators: [{ type: Component, args: [{ selector: 'c8y-advanced-translation-editor', standalone: true, imports: [ EditorComponent, MonacoEditorMarkerValidatorDirective, FormsModule, TitleComponent, LoadingComponent, NgIf, ActionBarItemComponent, IconDirective ], 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 [disabled]=\"!isValidJSON()\"\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-action-bar-item placement=\"right\">\n <button\n class=\"btn btn-link\"\n [disabled]=\"!isValidJSON()\"\n (click)=\"importTranslationKeys()\"\n data-cy=\"c8y-translation-editor--import-translation-keys\"\n >\n <i [c8yIcon]=\"'import'\"></i>\n <span translate>Import translation keys from Apps</span>\n </button>\n </c8y-action-bar-item>\n\n <div class=\"card card--fullpage content-fullpage\">\n <c8y-editor\n class=\"flex-grow\"\n [editorOptions]=\"editorOptions\"\n [ngModel]=\"valueString()\"\n (ngModelChange)=\"onValueChange($event)\"\n (editorInit)=\"onEditorInit($event)\"\n monacoEditorMarkerValidator\n ></c8y-editor>\n </div>\n</ng-container>\n\n<ng-template #loading>\n <c8y-loading></c8y-loading>\n</ng-template>" }] }], ctorParameters: () => [{ type: i1.AppStateService }, { type: i1$2.TranslationStoreService }, { type: i1.AlertService }, { type: i3.TranslateService }], propDecorators: { editorComponent: [{ type: ViewChild, args: [EditorComponent] }] } }); /** * Generated bundle index. Do not edit. */ export { AdvancedTranslationEditorComponent, TranslationEditorComponent }; //# sourceMappingURL=c8y-ngx-components-translation-editor-lazy.mjs.map