@c8y/ngx-components
Version:
Angular modules for Cumulocity IoT applications
363 lines (356 loc) • 33.7 kB
JavaScript
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