@es.framework/ng.ui.core 2.0.58 → 2.0.59
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.
- package/fesm2022/es.framework-ng.ui.core-filter-templates.mjs +867 -5
- package/fesm2022/es.framework-ng.ui.core-filter-templates.mjs.map +1 -1
- package/fesm2022/es.framework-ng.ui.core-generic-selector.mjs +73 -14
- package/fesm2022/es.framework-ng.ui.core-generic-selector.mjs.map +1 -1
- package/package.json +1 -1
- package/types/es.framework-ng.ui.core-filter-templates.d.ts +80 -2
- package/types/es.framework-ng.ui.core-generic-selector.d.ts +1 -0
|
@@ -1,9 +1,23 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { NgModule, inject, EventEmitter, Input, Output, Component } from '@angular/core';
|
|
2
|
+
import { NgModule, inject, EventEmitter, Input, Output, Component, signal, Injectable } from '@angular/core';
|
|
3
|
+
import * as i1 from '@angular/common';
|
|
3
4
|
import { CommonModule } from '@angular/common';
|
|
4
|
-
import
|
|
5
|
-
import {
|
|
5
|
+
import * as i2 from '@angular/forms';
|
|
6
|
+
import { UntypedFormGroup, FormsModule } from '@angular/forms';
|
|
7
|
+
import { BaseService, SwalService } from '@es.framework/ng.core/services';
|
|
6
8
|
import { GenericDialogComponent } from '@es.framework/ng.ui.core/generic-dialog';
|
|
9
|
+
import * as i7 from '@ngx-translate/core';
|
|
10
|
+
import { TranslateService, TranslateModule } from '@ngx-translate/core';
|
|
11
|
+
import * as i3 from 'primeng/button';
|
|
12
|
+
import { ButtonModule } from 'primeng/button';
|
|
13
|
+
import * as i4 from 'primeng/inputtext';
|
|
14
|
+
import { InputTextModule } from 'primeng/inputtext';
|
|
15
|
+
import * as i5 from 'primeng/tooltip';
|
|
16
|
+
import { TooltipModule } from 'primeng/tooltip';
|
|
17
|
+
import * as i6 from 'primeng/drawer';
|
|
18
|
+
import { DrawerModule } from 'primeng/drawer';
|
|
19
|
+
import { finalize, Subject } from 'rxjs';
|
|
20
|
+
import { LoadingSkeletonComponent } from '@es.framework/ng.ui.core/loading-skeletons';
|
|
7
21
|
|
|
8
22
|
class FilterTemplatesModule {
|
|
9
23
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: FilterTemplatesModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
|
|
@@ -376,11 +390,859 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImpor
|
|
|
376
390
|
type: Input
|
|
377
391
|
}] } });
|
|
378
392
|
|
|
379
|
-
|
|
393
|
+
class SavedReportTemplatesDrawerComponent {
|
|
394
|
+
svc = inject(BaseService);
|
|
395
|
+
swal = inject(SwalService);
|
|
396
|
+
tr = inject(TranslateService);
|
|
397
|
+
apiName = 'filter-templates';
|
|
398
|
+
module = 'crm';
|
|
399
|
+
service = '';
|
|
400
|
+
category = '';
|
|
401
|
+
feature = '';
|
|
402
|
+
templateSelected = new EventEmitter();
|
|
403
|
+
edit = new EventEmitter();
|
|
404
|
+
// ✅ جديد
|
|
405
|
+
add = new EventEmitter();
|
|
406
|
+
// ✅ التحكم من الأب
|
|
407
|
+
visible = false;
|
|
408
|
+
visibleChange = new EventEmitter();
|
|
409
|
+
// ✅ اختياري: خلّها قابلة للتخصيص من الأب
|
|
410
|
+
position = 'left';
|
|
411
|
+
showCloseIcon = true;
|
|
412
|
+
modal = true; // ✅ يغمّق اللي تحت
|
|
413
|
+
dismissable = true; // ✅ الضغط خارج/على الماسك يقفل
|
|
414
|
+
closeOnEscape = true; // ✅ ESC يقفل
|
|
415
|
+
blockScroll = true; // ✅ يمنع سكرول للخلفية
|
|
416
|
+
filterFields = [];
|
|
417
|
+
moduleName = '';
|
|
418
|
+
defaultFeature = '';
|
|
419
|
+
defaultCategory = '';
|
|
420
|
+
defaultPermission = '';
|
|
421
|
+
currentUserId = null;
|
|
422
|
+
templateEditorVisible = false;
|
|
423
|
+
templateEditorMode = 'create';
|
|
424
|
+
templateEditorModel = {};
|
|
425
|
+
templates = [];
|
|
426
|
+
selected = null;
|
|
427
|
+
loading = false;
|
|
428
|
+
search = '';
|
|
429
|
+
favOpen = true;
|
|
430
|
+
sharedOpen = true;
|
|
431
|
+
privateOpen = true;
|
|
432
|
+
ngOnInit() {
|
|
433
|
+
this.refresh();
|
|
434
|
+
}
|
|
435
|
+
refresh() {
|
|
436
|
+
this.loading = true;
|
|
437
|
+
this.svc.apiName = this.apiName;
|
|
438
|
+
this.svc.moduleName = this.module;
|
|
439
|
+
const filters = {
|
|
440
|
+
service: this.service,
|
|
441
|
+
module: this.module,
|
|
442
|
+
category: this.category,
|
|
443
|
+
};
|
|
444
|
+
this.svc.getList({ sorting: 'id DESC', filtering: { filters } })
|
|
445
|
+
.pipe(finalize(() => (this.loading = false)))
|
|
446
|
+
.subscribe({
|
|
447
|
+
next: (res) => {
|
|
448
|
+
this.templates = res?.items ?? res ?? [];
|
|
449
|
+
if (this.selected) {
|
|
450
|
+
this.selected =
|
|
451
|
+
this.templates.find(x => String(x.id) === String(this.selected.id)) ?? null;
|
|
452
|
+
}
|
|
453
|
+
},
|
|
454
|
+
error: () => this.swal.error(this.tr.instant('ERROR_TITLE'), this.tr.instant('ERROR.FAILED_LOAD_DATA')),
|
|
455
|
+
});
|
|
456
|
+
}
|
|
457
|
+
get filteredAll() {
|
|
458
|
+
const q = (this.search || '').trim().toLowerCase();
|
|
459
|
+
if (!q)
|
|
460
|
+
return [...this.templates];
|
|
461
|
+
return this.templates.filter(t => (this.getName(t) || '').toLowerCase().includes(q));
|
|
462
|
+
}
|
|
463
|
+
get favList() {
|
|
464
|
+
return this.filteredAll.filter(x => !!x.isFav);
|
|
465
|
+
}
|
|
466
|
+
get privateList() {
|
|
467
|
+
return this.filteredAll.filter(x => x.shareScope === 'ME');
|
|
468
|
+
}
|
|
469
|
+
get sharedList() {
|
|
470
|
+
return this.filteredAll.filter(x => x.shareScope !== 'ME' && !x.isFav);
|
|
471
|
+
}
|
|
472
|
+
select(t) {
|
|
473
|
+
if (this.isSelected(t)) {
|
|
474
|
+
this.clearSelection();
|
|
475
|
+
return;
|
|
476
|
+
}
|
|
477
|
+
this.selected = t;
|
|
478
|
+
this.templateSelected.emit(t);
|
|
479
|
+
}
|
|
480
|
+
isSelected(t) {
|
|
481
|
+
return this.selected && String(this.selected.id) === String(t.id);
|
|
482
|
+
}
|
|
483
|
+
getName(t) {
|
|
484
|
+
const lang = this.tr.currentLang || 'ar';
|
|
485
|
+
return (lang.startsWith('ar') ? (t.nameAr || t.nameEn) : (t.nameEn || t.nameAr)) || '';
|
|
486
|
+
}
|
|
487
|
+
toggleFav(t) {
|
|
488
|
+
const payload = { ...t, isFav: !t.isFav };
|
|
489
|
+
this.svc.update(String(t.id), payload).subscribe({
|
|
490
|
+
next: (u) => (t.isFav = u?.isFav ?? payload.isFav),
|
|
491
|
+
error: () => this.swal.error(this.tr.instant('ERROR_TITLE'), this.tr.instant('OPERATION_FAILED')),
|
|
492
|
+
});
|
|
493
|
+
}
|
|
494
|
+
confirmDelete(t) {
|
|
495
|
+
this.swal.confirm(this.tr.instant('DELETE_CONFIRM_TITLE'), this.tr.instant('DELETE_CONFIRM_MESSAGE'), this.tr.instant('COMMON.DELETE')).then((r) => {
|
|
496
|
+
if (!r?.isConfirmed)
|
|
497
|
+
return;
|
|
498
|
+
this.deleteTemplate(t);
|
|
499
|
+
});
|
|
500
|
+
}
|
|
501
|
+
deleteTemplate(t) {
|
|
502
|
+
// مهم: نفس إعدادات الاستدعاءات الثانية
|
|
503
|
+
this.svc.apiName = this.apiName;
|
|
504
|
+
this.svc.moduleName = this.module;
|
|
505
|
+
// ✅ استدعاء Endpoint الحذف
|
|
506
|
+
// ملاحظة: اسم الميثود يعتمد على BaseService عندكم:
|
|
507
|
+
// غالباً delete(id) أو remove(id)
|
|
508
|
+
const id = String(t.id);
|
|
509
|
+
this.svc.delete(id).subscribe({
|
|
510
|
+
next: () => {
|
|
511
|
+
// حدّث القائمة محلياً
|
|
512
|
+
this.templates = this.templates.filter(x => String(x.id) !== id);
|
|
513
|
+
// لو المحذوف هو المحدد
|
|
514
|
+
if (this.selected && String(this.selected.id) === id) {
|
|
515
|
+
this.selected = null;
|
|
516
|
+
this.templateSelected.emit(null);
|
|
517
|
+
}
|
|
518
|
+
this.swal.toast(this.tr.instant('RECORD_DELETED_SUCCESSFULLY'));
|
|
519
|
+
},
|
|
520
|
+
error: () => this.swal.error(this.tr.instant('ERROR_TITLE'), this.tr.instant('OPERATION_FAILED')),
|
|
521
|
+
});
|
|
522
|
+
}
|
|
523
|
+
onVisibleChange(v) {
|
|
524
|
+
this.visible = v;
|
|
525
|
+
this.visibleChange.emit(v);
|
|
526
|
+
}
|
|
527
|
+
clearSelection() {
|
|
528
|
+
this.selected = null;
|
|
529
|
+
this.templateSelected.emit(null); // ✅ يبلغ الأب: ما عاد فيه قالب
|
|
530
|
+
}
|
|
531
|
+
openTemplateCreate() {
|
|
532
|
+
this.templateEditorMode = 'create';
|
|
533
|
+
this.templateEditorModel = {
|
|
534
|
+
isActive: true,
|
|
535
|
+
shareScope: 'ALL',
|
|
536
|
+
};
|
|
537
|
+
this.templateEditorVisible = true;
|
|
538
|
+
}
|
|
539
|
+
openTemplateEdit(t) {
|
|
540
|
+
this.templateEditorMode = 'edit';
|
|
541
|
+
this.templateEditorModel = { ...t };
|
|
542
|
+
this.templateEditorVisible = true;
|
|
543
|
+
}
|
|
544
|
+
onTemplateSaved(saved) {
|
|
545
|
+
this.refresh(); // ✅ هو نفسه يحدث القائمة
|
|
546
|
+
this.templateEditorVisible = false;
|
|
547
|
+
}
|
|
548
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: SavedReportTemplatesDrawerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
549
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.3", type: SavedReportTemplatesDrawerComponent, isStandalone: true, selector: "saved-report-templates-drawer", inputs: { apiName: "apiName", module: "module", service: "service", category: "category", feature: "feature", visible: "visible", position: "position", showCloseIcon: "showCloseIcon", modal: "modal", dismissable: "dismissable", closeOnEscape: "closeOnEscape", blockScroll: "blockScroll", filterFields: "filterFields", moduleName: "moduleName", defaultFeature: "defaultFeature", defaultCategory: "defaultCategory", defaultPermission: "defaultPermission", currentUserId: "currentUserId" }, outputs: { templateSelected: "templateSelected", edit: "edit", add: "add", visibleChange: "visibleChange" }, providers: [BaseService], ngImport: i0, template: `
|
|
550
|
+
<p-drawer
|
|
551
|
+
[visible]="visible"
|
|
552
|
+
(visibleChange)="onVisibleChange($event)"
|
|
553
|
+
[position]="position"
|
|
554
|
+
[modal]="modal"
|
|
555
|
+
[dismissible]="dismissable"
|
|
556
|
+
[closeOnEscape]="closeOnEscape"
|
|
557
|
+
[blockScroll]="blockScroll"
|
|
558
|
+
[showCloseIcon]="showCloseIcon"
|
|
559
|
+
>
|
|
560
|
+
<div class="h-full flex flex-col bg-white">
|
|
561
|
+
|
|
562
|
+
<!-- Header -->
|
|
563
|
+
<div class="sticky top-0 z-10 bg-white border-b border-gray-200 px-4 py-4">
|
|
564
|
+
<div class="flex items-center gap-3">
|
|
565
|
+
<div class="w-9 h-9 rounded-xl flex items-center justify-center bg-gray-100 text-gray-700">
|
|
566
|
+
<i class="pi pi-bookmark"></i>
|
|
567
|
+
</div>
|
|
568
|
+
|
|
569
|
+
<div class="flex-1 min-w-0">
|
|
570
|
+
<div class="text-xs text-gray-500">
|
|
571
|
+
{{ 'TEMPLATES' | translate }}
|
|
572
|
+
</div>
|
|
573
|
+
<div class="text-base font-semibold text-gray-900 truncate">
|
|
574
|
+
{{ selected ? getName(selected) : ('SELECT_TEMPLATE' | translate) }}
|
|
575
|
+
</div>
|
|
576
|
+
</div>
|
|
577
|
+
|
|
578
|
+
<button
|
|
579
|
+
pButton
|
|
580
|
+
type="button"
|
|
581
|
+
class="p-button-rounded p-button-sm p-button-text"
|
|
582
|
+
icon="pi pi-refresh"
|
|
583
|
+
(click)="refresh()"
|
|
584
|
+
[disabled]="loading"
|
|
585
|
+
pTooltip="{{ 'REFRESH' | translate }}"
|
|
586
|
+
tooltipPosition="bottom"
|
|
587
|
+
></button>
|
|
588
|
+
|
|
589
|
+
<button
|
|
590
|
+
pButton
|
|
591
|
+
type="button"
|
|
592
|
+
class="p-button-rounded p-button-sm p-button-primary"
|
|
593
|
+
icon="pi pi-plus"
|
|
594
|
+
(click)="openTemplateCreate()"
|
|
595
|
+
[disabled]="loading"
|
|
596
|
+
pTooltip="{{ 'COMMON.ADD' | translate }}"
|
|
597
|
+
tooltipPosition="bottom"
|
|
598
|
+
></button>
|
|
599
|
+
</div>
|
|
600
|
+
|
|
601
|
+
<!-- Search -->
|
|
602
|
+
<div class="mt-4">
|
|
603
|
+
<span class="p-input-icon-left w-full">
|
|
604
|
+
<i class="pi pi-search"></i>
|
|
605
|
+
<input
|
|
606
|
+
pInputText
|
|
607
|
+
class="w-full !rounded-xl"
|
|
608
|
+
[(ngModel)]="search"
|
|
609
|
+
[disabled]="loading"
|
|
610
|
+
[placeholder]="'SEARCH_FOR_A_VIEW' | translate"
|
|
611
|
+
/>
|
|
612
|
+
</span>
|
|
613
|
+
</div>
|
|
614
|
+
</div>
|
|
615
|
+
|
|
616
|
+
<!-- Content -->
|
|
617
|
+
<div class="flex-1 overflow-auto px-3 py-3">
|
|
618
|
+
|
|
619
|
+
<!-- ✅ Loading -->
|
|
620
|
+
<div *ngIf="loading" class="py-4">
|
|
621
|
+
<app-loading-skeleton [itemsCount]="4"></app-loading-skeleton>
|
|
622
|
+
</div>
|
|
623
|
+
|
|
624
|
+
<!-- ✅ Empty -->
|
|
625
|
+
<div *ngIf="!loading && filteredAll.length === 0" class="text-sm text-gray-500 text-center py-12">
|
|
626
|
+
<div class="mx-auto mb-3 w-12 h-12 rounded-2xl bg-gray-100 flex items-center justify-center">
|
|
627
|
+
<i class="pi pi-inbox text-gray-500"></i>
|
|
628
|
+
</div>
|
|
629
|
+
{{ 'NO_DATA_FOUND' | translate }}
|
|
630
|
+
</div>
|
|
631
|
+
|
|
632
|
+
<!-- ✅ Content when not loading -->
|
|
633
|
+
<ng-container *ngIf="!loading">
|
|
634
|
+
|
|
635
|
+
<!-- Favorites -->
|
|
636
|
+
<ng-container *ngIf="favList.length > 0">
|
|
637
|
+
<button
|
|
638
|
+
type="button"
|
|
639
|
+
class="w-full flex items-center justify-between px-2 py-2 text-sm font-semibold text-gray-800"
|
|
640
|
+
(click)="favOpen = !favOpen"
|
|
641
|
+
>
|
|
642
|
+
<span class="flex items-center gap-2">
|
|
643
|
+
<i class="pi pi-star-fill text-yellow-500"></i>
|
|
644
|
+
{{ 'FAVOURITES' | translate }}
|
|
645
|
+
<span class="text-xs px-2 py-0.5 rounded-full bg-gray-100 text-gray-600">{{ favList.length }}</span>
|
|
646
|
+
</span>
|
|
647
|
+
<i class="pi text-xs" [ngClass]="favOpen ? 'pi-chevron-up' : 'pi-chevron-down'"></i>
|
|
648
|
+
</button>
|
|
649
|
+
|
|
650
|
+
<div *ngIf="favOpen" class="mt-1 space-y-1">
|
|
651
|
+
<ng-container *ngFor="let t of favList">
|
|
652
|
+
<div
|
|
653
|
+
class="group relative flex items-center gap-3 px-3 py-2 rounded-xl transition cursor-pointer
|
|
654
|
+
hover:bg-gray-50"
|
|
655
|
+
[style.backgroundColor]="isSelected(t) ? 'var(--p-primary-50, rgba(59,130,246,0.10))' : ''"
|
|
656
|
+
(click)="select(t)"
|
|
657
|
+
>
|
|
658
|
+
<span
|
|
659
|
+
class="absolute left-0 top-1 bottom-1 w-1 rounded-full"
|
|
660
|
+
[style.backgroundColor]="isSelected(t) ? 'var(--p-primary-color, #3b82f6)' : 'transparent'"
|
|
661
|
+
></span>
|
|
662
|
+
|
|
663
|
+
<i class="text-base shrink-0"
|
|
664
|
+
[ngClass]="t.icon || 'pi pi-check-circle'"
|
|
665
|
+
[style.color]="isSelected(t) ? 'var(--p-primary-color, #3b82f6)' : ''"></i>
|
|
666
|
+
|
|
667
|
+
<span class="flex-1 truncate"
|
|
668
|
+
[class.font-semibold]="isSelected(t)"
|
|
669
|
+
[style.color]="isSelected(t) ? 'var(--p-primary-color, #3b82f6)' : ''">
|
|
670
|
+
{{ getName(t) }}
|
|
671
|
+
</span>
|
|
672
|
+
|
|
673
|
+
<!-- Actions -->
|
|
674
|
+
<div class="flex items-center gap-1 opacity-0 group-hover:opacity-100 transition"
|
|
675
|
+
(click)="$event.stopPropagation()">
|
|
676
|
+
<button pButton type="button" class="p-button-text p-button-sm"
|
|
677
|
+
[icon]="t.isFav ? 'pi pi-star-fill' : 'pi pi-star'"
|
|
678
|
+
(click)="toggleFav(t)"></button>
|
|
679
|
+
|
|
680
|
+
@if (!isSelected(t)) {
|
|
681
|
+
<button pButton type="button" class="p-button-text p-button-sm"
|
|
682
|
+
icon="pi pi-pencil"
|
|
683
|
+
(click)="openTemplateEdit(t)"></button>
|
|
684
|
+
|
|
685
|
+
<button pButton type="button" class="p-button-text p-button-sm p-button-danger"
|
|
686
|
+
icon="pi pi-trash"
|
|
687
|
+
(click)="confirmDelete(t)"></button>
|
|
688
|
+
}
|
|
689
|
+
</div>
|
|
690
|
+
</div>
|
|
691
|
+
</ng-container>
|
|
692
|
+
</div>
|
|
693
|
+
|
|
694
|
+
<div class="my-3 border-b border-gray-200"></div>
|
|
695
|
+
</ng-container>
|
|
696
|
+
|
|
697
|
+
<!-- Shared -->
|
|
698
|
+
<ng-container *ngIf="sharedList.length > 0">
|
|
699
|
+
<button
|
|
700
|
+
type="button"
|
|
701
|
+
class="w-full flex items-center justify-between px-2 py-2 text-sm font-semibold text-gray-800"
|
|
702
|
+
(click)="sharedOpen = !sharedOpen"
|
|
703
|
+
>
|
|
704
|
+
<span class="flex items-center gap-2">
|
|
705
|
+
<i class="pi pi-users text-gray-600"></i>
|
|
706
|
+
{{ 'SHARED' | translate }}
|
|
707
|
+
<span class="text-xs px-2 py-0.5 rounded-full bg-gray-100 text-gray-600">{{ sharedList.length }}</span>
|
|
708
|
+
</span>
|
|
709
|
+
<i class="pi text-xs" [ngClass]="sharedOpen ? 'pi-chevron-up' : 'pi-chevron-down'"></i>
|
|
710
|
+
</button>
|
|
711
|
+
|
|
712
|
+
<div *ngIf="sharedOpen" class="mt-1 space-y-1">
|
|
713
|
+
<ng-container *ngFor="let t of sharedList">
|
|
714
|
+
<div
|
|
715
|
+
class="group relative flex items-center gap-3 px-3 py-2 rounded-xl transition cursor-pointer hover:bg-gray-50"
|
|
716
|
+
[style.backgroundColor]="isSelected(t) ? 'var(--p-primary-50, rgba(59,130,246,0.10))' : ''"
|
|
717
|
+
(click)="select(t)"
|
|
718
|
+
>
|
|
719
|
+
<span
|
|
720
|
+
class="absolute left-0 top-1 bottom-1 w-1 rounded-full"
|
|
721
|
+
[style.backgroundColor]="isSelected(t) ? 'var(--p-primary-color, #3b82f6)' : 'transparent'"
|
|
722
|
+
></span>
|
|
723
|
+
|
|
724
|
+
<i class="text-base shrink-0"
|
|
725
|
+
[ngClass]="t.icon || 'pi pi-check-circle'"
|
|
726
|
+
[style.color]="isSelected(t) ? 'var(--p-primary-color, #3b82f6)' : ''"></i>
|
|
727
|
+
|
|
728
|
+
<span class="flex-1 truncate"
|
|
729
|
+
[class.font-semibold]="isSelected(t)"
|
|
730
|
+
[style.color]="isSelected(t) ? 'var(--p-primary-color, #3b82f6)' : ''">
|
|
731
|
+
{{ getName(t) }}
|
|
732
|
+
</span>
|
|
733
|
+
|
|
734
|
+
<div class="flex items-center gap-1 opacity-0 group-hover:opacity-100 transition"
|
|
735
|
+
(click)="$event.stopPropagation()">
|
|
736
|
+
<button pButton type="button" class="p-button-text p-button-sm"
|
|
737
|
+
[icon]="t.isFav ? 'pi pi-star-fill' : 'pi pi-star'"
|
|
738
|
+
(click)="toggleFav(t)"></button>
|
|
739
|
+
|
|
740
|
+
@if (!isSelected(t)) {
|
|
741
|
+
<button pButton type="button" class="p-button-text p-button-sm"
|
|
742
|
+
icon="pi pi-pencil"
|
|
743
|
+
(click)="openTemplateEdit(t)"></button>
|
|
744
|
+
|
|
745
|
+
<button pButton type="button" class="p-button-text p-button-sm p-button-danger"
|
|
746
|
+
icon="pi pi-trash"
|
|
747
|
+
(click)="confirmDelete(t)"></button>
|
|
748
|
+
}
|
|
749
|
+
</div>
|
|
750
|
+
</div>
|
|
751
|
+
</ng-container>
|
|
752
|
+
</div>
|
|
753
|
+
|
|
754
|
+
<div class="my-3 border-b border-gray-200"></div>
|
|
755
|
+
</ng-container>
|
|
756
|
+
|
|
757
|
+
<!-- Private -->
|
|
758
|
+
<ng-container *ngIf="privateList.length > 0">
|
|
759
|
+
<button
|
|
760
|
+
type="button"
|
|
761
|
+
class="w-full flex items-center justify-between px-2 py-2 text-sm font-semibold text-gray-800"
|
|
762
|
+
(click)="privateOpen = !privateOpen"
|
|
763
|
+
>
|
|
764
|
+
<span class="flex items-center gap-2">
|
|
765
|
+
<i class="pi pi-lock text-gray-600"></i>
|
|
766
|
+
{{ 'PRIVATE' | translate }}
|
|
767
|
+
<span class="text-xs px-2 py-0.5 rounded-full bg-gray-100 text-gray-600">{{ privateList.length }}</span>
|
|
768
|
+
</span>
|
|
769
|
+
<i class="pi text-xs" [ngClass]="privateOpen ? 'pi-chevron-up' : 'pi-chevron-down'"></i>
|
|
770
|
+
</button>
|
|
771
|
+
|
|
772
|
+
<div *ngIf="privateOpen" class="mt-1 space-y-1">
|
|
773
|
+
<ng-container *ngFor="let t of privateList">
|
|
774
|
+
<div
|
|
775
|
+
class="group relative flex items-center gap-3 px-3 py-2 rounded-xl transition cursor-pointer hover:bg-gray-50"
|
|
776
|
+
[style.backgroundColor]="isSelected(t) ? 'var(--p-primary-50, rgba(59,130,246,0.10))' : ''"
|
|
777
|
+
(click)="select(t)"
|
|
778
|
+
>
|
|
779
|
+
<span
|
|
780
|
+
class="absolute left-0 top-1 bottom-1 w-1 rounded-full"
|
|
781
|
+
[style.backgroundColor]="isSelected(t) ? 'var(--p-primary-color, #3b82f6)' : 'transparent'"
|
|
782
|
+
></span>
|
|
783
|
+
|
|
784
|
+
<i class="text-base shrink-0"
|
|
785
|
+
[ngClass]="t.icon || 'pi pi-check-circle'"
|
|
786
|
+
[style.color]="isSelected(t) ? 'var(--p-primary-color, #3b82f6)' : ''"></i>
|
|
787
|
+
|
|
788
|
+
<span class="flex-1 truncate"
|
|
789
|
+
[class.font-semibold]="isSelected(t)"
|
|
790
|
+
[style.color]="isSelected(t) ? 'var(--p-primary-color, #3b82f6)' : ''">
|
|
791
|
+
{{ getName(t) }}
|
|
792
|
+
</span>
|
|
793
|
+
|
|
794
|
+
<div class="flex items-center gap-1 opacity-0 group-hover:opacity-100 transition"
|
|
795
|
+
(click)="$event.stopPropagation()">
|
|
796
|
+
<button pButton type="button" class="p-button-text p-button-sm"
|
|
797
|
+
[icon]="t.isFav ? 'pi pi-star-fill' : 'pi pi-star'"
|
|
798
|
+
(click)="toggleFav(t)"></button>
|
|
799
|
+
|
|
800
|
+
@if (!isSelected(t)) {
|
|
801
|
+
<button pButton type="button" class="p-button-text p-button-sm"
|
|
802
|
+
icon="pi pi-pencil"
|
|
803
|
+
(click)="openTemplateEdit(t)"></button>
|
|
804
|
+
|
|
805
|
+
<button pButton type="button" class="p-button-text p-button-sm p-button-danger"
|
|
806
|
+
icon="pi pi-trash"
|
|
807
|
+
(click)="confirmDelete(t)"></button>
|
|
808
|
+
}
|
|
809
|
+
</div>
|
|
810
|
+
</div>
|
|
811
|
+
</ng-container>
|
|
812
|
+
</div>
|
|
813
|
+
</ng-container>
|
|
814
|
+
|
|
815
|
+
</ng-container>
|
|
816
|
+
</div>
|
|
817
|
+
</div>
|
|
818
|
+
</p-drawer>
|
|
819
|
+
|
|
820
|
+
<filter-template-editor-dialog
|
|
821
|
+
[(visible)]="templateEditorVisible"
|
|
822
|
+
[mode]="templateEditorMode"
|
|
823
|
+
[model]="templateEditorModel"
|
|
824
|
+
[filterFields]="filterFields"
|
|
825
|
+
[moduleName]="moduleName"
|
|
826
|
+
[apiName]="apiName"
|
|
827
|
+
[defaultFeature]="defaultFeature"
|
|
828
|
+
[defaultCategory]="defaultCategory"
|
|
829
|
+
[defaultPermission]="defaultPermission"
|
|
830
|
+
[currentUserId]="currentUserId"
|
|
831
|
+
(saved)="onTemplateSaved($event)">
|
|
832
|
+
</filter-template-editor-dialog>
|
|
833
|
+
|
|
834
|
+
|
|
835
|
+
`, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.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: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "ngmodule", type: ButtonModule }, { kind: "directive", type: i3.ButtonDirective, selector: "[pButton]", inputs: ["ptButtonDirective", "hostName", "text", "plain", "raised", "size", "outlined", "rounded", "iconPos", "loadingIcon", "fluid", "label", "icon", "loading", "buttonProps", "severity"] }, { kind: "ngmodule", type: InputTextModule }, { kind: "directive", type: i4.InputText, selector: "[pInputText]", inputs: ["hostName", "ptInputText", "pSize", "variant", "fluid", "invalid"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i5.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions", "appendTo", "ptTooltip"] }, { kind: "ngmodule", type: DrawerModule }, { kind: "component", type: i6.Drawer, selector: "p-drawer", inputs: ["appendTo", "blockScroll", "style", "styleClass", "ariaCloseLabel", "autoZIndex", "baseZIndex", "modal", "closeButtonProps", "dismissible", "showCloseIcon", "closeOnEscape", "transitionOptions", "visible", "position", "fullScreen", "header", "maskStyle", "closable"], outputs: ["onShow", "onHide", "visibleChange"] }, { kind: "component", type: LoadingSkeletonComponent, selector: "app-loading-skeleton", inputs: ["itemsCount"] }, { kind: "component", type: FilterTemplateEditorDialogComponent, selector: "filter-template-editor-dialog", inputs: ["visible", "mode", "model", "filterFields", "apiName", "moduleName", "idField", "defaultFeature", "defaultPermission", "defaultCategory", "dialogMaxWidth", "currentUserId"], outputs: ["visibleChange", "saved"] }, { kind: "pipe", type: i7.TranslatePipe, name: "translate" }] });
|
|
836
|
+
}
|
|
837
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: SavedReportTemplatesDrawerComponent, decorators: [{
|
|
838
|
+
type: Component,
|
|
839
|
+
args: [{
|
|
840
|
+
selector: 'saved-report-templates-drawer',
|
|
841
|
+
standalone: true,
|
|
842
|
+
imports: [
|
|
843
|
+
CommonModule,
|
|
844
|
+
FormsModule,
|
|
845
|
+
TranslateModule,
|
|
846
|
+
ButtonModule,
|
|
847
|
+
InputTextModule,
|
|
848
|
+
TooltipModule,
|
|
849
|
+
DrawerModule,
|
|
850
|
+
LoadingSkeletonComponent,
|
|
851
|
+
FilterTemplateEditorDialogComponent
|
|
852
|
+
],
|
|
853
|
+
providers: [BaseService],
|
|
854
|
+
template: `
|
|
855
|
+
<p-drawer
|
|
856
|
+
[visible]="visible"
|
|
857
|
+
(visibleChange)="onVisibleChange($event)"
|
|
858
|
+
[position]="position"
|
|
859
|
+
[modal]="modal"
|
|
860
|
+
[dismissible]="dismissable"
|
|
861
|
+
[closeOnEscape]="closeOnEscape"
|
|
862
|
+
[blockScroll]="blockScroll"
|
|
863
|
+
[showCloseIcon]="showCloseIcon"
|
|
864
|
+
>
|
|
865
|
+
<div class="h-full flex flex-col bg-white">
|
|
866
|
+
|
|
867
|
+
<!-- Header -->
|
|
868
|
+
<div class="sticky top-0 z-10 bg-white border-b border-gray-200 px-4 py-4">
|
|
869
|
+
<div class="flex items-center gap-3">
|
|
870
|
+
<div class="w-9 h-9 rounded-xl flex items-center justify-center bg-gray-100 text-gray-700">
|
|
871
|
+
<i class="pi pi-bookmark"></i>
|
|
872
|
+
</div>
|
|
873
|
+
|
|
874
|
+
<div class="flex-1 min-w-0">
|
|
875
|
+
<div class="text-xs text-gray-500">
|
|
876
|
+
{{ 'TEMPLATES' | translate }}
|
|
877
|
+
</div>
|
|
878
|
+
<div class="text-base font-semibold text-gray-900 truncate">
|
|
879
|
+
{{ selected ? getName(selected) : ('SELECT_TEMPLATE' | translate) }}
|
|
880
|
+
</div>
|
|
881
|
+
</div>
|
|
882
|
+
|
|
883
|
+
<button
|
|
884
|
+
pButton
|
|
885
|
+
type="button"
|
|
886
|
+
class="p-button-rounded p-button-sm p-button-text"
|
|
887
|
+
icon="pi pi-refresh"
|
|
888
|
+
(click)="refresh()"
|
|
889
|
+
[disabled]="loading"
|
|
890
|
+
pTooltip="{{ 'REFRESH' | translate }}"
|
|
891
|
+
tooltipPosition="bottom"
|
|
892
|
+
></button>
|
|
893
|
+
|
|
894
|
+
<button
|
|
895
|
+
pButton
|
|
896
|
+
type="button"
|
|
897
|
+
class="p-button-rounded p-button-sm p-button-primary"
|
|
898
|
+
icon="pi pi-plus"
|
|
899
|
+
(click)="openTemplateCreate()"
|
|
900
|
+
[disabled]="loading"
|
|
901
|
+
pTooltip="{{ 'COMMON.ADD' | translate }}"
|
|
902
|
+
tooltipPosition="bottom"
|
|
903
|
+
></button>
|
|
904
|
+
</div>
|
|
905
|
+
|
|
906
|
+
<!-- Search -->
|
|
907
|
+
<div class="mt-4">
|
|
908
|
+
<span class="p-input-icon-left w-full">
|
|
909
|
+
<i class="pi pi-search"></i>
|
|
910
|
+
<input
|
|
911
|
+
pInputText
|
|
912
|
+
class="w-full !rounded-xl"
|
|
913
|
+
[(ngModel)]="search"
|
|
914
|
+
[disabled]="loading"
|
|
915
|
+
[placeholder]="'SEARCH_FOR_A_VIEW' | translate"
|
|
916
|
+
/>
|
|
917
|
+
</span>
|
|
918
|
+
</div>
|
|
919
|
+
</div>
|
|
920
|
+
|
|
921
|
+
<!-- Content -->
|
|
922
|
+
<div class="flex-1 overflow-auto px-3 py-3">
|
|
923
|
+
|
|
924
|
+
<!-- ✅ Loading -->
|
|
925
|
+
<div *ngIf="loading" class="py-4">
|
|
926
|
+
<app-loading-skeleton [itemsCount]="4"></app-loading-skeleton>
|
|
927
|
+
</div>
|
|
928
|
+
|
|
929
|
+
<!-- ✅ Empty -->
|
|
930
|
+
<div *ngIf="!loading && filteredAll.length === 0" class="text-sm text-gray-500 text-center py-12">
|
|
931
|
+
<div class="mx-auto mb-3 w-12 h-12 rounded-2xl bg-gray-100 flex items-center justify-center">
|
|
932
|
+
<i class="pi pi-inbox text-gray-500"></i>
|
|
933
|
+
</div>
|
|
934
|
+
{{ 'NO_DATA_FOUND' | translate }}
|
|
935
|
+
</div>
|
|
936
|
+
|
|
937
|
+
<!-- ✅ Content when not loading -->
|
|
938
|
+
<ng-container *ngIf="!loading">
|
|
939
|
+
|
|
940
|
+
<!-- Favorites -->
|
|
941
|
+
<ng-container *ngIf="favList.length > 0">
|
|
942
|
+
<button
|
|
943
|
+
type="button"
|
|
944
|
+
class="w-full flex items-center justify-between px-2 py-2 text-sm font-semibold text-gray-800"
|
|
945
|
+
(click)="favOpen = !favOpen"
|
|
946
|
+
>
|
|
947
|
+
<span class="flex items-center gap-2">
|
|
948
|
+
<i class="pi pi-star-fill text-yellow-500"></i>
|
|
949
|
+
{{ 'FAVOURITES' | translate }}
|
|
950
|
+
<span class="text-xs px-2 py-0.5 rounded-full bg-gray-100 text-gray-600">{{ favList.length }}</span>
|
|
951
|
+
</span>
|
|
952
|
+
<i class="pi text-xs" [ngClass]="favOpen ? 'pi-chevron-up' : 'pi-chevron-down'"></i>
|
|
953
|
+
</button>
|
|
954
|
+
|
|
955
|
+
<div *ngIf="favOpen" class="mt-1 space-y-1">
|
|
956
|
+
<ng-container *ngFor="let t of favList">
|
|
957
|
+
<div
|
|
958
|
+
class="group relative flex items-center gap-3 px-3 py-2 rounded-xl transition cursor-pointer
|
|
959
|
+
hover:bg-gray-50"
|
|
960
|
+
[style.backgroundColor]="isSelected(t) ? 'var(--p-primary-50, rgba(59,130,246,0.10))' : ''"
|
|
961
|
+
(click)="select(t)"
|
|
962
|
+
>
|
|
963
|
+
<span
|
|
964
|
+
class="absolute left-0 top-1 bottom-1 w-1 rounded-full"
|
|
965
|
+
[style.backgroundColor]="isSelected(t) ? 'var(--p-primary-color, #3b82f6)' : 'transparent'"
|
|
966
|
+
></span>
|
|
967
|
+
|
|
968
|
+
<i class="text-base shrink-0"
|
|
969
|
+
[ngClass]="t.icon || 'pi pi-check-circle'"
|
|
970
|
+
[style.color]="isSelected(t) ? 'var(--p-primary-color, #3b82f6)' : ''"></i>
|
|
971
|
+
|
|
972
|
+
<span class="flex-1 truncate"
|
|
973
|
+
[class.font-semibold]="isSelected(t)"
|
|
974
|
+
[style.color]="isSelected(t) ? 'var(--p-primary-color, #3b82f6)' : ''">
|
|
975
|
+
{{ getName(t) }}
|
|
976
|
+
</span>
|
|
977
|
+
|
|
978
|
+
<!-- Actions -->
|
|
979
|
+
<div class="flex items-center gap-1 opacity-0 group-hover:opacity-100 transition"
|
|
980
|
+
(click)="$event.stopPropagation()">
|
|
981
|
+
<button pButton type="button" class="p-button-text p-button-sm"
|
|
982
|
+
[icon]="t.isFav ? 'pi pi-star-fill' : 'pi pi-star'"
|
|
983
|
+
(click)="toggleFav(t)"></button>
|
|
984
|
+
|
|
985
|
+
@if (!isSelected(t)) {
|
|
986
|
+
<button pButton type="button" class="p-button-text p-button-sm"
|
|
987
|
+
icon="pi pi-pencil"
|
|
988
|
+
(click)="openTemplateEdit(t)"></button>
|
|
989
|
+
|
|
990
|
+
<button pButton type="button" class="p-button-text p-button-sm p-button-danger"
|
|
991
|
+
icon="pi pi-trash"
|
|
992
|
+
(click)="confirmDelete(t)"></button>
|
|
993
|
+
}
|
|
994
|
+
</div>
|
|
995
|
+
</div>
|
|
996
|
+
</ng-container>
|
|
997
|
+
</div>
|
|
998
|
+
|
|
999
|
+
<div class="my-3 border-b border-gray-200"></div>
|
|
1000
|
+
</ng-container>
|
|
1001
|
+
|
|
1002
|
+
<!-- Shared -->
|
|
1003
|
+
<ng-container *ngIf="sharedList.length > 0">
|
|
1004
|
+
<button
|
|
1005
|
+
type="button"
|
|
1006
|
+
class="w-full flex items-center justify-between px-2 py-2 text-sm font-semibold text-gray-800"
|
|
1007
|
+
(click)="sharedOpen = !sharedOpen"
|
|
1008
|
+
>
|
|
1009
|
+
<span class="flex items-center gap-2">
|
|
1010
|
+
<i class="pi pi-users text-gray-600"></i>
|
|
1011
|
+
{{ 'SHARED' | translate }}
|
|
1012
|
+
<span class="text-xs px-2 py-0.5 rounded-full bg-gray-100 text-gray-600">{{ sharedList.length }}</span>
|
|
1013
|
+
</span>
|
|
1014
|
+
<i class="pi text-xs" [ngClass]="sharedOpen ? 'pi-chevron-up' : 'pi-chevron-down'"></i>
|
|
1015
|
+
</button>
|
|
1016
|
+
|
|
1017
|
+
<div *ngIf="sharedOpen" class="mt-1 space-y-1">
|
|
1018
|
+
<ng-container *ngFor="let t of sharedList">
|
|
1019
|
+
<div
|
|
1020
|
+
class="group relative flex items-center gap-3 px-3 py-2 rounded-xl transition cursor-pointer hover:bg-gray-50"
|
|
1021
|
+
[style.backgroundColor]="isSelected(t) ? 'var(--p-primary-50, rgba(59,130,246,0.10))' : ''"
|
|
1022
|
+
(click)="select(t)"
|
|
1023
|
+
>
|
|
1024
|
+
<span
|
|
1025
|
+
class="absolute left-0 top-1 bottom-1 w-1 rounded-full"
|
|
1026
|
+
[style.backgroundColor]="isSelected(t) ? 'var(--p-primary-color, #3b82f6)' : 'transparent'"
|
|
1027
|
+
></span>
|
|
1028
|
+
|
|
1029
|
+
<i class="text-base shrink-0"
|
|
1030
|
+
[ngClass]="t.icon || 'pi pi-check-circle'"
|
|
1031
|
+
[style.color]="isSelected(t) ? 'var(--p-primary-color, #3b82f6)' : ''"></i>
|
|
1032
|
+
|
|
1033
|
+
<span class="flex-1 truncate"
|
|
1034
|
+
[class.font-semibold]="isSelected(t)"
|
|
1035
|
+
[style.color]="isSelected(t) ? 'var(--p-primary-color, #3b82f6)' : ''">
|
|
1036
|
+
{{ getName(t) }}
|
|
1037
|
+
</span>
|
|
1038
|
+
|
|
1039
|
+
<div class="flex items-center gap-1 opacity-0 group-hover:opacity-100 transition"
|
|
1040
|
+
(click)="$event.stopPropagation()">
|
|
1041
|
+
<button pButton type="button" class="p-button-text p-button-sm"
|
|
1042
|
+
[icon]="t.isFav ? 'pi pi-star-fill' : 'pi pi-star'"
|
|
1043
|
+
(click)="toggleFav(t)"></button>
|
|
1044
|
+
|
|
1045
|
+
@if (!isSelected(t)) {
|
|
1046
|
+
<button pButton type="button" class="p-button-text p-button-sm"
|
|
1047
|
+
icon="pi pi-pencil"
|
|
1048
|
+
(click)="openTemplateEdit(t)"></button>
|
|
1049
|
+
|
|
1050
|
+
<button pButton type="button" class="p-button-text p-button-sm p-button-danger"
|
|
1051
|
+
icon="pi pi-trash"
|
|
1052
|
+
(click)="confirmDelete(t)"></button>
|
|
1053
|
+
}
|
|
1054
|
+
</div>
|
|
1055
|
+
</div>
|
|
1056
|
+
</ng-container>
|
|
1057
|
+
</div>
|
|
1058
|
+
|
|
1059
|
+
<div class="my-3 border-b border-gray-200"></div>
|
|
1060
|
+
</ng-container>
|
|
1061
|
+
|
|
1062
|
+
<!-- Private -->
|
|
1063
|
+
<ng-container *ngIf="privateList.length > 0">
|
|
1064
|
+
<button
|
|
1065
|
+
type="button"
|
|
1066
|
+
class="w-full flex items-center justify-between px-2 py-2 text-sm font-semibold text-gray-800"
|
|
1067
|
+
(click)="privateOpen = !privateOpen"
|
|
1068
|
+
>
|
|
1069
|
+
<span class="flex items-center gap-2">
|
|
1070
|
+
<i class="pi pi-lock text-gray-600"></i>
|
|
1071
|
+
{{ 'PRIVATE' | translate }}
|
|
1072
|
+
<span class="text-xs px-2 py-0.5 rounded-full bg-gray-100 text-gray-600">{{ privateList.length }}</span>
|
|
1073
|
+
</span>
|
|
1074
|
+
<i class="pi text-xs" [ngClass]="privateOpen ? 'pi-chevron-up' : 'pi-chevron-down'"></i>
|
|
1075
|
+
</button>
|
|
1076
|
+
|
|
1077
|
+
<div *ngIf="privateOpen" class="mt-1 space-y-1">
|
|
1078
|
+
<ng-container *ngFor="let t of privateList">
|
|
1079
|
+
<div
|
|
1080
|
+
class="group relative flex items-center gap-3 px-3 py-2 rounded-xl transition cursor-pointer hover:bg-gray-50"
|
|
1081
|
+
[style.backgroundColor]="isSelected(t) ? 'var(--p-primary-50, rgba(59,130,246,0.10))' : ''"
|
|
1082
|
+
(click)="select(t)"
|
|
1083
|
+
>
|
|
1084
|
+
<span
|
|
1085
|
+
class="absolute left-0 top-1 bottom-1 w-1 rounded-full"
|
|
1086
|
+
[style.backgroundColor]="isSelected(t) ? 'var(--p-primary-color, #3b82f6)' : 'transparent'"
|
|
1087
|
+
></span>
|
|
1088
|
+
|
|
1089
|
+
<i class="text-base shrink-0"
|
|
1090
|
+
[ngClass]="t.icon || 'pi pi-check-circle'"
|
|
1091
|
+
[style.color]="isSelected(t) ? 'var(--p-primary-color, #3b82f6)' : ''"></i>
|
|
1092
|
+
|
|
1093
|
+
<span class="flex-1 truncate"
|
|
1094
|
+
[class.font-semibold]="isSelected(t)"
|
|
1095
|
+
[style.color]="isSelected(t) ? 'var(--p-primary-color, #3b82f6)' : ''">
|
|
1096
|
+
{{ getName(t) }}
|
|
1097
|
+
</span>
|
|
1098
|
+
|
|
1099
|
+
<div class="flex items-center gap-1 opacity-0 group-hover:opacity-100 transition"
|
|
1100
|
+
(click)="$event.stopPropagation()">
|
|
1101
|
+
<button pButton type="button" class="p-button-text p-button-sm"
|
|
1102
|
+
[icon]="t.isFav ? 'pi pi-star-fill' : 'pi pi-star'"
|
|
1103
|
+
(click)="toggleFav(t)"></button>
|
|
1104
|
+
|
|
1105
|
+
@if (!isSelected(t)) {
|
|
1106
|
+
<button pButton type="button" class="p-button-text p-button-sm"
|
|
1107
|
+
icon="pi pi-pencil"
|
|
1108
|
+
(click)="openTemplateEdit(t)"></button>
|
|
1109
|
+
|
|
1110
|
+
<button pButton type="button" class="p-button-text p-button-sm p-button-danger"
|
|
1111
|
+
icon="pi pi-trash"
|
|
1112
|
+
(click)="confirmDelete(t)"></button>
|
|
1113
|
+
}
|
|
1114
|
+
</div>
|
|
1115
|
+
</div>
|
|
1116
|
+
</ng-container>
|
|
1117
|
+
</div>
|
|
1118
|
+
</ng-container>
|
|
1119
|
+
|
|
1120
|
+
</ng-container>
|
|
1121
|
+
</div>
|
|
1122
|
+
</div>
|
|
1123
|
+
</p-drawer>
|
|
1124
|
+
|
|
1125
|
+
<filter-template-editor-dialog
|
|
1126
|
+
[(visible)]="templateEditorVisible"
|
|
1127
|
+
[mode]="templateEditorMode"
|
|
1128
|
+
[model]="templateEditorModel"
|
|
1129
|
+
[filterFields]="filterFields"
|
|
1130
|
+
[moduleName]="moduleName"
|
|
1131
|
+
[apiName]="apiName"
|
|
1132
|
+
[defaultFeature]="defaultFeature"
|
|
1133
|
+
[defaultCategory]="defaultCategory"
|
|
1134
|
+
[defaultPermission]="defaultPermission"
|
|
1135
|
+
[currentUserId]="currentUserId"
|
|
1136
|
+
(saved)="onTemplateSaved($event)">
|
|
1137
|
+
</filter-template-editor-dialog>
|
|
1138
|
+
|
|
1139
|
+
|
|
1140
|
+
`,
|
|
1141
|
+
}]
|
|
1142
|
+
}], propDecorators: { apiName: [{
|
|
1143
|
+
type: Input
|
|
1144
|
+
}], module: [{
|
|
1145
|
+
type: Input
|
|
1146
|
+
}], service: [{
|
|
1147
|
+
type: Input
|
|
1148
|
+
}], category: [{
|
|
1149
|
+
type: Input
|
|
1150
|
+
}], feature: [{
|
|
1151
|
+
type: Input
|
|
1152
|
+
}], templateSelected: [{
|
|
1153
|
+
type: Output
|
|
1154
|
+
}], edit: [{
|
|
1155
|
+
type: Output
|
|
1156
|
+
}], add: [{
|
|
1157
|
+
type: Output
|
|
1158
|
+
}], visible: [{
|
|
1159
|
+
type: Input
|
|
1160
|
+
}], visibleChange: [{
|
|
1161
|
+
type: Output
|
|
1162
|
+
}], position: [{
|
|
1163
|
+
type: Input
|
|
1164
|
+
}], showCloseIcon: [{
|
|
1165
|
+
type: Input
|
|
1166
|
+
}], modal: [{
|
|
1167
|
+
type: Input
|
|
1168
|
+
}], dismissable: [{
|
|
1169
|
+
type: Input
|
|
1170
|
+
}], closeOnEscape: [{
|
|
1171
|
+
type: Input
|
|
1172
|
+
}], blockScroll: [{
|
|
1173
|
+
type: Input
|
|
1174
|
+
}], filterFields: [{
|
|
1175
|
+
type: Input
|
|
1176
|
+
}], moduleName: [{
|
|
1177
|
+
type: Input
|
|
1178
|
+
}], defaultFeature: [{
|
|
1179
|
+
type: Input
|
|
1180
|
+
}], defaultCategory: [{
|
|
1181
|
+
type: Input
|
|
1182
|
+
}], defaultPermission: [{
|
|
1183
|
+
type: Input
|
|
1184
|
+
}], currentUserId: [{
|
|
1185
|
+
type: Input
|
|
1186
|
+
}] } });
|
|
1187
|
+
|
|
1188
|
+
class CrudContextService {
|
|
1189
|
+
// استخدام Signals لأداء أسرع
|
|
1190
|
+
moduleName = signal('', ...(ngDevMode ? [{ debugName: "moduleName" }] : []));
|
|
1191
|
+
category = signal('', ...(ngDevMode ? [{ debugName: "category" }] : []));
|
|
1192
|
+
feature = signal('', ...(ngDevMode ? [{ debugName: "feature" }] : []));
|
|
1193
|
+
filters = signal([], ...(ngDevMode ? [{ debugName: "filters" }] : []));
|
|
1194
|
+
templateDrawerVisible = signal(false, ...(ngDevMode ? [{ debugName: "templateDrawerVisible" }] : []));
|
|
1195
|
+
// حدث يطلق عند اختيار قالب
|
|
1196
|
+
templateSelected$ = new Subject();
|
|
1197
|
+
openTemplates() { this.templateDrawerVisible.set(true); }
|
|
1198
|
+
closeTemplates() { this.templateDrawerVisible.set(false); }
|
|
1199
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: CrudContextService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
1200
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: CrudContextService });
|
|
1201
|
+
}
|
|
1202
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: CrudContextService, decorators: [{
|
|
1203
|
+
type: Injectable
|
|
1204
|
+
}] });
|
|
1205
|
+
|
|
1206
|
+
class ReportTemplatesWrapperComponent {
|
|
1207
|
+
context = inject(CrudContextService); // يحصل على نفس النسخة الخاصة بالجدول الأب
|
|
1208
|
+
onSelect(template) {
|
|
1209
|
+
this.context.templateSelected$.next(template);
|
|
1210
|
+
this.context.closeTemplates();
|
|
1211
|
+
}
|
|
1212
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ReportTemplatesWrapperComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1213
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.1.3", type: ReportTemplatesWrapperComponent, isStandalone: true, selector: "app-report-templates-wrapper", ngImport: i0, template: `
|
|
1214
|
+
<saved-report-templates-drawer
|
|
1215
|
+
[visible]="context.templateDrawerVisible()"
|
|
1216
|
+
[filterFields]="context.filters()"
|
|
1217
|
+
[service]="context.moduleName()"
|
|
1218
|
+
[category]="context.category()"
|
|
1219
|
+
[feature]="context.feature()"
|
|
1220
|
+
(templateSelected)="onSelect($event)">
|
|
1221
|
+
</saved-report-templates-drawer>
|
|
1222
|
+
`, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: SavedReportTemplatesDrawerComponent, selector: "saved-report-templates-drawer", inputs: ["apiName", "module", "service", "category", "feature", "visible", "position", "showCloseIcon", "modal", "dismissable", "closeOnEscape", "blockScroll", "filterFields", "moduleName", "defaultFeature", "defaultCategory", "defaultPermission", "currentUserId"], outputs: ["templateSelected", "edit", "add", "visibleChange"] }] });
|
|
1223
|
+
}
|
|
1224
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ReportTemplatesWrapperComponent, decorators: [{
|
|
1225
|
+
type: Component,
|
|
1226
|
+
args: [{
|
|
1227
|
+
selector: 'app-report-templates-wrapper',
|
|
1228
|
+
standalone: true,
|
|
1229
|
+
imports: [CommonModule, SavedReportTemplatesDrawerComponent],
|
|
1230
|
+
template: `
|
|
1231
|
+
<saved-report-templates-drawer
|
|
1232
|
+
[visible]="context.templateDrawerVisible()"
|
|
1233
|
+
[filterFields]="context.filters()"
|
|
1234
|
+
[service]="context.moduleName()"
|
|
1235
|
+
[category]="context.category()"
|
|
1236
|
+
[feature]="context.feature()"
|
|
1237
|
+
(templateSelected)="onSelect($event)">
|
|
1238
|
+
</saved-report-templates-drawer>
|
|
1239
|
+
`
|
|
1240
|
+
}]
|
|
1241
|
+
}] });
|
|
380
1242
|
|
|
381
1243
|
/**
|
|
382
1244
|
* Generated bundle index. Do not edit.
|
|
383
1245
|
*/
|
|
384
1246
|
|
|
385
|
-
export { FilterTemplateEditorDialogComponent, FilterTemplateFormFields, FilterTemplatesModule };
|
|
1247
|
+
export { FilterTemplateEditorDialogComponent, FilterTemplateFormFields, FilterTemplatesModule, ReportTemplatesWrapperComponent, SavedReportTemplatesDrawerComponent };
|
|
386
1248
|
//# sourceMappingURL=es.framework-ng.ui.core-filter-templates.mjs.map
|