@flusys/ng-localization 9.1.0-rc.1 → 9.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,738 @@
1
+ import { LanguageApiService, TranslationApiService, TranslationKeyApiService } from "./flusys-ng-localization.mjs";
2
+ import * as i0 from "@angular/core";
3
+ import { Component, DestroyRef, computed, inject, signal } from "@angular/core";
4
+ import { HasPermissionDirective, TRANSLATION_KEY_PERMISSIONS, TranslatePipe, TranslateService } from "@flusys/ng-shared";
5
+ import { forkJoin, from } from "rxjs";
6
+ import { takeUntilDestroyed } from "@angular/core/rxjs-interop";
7
+ import { ConfirmationService, FButtonDirective, IconFieldComponent, InputIconComponent, InputTextDirective, MessageService, SelectComponent, TableComponent, TagComponent, TooltipDirective, UiIconComponent } from "@flusys/ng-ui";
8
+ import * as i1 from "@angular/forms";
9
+ import { FormsModule } from "@angular/forms";
10
+ import { Router } from "@angular/router";
11
+ var TranslationKeyListPage = class TranslationKeyListPage {
12
+ TRANSLATION_KEY_PERMISSIONS = TRANSLATION_KEY_PERMISSIONS;
13
+ router = inject(Router);
14
+ languageService = inject(LanguageApiService);
15
+ translationKeyService = inject(TranslationKeyApiService);
16
+ translationService = inject(TranslationApiService);
17
+ confirmationService = inject(ConfirmationService);
18
+ messageService = inject(MessageService);
19
+ translateService = inject(TranslateService);
20
+ destroyRef = inject(DestroyRef);
21
+ isLoading = signal(false, ...ngDevMode ? [{ debugName: "isLoading" }] : /* istanbul ignore next */ []);
22
+ languages = signal([], ...ngDevMode ? [{ debugName: "languages" }] : /* istanbul ignore next */ []);
23
+ modules = signal([], ...ngDevMode ? [{ debugName: "modules" }] : /* istanbul ignore next */ []);
24
+ translationKeys = signal([], ...ngDevMode ? [{ debugName: "translationKeys" }] : /* istanbul ignore next */ []);
25
+ translationCounts = signal(/* @__PURE__ */ new Map(), ...ngDevMode ? [{ debugName: "translationCounts" }] : /* istanbul ignore next */ []);
26
+ selectedModule = signal(null, ...ngDevMode ? [{ debugName: "selectedModule" }] : /* istanbul ignore next */ []);
27
+ searchTerm = signal("", ...ngDevMode ? [{ debugName: "searchTerm" }] : /* istanbul ignore next */ []);
28
+ moduleOptions = computed(() => [{
29
+ label: this.translateService.translate("shared.all"),
30
+ value: null
31
+ }, ...this.modules().map((m) => ({
32
+ label: m,
33
+ value: m
34
+ }))], ...ngDevMode ? [{ debugName: "moduleOptions" }] : /* istanbul ignore next */ []);
35
+ filteredKeys = computed(() => {
36
+ let keys = this.translationKeys();
37
+ const module = this.selectedModule();
38
+ const search = this.searchTerm().toLowerCase().trim();
39
+ if (module) keys = keys.filter((k) => k.module === module);
40
+ if (search) keys = keys.filter((k) => k.key.toLowerCase().includes(search) || k.defaultMessage.toLowerCase().includes(search) || k.module.toLowerCase().includes(search));
41
+ return keys;
42
+ }, ...ngDevMode ? [{ debugName: "filteredKeys" }] : /* istanbul ignore next */ []);
43
+ ngOnInit() {
44
+ this.loadData();
45
+ }
46
+ loadData() {
47
+ this.isLoading.set(true);
48
+ forkJoin({
49
+ languages: from(this.languageService.getAll({
50
+ pagination: {
51
+ currentPage: 0,
52
+ pageSize: 100
53
+ },
54
+ filter: {},
55
+ sort: {
56
+ serial: "ASC",
57
+ name: "ASC"
58
+ }
59
+ })),
60
+ modules: this.translationKeyService.getModules(),
61
+ keys: from(this.translationKeyService.getAll({
62
+ pagination: {
63
+ currentPage: 0,
64
+ pageSize: 1e3
65
+ },
66
+ filter: {},
67
+ sort: {
68
+ module: "ASC",
69
+ key: "ASC"
70
+ }
71
+ }))
72
+ }).pipe(takeUntilDestroyed(this.destroyRef)).subscribe({
73
+ next: ({ languages, modules, keys }) => {
74
+ if (languages.success && languages.data) this.languages.set(languages.data.filter((l) => l.isActive));
75
+ if (modules.success && modules.data) this.modules.set(modules.data);
76
+ if (keys.success && keys.data) {
77
+ this.translationKeys.set(keys.data);
78
+ this.loadTranslationCounts();
79
+ }
80
+ this.isLoading.set(false);
81
+ },
82
+ error: () => {
83
+ this.isLoading.set(false);
84
+ }
85
+ });
86
+ }
87
+ loadTranslationCounts() {
88
+ this.translationService.getCounts().pipe(takeUntilDestroyed(this.destroyRef)).subscribe({ next: (response) => {
89
+ if (response.success && response.data) this.translationCounts.set(new Map(Object.entries(response.data)));
90
+ } });
91
+ }
92
+ getTranslationCount(keyId) {
93
+ return this.translationCounts().get(keyId) ?? 0;
94
+ }
95
+ onModuleChange(value) {
96
+ this.selectedModule.set(value);
97
+ }
98
+ onCreate() {
99
+ this.router.navigate(["/localization/keys/new"]);
100
+ }
101
+ onEdit(key) {
102
+ this.router.navigate(["/localization/keys", key.id]);
103
+ }
104
+ onDelete(key) {
105
+ this.confirmationService.confirm({
106
+ message: this.translateService.translate("shared.confirm.delete"),
107
+ header: this.translateService.translate("localization.key.delete.title"),
108
+ icon: "exclamation-triangle",
109
+ acceptButtonStyleClass: "p-button-danger",
110
+ accept: () => {
111
+ from(this.translationKeyService.delete({
112
+ id: key.id,
113
+ type: "delete"
114
+ })).pipe(takeUntilDestroyed(this.destroyRef)).subscribe({ next: (response) => {
115
+ if (response.success) {
116
+ this.messageService.add({
117
+ severity: "success",
118
+ summary: this.translateService.translate("shared.success"),
119
+ detail: response.messageKey ? this.translateService.translate(response.messageKey, response.messageVariables) : response.message ?? ""
120
+ });
121
+ this.loadData();
122
+ }
123
+ } });
124
+ }
125
+ });
126
+ }
127
+ static ɵfac = i0.ɵɵngDeclareFactory({
128
+ minVersion: "12.0.0",
129
+ version: "22.2.1",
130
+ ngImport: i0,
131
+ type: TranslationKeyListPage,
132
+ deps: [],
133
+ target: i0.ɵɵFactoryTarget.Component
134
+ });
135
+ static ɵcmp = i0.ɵɵngDeclareComponent({
136
+ minVersion: "17.0.0",
137
+ version: "22.2.1",
138
+ type: TranslationKeyListPage,
139
+ isStandalone: true,
140
+ selector: "lib-translation-key-list-page",
141
+ ngImport: i0,
142
+ template: `
143
+ <div class="card">
144
+ <div
145
+ class="flex flex-col sm:flex-row justify-between items-start sm:items-center gap-3 mb-4"
146
+ >
147
+ <div>
148
+ <h3 class="text-lg sm:text-xl font-semibold m-0">
149
+ {{ 'localization.key.title' | translate }}
150
+ </h3>
151
+ <p class="text-sm text-muted-color mt-1">
152
+ {{ 'localization.key.subtitle' | translate }}
153
+ </p>
154
+ </div>
155
+ <div class="flex gap-2">
156
+ <button
157
+ fButton
158
+ *hasPermission="TRANSLATION_KEY_PERMISSIONS.CREATE"
159
+ (click)="onCreate()"
160
+ >
161
+ <ui-icon pButtonIcon name="plus"></ui-icon>
162
+ <span pButtonLabel>{{ 'localization.key.new' | translate }}</span>
163
+ </button>
164
+ </div>
165
+ </div>
166
+
167
+ <div class="flex flex-col md:flex-row gap-4 mb-4">
168
+ <div class="flex-1">
169
+ <f-select
170
+ [options]="moduleOptions()"
171
+ [ngModel]="selectedModule()"
172
+ (ngModelChange)="onModuleChange($event)"
173
+ [ngModelOptions]="{ standalone: true }"
174
+ optionLabel="label"
175
+ optionValue="value"
176
+ [placeholder]="'localization.key.filter.module' | translate"
177
+ [showClear]="true"
178
+ class="w-full"
179
+ />
180
+ </div>
181
+ <div class="flex-1">
182
+ <f-iconfield class="w-full">
183
+ <f-inputicon icon="search" />
184
+ <input
185
+ fInputText
186
+ [ngModel]="searchTerm()"
187
+ (ngModelChange)="searchTerm.set($event)"
188
+ [ngModelOptions]="{ standalone: true }"
189
+ [placeholder]="'shared.search' | translate"
190
+ class="w-full"
191
+ />
192
+ </f-iconfield>
193
+ </div>
194
+ </div>
195
+
196
+ <!-- Table -->
197
+ <f-table
198
+ [value]="filteredKeys()"
199
+ [loading]="isLoading()"
200
+ [paginator]="true"
201
+ [rows]="15"
202
+ [rowsPerPageOptions]="[10, 15, 25, 50]"
203
+ >
204
+ <ng-template #header>
205
+ <tr>
206
+ <th style="width: 15%">
207
+ {{ 'localization.key.module' | translate }}
208
+ </th>
209
+ <th style="width: 25%">
210
+ {{ 'localization.key.name' | translate }}
211
+ </th>
212
+ <th style="width: 35%">
213
+ {{ 'localization.key.default.message' | translate }}
214
+ </th>
215
+ <th style="width: 10%">
216
+ {{ 'localization.key.translations' | translate }}
217
+ </th>
218
+ <th style="width: 15%">{{ 'shared.actions' | translate }}</th>
219
+ </tr>
220
+ </ng-template>
221
+ <ng-template #body let-key>
222
+ @let translationCount = getTranslationCount(key.id);
223
+ @let languageCount = languages().length;
224
+ <tr>
225
+ <td>
226
+ <f-tag [value]="key.module" severity="secondary" />
227
+ </td>
228
+ <td>
229
+ <div class="flex items-center gap-2">
230
+ <span class="font-medium">{{ key.key }}</span>
231
+ @if (key.isReadonly) {
232
+ <f-tag
233
+ [value]="'shared.read.only' | translate"
234
+ severity="warn"
235
+ />
236
+ }
237
+ </div>
238
+ @if (key.description) {
239
+ <small class="text-muted-color">{{ key.description }}</small>
240
+ }
241
+ </td>
242
+ <td>{{ key.defaultMessage }}</td>
243
+ <td class="text-center">
244
+ <span
245
+ class="text-sm"
246
+ [class.text-green-500]="translationCount === languageCount"
247
+ [class.text-orange-500]="
248
+ translationCount < languageCount && translationCount > 0
249
+ "
250
+ [class.text-muted-color]="translationCount === 0"
251
+ >
252
+ {{ translationCount }}/{{ languageCount }}
253
+ </span>
254
+ </td>
255
+ <td>
256
+ <div class="flex gap-1">
257
+ <button
258
+ fButton
259
+ *hasPermission="TRANSLATION_KEY_PERMISSIONS.UPDATE"
260
+ [text]="true"
261
+ severity="secondary"
262
+ size="small"
263
+ [fTooltip]="'shared.edit' | translate"
264
+ (click)="onEdit(key)"
265
+ >
266
+ <ui-icon pButtonIcon name="pencil"></ui-icon>
267
+ </button>
268
+ <button
269
+ fButton
270
+ *hasPermission="TRANSLATION_KEY_PERMISSIONS.DELETE"
271
+ [text]="true"
272
+ severity="danger"
273
+ size="small"
274
+ [disabled]="key.isReadonly"
275
+ [fTooltip]="
276
+ (key.isReadonly
277
+ ? 'localization.key.readonly.delete.forbidden'
278
+ : 'shared.delete'
279
+ ) | translate
280
+ "
281
+ (click)="onDelete(key)"
282
+ >
283
+ <ui-icon pButtonIcon name="trash"></ui-icon>
284
+ </button>
285
+ </div>
286
+ </td>
287
+ </tr>
288
+ </ng-template>
289
+ <ng-template #emptymessage>
290
+ <tr>
291
+ <td colspan="5" class="text-center py-4 text-muted-color">
292
+ {{ 'localization.key.empty' | translate }}
293
+ </td>
294
+ </tr>
295
+ </ng-template>
296
+ </f-table>
297
+ </div>
298
+ `,
299
+ isInline: true,
300
+ dependencies: [
301
+ {
302
+ kind: "directive",
303
+ type: FButtonDirective,
304
+ selector: "[fButton]",
305
+ inputs: [
306
+ "severity",
307
+ "text",
308
+ "outlined",
309
+ "link",
310
+ "variant",
311
+ "rounded",
312
+ "raised",
313
+ "fluid",
314
+ "disabled",
315
+ "loading",
316
+ "loadingIcon",
317
+ "size",
318
+ "label",
319
+ "icon",
320
+ "iconPos",
321
+ "ariaLabel",
322
+ "plain"
323
+ ]
324
+ },
325
+ {
326
+ kind: "component",
327
+ type: UiIconComponent,
328
+ selector: "ui-icon",
329
+ inputs: [
330
+ "name",
331
+ "size",
332
+ "spin",
333
+ "fill",
334
+ "severity"
335
+ ]
336
+ },
337
+ {
338
+ kind: "component",
339
+ type: SelectComponent,
340
+ selector: "f-select",
341
+ inputs: [
342
+ "options",
343
+ "optionLabel",
344
+ "optionValue",
345
+ "placeholder",
346
+ "disabled",
347
+ "filter",
348
+ "filterBy",
349
+ "filterMatchMode",
350
+ "filterLocale",
351
+ "filterPlaceholder",
352
+ "resetFilterOnHide",
353
+ "autofocusFilter",
354
+ "emptyMessage",
355
+ "emptyFilterMessage",
356
+ "showClear",
357
+ "loading",
358
+ "loadingIcon",
359
+ "dropdownIcon",
360
+ "clearIcon",
361
+ "inputId",
362
+ "invalid",
363
+ "touched",
364
+ "styleClass",
365
+ "style",
366
+ "appendTo",
367
+ "editable",
368
+ "readonly",
369
+ "autofocus",
370
+ "checkmark",
371
+ "group",
372
+ "optionGroupLabel",
373
+ "optionGroupChildren",
374
+ "virtualScroll",
375
+ "virtualScrollItemSize",
376
+ "lazy",
377
+ "selectedObject"
378
+ ],
379
+ outputs: [
380
+ "onFilter",
381
+ "onChange",
382
+ "onShow",
383
+ "onHide",
384
+ "onBlur",
385
+ "onFocus",
386
+ "onClear",
387
+ "onLazyLoad"
388
+ ]
389
+ },
390
+ {
391
+ kind: "component",
392
+ type: IconFieldComponent,
393
+ selector: "f-iconfield",
394
+ inputs: ["iconPosition", "styleClass"]
395
+ },
396
+ {
397
+ kind: "component",
398
+ type: InputIconComponent,
399
+ selector: "f-inputicon",
400
+ inputs: [
401
+ "icon",
402
+ "position",
403
+ "styleClass",
404
+ "style"
405
+ ]
406
+ },
407
+ {
408
+ kind: "directive",
409
+ type: InputTextDirective,
410
+ selector: "[fInputText]",
411
+ inputs: [
412
+ "invalid",
413
+ "touched",
414
+ "variant",
415
+ "size",
416
+ "fluid"
417
+ ]
418
+ },
419
+ {
420
+ kind: "component",
421
+ type: TableComponent,
422
+ selector: "f-table",
423
+ inputs: [
424
+ "value",
425
+ "lazy",
426
+ "loading",
427
+ "rows",
428
+ "totalRecords",
429
+ "rowHover",
430
+ "dataKey",
431
+ "scrollable",
432
+ "scrollHeight",
433
+ "paginator",
434
+ "first",
435
+ "rowsPerPageOptions",
436
+ "showCurrentPageReport",
437
+ "currentPageReportTemplate",
438
+ "tableStyle",
439
+ "styleClass",
440
+ "globalFilterFields",
441
+ "filterDelay",
442
+ "responsiveLayout",
443
+ "selectionMode",
444
+ "sortMode",
445
+ "rowExpandMode",
446
+ "resizableColumns",
447
+ "rowStyleClass",
448
+ "virtualScroll",
449
+ "virtualScrollItemSize",
450
+ "sortField",
451
+ "sortOrder",
452
+ "multiSortMeta",
453
+ "filters",
454
+ "selection",
455
+ "expandedRowKeys",
456
+ "contextMenuSelection"
457
+ ],
458
+ outputs: [
459
+ "sortFieldChange",
460
+ "sortOrderChange",
461
+ "multiSortMetaChange",
462
+ "filtersChange",
463
+ "selectionChange",
464
+ "expandedRowKeysChange",
465
+ "contextMenuSelectionChange",
466
+ "onLazyLoad",
467
+ "onSort",
468
+ "onFilter",
469
+ "onRowSelect",
470
+ "onRowUnselect",
471
+ "onSelectAllChange",
472
+ "onRowExpand",
473
+ "onRowCollapse",
474
+ "onColResize",
475
+ "onRowContextMenu"
476
+ ]
477
+ },
478
+ {
479
+ kind: "component",
480
+ type: TagComponent,
481
+ selector: "f-tag",
482
+ inputs: [
483
+ "value",
484
+ "severity",
485
+ "icon",
486
+ "rounded",
487
+ "color",
488
+ "styleClass",
489
+ "style"
490
+ ]
491
+ },
492
+ {
493
+ kind: "directive",
494
+ type: TooltipDirective,
495
+ selector: "[fTooltip]",
496
+ inputs: [
497
+ "fTooltip",
498
+ "tooltipPosition",
499
+ "positionStyle",
500
+ "tooltipStyleClass",
501
+ "disabled",
502
+ "tooltipEvent",
503
+ "showDelay",
504
+ "hideDelay",
505
+ "life",
506
+ "autoHide",
507
+ "positionTop",
508
+ "positionLeft",
509
+ "escape"
510
+ ]
511
+ },
512
+ {
513
+ kind: "ngmodule",
514
+ type: FormsModule
515
+ },
516
+ {
517
+ kind: "directive",
518
+ type: i1.DefaultValueAccessor,
519
+ selector: "input:not([type=checkbox]):not([ngNoCva])[formControlName],textarea:not([ngNoCva])[formControlName],input:not([type=checkbox]):not([ngNoCva])[formControl],textarea:not([ngNoCva])[formControl],input:not([type=checkbox]):not([ngNoCva])[ngModel],textarea:not([ngNoCva])[ngModel],[ngDefaultControl]"
520
+ },
521
+ {
522
+ kind: "directive",
523
+ type: i1.NgControlStatus,
524
+ selector: "[formControlName],[ngModel],[formControl]"
525
+ },
526
+ {
527
+ kind: "directive",
528
+ type: i1.NgModel,
529
+ selector: "[ngModel]:not([formControlName]):not([formControl])",
530
+ inputs: [
531
+ "name",
532
+ "disabled",
533
+ "ngModel",
534
+ "ngModelOptions"
535
+ ],
536
+ outputs: ["ngModelChange"],
537
+ exportAs: ["ngModel"]
538
+ },
539
+ {
540
+ kind: "directive",
541
+ type: HasPermissionDirective,
542
+ selector: "[hasPermission]",
543
+ inputs: ["hasPermission"]
544
+ },
545
+ {
546
+ kind: "pipe",
547
+ type: TranslatePipe,
548
+ name: "translate"
549
+ }
550
+ ]
551
+ });
552
+ };
553
+ i0.ɵɵngDeclareClassMetadata({
554
+ minVersion: "12.0.0",
555
+ version: "22.2.1",
556
+ ngImport: i0,
557
+ type: TranslationKeyListPage,
558
+ decorators: [{
559
+ type: Component,
560
+ args: [{
561
+ selector: "lib-translation-key-list-page",
562
+ imports: [
563
+ FButtonDirective,
564
+ UiIconComponent,
565
+ SelectComponent,
566
+ IconFieldComponent,
567
+ InputIconComponent,
568
+ InputTextDirective,
569
+ TableComponent,
570
+ TagComponent,
571
+ TooltipDirective,
572
+ FormsModule,
573
+ HasPermissionDirective,
574
+ TranslatePipe
575
+ ],
576
+ template: `
577
+ <div class="card">
578
+ <div
579
+ class="flex flex-col sm:flex-row justify-between items-start sm:items-center gap-3 mb-4"
580
+ >
581
+ <div>
582
+ <h3 class="text-lg sm:text-xl font-semibold m-0">
583
+ {{ 'localization.key.title' | translate }}
584
+ </h3>
585
+ <p class="text-sm text-muted-color mt-1">
586
+ {{ 'localization.key.subtitle' | translate }}
587
+ </p>
588
+ </div>
589
+ <div class="flex gap-2">
590
+ <button
591
+ fButton
592
+ *hasPermission="TRANSLATION_KEY_PERMISSIONS.CREATE"
593
+ (click)="onCreate()"
594
+ >
595
+ <ui-icon pButtonIcon name="plus"></ui-icon>
596
+ <span pButtonLabel>{{ 'localization.key.new' | translate }}</span>
597
+ </button>
598
+ </div>
599
+ </div>
600
+
601
+ <div class="flex flex-col md:flex-row gap-4 mb-4">
602
+ <div class="flex-1">
603
+ <f-select
604
+ [options]="moduleOptions()"
605
+ [ngModel]="selectedModule()"
606
+ (ngModelChange)="onModuleChange($event)"
607
+ [ngModelOptions]="{ standalone: true }"
608
+ optionLabel="label"
609
+ optionValue="value"
610
+ [placeholder]="'localization.key.filter.module' | translate"
611
+ [showClear]="true"
612
+ class="w-full"
613
+ />
614
+ </div>
615
+ <div class="flex-1">
616
+ <f-iconfield class="w-full">
617
+ <f-inputicon icon="search" />
618
+ <input
619
+ fInputText
620
+ [ngModel]="searchTerm()"
621
+ (ngModelChange)="searchTerm.set($event)"
622
+ [ngModelOptions]="{ standalone: true }"
623
+ [placeholder]="'shared.search' | translate"
624
+ class="w-full"
625
+ />
626
+ </f-iconfield>
627
+ </div>
628
+ </div>
629
+
630
+ <!-- Table -->
631
+ <f-table
632
+ [value]="filteredKeys()"
633
+ [loading]="isLoading()"
634
+ [paginator]="true"
635
+ [rows]="15"
636
+ [rowsPerPageOptions]="[10, 15, 25, 50]"
637
+ >
638
+ <ng-template #header>
639
+ <tr>
640
+ <th style="width: 15%">
641
+ {{ 'localization.key.module' | translate }}
642
+ </th>
643
+ <th style="width: 25%">
644
+ {{ 'localization.key.name' | translate }}
645
+ </th>
646
+ <th style="width: 35%">
647
+ {{ 'localization.key.default.message' | translate }}
648
+ </th>
649
+ <th style="width: 10%">
650
+ {{ 'localization.key.translations' | translate }}
651
+ </th>
652
+ <th style="width: 15%">{{ 'shared.actions' | translate }}</th>
653
+ </tr>
654
+ </ng-template>
655
+ <ng-template #body let-key>
656
+ @let translationCount = getTranslationCount(key.id);
657
+ @let languageCount = languages().length;
658
+ <tr>
659
+ <td>
660
+ <f-tag [value]="key.module" severity="secondary" />
661
+ </td>
662
+ <td>
663
+ <div class="flex items-center gap-2">
664
+ <span class="font-medium">{{ key.key }}</span>
665
+ @if (key.isReadonly) {
666
+ <f-tag
667
+ [value]="'shared.read.only' | translate"
668
+ severity="warn"
669
+ />
670
+ }
671
+ </div>
672
+ @if (key.description) {
673
+ <small class="text-muted-color">{{ key.description }}</small>
674
+ }
675
+ </td>
676
+ <td>{{ key.defaultMessage }}</td>
677
+ <td class="text-center">
678
+ <span
679
+ class="text-sm"
680
+ [class.text-green-500]="translationCount === languageCount"
681
+ [class.text-orange-500]="
682
+ translationCount < languageCount && translationCount > 0
683
+ "
684
+ [class.text-muted-color]="translationCount === 0"
685
+ >
686
+ {{ translationCount }}/{{ languageCount }}
687
+ </span>
688
+ </td>
689
+ <td>
690
+ <div class="flex gap-1">
691
+ <button
692
+ fButton
693
+ *hasPermission="TRANSLATION_KEY_PERMISSIONS.UPDATE"
694
+ [text]="true"
695
+ severity="secondary"
696
+ size="small"
697
+ [fTooltip]="'shared.edit' | translate"
698
+ (click)="onEdit(key)"
699
+ >
700
+ <ui-icon pButtonIcon name="pencil"></ui-icon>
701
+ </button>
702
+ <button
703
+ fButton
704
+ *hasPermission="TRANSLATION_KEY_PERMISSIONS.DELETE"
705
+ [text]="true"
706
+ severity="danger"
707
+ size="small"
708
+ [disabled]="key.isReadonly"
709
+ [fTooltip]="
710
+ (key.isReadonly
711
+ ? 'localization.key.readonly.delete.forbidden'
712
+ : 'shared.delete'
713
+ ) | translate
714
+ "
715
+ (click)="onDelete(key)"
716
+ >
717
+ <ui-icon pButtonIcon name="trash"></ui-icon>
718
+ </button>
719
+ </div>
720
+ </td>
721
+ </tr>
722
+ </ng-template>
723
+ <ng-template #emptymessage>
724
+ <tr>
725
+ <td colspan="5" class="text-center py-4 text-muted-color">
726
+ {{ 'localization.key.empty' | translate }}
727
+ </td>
728
+ </tr>
729
+ </ng-template>
730
+ </f-table>
731
+ </div>
732
+ `
733
+ }]
734
+ }]
735
+ });
736
+ export { TranslationKeyListPage };
737
+
738
+ //# sourceMappingURL=flusys-ng-localization-translation-key-list.page-DhRI5UvT.mjs.map