@elite.framework/ng.ui.core 1.0.83 → 1.0.84
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/elite.framework-ng.ui.core-formly-ui-all.mjs +9 -1
- package/fesm2022/elite.framework-ng.ui.core-formly-ui-all.mjs.map +1 -1
- package/fesm2022/elite.framework-ng.ui.core-generic-search-advanced.mjs +849 -898
- package/fesm2022/elite.framework-ng.ui.core-generic-search-advanced.mjs.map +1 -1
- package/package.json +35 -35
|
@@ -5,7 +5,7 @@ import { CommonModule } from '@angular/common';
|
|
|
5
5
|
import * as i2$1 from '@angular/forms';
|
|
6
6
|
import { FormGroup, ReactiveFormsModule, FormsModule, FormControl, FormArray } from '@angular/forms';
|
|
7
7
|
import { FormlyForm, FieldType, FormlyField, provideFormlyConfig } from '@ngx-formly/core';
|
|
8
|
-
import * as
|
|
8
|
+
import * as i8$1 from '@ngx-translate/core';
|
|
9
9
|
import { TranslateService, TranslateModule } from '@ngx-translate/core';
|
|
10
10
|
import { ToolbarModule } from 'primeng/toolbar';
|
|
11
11
|
import * as i4 from 'primeng/button';
|
|
@@ -648,7 +648,7 @@ class GenericSearchAdvanced {
|
|
|
648
648
|
this.drawerVisible = false;
|
|
649
649
|
}
|
|
650
650
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: GenericSearchAdvanced, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
651
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.8", type: GenericSearchAdvanced, isStandalone: true, selector: "lib-generic-search-advanced", inputs: { model: "model", fields: "fields", enableSelect: "enableSelect", enableGroup: "enableGroup", odataConfig: "odataConfig" }, outputs: { search: "search", paginationChange: "paginationChange", odataSearch: "odataSearch" }, ngImport: i0, template: "<div class=\"flex flex-wrap items-center gap-3 w-full\">\r\n <!-- Search Input with Icon -->\r\n <p-inputgroup class=\"w-full\">\r\n <input\r\n pInputText\r\n type=\"text\"\r\n [(ngModel)]=\"model['filter']\"\r\n placeholder=\"{{ 'SEARCH' | translate }}\"\r\n (keyup.enter)=\"onSubmit()\"\r\n />\r\n\r\n\r\n <p-inputgroup-addon>\r\n <p-button\r\n icon=\"pi pi-search\"\r\n severity=\"secondary\"\r\n (click)=\"onSubmit()\"\r\n ></p-button>\r\n </p-inputgroup-addon>\r\n<p-inputgroup-addon>\r\n <div class=\"relative inline-flex\">\r\n <p-button\r\n icon=\"pi pi-filter\"\r\n severity=\"secondary\"\r\n (onClick)=\"drawerVisible = true\">\r\n </p-button>\r\n\r\n <p-badge\r\n *ngIf=\"filterCount > 0\"\r\n [value]=\"filterCount\"\r\n severity=\"warn\"\r\n size=\"small\"\r\n class=\"absolute -top-0 -right-0\">\r\n </p-badge>\r\n </div>\r\n</p-inputgroup-addon>\r\n\r\n <p-inputgroup-addon *ngIf=\"model['filter'] || filterCount > 0\">\r\n <p-button\r\n icon=\"pi pi-times\"\r\n severity=\"danger\"\r\n (click)=\"model['filter']=''; onReset()\"\r\n ></p-button>\r\n </p-inputgroup-addon>\r\n</p-inputgroup>\r\n\r\n\r\n</div>\r\n\r\n<!-- Drawer for Advanced Multi-field Search -->\r\n @if(drawerVisible){\r\n<p-drawer\r\n [(visible)]=\"drawerVisible\"\r\n position=\"right\"\r\n [styleClass]=\"'!w-full md:!w-80 lg:!w-[40rem] !h-full' \"\r\n [modal]=\"true\"\r\n [dismissible]=\"true\"\r\n styleClass=\"p-4 w-full max-w-md max-h-[90vh] flex flex-col\"\r\n>\r\n <!-- Entire form wrapper -->\r\n <form [formGroup]=\"form\" (ngSubmit)=\"onSubmit(); drawerVisible=false\" class=\"flex flex-col flex-1\">\r\n <!-- Scrollable Form -->\r\n <div class=\"flex-1 overflow-auto\">\r\n <formly-form\r\n [form]=\"form\"\r\n [fields]=\"fields_\"\r\n [model]=\"model\"\r\n [options]=\"options\"\r\n >\r\n </formly-form>\r\n </div>\r\n\r\n </form>\r\n <!-- Action Buttons -->\r\n <ng-template pTemplate=\"footer\">\r\n <div class=\"flex justify-end mt-2 space-x-2 flex-none\">\r\n <button\r\n type=\"submit\"\r\n pButton size=\"small\"\r\n (click)=\" onSubmit(); drawerVisible=false\"\r\n label=\"{{ 'SEARCH' | translate }}\">\r\n </button>\r\n <button\r\n type=\"button\"\r\n pButton\r\n size=\"small\"\r\n class=\"p-button-text\"\r\n (click)=\"onReset(); drawerVisible=false\"\r\n >\r\n {{ 'CLEAR' | translate }}\r\n </button>\r\n </div>\r\n </ng-template>\r\n</p-drawer>\r\n\r\n }\r\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: FormlyForm, selector: "formly-form", inputs: ["form", "model", "fields", "options"], outputs: ["modelChange"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "ngmodule", type: ToolbarModule }, { kind: "directive", type: i2.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "directive", type: i4.ButtonDirective, selector: "[pButton]", inputs: ["iconPos", "loadingIcon", "loading", "severity", "raised", "rounded", "text", "outlined", "size", "plain", "fluid", "label", "icon", "buttonProps"] }, { kind: "component", type: i4.Button, selector: "p-button", inputs: ["type", "iconPos", "icon", "badge", "label", "disabled", "loading", "loadingIcon", "raised", "rounded", "text", "plain", "severity", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "buttonProps", "autofocus", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i2$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i2$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: i2$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: InputIconModule }, { kind: "ngmodule", type: IconFieldModule }, { kind: "ngmodule", type: InputTextModule }, { kind: "directive", type: i5.InputText, selector: "[pInputText]", inputs: ["pSize", "variant", "fluid", "invalid"] }, { 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: "ngmodule", type: InputGroupModule }, { kind: "component", type: i7.InputGroup, selector: "p-inputgroup, p-inputGroup, p-input-group", inputs: ["styleClass"] }, { kind: "ngmodule", type: InputGroupAddonModule }, { kind: "component", type: i8.InputGroupAddon, selector: "p-inputgroup-addon, p-inputGroupAddon", inputs: ["style", "styleClass"] }, { kind: "ngmodule", type: BadgeModule }, { kind: "component", type: i9.Badge, selector: "p-badge", inputs: ["styleClass", "badgeSize", "size", "severity", "value", "badgeDisabled"] }, { kind: "pipe", type:
|
|
651
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.8", type: GenericSearchAdvanced, isStandalone: true, selector: "lib-generic-search-advanced", inputs: { model: "model", fields: "fields", enableSelect: "enableSelect", enableGroup: "enableGroup", odataConfig: "odataConfig" }, outputs: { search: "search", paginationChange: "paginationChange", odataSearch: "odataSearch" }, ngImport: i0, template: "<div class=\"flex flex-wrap items-center gap-3 w-full\">\r\n <!-- Search Input with Icon -->\r\n <p-inputgroup class=\"w-full\">\r\n <input\r\n pInputText\r\n type=\"text\"\r\n [(ngModel)]=\"model['filter']\"\r\n placeholder=\"{{ 'SEARCH' | translate }}\"\r\n (keyup.enter)=\"onSubmit()\"\r\n />\r\n\r\n\r\n <p-inputgroup-addon>\r\n <p-button\r\n icon=\"pi pi-search\"\r\n severity=\"secondary\"\r\n (click)=\"onSubmit()\"\r\n ></p-button>\r\n </p-inputgroup-addon>\r\n<p-inputgroup-addon>\r\n <div class=\"relative inline-flex\">\r\n <p-button\r\n icon=\"pi pi-filter\"\r\n severity=\"secondary\"\r\n (onClick)=\"drawerVisible = true\">\r\n </p-button>\r\n\r\n <p-badge\r\n *ngIf=\"filterCount > 0\"\r\n [value]=\"filterCount\"\r\n severity=\"warn\"\r\n size=\"small\"\r\n class=\"absolute -top-0 -right-0\">\r\n </p-badge>\r\n </div>\r\n</p-inputgroup-addon>\r\n\r\n <p-inputgroup-addon *ngIf=\"model['filter'] || filterCount > 0\">\r\n <p-button\r\n icon=\"pi pi-times\"\r\n severity=\"danger\"\r\n (click)=\"model['filter']=''; onReset()\"\r\n ></p-button>\r\n </p-inputgroup-addon>\r\n</p-inputgroup>\r\n\r\n\r\n</div>\r\n\r\n<!-- Drawer for Advanced Multi-field Search -->\r\n @if(drawerVisible){\r\n<p-drawer\r\n [(visible)]=\"drawerVisible\"\r\n position=\"right\"\r\n [styleClass]=\"'!w-full md:!w-80 lg:!w-[40rem] !h-full' \"\r\n [modal]=\"true\"\r\n [dismissible]=\"true\"\r\n styleClass=\"p-4 w-full max-w-md max-h-[90vh] flex flex-col\"\r\n>\r\n <!-- Entire form wrapper -->\r\n <form [formGroup]=\"form\" (ngSubmit)=\"onSubmit(); drawerVisible=false\" class=\"flex flex-col flex-1\">\r\n <!-- Scrollable Form -->\r\n <div class=\"flex-1 overflow-auto\">\r\n <formly-form\r\n [form]=\"form\"\r\n [fields]=\"fields_\"\r\n [model]=\"model\"\r\n [options]=\"options\"\r\n >\r\n </formly-form>\r\n </div>\r\n\r\n </form>\r\n <!-- Action Buttons -->\r\n <ng-template pTemplate=\"footer\">\r\n <div class=\"flex justify-end mt-2 space-x-2 flex-none\">\r\n <button\r\n type=\"submit\"\r\n pButton size=\"small\"\r\n (click)=\" onSubmit(); drawerVisible=false\"\r\n label=\"{{ 'SEARCH' | translate }}\">\r\n </button>\r\n <button\r\n type=\"button\"\r\n pButton\r\n size=\"small\"\r\n class=\"p-button-text\"\r\n (click)=\"onReset(); drawerVisible=false\"\r\n >\r\n {{ 'CLEAR' | translate }}\r\n </button>\r\n </div>\r\n </ng-template>\r\n</p-drawer>\r\n\r\n }\r\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: FormlyForm, selector: "formly-form", inputs: ["form", "model", "fields", "options"], outputs: ["modelChange"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "ngmodule", type: ToolbarModule }, { kind: "directive", type: i2.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "directive", type: i4.ButtonDirective, selector: "[pButton]", inputs: ["iconPos", "loadingIcon", "loading", "severity", "raised", "rounded", "text", "outlined", "size", "plain", "fluid", "label", "icon", "buttonProps"] }, { kind: "component", type: i4.Button, selector: "p-button", inputs: ["type", "iconPos", "icon", "badge", "label", "disabled", "loading", "loadingIcon", "raised", "rounded", "text", "plain", "severity", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "buttonProps", "autofocus", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i2$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i2$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: i2$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: InputIconModule }, { kind: "ngmodule", type: IconFieldModule }, { kind: "ngmodule", type: InputTextModule }, { kind: "directive", type: i5.InputText, selector: "[pInputText]", inputs: ["pSize", "variant", "fluid", "invalid"] }, { 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: "ngmodule", type: InputGroupModule }, { kind: "component", type: i7.InputGroup, selector: "p-inputgroup, p-inputGroup, p-input-group", inputs: ["styleClass"] }, { kind: "ngmodule", type: InputGroupAddonModule }, { kind: "component", type: i8.InputGroupAddon, selector: "p-inputgroup-addon, p-inputGroupAddon", inputs: ["style", "styleClass"] }, { kind: "ngmodule", type: BadgeModule }, { kind: "component", type: i9.Badge, selector: "p-badge", inputs: ["styleClass", "badgeSize", "size", "severity", "value", "badgeDisabled"] }, { kind: "pipe", type: i8$1.TranslatePipe, name: "translate" }] });
|
|
652
652
|
}
|
|
653
653
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: GenericSearchAdvanced, decorators: [{
|
|
654
654
|
type: Component,
|
|
@@ -783,183 +783,161 @@ class SortBuilderComponent extends FieldType {
|
|
|
783
783
|
return availableFields.length > 0 ? availableFields[0].key : '';
|
|
784
784
|
}
|
|
785
785
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: SortBuilderComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
|
|
786
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.8", type: SortBuilderComponent, isStandalone: true, selector: "formly-sort-builder", usesInheritance: true, ngImport: i0, template:
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
appendTo="body"
|
|
827
|
-
styleClass="w-full">
|
|
828
|
-
</p-select>
|
|
829
|
-
</div>
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
<!-- Direction Icon -->
|
|
833
|
-
<div class="col-fixed">
|
|
834
|
-
<p-select
|
|
835
|
-
[options]="directionOptions"
|
|
836
|
-
[(ngModel)]="sort.direction"
|
|
837
|
-
(onChange)="updateValue()"
|
|
838
|
-
placeholder="الاتجاه"
|
|
839
|
-
appendTo="body"
|
|
840
|
-
styleClass="w-full">
|
|
841
|
-
</p-select>
|
|
842
|
-
</div>
|
|
843
|
-
|
|
844
|
-
<!-- Actions -->
|
|
845
|
-
<div class="col-fixed flex gap-2" style="justify-content: flex-end;">
|
|
846
|
-
|
|
847
|
-
<!--
|
|
848
|
-
<button
|
|
849
|
-
outlined
|
|
850
|
-
pButton
|
|
851
|
-
[icon]="getDirectionIcon(sort.direction)"
|
|
852
|
-
type="button"
|
|
853
|
-
[ngClass]="'p-button-text p-button-sm' + getDirectionColor(sort.direction)"
|
|
854
|
-
pTooltip="{{ sort.direction === 'asc' ? 'تصاعدي' : 'تنازلي' }}"
|
|
855
|
-
tooltipPosition="top">
|
|
856
|
-
</button> -->
|
|
857
|
-
<!-- Move Up -->
|
|
858
|
-
<button
|
|
859
|
-
outlined
|
|
860
|
-
style=" width: var(--p-button-icon-only-width);"
|
|
861
|
-
*ngIf="!isFirst"
|
|
862
|
-
pButton
|
|
863
|
-
icon="pi pi-arrow-up"
|
|
864
|
-
type="button"
|
|
865
|
-
class=" p-button-sm p-button-success"
|
|
866
|
-
(click)="moveSort(i, i - 1)"
|
|
867
|
-
pTooltip="تحريك للأعلى"
|
|
868
|
-
tooltipPosition="top">
|
|
869
|
-
</button>
|
|
870
|
-
|
|
871
|
-
<!-- Move Down -->
|
|
872
|
-
<button
|
|
873
|
-
outlined
|
|
874
|
-
style=" width: var(--p-button-icon-only-width);"
|
|
875
|
-
*ngIf="!isLast"
|
|
876
|
-
pButton
|
|
877
|
-
icon="pi pi-arrow-down"
|
|
878
|
-
type="button"
|
|
879
|
-
class=" p-button-sm p-button-success"
|
|
880
|
-
(click)="moveSort(i, i + 1)"
|
|
881
|
-
pTooltip="تحريك للأسفل"
|
|
882
|
-
tooltipPosition="top">
|
|
883
|
-
</button>
|
|
884
|
-
|
|
885
|
-
<!-- Remove -->
|
|
886
|
-
<button
|
|
887
|
-
style=" width: var(--p-button-icon-only-width);"
|
|
888
|
-
pButton
|
|
889
|
-
icon="pi pi-times"
|
|
890
|
-
type="button"
|
|
891
|
-
class=" p-button-sm p-button-danger"
|
|
892
|
-
(click)="removeSort(i)"
|
|
893
|
-
pTooltip="حذف الترتيب"
|
|
894
|
-
tooltipPosition="top">
|
|
895
|
-
</button>
|
|
896
|
-
</div>
|
|
897
|
-
</div>
|
|
786
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.8", type: SortBuilderComponent, isStandalone: true, selector: "formly-sort-builder", usesInheritance: true, ngImport: i0, template: `<div class="sort-builder p-3 border-round border-1 surface-border">
|
|
787
|
+
<div class="mb-6">
|
|
788
|
+
<h5 class="text-lg font-semibold text-gray-900 mb-2">{{ props.label || ('SORTING' | translate) }}</h5>
|
|
789
|
+
<p class="text-gray-600 text-sm">{{ ('PRIORITY_HINT' | translate) }}</p>
|
|
790
|
+
</div>
|
|
791
|
+
|
|
792
|
+
<!-- Sort List -->
|
|
793
|
+
<div *ngIf="sorts.length > 0" class="sort-list space-y-2 mb-3">
|
|
794
|
+
<div
|
|
795
|
+
*ngFor="let sort of sorts; let i = index; let isFirst = first; let isLast = last"
|
|
796
|
+
class="sort-row p-2 border-round surface-card"
|
|
797
|
+
pDraggable
|
|
798
|
+
pDroppable
|
|
799
|
+
(onDragStart)="onDragStart(i)"
|
|
800
|
+
(onDrop)="onDrop($event, i)"
|
|
801
|
+
[ngClass]="{'border-left-3 border-primary': isFirst, 'border-left-3 border-200': !isFirst}">
|
|
802
|
+
|
|
803
|
+
<div class="grid grid-cols-4 align-items-center gap-2">
|
|
804
|
+
<!-- Drag Handle -->
|
|
805
|
+
<div class="col-span-2 flex">
|
|
806
|
+
<button
|
|
807
|
+
pButton
|
|
808
|
+
icon="pi pi-bars"
|
|
809
|
+
type="button"
|
|
810
|
+
class="p-button-text p-button-plain cursor-move"
|
|
811
|
+
[pTooltip]="'DRAG_TOOLTIP' | translate"
|
|
812
|
+
tooltipPosition="top">
|
|
813
|
+
</button>
|
|
814
|
+
<p-select
|
|
815
|
+
[options]="getAvailableFields(sort.field)"
|
|
816
|
+
optionLabel="label"
|
|
817
|
+
optionValue="key"
|
|
818
|
+
[(ngModel)]="sort.field"
|
|
819
|
+
(onChange)="updateValue()"
|
|
820
|
+
[placeholder]="'SELECT_FIELD_SORT' | translate"
|
|
821
|
+
[showClear]="true"
|
|
822
|
+
appendTo="body"
|
|
823
|
+
styleClass="w-full">
|
|
824
|
+
</p-select>
|
|
825
|
+
</div>
|
|
898
826
|
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
827
|
+
<!-- Direction Selector -->
|
|
828
|
+
<div class="col-fixed">
|
|
829
|
+
<p-select
|
|
830
|
+
[options]="directionOptions"
|
|
831
|
+
[(ngModel)]="sort.direction"
|
|
832
|
+
(onChange)="updateValue()"
|
|
833
|
+
[placeholder]="'DIRECTION' | translate"
|
|
834
|
+
appendTo="body"
|
|
835
|
+
styleClass="w-full">
|
|
836
|
+
</p-select>
|
|
903
837
|
</div>
|
|
904
|
-
</div>
|
|
905
838
|
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
839
|
+
<!-- Actions -->
|
|
840
|
+
<div class="col-fixed flex gap-2" style="justify-content: flex-end;">
|
|
841
|
+
<!-- Move Up -->
|
|
842
|
+
<button
|
|
843
|
+
outlined
|
|
844
|
+
style="width: var(--p-button-icon-only-width);"
|
|
845
|
+
*ngIf="!isFirst"
|
|
846
|
+
pButton
|
|
847
|
+
icon="pi pi-arrow-up"
|
|
848
|
+
type="button"
|
|
849
|
+
class="p-button-sm p-button-success"
|
|
850
|
+
(click)="moveSort(i, i - 1)"
|
|
851
|
+
[pTooltip]="'MOVE_UP' | translate"
|
|
852
|
+
tooltipPosition="top">
|
|
853
|
+
</button>
|
|
912
854
|
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
pButton
|
|
927
|
-
icon="pi pi-random"
|
|
928
|
-
label="عكس الترتيب"
|
|
929
|
-
type="button"
|
|
930
|
-
class="p-button-outlined"
|
|
931
|
-
(click)="reverseSorts()"
|
|
932
|
-
pTooltip="عكس اتجاه جميع قواعد الترتيب"
|
|
933
|
-
tooltipPosition="top">
|
|
934
|
-
</button>
|
|
935
|
-
|
|
936
|
-
<button
|
|
937
|
-
*ngIf="sorts.length > 0"
|
|
938
|
-
pButton
|
|
939
|
-
icon="pi pi-trash"
|
|
940
|
-
type="button"
|
|
941
|
-
class="p-button-outlined p-button-danger"
|
|
942
|
-
(click)="clearAll()"
|
|
943
|
-
pTooltip="مسح جميع قواعد الترتيب"
|
|
944
|
-
tooltipPosition="top">
|
|
945
|
-
</button>
|
|
946
|
-
</div>
|
|
855
|
+
<!-- Move Down -->
|
|
856
|
+
<button
|
|
857
|
+
outlined
|
|
858
|
+
style="width: var(--p-button-icon-only-width);"
|
|
859
|
+
*ngIf="!isLast"
|
|
860
|
+
pButton
|
|
861
|
+
icon="pi pi-arrow-down"
|
|
862
|
+
type="button"
|
|
863
|
+
class="p-button-sm p-button-success"
|
|
864
|
+
(click)="moveSort(i, i + 1)"
|
|
865
|
+
[pTooltip]="'MOVE_DOWN' | translate"
|
|
866
|
+
tooltipPosition="top">
|
|
867
|
+
</button>
|
|
947
868
|
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
</
|
|
869
|
+
<!-- Remove -->
|
|
870
|
+
<button
|
|
871
|
+
style="width: var(--p-button-icon-only-width);"
|
|
872
|
+
pButton
|
|
873
|
+
icon="pi pi-times"
|
|
874
|
+
type="button"
|
|
875
|
+
class="p-button-sm p-button-danger"
|
|
876
|
+
(click)="removeSort(i)"
|
|
877
|
+
[pTooltip]="'REMOVE_SORT' | translate"
|
|
878
|
+
tooltipPosition="top">
|
|
879
|
+
</button>
|
|
959
880
|
</div>
|
|
960
881
|
</div>
|
|
961
882
|
</div>
|
|
962
|
-
|
|
883
|
+
</div>
|
|
884
|
+
|
|
885
|
+
<!-- Empty State -->
|
|
886
|
+
<div *ngIf="sorts.length === 0" class="empty-state text-center p-4 border-round surface-section">
|
|
887
|
+
<i class="pi pi-sort-alt text-4xl text-500 mb-3"></i>
|
|
888
|
+
<p class="text-500 mb-3">{{ 'NO_SORT_RULES' | translate }}</p>
|
|
889
|
+
<p class="text-400 text-sm mb-3">{{ 'DEFAULT_ORDER' | translate }}</p>
|
|
890
|
+
</div>
|
|
891
|
+
|
|
892
|
+
<!-- Actions -->
|
|
893
|
+
<div class="flex gap-2">
|
|
894
|
+
<button
|
|
895
|
+
pButton
|
|
896
|
+
icon="pi pi-sort-alt"
|
|
897
|
+
[label]="'ADD_SORT' | translate"
|
|
898
|
+
type="button"
|
|
899
|
+
class="p-button-outlined flex-1"
|
|
900
|
+
(click)="addSort()">
|
|
901
|
+
</button>
|
|
902
|
+
|
|
903
|
+
<button
|
|
904
|
+
*ngIf="sorts.length > 1"
|
|
905
|
+
pButton
|
|
906
|
+
icon="pi pi-random"
|
|
907
|
+
[label]="'REVERSE_ORDER' | translate"
|
|
908
|
+
type="button"
|
|
909
|
+
class="p-button-outlined"
|
|
910
|
+
(click)="reverseSorts()"
|
|
911
|
+
[pTooltip]="'REVERSE_TOOLTIP' | translate"
|
|
912
|
+
tooltipPosition="top">
|
|
913
|
+
</button>
|
|
914
|
+
|
|
915
|
+
<button
|
|
916
|
+
*ngIf="sorts.length > 0"
|
|
917
|
+
pButton
|
|
918
|
+
icon="pi pi-trash"
|
|
919
|
+
type="button"
|
|
920
|
+
class="p-button-outlined p-button-danger"
|
|
921
|
+
(click)="clearAll()"
|
|
922
|
+
[pTooltip]="'CLEAR_ALL_TOOLTIP' | translate"
|
|
923
|
+
tooltipPosition="top">
|
|
924
|
+
</button>
|
|
925
|
+
</div>
|
|
926
|
+
|
|
927
|
+
<!-- Summary -->
|
|
928
|
+
<div *ngIf="sorts.length > 0" class="sort-summary mt-3 p-2 border-round surface-ground">
|
|
929
|
+
<h5 class="mt-0 mb-2 text-sm">{{ 'SORT_SUMMARY' | translate }}:</h5>
|
|
930
|
+
<div class="text-sm text-500">
|
|
931
|
+
<span *ngFor="let sort of sorts; let i = index" class="sort-step">
|
|
932
|
+
<span class="font-semibold">{{ getFieldLabel(sort.field) }}</span>
|
|
933
|
+
<span class="direction-badge" [ngClass]="sort.direction === 'asc' ? 'bg-green-100 text-green-800' : 'bg-red-100 text-red-800'">
|
|
934
|
+
{{ sort.direction === 'asc' ? '▲' : '▼' }}
|
|
935
|
+
</span>
|
|
936
|
+
<span *ngIf="!isLast"> {{ 'THEN' | translate }} </span>
|
|
937
|
+
</span>
|
|
938
|
+
</div>
|
|
939
|
+
</div>
|
|
940
|
+
</div>`, isInline: true, styles: [""], 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$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: SelectModule }, { kind: "component", type: i3.Select, selector: "p-select", inputs: ["id", "scrollHeight", "filter", "panelStyle", "styleClass", "panelStyleClass", "readonly", "editable", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "filterValue", "options", "appendTo"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "directive", type: i4.ButtonDirective, selector: "[pButton]", inputs: ["iconPos", "loadingIcon", "loading", "severity", "raised", "rounded", "text", "outlined", "size", "plain", "fluid", "label", "icon", "buttonProps"] }, { kind: "ngmodule", type: DragDropModule }, { kind: "directive", type: i5$1.Draggable, selector: "[pDraggable]", inputs: ["pDraggable", "dragEffect", "dragHandle", "pDraggableDisabled"], outputs: ["onDragStart", "onDragEnd", "onDrag"] }, { kind: "directive", type: i5$1.Droppable, selector: "[pDroppable]", inputs: ["pDroppable", "pDroppableDisabled", "dropEffect"], outputs: ["onDragEnter", "onDragLeave", "onDrop"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i6$1.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions", "appendTo"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i8$1.TranslatePipe, name: "translate" }] });
|
|
963
941
|
}
|
|
964
942
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: SortBuilderComponent, decorators: [{
|
|
965
943
|
type: Component,
|
|
@@ -969,184 +947,163 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImpor
|
|
|
969
947
|
SelectModule,
|
|
970
948
|
ButtonModule,
|
|
971
949
|
DragDropModule,
|
|
972
|
-
TooltipModule
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
styleClass="w-full">
|
|
1015
|
-
</p-select>
|
|
1016
|
-
</div>
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
<!-- Direction Icon -->
|
|
1020
|
-
<div class="col-fixed">
|
|
1021
|
-
<p-select
|
|
1022
|
-
[options]="directionOptions"
|
|
1023
|
-
[(ngModel)]="sort.direction"
|
|
1024
|
-
(onChange)="updateValue()"
|
|
1025
|
-
placeholder="الاتجاه"
|
|
1026
|
-
appendTo="body"
|
|
1027
|
-
styleClass="w-full">
|
|
1028
|
-
</p-select>
|
|
1029
|
-
</div>
|
|
1030
|
-
|
|
1031
|
-
<!-- Actions -->
|
|
1032
|
-
<div class="col-fixed flex gap-2" style="justify-content: flex-end;">
|
|
1033
|
-
|
|
1034
|
-
<!--
|
|
1035
|
-
<button
|
|
1036
|
-
outlined
|
|
1037
|
-
pButton
|
|
1038
|
-
[icon]="getDirectionIcon(sort.direction)"
|
|
1039
|
-
type="button"
|
|
1040
|
-
[ngClass]="'p-button-text p-button-sm' + getDirectionColor(sort.direction)"
|
|
1041
|
-
pTooltip="{{ sort.direction === 'asc' ? 'تصاعدي' : 'تنازلي' }}"
|
|
1042
|
-
tooltipPosition="top">
|
|
1043
|
-
</button> -->
|
|
1044
|
-
<!-- Move Up -->
|
|
1045
|
-
<button
|
|
1046
|
-
outlined
|
|
1047
|
-
style=" width: var(--p-button-icon-only-width);"
|
|
1048
|
-
*ngIf="!isFirst"
|
|
1049
|
-
pButton
|
|
1050
|
-
icon="pi pi-arrow-up"
|
|
1051
|
-
type="button"
|
|
1052
|
-
class=" p-button-sm p-button-success"
|
|
1053
|
-
(click)="moveSort(i, i - 1)"
|
|
1054
|
-
pTooltip="تحريك للأعلى"
|
|
1055
|
-
tooltipPosition="top">
|
|
1056
|
-
</button>
|
|
1057
|
-
|
|
1058
|
-
<!-- Move Down -->
|
|
1059
|
-
<button
|
|
1060
|
-
outlined
|
|
1061
|
-
style=" width: var(--p-button-icon-only-width);"
|
|
1062
|
-
*ngIf="!isLast"
|
|
1063
|
-
pButton
|
|
1064
|
-
icon="pi pi-arrow-down"
|
|
1065
|
-
type="button"
|
|
1066
|
-
class=" p-button-sm p-button-success"
|
|
1067
|
-
(click)="moveSort(i, i + 1)"
|
|
1068
|
-
pTooltip="تحريك للأسفل"
|
|
1069
|
-
tooltipPosition="top">
|
|
1070
|
-
</button>
|
|
1071
|
-
|
|
1072
|
-
<!-- Remove -->
|
|
1073
|
-
<button
|
|
1074
|
-
style=" width: var(--p-button-icon-only-width);"
|
|
1075
|
-
pButton
|
|
1076
|
-
icon="pi pi-times"
|
|
1077
|
-
type="button"
|
|
1078
|
-
class=" p-button-sm p-button-danger"
|
|
1079
|
-
(click)="removeSort(i)"
|
|
1080
|
-
pTooltip="حذف الترتيب"
|
|
1081
|
-
tooltipPosition="top">
|
|
1082
|
-
</button>
|
|
1083
|
-
</div>
|
|
1084
|
-
</div>
|
|
950
|
+
TooltipModule,
|
|
951
|
+
TranslateModule
|
|
952
|
+
], template: `<div class="sort-builder p-3 border-round border-1 surface-border">
|
|
953
|
+
<div class="mb-6">
|
|
954
|
+
<h5 class="text-lg font-semibold text-gray-900 mb-2">{{ props.label || ('SORTING' | translate) }}</h5>
|
|
955
|
+
<p class="text-gray-600 text-sm">{{ ('PRIORITY_HINT' | translate) }}</p>
|
|
956
|
+
</div>
|
|
957
|
+
|
|
958
|
+
<!-- Sort List -->
|
|
959
|
+
<div *ngIf="sorts.length > 0" class="sort-list space-y-2 mb-3">
|
|
960
|
+
<div
|
|
961
|
+
*ngFor="let sort of sorts; let i = index; let isFirst = first; let isLast = last"
|
|
962
|
+
class="sort-row p-2 border-round surface-card"
|
|
963
|
+
pDraggable
|
|
964
|
+
pDroppable
|
|
965
|
+
(onDragStart)="onDragStart(i)"
|
|
966
|
+
(onDrop)="onDrop($event, i)"
|
|
967
|
+
[ngClass]="{'border-left-3 border-primary': isFirst, 'border-left-3 border-200': !isFirst}">
|
|
968
|
+
|
|
969
|
+
<div class="grid grid-cols-4 align-items-center gap-2">
|
|
970
|
+
<!-- Drag Handle -->
|
|
971
|
+
<div class="col-span-2 flex">
|
|
972
|
+
<button
|
|
973
|
+
pButton
|
|
974
|
+
icon="pi pi-bars"
|
|
975
|
+
type="button"
|
|
976
|
+
class="p-button-text p-button-plain cursor-move"
|
|
977
|
+
[pTooltip]="'DRAG_TOOLTIP' | translate"
|
|
978
|
+
tooltipPosition="top">
|
|
979
|
+
</button>
|
|
980
|
+
<p-select
|
|
981
|
+
[options]="getAvailableFields(sort.field)"
|
|
982
|
+
optionLabel="label"
|
|
983
|
+
optionValue="key"
|
|
984
|
+
[(ngModel)]="sort.field"
|
|
985
|
+
(onChange)="updateValue()"
|
|
986
|
+
[placeholder]="'SELECT_FIELD_SORT' | translate"
|
|
987
|
+
[showClear]="true"
|
|
988
|
+
appendTo="body"
|
|
989
|
+
styleClass="w-full">
|
|
990
|
+
</p-select>
|
|
991
|
+
</div>
|
|
1085
992
|
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
993
|
+
<!-- Direction Selector -->
|
|
994
|
+
<div class="col-fixed">
|
|
995
|
+
<p-select
|
|
996
|
+
[options]="directionOptions"
|
|
997
|
+
[(ngModel)]="sort.direction"
|
|
998
|
+
(onChange)="updateValue()"
|
|
999
|
+
[placeholder]="'DIRECTION' | translate"
|
|
1000
|
+
appendTo="body"
|
|
1001
|
+
styleClass="w-full">
|
|
1002
|
+
</p-select>
|
|
1090
1003
|
</div>
|
|
1091
|
-
</div>
|
|
1092
1004
|
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1005
|
+
<!-- Actions -->
|
|
1006
|
+
<div class="col-fixed flex gap-2" style="justify-content: flex-end;">
|
|
1007
|
+
<!-- Move Up -->
|
|
1008
|
+
<button
|
|
1009
|
+
outlined
|
|
1010
|
+
style="width: var(--p-button-icon-only-width);"
|
|
1011
|
+
*ngIf="!isFirst"
|
|
1012
|
+
pButton
|
|
1013
|
+
icon="pi pi-arrow-up"
|
|
1014
|
+
type="button"
|
|
1015
|
+
class="p-button-sm p-button-success"
|
|
1016
|
+
(click)="moveSort(i, i - 1)"
|
|
1017
|
+
[pTooltip]="'MOVE_UP' | translate"
|
|
1018
|
+
tooltipPosition="top">
|
|
1019
|
+
</button>
|
|
1099
1020
|
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
pButton
|
|
1114
|
-
icon="pi pi-random"
|
|
1115
|
-
label="عكس الترتيب"
|
|
1116
|
-
type="button"
|
|
1117
|
-
class="p-button-outlined"
|
|
1118
|
-
(click)="reverseSorts()"
|
|
1119
|
-
pTooltip="عكس اتجاه جميع قواعد الترتيب"
|
|
1120
|
-
tooltipPosition="top">
|
|
1121
|
-
</button>
|
|
1122
|
-
|
|
1123
|
-
<button
|
|
1124
|
-
*ngIf="sorts.length > 0"
|
|
1125
|
-
pButton
|
|
1126
|
-
icon="pi pi-trash"
|
|
1127
|
-
type="button"
|
|
1128
|
-
class="p-button-outlined p-button-danger"
|
|
1129
|
-
(click)="clearAll()"
|
|
1130
|
-
pTooltip="مسح جميع قواعد الترتيب"
|
|
1131
|
-
tooltipPosition="top">
|
|
1132
|
-
</button>
|
|
1133
|
-
</div>
|
|
1021
|
+
<!-- Move Down -->
|
|
1022
|
+
<button
|
|
1023
|
+
outlined
|
|
1024
|
+
style="width: var(--p-button-icon-only-width);"
|
|
1025
|
+
*ngIf="!isLast"
|
|
1026
|
+
pButton
|
|
1027
|
+
icon="pi pi-arrow-down"
|
|
1028
|
+
type="button"
|
|
1029
|
+
class="p-button-sm p-button-success"
|
|
1030
|
+
(click)="moveSort(i, i + 1)"
|
|
1031
|
+
[pTooltip]="'MOVE_DOWN' | translate"
|
|
1032
|
+
tooltipPosition="top">
|
|
1033
|
+
</button>
|
|
1134
1034
|
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
</
|
|
1035
|
+
<!-- Remove -->
|
|
1036
|
+
<button
|
|
1037
|
+
style="width: var(--p-button-icon-only-width);"
|
|
1038
|
+
pButton
|
|
1039
|
+
icon="pi pi-times"
|
|
1040
|
+
type="button"
|
|
1041
|
+
class="p-button-sm p-button-danger"
|
|
1042
|
+
(click)="removeSort(i)"
|
|
1043
|
+
[pTooltip]="'REMOVE_SORT' | translate"
|
|
1044
|
+
tooltipPosition="top">
|
|
1045
|
+
</button>
|
|
1146
1046
|
</div>
|
|
1147
1047
|
</div>
|
|
1148
1048
|
</div>
|
|
1149
|
-
|
|
1049
|
+
</div>
|
|
1050
|
+
|
|
1051
|
+
<!-- Empty State -->
|
|
1052
|
+
<div *ngIf="sorts.length === 0" class="empty-state text-center p-4 border-round surface-section">
|
|
1053
|
+
<i class="pi pi-sort-alt text-4xl text-500 mb-3"></i>
|
|
1054
|
+
<p class="text-500 mb-3">{{ 'NO_SORT_RULES' | translate }}</p>
|
|
1055
|
+
<p class="text-400 text-sm mb-3">{{ 'DEFAULT_ORDER' | translate }}</p>
|
|
1056
|
+
</div>
|
|
1057
|
+
|
|
1058
|
+
<!-- Actions -->
|
|
1059
|
+
<div class="flex gap-2">
|
|
1060
|
+
<button
|
|
1061
|
+
pButton
|
|
1062
|
+
icon="pi pi-sort-alt"
|
|
1063
|
+
[label]="'ADD_SORT' | translate"
|
|
1064
|
+
type="button"
|
|
1065
|
+
class="p-button-outlined flex-1"
|
|
1066
|
+
(click)="addSort()">
|
|
1067
|
+
</button>
|
|
1068
|
+
|
|
1069
|
+
<button
|
|
1070
|
+
*ngIf="sorts.length > 1"
|
|
1071
|
+
pButton
|
|
1072
|
+
icon="pi pi-random"
|
|
1073
|
+
[label]="'REVERSE_ORDER' | translate"
|
|
1074
|
+
type="button"
|
|
1075
|
+
class="p-button-outlined"
|
|
1076
|
+
(click)="reverseSorts()"
|
|
1077
|
+
[pTooltip]="'REVERSE_TOOLTIP' | translate"
|
|
1078
|
+
tooltipPosition="top">
|
|
1079
|
+
</button>
|
|
1080
|
+
|
|
1081
|
+
<button
|
|
1082
|
+
*ngIf="sorts.length > 0"
|
|
1083
|
+
pButton
|
|
1084
|
+
icon="pi pi-trash"
|
|
1085
|
+
type="button"
|
|
1086
|
+
class="p-button-outlined p-button-danger"
|
|
1087
|
+
(click)="clearAll()"
|
|
1088
|
+
[pTooltip]="'CLEAR_ALL_TOOLTIP' | translate"
|
|
1089
|
+
tooltipPosition="top">
|
|
1090
|
+
</button>
|
|
1091
|
+
</div>
|
|
1092
|
+
|
|
1093
|
+
<!-- Summary -->
|
|
1094
|
+
<div *ngIf="sorts.length > 0" class="sort-summary mt-3 p-2 border-round surface-ground">
|
|
1095
|
+
<h5 class="mt-0 mb-2 text-sm">{{ 'SORT_SUMMARY' | translate }}:</h5>
|
|
1096
|
+
<div class="text-sm text-500">
|
|
1097
|
+
<span *ngFor="let sort of sorts; let i = index" class="sort-step">
|
|
1098
|
+
<span class="font-semibold">{{ getFieldLabel(sort.field) }}</span>
|
|
1099
|
+
<span class="direction-badge" [ngClass]="sort.direction === 'asc' ? 'bg-green-100 text-green-800' : 'bg-red-100 text-red-800'">
|
|
1100
|
+
{{ sort.direction === 'asc' ? '▲' : '▼' }}
|
|
1101
|
+
</span>
|
|
1102
|
+
<span *ngIf="!isLast"> {{ 'THEN' | translate }} </span>
|
|
1103
|
+
</span>
|
|
1104
|
+
</div>
|
|
1105
|
+
</div>
|
|
1106
|
+
</div>` }]
|
|
1150
1107
|
}] });
|
|
1151
1108
|
|
|
1152
1109
|
// query-builder.component.ts
|
|
@@ -1437,7 +1394,7 @@ class QueryBuilderComponent extends FieldType {
|
|
|
1437
1394
|
}
|
|
1438
1395
|
}
|
|
1439
1396
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: QueryBuilderComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
|
|
1440
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.8", type: QueryBuilderComponent, isStandalone: true, selector: "formly-query-builder", usesInheritance: true, ngImport: i0, template: "<div>\r\n\r\n <!-- Groups Container with Connecting Lines -->\r\n <div class=\"groups-container\" #groupsContainer>\r\n <div *ngFor=\"let group of groups; let groupIndex = index\"\r\n class=\"group-wrapper relative\"\r\n #groupElement>\r\n\r\n <!-- Vertical Connector Line from Previous Group -->\r\n<div *ngIf=\"groupIndex > 0\" class=\"vertical-connector\">\r\n <div class=\"vertical-line\"></div>\r\n\r\n <!-- Operator Button -->\r\n <button\r\n type=\"button\"\r\n class=\"group-logical-operator-box\"\r\n [class.and]=\"group.groupLogicalOperator === 'and'\"\r\n [class.or]=\"group.groupLogicalOperator === 'or'\"\r\n (click)=\"opPopover.toggle($event)\">\r\n <span class=\"operator-text\">\r\n {{ getLogicalOperatorText(group.groupLogicalOperator || 'and') }}\r\n </span>\r\n <div class=\"connector-arrow\"></div>\r\n </button>\r\n\r\n <!-- Popover -->\r\n <p-popover #opPopover appendTo=\"body\">\r\n <div class=\"w-12rem\">\r\n <p-listbox\r\n [options]=\"logicalOperators\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n [(ngModel)]=\"group.groupLogicalOperator\"\r\n (onChange)=\" opPopover.toggle($event)\"\r\n [style]=\"{ width: '100%' }\">\r\n </p-listbox>\r\n </div>\r\n </p-popover>\r\n</div>\r\n\r\n <div class=\"group-container mb-6 p-1 bg-white rounded-lg border-l-4 border-t-1 border-b-1 border-r-1 shadow-sm transition-all duration-300 relative\"\r\n [class.border-blue-500]=\"group.logicalOperator === 'and'\"\r\n [class.border-or-500]=\"group.logicalOperator === 'or'\"\r\n [class.pulse]=\"groupIndex === 0\">\r\n\r\n <!-- Rounded Button for \"\u0631\u0628\u0637 \u0627\u0644\u0634\u0631\u0648\u0637\" on left border -->\r\n<div\r\n class=\"absolute -left-4 top-1/2 transform -translate-y-1/2 z-10 transition-all duration-300\"\r\n\r\n>\r\n\r\n\r\n\r\n<!-- Logical Operator Popover Button -->\r\n<p-button\r\n [severity]=\"group.logicalOperator === 'and' ? 'success' : 'info'\"\r\n [styleClass]=\"group.logicalOperator === 'and'\r\n ? 'p-button-icon-only p-button-rounded p-button-sm logical-and'\r\n : 'p-button-icon-only p-button-rounded p-button-sm logical-or'\"\r\n (click)=\"opPopover.toggle($event)\">\r\n {{group.logicalOperator === 'and' ? ('and' | translate) : ('or' | translate)}}\r\n</p-button>\r\n\r\n<!-- Popover for Operator Selection -->\r\n<p-popover #opPopover appendTo=\"body\">\r\n <div class=\"w-10rem\">\r\n <p-listbox\r\n [options]=\"[\r\n { label: 'and' | translate, value: 'and' },\r\n { label: 'or' | translate, value: 'or' }\r\n ]\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n [(ngModel)]=\"group.logicalOperator\"\r\n (onChange)=\"updateValue(); opPopover.toggle($event)\"\r\n [style]=\"{ width: '100%' }\">\r\n <ng-template let-item pTemplate=\"item\">\r\n {{ item.label }}\r\n </ng-template>\r\n </p-listbox>\r\n </div>\r\n</p-popover>\r\n\r\n</div>\r\n\r\n\r\n\r\n <!-- Group Header -->\r\n <div class=\"group-header-wrapper mb-4 pl-8\">\r\n <div class=\"group-header flex justify-between items-center\">\r\n\r\n <div class=\"flex gap-1\">\r\n <button\r\n pButton\r\n icon=\"pi pi-plus\"\r\n type=\"button\"\r\n class=\"p-button-success p-button p-button-sm !p-1.5 rounded-md transition-colors\"\r\n (click)=\"addCondition(groupIndex)\"\r\n pTooltip=\"{{ 'ADD_CONDITION' | translate }}\"\r\n tooltipPosition=\"top\">\r\n </button>\r\n <button\r\n *ngIf=\"groups.length > 1\"\r\n pButton\r\n icon=\"pi pi-times\"\r\n type=\"button\"\r\n class=\"p-button-danger p-button p-button-sm !p-1.5 rounded-md transition-colors\"\r\n (click)=\"removeGroup(groupIndex)\"\r\n pTooltip=\"{{ 'DELETE_GROUP' | translate }}\"\r\n tooltipPosition=\"top\">\r\n </button>\r\n</div>\r\n </div>\r\n </div>\r\n\r\n <!-- Conditions in this group -->\r\n <div *ngFor=\"let condition of group.conditions; let conditionIndex = index\"\r\n class=\"p-1 bg-gray-50 \">\r\n <div class=\"grid grid-cols-1 gap-1 items-center\">\r\n <!-- Field Selector -->\r\n <div class=\"md:col-span-2\">\r\n <div class=\"flex w-full rounded-md overflow-hidden border border-gray-300 bg-white shadow-sm\">\r\n <!-- Field Selector Button -->\r\n <div style=\"align-items: center;display: flex; min-width: 130px;max-width: 130px;\" class=\"flex-shrink-0 \">\r\n <button\r\n type=\"button\"\r\n style=\"height: -webkit-fill-available;\"\r\n class=\"flex items-center justify-between w-full px-3 py-2 text-sm bg-white hover:bg-gray-50 focus:outline-none focus:ring-2 focus:z-10\"\r\n (click)=\"overlay.toggle($event)\">\r\n <span style=\"\r\n display: inline-block;\r\n max-width: 100px;\r\n overflow: hidden;\r\n text-overflow: ellipsis;\r\n white-space: nowrap;\r\n \">{{ getFieldLabel(condition.field) || ('SELECT_FIELD' | translate) }}</span>\r\n <i class=\"pi pi-chevron-down mr-2 ml-2 text-xs\"></i>\r\n </button>\r\n\r\n <!-- Overlay Content -->\r\n <p-popover #overlay appendTo=\"body\">\r\n <div class=\"w-60\">\r\n <p-listbox\r\n tabindex=\"0\"\r\n [options]=\"props['fields']\"\r\n optionLabel=\"label\"\r\n optionValue=\"key\"\r\n [(ngModel)]=\"condition.field\"\r\n (onChange)=\"onFieldChange(condition, groupIndex, conditionIndex); overlay.toggle($event)\"\r\n [style]=\"{ width: '100%' }\">\r\n </p-listbox>\r\n </div>\r\n </p-popover>\r\n </div>\r\n <!-- Operator Button -->\r\n <div style=\"align-items: center;display: flex;\" class=\"flex-shrink-0 border-l border-r border-gray-300\">\r\n <button\r\n type=\"button\"\r\n class=\"flex items-center justify-center w-full px-3 py-2 text-sm bg-gray-50 hover:bg-gray-100 focus:outline-none focus:ring-2 focus:z-10\"\r\n style=\"height: -webkit-fill-available;\"\r\n pTooltip=\"{{ getOperatorLabel(condition.operator).label }}\"\r\n (click)=\"opPopover.toggle($event)\">\r\n <i [class]=\"getOperatorLabel(condition.operator).icon\"></i>\r\n </button>\r\n\r\n <p-popover #opPopover appendTo=\"body\">\r\n <div class=\"w-60\">\r\n <p-listbox\r\n [options]=\"condition.operatorsForField\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n [(ngModel)]=\"condition.operator\"\r\n (onChange)=\"opPopover.toggle($event)\"\r\n [style]=\"{ width: '100%' }\">\r\n </p-listbox>\r\n </div>\r\n </p-popover>\r\n </div>\r\n <!-- Form Field -->\r\n <div style=\"background: #f9fafb\" class=\"flex-grow p-1\">\r\n <formly-form\r\n [form]=\"form\"\r\n [fields]=\"[condition.valueFieldConfig]\"\r\n [model]=\"model\">\r\n </formly-form>\r\n </div>\r\n\r\n\r\n\r\n <!-- Delete Button -->\r\n <div style=\"align-items: center;display: flex;\" class=\"flex-shrink-0\">\r\n <button\r\n style=\"height: -webkit-fill-available;\"\r\n class=\"flex items-center justify-center w-full px-3 py-2 text-sm bg-red-50 text-red-600 hover:bg-red-100 focus:outline-none focus:ring-2 focus:ring-red-500 focus:z-10\"\r\n type=\"button\"\r\n (click)=\"removeCondition(groupIndex, conditionIndex)\"\r\n pTooltip=\"\u062D\u0630\u0641 \u0627\u0644\u0634\u0631\u0637\"\r\n tooltipPosition=\"top\">\r\n <i class=\"pi pi-times\"></i>\r\n </button>\r\n </div>\r\n</div>\r\n </div>\r\n\r\n\r\n </div>\r\n </div>\r\n\r\n <!-- Group Footer -->\r\n <div class=\"group-footer flex justify-between items-center mt-3 pt-3 border-t border-gray-200 \">\r\n <small class=\"text-gray-500\">\r\n {{ group.conditions.length }} \u0634\u0631\u0637 \u0641\u064A \u0647\u0630\u0647 \u0627\u0644\u0645\u062C\u0645\u0648\u0639\u0629\r\n </small>\r\n <small class=\"text-gray-500\">\r\n <span *ngIf=\"groupIndex > 0\">\r\n \u0645\u0631\u062A\u0628\u0637 \u0645\u0639 \u0627\u0644\u0633\u0627\u0628\u0642\u0629 \u0628\u0640 <strong [class.text-blue-600]=\"group.groupLogicalOperator === 'and'\"\r\n [class.text-amber-600]=\"group.groupLogicalOperator === 'or'\">\r\n {{ group.groupLogicalOperator === 'and' ? '\u0648' : '\u0623\u0648' }}\r\n </strong>\r\n </span>\r\n </small>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Actions -->\r\n<div class=\"flex flex-wrap gap-3 mt-6\">\r\n <button\r\n pButton\r\n type=\"button\"\r\n icon=\"pi pi-plus\"\r\n [label]=\"'GROUP' | translate\"\r\n class=\"p-button-outlined p-button-sm !bg-white !border !border-blue-500 !text-blue-600 hover:!bg-blue-50 transition-colors flex items-center gap-2\"\r\n (click)=\"addGroup();\">\r\n </button>\r\n\r\n <button\r\n pButton\r\n type=\"button\"\r\n icon=\"pi pi-plus\"\r\n [label]=\"'CONDITION' | translate\"\r\n class=\"p-button-outlined p-button-sm !bg-white !border !border-blue-500 !text-blue-600 hover:!bg-blue-50 transition-colors flex items-center gap-2\"\r\n (click)=\"addConditionToLastGroup()\">\r\n </button>\r\n\r\n <button\r\n *ngIf=\"groups.length > 0\"\r\n pButton\r\n type=\"button\"\r\n icon=\"pi pi-trash\"\r\n [label]=\"'CLEAR' | translate\"\r\n class=\"p-button-danger p-button-outlined p-button-sm !bg-white !border !border-red-500 !text-red-600 hover:!bg-red-50 transition-colors flex items-center gap-2\"\r\n (click)=\"clearAll()\">\r\n </button>\r\n</div>\r\n\r\n<!-- Empty State -->\r\n<div *ngIf=\"groups.length === 0\" class=\"empty-state text-center p-6 border-2 border-dashed border-gray-300 rounded-xl bg-gray-50\">\r\n <i class=\"pi pi-search text-4xl text-gray-400 mb-3\"></i>\r\n <p class=\"text-gray-500 mb-4\">{{ 'NO_SEARCH_CONDITIONS' | translate }}</p>\r\n <button\r\n pButton\r\n type=\"button\"\r\n icon=\"pi pi-plus\"\r\n [label]=\"'ADD_SEARCH_CONDITION' | translate\"\r\n class=\"p-button-outlined !px-4 !py-2\"\r\n (click)=\"addGroup()\">\r\n </button>\r\n</div>\r\n</div>\r\n", styles: [".vertical-connector{position:relative;display:flex;justify-content:center;margin-bottom:1rem}.vertical-line{position:absolute;top:-1rem;height:1rem;width:2px;background-color:#d1d5db}.group-logical-operator-box{position:relative;padding:.25rem .75rem;border-radius:.375rem;font-weight:500;font-size:.75rem;z-index:10;transition:all .3s ease}.group-logical-operator-box.and{background-color:#dbeafe;color:#1d4ed8;border:1px solid #93c5fd}.group-logical-operator-box.or{background-color:#fef3c7;color:#92400e;border:1px solid #fcd34d}.connector-arrow{position:absolute;top:100%;left:50%;transform:translate(-50%);width:0;height:0;border-left:6px solid transparent;border-right:6px solid transparent}.group-logical-operator-box.and .connector-arrow{border-top:6px solid #93c5fd}.group-logical-operator-box.or .connector-arrow{border-top:6px solid #fcd34d}.border-blue-500{border-color:#93c5fd}.border-or-500{border-color:#fcd34d}.border-t-1{border-top-width:1px}.border-b-1{border-bottom-width:1px}.border-r-1{border-right-width:1px}.p-popover-content{padding:5px!important}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { 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$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "ngmodule", type: SelectModule }, { kind: "directive", type: i2.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "ngmodule", type: InputTextModule }, { kind: "ngmodule", type: ButtonModule }, { kind: "directive", type: i4.ButtonDirective, selector: "[pButton]", inputs: ["iconPos", "loadingIcon", "loading", "severity", "raised", "rounded", "text", "outlined", "size", "plain", "fluid", "label", "icon", "buttonProps"] }, { kind: "component", type: i4.Button, selector: "p-button", inputs: ["type", "iconPos", "icon", "badge", "label", "disabled", "loading", "loadingIcon", "raised", "rounded", "text", "plain", "severity", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "buttonProps", "autofocus", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: DatePickerModule }, { kind: "ngmodule", type: CheckboxModule }, { kind: "ngmodule", type: RadioButtonModule }, { kind: "component", type: FormlyForm, selector: "formly-form", inputs: ["form", "model", "fields", "options"], outputs: ["modelChange"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i6$1.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions", "appendTo"] }, { kind: "ngmodule", type: MenuModule }, { kind: "ngmodule", type: TranslateModule }, { kind: "ngmodule", type: InputGroupModule }, { kind: "ngmodule", type: InputGroupAddonModule }, { kind: "ngmodule", type: PopoverModule }, { kind: "component", type: i6$2.Popover, selector: "p-popover", inputs: ["ariaLabel", "ariaLabelledBy", "dismissable", "style", "styleClass", "appendTo", "autoZIndex", "ariaCloseLabel", "baseZIndex", "focusOnShow", "showTransitionOptions", "hideTransitionOptions"], outputs: ["onShow", "onHide"] }, { kind: "ngmodule", type: ListboxModule }, { kind: "component", type: i7$1.Listbox, selector: "p-listbox, p-listBox, p-list-box", inputs: ["id", "searchMessage", "emptySelectionMessage", "selectionMessage", "autoOptionFocus", "ariaLabel", "selectOnFocus", "searchLocale", "focusOnHover", "filterMessage", "filterFields", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "scrollHeight", "tabindex", "multiple", "styleClass", "listStyle", "listStyleClass", "readonly", "checkbox", "filter", "filterBy", "filterMatchMode", "filterLocale", "metaKeySelection", "dataKey", "showToggleAll", "optionLabel", "optionValue", "optionGroupChildren", "optionGroupLabel", "optionDisabled", "ariaFilterLabel", "filterPlaceHolder", "emptyFilterMessage", "emptyMessage", "group", "options", "filterValue", "selectAll", "striped", "highlightOnSelect", "checkmark", "dragdrop", "fluid"], outputs: ["onChange", "onClick", "onDblClick", "onFilter", "onFocus", "onBlur", "onSelectAllChange", "onLazyLoad", "onDrop"] }, { kind: "pipe", type: i10.TranslatePipe, name: "translate" }] });
|
|
1397
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.8", type: QueryBuilderComponent, isStandalone: true, selector: "formly-query-builder", usesInheritance: true, ngImport: i0, template: "<div>\r\n\r\n <!-- Groups Container with Connecting Lines -->\r\n <div class=\"groups-container\" #groupsContainer>\r\n <div *ngFor=\"let group of groups; let groupIndex = index\"\r\n class=\"group-wrapper relative\"\r\n #groupElement>\r\n\r\n <!-- Vertical Connector Line from Previous Group -->\r\n<div *ngIf=\"groupIndex > 0\" class=\"vertical-connector\">\r\n <div class=\"vertical-line\"></div>\r\n\r\n <!-- Operator Button -->\r\n <button\r\n type=\"button\"\r\n class=\"group-logical-operator-box\"\r\n [class.and]=\"group.groupLogicalOperator === 'and'\"\r\n [class.or]=\"group.groupLogicalOperator === 'or'\"\r\n (click)=\"opPopover.toggle($event)\">\r\n <span class=\"operator-text\">\r\n {{ getLogicalOperatorText(group.groupLogicalOperator || 'and') }}\r\n </span>\r\n <div class=\"connector-arrow\"></div>\r\n </button>\r\n\r\n <!-- Popover -->\r\n <p-popover #opPopover appendTo=\"body\">\r\n <div class=\"w-12rem\">\r\n <p-listbox\r\n [options]=\"logicalOperators\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n [(ngModel)]=\"group.groupLogicalOperator\"\r\n (onChange)=\" opPopover.toggle($event)\"\r\n [style]=\"{ width: '100%' }\">\r\n </p-listbox>\r\n </div>\r\n </p-popover>\r\n</div>\r\n\r\n <div class=\"group-container mb-6 p-1 bg-white rounded-lg border-l-4 border-t-1 border-b-1 border-r-1 shadow-sm transition-all duration-300 relative\"\r\n [class.border-blue-500]=\"group.logicalOperator === 'and'\"\r\n [class.border-or-500]=\"group.logicalOperator === 'or'\"\r\n [class.pulse]=\"groupIndex === 0\">\r\n\r\n <!-- Rounded Button for \"\u0631\u0628\u0637 \u0627\u0644\u0634\u0631\u0648\u0637\" on left border -->\r\n<div\r\n class=\"absolute -left-4 top-1/2 transform -translate-y-1/2 z-10 transition-all duration-300\"\r\n\r\n>\r\n\r\n\r\n\r\n<!-- Logical Operator Popover Button -->\r\n<p-button\r\n [severity]=\"group.logicalOperator === 'and' ? 'success' : 'info'\"\r\n [styleClass]=\"group.logicalOperator === 'and'\r\n ? 'p-button-icon-only p-button-rounded p-button-sm logical-and'\r\n : 'p-button-icon-only p-button-rounded p-button-sm logical-or'\"\r\n (click)=\"opPopover.toggle($event)\">\r\n {{group.logicalOperator === 'and' ? ('and' | translate) : ('or' | translate)}}\r\n</p-button>\r\n\r\n<!-- Popover for Operator Selection -->\r\n<p-popover #opPopover appendTo=\"body\">\r\n <div class=\"w-10rem\">\r\n <p-listbox\r\n [options]=\"[\r\n { label: 'and' | translate, value: 'and' },\r\n { label: 'or' | translate, value: 'or' }\r\n ]\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n [(ngModel)]=\"group.logicalOperator\"\r\n (onChange)=\"updateValue(); opPopover.toggle($event)\"\r\n [style]=\"{ width: '100%' }\">\r\n <ng-template let-item pTemplate=\"item\">\r\n {{ item.label }}\r\n </ng-template>\r\n </p-listbox>\r\n </div>\r\n</p-popover>\r\n\r\n</div>\r\n\r\n\r\n\r\n <!-- Group Header -->\r\n <div class=\"group-header-wrapper mb-4 pl-8\">\r\n <div class=\"group-header flex justify-between items-center\">\r\n\r\n <div class=\"flex gap-1\">\r\n <button\r\n pButton\r\n icon=\"pi pi-plus\"\r\n type=\"button\"\r\n class=\"p-button-success p-button p-button-sm !p-1.5 rounded-md transition-colors\"\r\n (click)=\"addCondition(groupIndex)\"\r\n pTooltip=\"{{ 'ADD_CONDITION' | translate }}\"\r\n tooltipPosition=\"top\">\r\n </button>\r\n <button\r\n *ngIf=\"groups.length > 1\"\r\n pButton\r\n icon=\"pi pi-times\"\r\n type=\"button\"\r\n class=\"p-button-danger p-button p-button-sm !p-1.5 rounded-md transition-colors\"\r\n (click)=\"removeGroup(groupIndex)\"\r\n pTooltip=\"{{ 'DELETE_GROUP' | translate }}\"\r\n tooltipPosition=\"top\">\r\n </button>\r\n</div>\r\n </div>\r\n </div>\r\n\r\n <!-- Conditions in this group -->\r\n <div *ngFor=\"let condition of group.conditions; let conditionIndex = index\"\r\n class=\"p-1 bg-gray-50 \">\r\n <div class=\"grid grid-cols-1 gap-1 items-center\">\r\n <!-- Field Selector -->\r\n <div class=\"md:col-span-2\">\r\n <div class=\"flex w-full rounded-md overflow-hidden border border-gray-300 bg-white shadow-sm\">\r\n <!-- Field Selector Button -->\r\n <div style=\"align-items: center;display: flex; min-width: 130px;max-width: 130px;\" class=\"flex-shrink-0 \">\r\n <button\r\n type=\"button\"\r\n style=\"height: -webkit-fill-available;\"\r\n class=\"flex items-center justify-between w-full px-3 py-2 text-sm bg-white hover:bg-gray-50 focus:outline-none focus:ring-2 focus:z-10\"\r\n (click)=\"overlay.toggle($event)\">\r\n <span style=\"\r\n display: inline-block;\r\n max-width: 100px;\r\n overflow: hidden;\r\n text-overflow: ellipsis;\r\n white-space: nowrap;\r\n \">{{ getFieldLabel(condition.field) || ('SELECT_FIELD' | translate) }}</span>\r\n <i class=\"pi pi-chevron-down mr-2 ml-2 text-xs\"></i>\r\n </button>\r\n\r\n <!-- Overlay Content -->\r\n <p-popover #overlay appendTo=\"body\">\r\n <div class=\"w-60\">\r\n <p-listbox\r\n tabindex=\"0\"\r\n [options]=\"props['fields']\"\r\n optionLabel=\"label\"\r\n optionValue=\"key\"\r\n [(ngModel)]=\"condition.field\"\r\n (onChange)=\"onFieldChange(condition, groupIndex, conditionIndex); overlay.toggle($event)\"\r\n [style]=\"{ width: '100%' }\">\r\n </p-listbox>\r\n </div>\r\n </p-popover>\r\n </div>\r\n <!-- Operator Button -->\r\n <div style=\"align-items: center;display: flex;\" class=\"flex-shrink-0 border-l border-r border-gray-300\">\r\n <button\r\n type=\"button\"\r\n class=\"flex items-center justify-center w-full px-3 py-2 text-sm bg-gray-50 hover:bg-gray-100 focus:outline-none focus:ring-2 focus:z-10\"\r\n style=\"height: -webkit-fill-available;\"\r\n pTooltip=\"{{ getOperatorLabel(condition.operator).label }}\"\r\n (click)=\"opPopover.toggle($event)\">\r\n <i [class]=\"getOperatorLabel(condition.operator).icon\"></i>\r\n </button>\r\n\r\n <p-popover #opPopover appendTo=\"body\">\r\n <div class=\"w-60\">\r\n <p-listbox\r\n [options]=\"condition.operatorsForField\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n [(ngModel)]=\"condition.operator\"\r\n (onChange)=\"opPopover.toggle($event)\"\r\n [style]=\"{ width: '100%' }\">\r\n </p-listbox>\r\n </div>\r\n </p-popover>\r\n </div>\r\n <!-- Form Field -->\r\n <div style=\"background: #f9fafb\" class=\"flex-grow p-1\">\r\n <formly-form\r\n [form]=\"form\"\r\n [fields]=\"[condition.valueFieldConfig]\"\r\n [model]=\"model\">\r\n </formly-form>\r\n </div>\r\n\r\n\r\n\r\n <!-- Delete Button -->\r\n <div style=\"align-items: center;display: flex;\" class=\"flex-shrink-0\">\r\n <button\r\n style=\"height: -webkit-fill-available;\"\r\n class=\"flex items-center justify-center w-full px-3 py-2 text-sm bg-red-50 text-red-600 hover:bg-red-100 focus:outline-none focus:ring-2 focus:ring-red-500 focus:z-10\"\r\n type=\"button\"\r\n (click)=\"removeCondition(groupIndex, conditionIndex)\"\r\n pTooltip=\"\u062D\u0630\u0641 \u0627\u0644\u0634\u0631\u0637\"\r\n tooltipPosition=\"top\">\r\n <i class=\"pi pi-times\"></i>\r\n </button>\r\n </div>\r\n</div>\r\n </div>\r\n\r\n\r\n </div>\r\n </div>\r\n\r\n <!-- Group Footer -->\r\n <div class=\"group-footer flex justify-between items-center mt-3 pt-3 border-t border-gray-200 \">\r\n <small class=\"text-gray-500\">\r\n {{ group.conditions.length }} \u0634\u0631\u0637 \u0641\u064A \u0647\u0630\u0647 \u0627\u0644\u0645\u062C\u0645\u0648\u0639\u0629\r\n </small>\r\n <small class=\"text-gray-500\">\r\n <span *ngIf=\"groupIndex > 0\">\r\n \u0645\u0631\u062A\u0628\u0637 \u0645\u0639 \u0627\u0644\u0633\u0627\u0628\u0642\u0629 \u0628\u0640 <strong [class.text-blue-600]=\"group.groupLogicalOperator === 'and'\"\r\n [class.text-amber-600]=\"group.groupLogicalOperator === 'or'\">\r\n {{ group.groupLogicalOperator === 'and' ? '\u0648' : '\u0623\u0648' }}\r\n </strong>\r\n </span>\r\n </small>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Actions -->\r\n<div class=\"flex flex-wrap gap-3 mt-6\">\r\n <button\r\n pButton\r\n type=\"button\"\r\n icon=\"pi pi-plus\"\r\n [label]=\"'GROUP' | translate\"\r\n class=\"p-button-outlined p-button-sm !bg-white !border !border-blue-500 !text-blue-600 hover:!bg-blue-50 transition-colors flex items-center gap-2\"\r\n (click)=\"addGroup();\">\r\n </button>\r\n\r\n <button\r\n pButton\r\n type=\"button\"\r\n icon=\"pi pi-plus\"\r\n [label]=\"'CONDITION' | translate\"\r\n class=\"p-button-outlined p-button-sm !bg-white !border !border-blue-500 !text-blue-600 hover:!bg-blue-50 transition-colors flex items-center gap-2\"\r\n (click)=\"addConditionToLastGroup()\">\r\n </button>\r\n\r\n <button\r\n *ngIf=\"groups.length > 0\"\r\n pButton\r\n type=\"button\"\r\n icon=\"pi pi-trash\"\r\n [label]=\"'CLEAR' | translate\"\r\n class=\"p-button-danger p-button-outlined p-button-sm !bg-white !border !border-red-500 !text-red-600 hover:!bg-red-50 transition-colors flex items-center gap-2\"\r\n (click)=\"clearAll()\">\r\n </button>\r\n</div>\r\n\r\n<!-- Empty State -->\r\n<div *ngIf=\"groups.length === 0\" class=\"empty-state text-center p-6 border-2 border-dashed border-gray-300 rounded-xl bg-gray-50\">\r\n <i class=\"pi pi-search text-4xl text-gray-400 mb-3\"></i>\r\n <p class=\"text-gray-500 mb-4\">{{ 'NO_SEARCH_CONDITIONS' | translate }}</p>\r\n <button\r\n pButton\r\n type=\"button\"\r\n icon=\"pi pi-plus\"\r\n [label]=\"'ADD_SEARCH_CONDITION' | translate\"\r\n class=\"p-button-outlined !px-4 !py-2\"\r\n (click)=\"addGroup()\">\r\n </button>\r\n</div>\r\n</div>\r\n", styles: [".vertical-connector{position:relative;display:flex;justify-content:center;margin-bottom:1rem}.vertical-line{position:absolute;top:-1rem;height:1rem;width:2px;background-color:#d1d5db}.group-logical-operator-box{position:relative;padding:.25rem .75rem;border-radius:.375rem;font-weight:500;font-size:.75rem;z-index:10;transition:all .3s ease}.group-logical-operator-box.and{background-color:#dbeafe;color:#1d4ed8;border:1px solid #93c5fd}.group-logical-operator-box.or{background-color:#fef3c7;color:#92400e;border:1px solid #fcd34d}.connector-arrow{position:absolute;top:100%;left:50%;transform:translate(-50%);width:0;height:0;border-left:6px solid transparent;border-right:6px solid transparent}.group-logical-operator-box.and .connector-arrow{border-top:6px solid #93c5fd}.group-logical-operator-box.or .connector-arrow{border-top:6px solid #fcd34d}.border-blue-500{border-color:#93c5fd}.border-or-500{border-color:#fcd34d}.border-t-1{border-top-width:1px}.border-b-1{border-bottom-width:1px}.border-r-1{border-right-width:1px}.p-popover-content{padding:5px!important}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { 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$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "ngmodule", type: SelectModule }, { kind: "directive", type: i2.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "ngmodule", type: InputTextModule }, { kind: "ngmodule", type: ButtonModule }, { kind: "directive", type: i4.ButtonDirective, selector: "[pButton]", inputs: ["iconPos", "loadingIcon", "loading", "severity", "raised", "rounded", "text", "outlined", "size", "plain", "fluid", "label", "icon", "buttonProps"] }, { kind: "component", type: i4.Button, selector: "p-button", inputs: ["type", "iconPos", "icon", "badge", "label", "disabled", "loading", "loadingIcon", "raised", "rounded", "text", "plain", "severity", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "buttonProps", "autofocus", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: DatePickerModule }, { kind: "ngmodule", type: CheckboxModule }, { kind: "ngmodule", type: RadioButtonModule }, { kind: "component", type: FormlyForm, selector: "formly-form", inputs: ["form", "model", "fields", "options"], outputs: ["modelChange"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i6$1.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions", "appendTo"] }, { kind: "ngmodule", type: MenuModule }, { kind: "ngmodule", type: TranslateModule }, { kind: "ngmodule", type: InputGroupModule }, { kind: "ngmodule", type: InputGroupAddonModule }, { kind: "ngmodule", type: PopoverModule }, { kind: "component", type: i6$2.Popover, selector: "p-popover", inputs: ["ariaLabel", "ariaLabelledBy", "dismissable", "style", "styleClass", "appendTo", "autoZIndex", "ariaCloseLabel", "baseZIndex", "focusOnShow", "showTransitionOptions", "hideTransitionOptions"], outputs: ["onShow", "onHide"] }, { kind: "ngmodule", type: ListboxModule }, { kind: "component", type: i7$1.Listbox, selector: "p-listbox, p-listBox, p-list-box", inputs: ["id", "searchMessage", "emptySelectionMessage", "selectionMessage", "autoOptionFocus", "ariaLabel", "selectOnFocus", "searchLocale", "focusOnHover", "filterMessage", "filterFields", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "scrollHeight", "tabindex", "multiple", "styleClass", "listStyle", "listStyleClass", "readonly", "checkbox", "filter", "filterBy", "filterMatchMode", "filterLocale", "metaKeySelection", "dataKey", "showToggleAll", "optionLabel", "optionValue", "optionGroupChildren", "optionGroupLabel", "optionDisabled", "ariaFilterLabel", "filterPlaceHolder", "emptyFilterMessage", "emptyMessage", "group", "options", "filterValue", "selectAll", "striped", "highlightOnSelect", "checkmark", "dragdrop", "fluid"], outputs: ["onChange", "onClick", "onDblClick", "onFilter", "onFocus", "onBlur", "onSelectAllChange", "onLazyLoad", "onDrop"] }, { kind: "pipe", type: i8$1.TranslatePipe, name: "translate" }] });
|
|
1441
1398
|
}
|
|
1442
1399
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: QueryBuilderComponent, decorators: [{
|
|
1443
1400
|
type: Component,
|
|
@@ -1543,7 +1500,7 @@ class TabTypeComponent extends FieldType {
|
|
|
1543
1500
|
</p-tabpanel>
|
|
1544
1501
|
</p-tabpanels>
|
|
1545
1502
|
</p-tabs>
|
|
1546
|
-
`, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { 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: TabsModule }, { kind: "component", type: i2$2.Tabs, selector: "p-tabs", inputs: ["value", "scrollable", "lazy", "selectOnFocus", "showNavigators", "tabindex"], outputs: ["valueChange"] }, { kind: "component", type: i2$2.TabPanels, selector: "p-tabpanels" }, { kind: "component", type: i2$2.TabPanel, selector: "p-tabpanel", inputs: ["value"], outputs: ["valueChange"] }, { kind: "component", type: i2$2.TabList, selector: "p-tablist" }, { kind: "component", type: i2$2.Tab, selector: "p-tab", inputs: ["value", "disabled"], outputs: ["valueChange"] }, { kind: "ngmodule", type: BadgeModule }, { kind: "component", type: i9.Badge, selector: "p-badge", inputs: ["styleClass", "badgeSize", "size", "severity", "value", "badgeDisabled"] }, { kind: "component", type: FormlyField, selector: "formly-field", inputs: ["field"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type:
|
|
1503
|
+
`, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { 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: TabsModule }, { kind: "component", type: i2$2.Tabs, selector: "p-tabs", inputs: ["value", "scrollable", "lazy", "selectOnFocus", "showNavigators", "tabindex"], outputs: ["valueChange"] }, { kind: "component", type: i2$2.TabPanels, selector: "p-tabpanels" }, { kind: "component", type: i2$2.TabPanel, selector: "p-tabpanel", inputs: ["value"], outputs: ["valueChange"] }, { kind: "component", type: i2$2.TabList, selector: "p-tablist" }, { kind: "component", type: i2$2.Tab, selector: "p-tab", inputs: ["value", "disabled"], outputs: ["valueChange"] }, { kind: "ngmodule", type: BadgeModule }, { kind: "component", type: i9.Badge, selector: "p-badge", inputs: ["styleClass", "badgeSize", "size", "severity", "value", "badgeDisabled"] }, { kind: "component", type: FormlyField, selector: "formly-field", inputs: ["field"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i8$1.TranslatePipe, name: "translate" }] });
|
|
1547
1504
|
}
|
|
1548
1505
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: TabTypeComponent, decorators: [{
|
|
1549
1506
|
type: Component,
|
|
@@ -1801,311 +1758,309 @@ class ColumnsBuilderComponent extends FieldType {
|
|
|
1801
1758
|
}
|
|
1802
1759
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: ColumnsBuilderComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
|
|
1803
1760
|
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.8", type: ColumnsBuilderComponent, isStandalone: true, selector: "formly-columns-builder", usesInheritance: true, ngImport: i0, template: `
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
|
|
1816
|
-
|
|
1817
|
-
|
|
1818
|
-
|
|
1819
|
-
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
|
|
1825
|
-
|
|
1826
|
-
|
|
1827
|
-
|
|
1828
|
-
|
|
1829
|
-
|
|
1830
|
-
|
|
1831
|
-
|
|
1832
|
-
|
|
1833
|
-
|
|
1834
|
-
|
|
1835
|
-
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
|
|
1843
|
-
|
|
1844
|
-
|
|
1845
|
-
|
|
1846
|
-
|
|
1847
|
-
|
|
1848
|
-
|
|
1849
|
-
|
|
1850
|
-
|
|
1761
|
+
<div>
|
|
1762
|
+
<!-- Header -->
|
|
1763
|
+
<div class="mb-6">
|
|
1764
|
+
<h5 class="text-lg font-semibold text-gray-900 mb-2">{{ props.label || ('COLUMNS_MANAGEMENT' | translate) }}</h5>
|
|
1765
|
+
<p class="text-gray-600 text-sm">{{ props.description || ('COLUMNS_DESCRIPTION' | translate) }}</p>
|
|
1766
|
+
</div>
|
|
1767
|
+
|
|
1768
|
+
<!-- Quick Actions -->
|
|
1769
|
+
<div class="flex flex-wrap gap-2 mb-6">
|
|
1770
|
+
<button
|
|
1771
|
+
type="button"
|
|
1772
|
+
(click)="toggleAll(true)"
|
|
1773
|
+
class="inline-flex items-center gap-2 px-3 py-2 text-sm font-medium text-gray-700 bg-white border border-gray-300 rounded-lg hover:bg-gray-50 transition-colors"
|
|
1774
|
+
>
|
|
1775
|
+
<i class="pi pi-eye"></i>
|
|
1776
|
+
{{ 'SHOW_ALL' | translate }}
|
|
1777
|
+
</button>
|
|
1778
|
+
<button
|
|
1779
|
+
type="button"
|
|
1780
|
+
(click)="toggleAll(false)"
|
|
1781
|
+
class="inline-flex items-center gap-2 px-3 py-2 text-sm font-medium text-gray-700 bg-white border border-gray-300 rounded-lg hover:bg-gray-50 transition-colors"
|
|
1782
|
+
>
|
|
1783
|
+
<i class="pi pi-eye-slash"></i>
|
|
1784
|
+
{{ 'HIDE_ALL' | translate }}
|
|
1785
|
+
</button>
|
|
1786
|
+
<button
|
|
1787
|
+
type="button"
|
|
1788
|
+
(click)="resetToDefault()"
|
|
1789
|
+
class="inline-flex items-center gap-2 px-3 py-2 text-sm font-medium text-gray-700 bg-white border border-gray-300 rounded-lg hover:bg-gray-50 transition-colors"
|
|
1790
|
+
>
|
|
1791
|
+
<i class="pi pi-refresh"></i>
|
|
1792
|
+
{{ 'RESET_TO_DEFAULT' | translate }}
|
|
1793
|
+
</button>
|
|
1794
|
+
</div>
|
|
1795
|
+
|
|
1796
|
+
<!-- Drag Info -->
|
|
1797
|
+
<div class="mb-4 p-2 bg-blue-50 border border-blue-200 rounded text-sm text-blue-700">
|
|
1798
|
+
<i class="pi pi-info-circle mr-2"></i>
|
|
1799
|
+
{{ 'DRAG_COLUMNS_INFO' | translate }}
|
|
1800
|
+
</div>
|
|
1801
|
+
|
|
1802
|
+
<!-- Columns List -->
|
|
1803
|
+
<div class="space-y-3">
|
|
1804
|
+
<div *ngIf="columns.length === 0" class="text-center py-8 px-4 border-2 border-dashed border-gray-300 rounded-lg bg-gray-50">
|
|
1805
|
+
<i class="pi pi-table text-4xl text-gray-400 mb-3"></i>
|
|
1806
|
+
<p class="text-gray-500">{{ 'NO_COLUMNS_AVAILABLE' | translate }}</p>
|
|
1807
|
+
</div>
|
|
1851
1808
|
|
|
1852
|
-
|
|
1853
|
-
|
|
1809
|
+
<div *ngFor="let column of columns; let i = index"
|
|
1810
|
+
class="bg-gray-50 rounded-lg border border-gray-200 p-1 transition-colors hover:bg-gray-100"
|
|
1811
|
+
draggable="true"
|
|
1812
|
+
(dragstart)="onDragStart($event, i)"
|
|
1813
|
+
(dragover)="onDragOver($event)"
|
|
1814
|
+
(drop)="onDrop($event, i)"
|
|
1815
|
+
(dragenter)="onDragEnter($event)"
|
|
1816
|
+
(dragleave)="onDragLeave($event)">
|
|
1817
|
+
|
|
1818
|
+
<div class="grid grid-cols-12 gap-4 items-center">
|
|
1819
|
+
<!-- Drag Handle -->
|
|
1820
|
+
<div class="col-span-1 flex justify-center cursor-move text-gray-400 hover:text-gray-600"
|
|
1854
1821
|
draggable="true"
|
|
1855
|
-
(dragstart)="onDragStart($event, i)"
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
(dragenter)="onDragEnter($event)"
|
|
1859
|
-
(dragleave)="onDragLeave($event)">
|
|
1860
|
-
|
|
1861
|
-
<div class="grid grid-cols-12 gap-4 items-center">
|
|
1862
|
-
<!-- Drag Handle -->
|
|
1863
|
-
<div class="col-span-1 flex justify-center cursor-move text-gray-400 hover:text-gray-600"
|
|
1864
|
-
draggable="true"
|
|
1865
|
-
(dragstart)="onDragStart($event, i)">
|
|
1866
|
-
<i class="pi pi-bars"></i>
|
|
1867
|
-
</div>
|
|
1868
|
-
|
|
1869
|
-
<!-- Visibility Toggle -->
|
|
1870
|
-
<div class="col-span-1 flex justify-center">
|
|
1871
|
-
<p-checkbox
|
|
1872
|
-
[binary]="true"
|
|
1873
|
-
[formControl]="getColumnControl(column.key, 'isVisible')"
|
|
1874
|
-
[inputId]="'visible_' + column.key"
|
|
1875
|
-
styleClass="[&>div]:border-gray-300 [&>div]:hover:border-gray-400"
|
|
1876
|
-
(onChange)="onFormChange()"
|
|
1877
|
-
>
|
|
1878
|
-
</p-checkbox>
|
|
1879
|
-
</div>
|
|
1822
|
+
(dragstart)="onDragStart($event, i)">
|
|
1823
|
+
<i class="pi pi-bars"></i>
|
|
1824
|
+
</div>
|
|
1880
1825
|
|
|
1881
|
-
|
|
1882
|
-
|
|
1883
|
-
|
|
1884
|
-
|
|
1885
|
-
|
|
1886
|
-
|
|
1887
|
-
|
|
1826
|
+
<!-- Visibility Toggle -->
|
|
1827
|
+
<div class="col-span-1 flex justify-center">
|
|
1828
|
+
<p-checkbox
|
|
1829
|
+
[binary]="true"
|
|
1830
|
+
[formControl]="getColumnControl(column.key, 'isVisible')"
|
|
1831
|
+
[inputId]="'visible_' + column.key"
|
|
1832
|
+
styleClass="[&>div]:border-gray-300 [&>div]:hover:border-gray-400"
|
|
1833
|
+
(onChange)="onFormChange()"
|
|
1834
|
+
>
|
|
1835
|
+
</p-checkbox>
|
|
1836
|
+
</div>
|
|
1888
1837
|
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
|
|
1896
|
-
class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 text-sm"
|
|
1897
|
-
(blur)="onFormChange()"
|
|
1898
|
-
>
|
|
1899
|
-
</div>
|
|
1838
|
+
<!-- Column Info -->
|
|
1839
|
+
<div class="col-span-12 md:col-span-4">
|
|
1840
|
+
<label [for]="'visible_' + column.key" class="block font-medium text-gray-900 cursor-pointer hover:text-blue-600">
|
|
1841
|
+
{{ column.label }}
|
|
1842
|
+
</label>
|
|
1843
|
+
<p class="text-xs text-gray-500 mt-1">{{ column.key }}</p>
|
|
1844
|
+
</div>
|
|
1900
1845
|
|
|
1901
|
-
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
|
|
1909
|
-
|
|
1910
|
-
|
|
1911
|
-
|
|
1912
|
-
(onChange)="onFormChange()"
|
|
1913
|
-
>
|
|
1914
|
-
</p-select>
|
|
1915
|
-
</div>
|
|
1916
|
-
<span *ngIf="!column.aggregatable && isColumnVisible(column.key)" class="text-xs text-gray-500">
|
|
1917
|
-
No aggregates available
|
|
1918
|
-
</span>
|
|
1919
|
-
</div>
|
|
1920
|
-
</div>
|
|
1846
|
+
<!-- Display Name -->
|
|
1847
|
+
<div class="col-span-12 md:col-span-3">
|
|
1848
|
+
<input
|
|
1849
|
+
*ngIf="isColumnVisible(column.key)"
|
|
1850
|
+
type="text"
|
|
1851
|
+
[formControl]="getColumnControl(column.key, 'displayName')"
|
|
1852
|
+
[placeholder]="column.label"
|
|
1853
|
+
class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 text-sm"
|
|
1854
|
+
(blur)="onFormChange()"
|
|
1855
|
+
>
|
|
1856
|
+
</div>
|
|
1921
1857
|
|
|
1922
|
-
|
|
1923
|
-
|
|
1924
|
-
|
|
1925
|
-
<
|
|
1926
|
-
|
|
1927
|
-
|
|
1928
|
-
|
|
1929
|
-
|
|
1930
|
-
|
|
1931
|
-
|
|
1858
|
+
<!-- Aggregate Function -->
|
|
1859
|
+
<div class="col-span-12 md:col-span-3">
|
|
1860
|
+
<div *ngIf="column.aggregatable && isColumnVisible(column.key)">
|
|
1861
|
+
<p-select
|
|
1862
|
+
[options]="aggregateFunctions"
|
|
1863
|
+
optionLabel="label"
|
|
1864
|
+
optionValue="value"
|
|
1865
|
+
[formControl]="getColumnControl(column.key, 'aggregateFunction')"
|
|
1866
|
+
[placeholder]="'SELECT_AGGREGATE' | translate"
|
|
1867
|
+
[showClear]="true"
|
|
1868
|
+
styleClass="w-full"
|
|
1869
|
+
(onChange)="onFormChange()"
|
|
1870
|
+
>
|
|
1871
|
+
</p-select>
|
|
1932
1872
|
</div>
|
|
1873
|
+
<span *ngIf="!column.aggregatable && isColumnVisible(column.key)" class="text-xs text-gray-500">
|
|
1874
|
+
{{ 'NO_AGGREGATES_AVAILABLE' | translate }}
|
|
1875
|
+
</span>
|
|
1933
1876
|
</div>
|
|
1934
1877
|
</div>
|
|
1935
1878
|
|
|
1936
|
-
<!--
|
|
1937
|
-
<div
|
|
1938
|
-
|
|
1939
|
-
|
|
1940
|
-
|
|
1941
|
-
|
|
1942
|
-
|
|
1943
|
-
<i class="pi pi-chart-line"></i>
|
|
1944
|
-
{{ numericColumnsCount }} numeric
|
|
1945
|
-
</span>
|
|
1946
|
-
<span class="inline-flex items-center gap-1 text-blue-600">
|
|
1947
|
-
<i class="pi pi-calculator"></i>
|
|
1948
|
-
{{ aggregatedColumnsCount }} aggregated
|
|
1879
|
+
<!-- Aggregate Info -->
|
|
1880
|
+
<div *ngIf="hasAggregateFunction(column.key) && isColumnVisible(column.key)"
|
|
1881
|
+
class="mt-3 p-3 bg-blue-50 border border-blue-200 rounded-lg">
|
|
1882
|
+
<div class="flex items-center gap-2">
|
|
1883
|
+
<i class="pi pi-info-circle text-blue-500 text-sm"></i>
|
|
1884
|
+
<span class="text-sm text-blue-800">
|
|
1885
|
+
{{ 'AGGREGATE_INFO' | translate:{function: getAggregateLabel(getAggregateFunctionValue(column.key))} }}
|
|
1949
1886
|
</span>
|
|
1950
1887
|
</div>
|
|
1951
1888
|
</div>
|
|
1952
1889
|
</div>
|
|
1953
|
-
|
|
1890
|
+
</div>
|
|
1891
|
+
|
|
1892
|
+
<!-- Summary -->
|
|
1893
|
+
<div class="flex flex-col sm:flex-row justify-between items-center gap-4 mt-6 pt-4 border-t border-gray-200">
|
|
1894
|
+
<span class="text-sm text-gray-600">
|
|
1895
|
+
{{ 'COLUMNS_VISIBLE_COUNT' | translate:{visible: visibleColumnsCount, total: columns.length} }}
|
|
1896
|
+
</span>
|
|
1897
|
+
<div class="flex gap-4 text-sm">
|
|
1898
|
+
<span class="inline-flex items-center gap-1 text-green-600">
|
|
1899
|
+
<i class="pi pi-chart-line"></i>
|
|
1900
|
+
{{ numericColumnsCount }} {{ 'NUMERIC' | translate }}
|
|
1901
|
+
</span>
|
|
1902
|
+
<span class="inline-flex items-center gap-1 text-blue-600">
|
|
1903
|
+
<i class="pi pi-calculator"></i>
|
|
1904
|
+
{{ aggregatedColumnsCount }} {{ 'AGGREGATED' | translate }}
|
|
1905
|
+
</span>
|
|
1906
|
+
</div>
|
|
1907
|
+
</div>
|
|
1908
|
+
</div>
|
|
1909
|
+
`, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { 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$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: i2$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i2$1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: SelectModule }, { kind: "component", type: i3.Select, selector: "p-select", inputs: ["id", "scrollHeight", "filter", "panelStyle", "styleClass", "panelStyleClass", "readonly", "editable", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "filterValue", "options", "appendTo"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }, { kind: "ngmodule", type: InputTextModule }, { kind: "ngmodule", type: ButtonModule }, { kind: "ngmodule", type: DatePickerModule }, { kind: "ngmodule", type: CheckboxModule }, { kind: "component", type: i4$1.Checkbox, selector: "p-checkbox, p-checkBox, p-check-box", inputs: ["value", "binary", "ariaLabelledBy", "ariaLabel", "tabindex", "inputId", "inputStyle", "styleClass", "inputClass", "indeterminate", "formControl", "checkboxIcon", "readonly", "autofocus", "trueValue", "falseValue", "variant", "size"], outputs: ["onChange", "onFocus", "onBlur"] }, { kind: "ngmodule", type: RadioButtonModule }, { kind: "ngmodule", type: TooltipModule }, { kind: "ngmodule", type: MenuModule }, { kind: "ngmodule", type: TranslateModule }, { kind: "ngmodule", type: InputGroupModule }, { kind: "ngmodule", type: InputGroupAddonModule }, { kind: "ngmodule", type: PopoverModule }, { kind: "ngmodule", type: ListboxModule }, { kind: "pipe", type: i8$1.TranslatePipe, name: "translate" }] });
|
|
1954
1910
|
}
|
|
1955
1911
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: ColumnsBuilderComponent, decorators: [{
|
|
1956
1912
|
type: Component,
|
|
1957
1913
|
args: [{
|
|
1958
1914
|
selector: 'formly-columns-builder',
|
|
1959
1915
|
template: `
|
|
1960
|
-
|
|
1961
|
-
|
|
1962
|
-
|
|
1963
|
-
|
|
1964
|
-
|
|
1965
|
-
|
|
1966
|
-
|
|
1967
|
-
|
|
1968
|
-
|
|
1969
|
-
|
|
1970
|
-
|
|
1971
|
-
|
|
1972
|
-
|
|
1973
|
-
|
|
1974
|
-
|
|
1975
|
-
|
|
1976
|
-
|
|
1977
|
-
|
|
1978
|
-
|
|
1979
|
-
|
|
1980
|
-
|
|
1981
|
-
|
|
1982
|
-
|
|
1983
|
-
|
|
1984
|
-
|
|
1985
|
-
|
|
1986
|
-
|
|
1987
|
-
|
|
1988
|
-
|
|
1989
|
-
|
|
1990
|
-
|
|
1991
|
-
|
|
1992
|
-
|
|
1993
|
-
|
|
1994
|
-
|
|
1995
|
-
|
|
1996
|
-
|
|
1997
|
-
|
|
1998
|
-
|
|
1999
|
-
|
|
2000
|
-
|
|
2001
|
-
|
|
2002
|
-
|
|
2003
|
-
|
|
2004
|
-
|
|
2005
|
-
|
|
2006
|
-
|
|
1916
|
+
<div>
|
|
1917
|
+
<!-- Header -->
|
|
1918
|
+
<div class="mb-6">
|
|
1919
|
+
<h5 class="text-lg font-semibold text-gray-900 mb-2">{{ props.label || ('COLUMNS_MANAGEMENT' | translate) }}</h5>
|
|
1920
|
+
<p class="text-gray-600 text-sm">{{ props.description || ('COLUMNS_DESCRIPTION' | translate) }}</p>
|
|
1921
|
+
</div>
|
|
1922
|
+
|
|
1923
|
+
<!-- Quick Actions -->
|
|
1924
|
+
<div class="flex flex-wrap gap-2 mb-6">
|
|
1925
|
+
<button
|
|
1926
|
+
type="button"
|
|
1927
|
+
(click)="toggleAll(true)"
|
|
1928
|
+
class="inline-flex items-center gap-2 px-3 py-2 text-sm font-medium text-gray-700 bg-white border border-gray-300 rounded-lg hover:bg-gray-50 transition-colors"
|
|
1929
|
+
>
|
|
1930
|
+
<i class="pi pi-eye"></i>
|
|
1931
|
+
{{ 'SHOW_ALL' | translate }}
|
|
1932
|
+
</button>
|
|
1933
|
+
<button
|
|
1934
|
+
type="button"
|
|
1935
|
+
(click)="toggleAll(false)"
|
|
1936
|
+
class="inline-flex items-center gap-2 px-3 py-2 text-sm font-medium text-gray-700 bg-white border border-gray-300 rounded-lg hover:bg-gray-50 transition-colors"
|
|
1937
|
+
>
|
|
1938
|
+
<i class="pi pi-eye-slash"></i>
|
|
1939
|
+
{{ 'HIDE_ALL' | translate }}
|
|
1940
|
+
</button>
|
|
1941
|
+
<button
|
|
1942
|
+
type="button"
|
|
1943
|
+
(click)="resetToDefault()"
|
|
1944
|
+
class="inline-flex items-center gap-2 px-3 py-2 text-sm font-medium text-gray-700 bg-white border border-gray-300 rounded-lg hover:bg-gray-50 transition-colors"
|
|
1945
|
+
>
|
|
1946
|
+
<i class="pi pi-refresh"></i>
|
|
1947
|
+
{{ 'RESET_TO_DEFAULT' | translate }}
|
|
1948
|
+
</button>
|
|
1949
|
+
</div>
|
|
1950
|
+
|
|
1951
|
+
<!-- Drag Info -->
|
|
1952
|
+
<div class="mb-4 p-2 bg-blue-50 border border-blue-200 rounded text-sm text-blue-700">
|
|
1953
|
+
<i class="pi pi-info-circle mr-2"></i>
|
|
1954
|
+
{{ 'DRAG_COLUMNS_INFO' | translate }}
|
|
1955
|
+
</div>
|
|
1956
|
+
|
|
1957
|
+
<!-- Columns List -->
|
|
1958
|
+
<div class="space-y-3">
|
|
1959
|
+
<div *ngIf="columns.length === 0" class="text-center py-8 px-4 border-2 border-dashed border-gray-300 rounded-lg bg-gray-50">
|
|
1960
|
+
<i class="pi pi-table text-4xl text-gray-400 mb-3"></i>
|
|
1961
|
+
<p class="text-gray-500">{{ 'NO_COLUMNS_AVAILABLE' | translate }}</p>
|
|
1962
|
+
</div>
|
|
2007
1963
|
|
|
2008
|
-
|
|
2009
|
-
|
|
1964
|
+
<div *ngFor="let column of columns; let i = index"
|
|
1965
|
+
class="bg-gray-50 rounded-lg border border-gray-200 p-1 transition-colors hover:bg-gray-100"
|
|
1966
|
+
draggable="true"
|
|
1967
|
+
(dragstart)="onDragStart($event, i)"
|
|
1968
|
+
(dragover)="onDragOver($event)"
|
|
1969
|
+
(drop)="onDrop($event, i)"
|
|
1970
|
+
(dragenter)="onDragEnter($event)"
|
|
1971
|
+
(dragleave)="onDragLeave($event)">
|
|
1972
|
+
|
|
1973
|
+
<div class="grid grid-cols-12 gap-4 items-center">
|
|
1974
|
+
<!-- Drag Handle -->
|
|
1975
|
+
<div class="col-span-1 flex justify-center cursor-move text-gray-400 hover:text-gray-600"
|
|
2010
1976
|
draggable="true"
|
|
2011
|
-
(dragstart)="onDragStart($event, i)"
|
|
2012
|
-
|
|
2013
|
-
|
|
2014
|
-
(dragenter)="onDragEnter($event)"
|
|
2015
|
-
(dragleave)="onDragLeave($event)">
|
|
2016
|
-
|
|
2017
|
-
<div class="grid grid-cols-12 gap-4 items-center">
|
|
2018
|
-
<!-- Drag Handle -->
|
|
2019
|
-
<div class="col-span-1 flex justify-center cursor-move text-gray-400 hover:text-gray-600"
|
|
2020
|
-
draggable="true"
|
|
2021
|
-
(dragstart)="onDragStart($event, i)">
|
|
2022
|
-
<i class="pi pi-bars"></i>
|
|
2023
|
-
</div>
|
|
2024
|
-
|
|
2025
|
-
<!-- Visibility Toggle -->
|
|
2026
|
-
<div class="col-span-1 flex justify-center">
|
|
2027
|
-
<p-checkbox
|
|
2028
|
-
[binary]="true"
|
|
2029
|
-
[formControl]="getColumnControl(column.key, 'isVisible')"
|
|
2030
|
-
[inputId]="'visible_' + column.key"
|
|
2031
|
-
styleClass="[&>div]:border-gray-300 [&>div]:hover:border-gray-400"
|
|
2032
|
-
(onChange)="onFormChange()"
|
|
2033
|
-
>
|
|
2034
|
-
</p-checkbox>
|
|
2035
|
-
</div>
|
|
1977
|
+
(dragstart)="onDragStart($event, i)">
|
|
1978
|
+
<i class="pi pi-bars"></i>
|
|
1979
|
+
</div>
|
|
2036
1980
|
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
|
|
2040
|
-
|
|
2041
|
-
|
|
2042
|
-
|
|
2043
|
-
|
|
1981
|
+
<!-- Visibility Toggle -->
|
|
1982
|
+
<div class="col-span-1 flex justify-center">
|
|
1983
|
+
<p-checkbox
|
|
1984
|
+
[binary]="true"
|
|
1985
|
+
[formControl]="getColumnControl(column.key, 'isVisible')"
|
|
1986
|
+
[inputId]="'visible_' + column.key"
|
|
1987
|
+
styleClass="[&>div]:border-gray-300 [&>div]:hover:border-gray-400"
|
|
1988
|
+
(onChange)="onFormChange()"
|
|
1989
|
+
>
|
|
1990
|
+
</p-checkbox>
|
|
1991
|
+
</div>
|
|
2044
1992
|
|
|
2045
|
-
|
|
2046
|
-
|
|
2047
|
-
|
|
2048
|
-
|
|
2049
|
-
|
|
2050
|
-
|
|
2051
|
-
|
|
2052
|
-
class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 text-sm"
|
|
2053
|
-
(blur)="onFormChange()"
|
|
2054
|
-
>
|
|
2055
|
-
</div>
|
|
1993
|
+
<!-- Column Info -->
|
|
1994
|
+
<div class="col-span-12 md:col-span-4">
|
|
1995
|
+
<label [for]="'visible_' + column.key" class="block font-medium text-gray-900 cursor-pointer hover:text-blue-600">
|
|
1996
|
+
{{ column.label }}
|
|
1997
|
+
</label>
|
|
1998
|
+
<p class="text-xs text-gray-500 mt-1">{{ column.key }}</p>
|
|
1999
|
+
</div>
|
|
2056
2000
|
|
|
2057
|
-
|
|
2058
|
-
|
|
2059
|
-
|
|
2060
|
-
|
|
2061
|
-
|
|
2062
|
-
|
|
2063
|
-
|
|
2064
|
-
|
|
2065
|
-
|
|
2066
|
-
|
|
2067
|
-
|
|
2068
|
-
(onChange)="onFormChange()"
|
|
2069
|
-
>
|
|
2070
|
-
</p-select>
|
|
2071
|
-
</div>
|
|
2072
|
-
<span *ngIf="!column.aggregatable && isColumnVisible(column.key)" class="text-xs text-gray-500">
|
|
2073
|
-
No aggregates available
|
|
2074
|
-
</span>
|
|
2075
|
-
</div>
|
|
2076
|
-
</div>
|
|
2001
|
+
<!-- Display Name -->
|
|
2002
|
+
<div class="col-span-12 md:col-span-3">
|
|
2003
|
+
<input
|
|
2004
|
+
*ngIf="isColumnVisible(column.key)"
|
|
2005
|
+
type="text"
|
|
2006
|
+
[formControl]="getColumnControl(column.key, 'displayName')"
|
|
2007
|
+
[placeholder]="column.label"
|
|
2008
|
+
class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 text-sm"
|
|
2009
|
+
(blur)="onFormChange()"
|
|
2010
|
+
>
|
|
2011
|
+
</div>
|
|
2077
2012
|
|
|
2078
|
-
|
|
2079
|
-
|
|
2080
|
-
|
|
2081
|
-
<
|
|
2082
|
-
|
|
2083
|
-
|
|
2084
|
-
|
|
2085
|
-
|
|
2086
|
-
|
|
2087
|
-
|
|
2013
|
+
<!-- Aggregate Function -->
|
|
2014
|
+
<div class="col-span-12 md:col-span-3">
|
|
2015
|
+
<div *ngIf="column.aggregatable && isColumnVisible(column.key)">
|
|
2016
|
+
<p-select
|
|
2017
|
+
[options]="aggregateFunctions"
|
|
2018
|
+
optionLabel="label"
|
|
2019
|
+
optionValue="value"
|
|
2020
|
+
[formControl]="getColumnControl(column.key, 'aggregateFunction')"
|
|
2021
|
+
[placeholder]="'SELECT_AGGREGATE' | translate"
|
|
2022
|
+
[showClear]="true"
|
|
2023
|
+
styleClass="w-full"
|
|
2024
|
+
(onChange)="onFormChange()"
|
|
2025
|
+
>
|
|
2026
|
+
</p-select>
|
|
2088
2027
|
</div>
|
|
2028
|
+
<span *ngIf="!column.aggregatable && isColumnVisible(column.key)" class="text-xs text-gray-500">
|
|
2029
|
+
{{ 'NO_AGGREGATES_AVAILABLE' | translate }}
|
|
2030
|
+
</span>
|
|
2089
2031
|
</div>
|
|
2090
2032
|
</div>
|
|
2091
2033
|
|
|
2092
|
-
<!--
|
|
2093
|
-
<div
|
|
2094
|
-
|
|
2095
|
-
|
|
2096
|
-
|
|
2097
|
-
|
|
2098
|
-
|
|
2099
|
-
<i class="pi pi-chart-line"></i>
|
|
2100
|
-
{{ numericColumnsCount }} numeric
|
|
2101
|
-
</span>
|
|
2102
|
-
<span class="inline-flex items-center gap-1 text-blue-600">
|
|
2103
|
-
<i class="pi pi-calculator"></i>
|
|
2104
|
-
{{ aggregatedColumnsCount }} aggregated
|
|
2034
|
+
<!-- Aggregate Info -->
|
|
2035
|
+
<div *ngIf="hasAggregateFunction(column.key) && isColumnVisible(column.key)"
|
|
2036
|
+
class="mt-3 p-3 bg-blue-50 border border-blue-200 rounded-lg">
|
|
2037
|
+
<div class="flex items-center gap-2">
|
|
2038
|
+
<i class="pi pi-info-circle text-blue-500 text-sm"></i>
|
|
2039
|
+
<span class="text-sm text-blue-800">
|
|
2040
|
+
{{ 'AGGREGATE_INFO' | translate:{function: getAggregateLabel(getAggregateFunctionValue(column.key))} }}
|
|
2105
2041
|
</span>
|
|
2106
2042
|
</div>
|
|
2107
2043
|
</div>
|
|
2108
2044
|
</div>
|
|
2045
|
+
</div>
|
|
2046
|
+
|
|
2047
|
+
<!-- Summary -->
|
|
2048
|
+
<div class="flex flex-col sm:flex-row justify-between items-center gap-4 mt-6 pt-4 border-t border-gray-200">
|
|
2049
|
+
<span class="text-sm text-gray-600">
|
|
2050
|
+
{{ 'COLUMNS_VISIBLE_COUNT' | translate:{visible: visibleColumnsCount, total: columns.length} }}
|
|
2051
|
+
</span>
|
|
2052
|
+
<div class="flex gap-4 text-sm">
|
|
2053
|
+
<span class="inline-flex items-center gap-1 text-green-600">
|
|
2054
|
+
<i class="pi pi-chart-line"></i>
|
|
2055
|
+
{{ numericColumnsCount }} {{ 'NUMERIC' | translate }}
|
|
2056
|
+
</span>
|
|
2057
|
+
<span class="inline-flex items-center gap-1 text-blue-600">
|
|
2058
|
+
<i class="pi pi-calculator"></i>
|
|
2059
|
+
{{ aggregatedColumnsCount }} {{ 'AGGREGATED' | translate }}
|
|
2060
|
+
</span>
|
|
2061
|
+
</div>
|
|
2062
|
+
</div>
|
|
2063
|
+
</div>
|
|
2109
2064
|
`,
|
|
2110
2065
|
imports: [
|
|
2111
2066
|
CommonModule,
|
|
@@ -2266,321 +2221,317 @@ class GroupBuilderComponent extends FieldType {
|
|
|
2266
2221
|
return this.groups.length < this.maxGroups;
|
|
2267
2222
|
}
|
|
2268
2223
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: GroupBuilderComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
|
|
2269
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.8", type: GroupBuilderComponent, isStandalone: true, selector: "formly-group-builder", usesInheritance: true, ngImport: i0, template:
|
|
2270
|
-
|
|
2271
|
-
|
|
2272
|
-
|
|
2273
|
-
|
|
2274
|
-
|
|
2275
|
-
|
|
2276
|
-
|
|
2277
|
-
|
|
2278
|
-
|
|
2279
|
-
|
|
2280
|
-
|
|
2281
|
-
|
|
2282
|
-
|
|
2283
|
-
|
|
2284
|
-
|
|
2285
|
-
|
|
2286
|
-
|
|
2287
|
-
|
|
2288
|
-
|
|
2289
|
-
|
|
2290
|
-
|
|
2291
|
-
</div>
|
|
2224
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.8", type: GroupBuilderComponent, isStandalone: true, selector: "formly-group-builder", usesInheritance: true, ngImport: i0, template: `<div>
|
|
2225
|
+
<!-- Header -->
|
|
2226
|
+
<div class="mb-6">
|
|
2227
|
+
<h5 class="text-lg font-semibold text-gray-900 mb-2">{{ props.label || ('DATA_GROUPING' | translate) }}</h5>
|
|
2228
|
+
<p class="text-gray-600 text-sm">{{ props.description || ('GROUP_DESCRIPTION' | translate) }}</p>
|
|
2229
|
+
</div>
|
|
2230
|
+
|
|
2231
|
+
<!-- Group Configuration -->
|
|
2232
|
+
<div class="space-y-4">
|
|
2233
|
+
<div class="flex items-center justify-between">
|
|
2234
|
+
<span class="font-medium text-gray-700">{{ 'GROUP_LEVELS' | translate }}</span>
|
|
2235
|
+
<button
|
|
2236
|
+
type="button"
|
|
2237
|
+
*ngIf="canAddMoreGroups()"
|
|
2238
|
+
(click)="addGroup()"
|
|
2239
|
+
[disabled]="!canAddMoreGroups()"
|
|
2240
|
+
class="inline-flex items-center gap-2 px-3 py-2 text-sm font-medium text-blue-700 bg-blue-50 rounded-lg hover:bg-blue-100 disabled:opacity-50 disabled:cursor-not-allowed transition-colors"
|
|
2241
|
+
>
|
|
2242
|
+
<i class="pi pi-plus"></i>
|
|
2243
|
+
{{ 'ADD_GROUP_LEVEL' | translate }}
|
|
2244
|
+
</button>
|
|
2245
|
+
</div>
|
|
2292
2246
|
|
|
2293
|
-
|
|
2294
|
-
|
|
2295
|
-
|
|
2296
|
-
|
|
2297
|
-
|
|
2247
|
+
<!-- Drag Info -->
|
|
2248
|
+
<div *ngIf="groups.length > 1" class="mb-4 p-2 bg-blue-50 border border-blue-200 rounded text-sm text-blue-700">
|
|
2249
|
+
<i class="pi pi-info-circle mr-2"></i>
|
|
2250
|
+
{{ 'DRAG_INFO' | translate }}
|
|
2251
|
+
</div>
|
|
2298
2252
|
|
|
2299
|
-
|
|
2300
|
-
|
|
2301
|
-
|
|
2302
|
-
|
|
2303
|
-
|
|
2304
|
-
|
|
2305
|
-
|
|
2306
|
-
|
|
2307
|
-
|
|
2308
|
-
|
|
2309
|
-
|
|
2310
|
-
|
|
2311
|
-
|
|
2253
|
+
<!-- Empty State -->
|
|
2254
|
+
<div *ngIf="groups.length === 0" class="text-center py-8 px-4 border-2 border-dashed border-gray-300 rounded-lg bg-gray-50">
|
|
2255
|
+
<i class="pi pi-layer-group text-4xl text-gray-400 mb-3"></i>
|
|
2256
|
+
<p class="text-gray-500 mb-4">{{ 'NO_GROUPING_LEVELS' | translate }}</p>
|
|
2257
|
+
<button
|
|
2258
|
+
type="button"
|
|
2259
|
+
(click)="addGroup()"
|
|
2260
|
+
class="inline-flex items-center gap-2 px-4 py-2 text-sm font-medium text-white bg-blue-600 rounded-lg hover:bg-blue-700 transition-colors"
|
|
2261
|
+
>
|
|
2262
|
+
<i class="pi pi-plus"></i>
|
|
2263
|
+
{{ 'ADD_FIRST_GROUP_LEVEL' | translate }}
|
|
2264
|
+
</button>
|
|
2265
|
+
</div>
|
|
2312
2266
|
|
|
2313
|
-
|
|
2314
|
-
|
|
2315
|
-
|
|
2316
|
-
|
|
2267
|
+
<!-- Groups List with Drag & Drop -->
|
|
2268
|
+
<div class="space-y-3">
|
|
2269
|
+
<div *ngFor="let group of groups.controls; let i = index"
|
|
2270
|
+
class="bg-gray-50 rounded-lg border border-gray-200 p-4 transition-colors hover:bg-gray-100"
|
|
2271
|
+
draggable="true"
|
|
2272
|
+
(dragstart)="onDragStart($event, i)"
|
|
2273
|
+
(dragover)="onDragOver($event)"
|
|
2274
|
+
(drop)="onDrop($event, i)"
|
|
2275
|
+
(dragenter)="onDragEnter($event)"
|
|
2276
|
+
(dragleave)="onDragLeave($event)"
|
|
2277
|
+
(dragend)="onDragEnd($event)">
|
|
2278
|
+
|
|
2279
|
+
<div class="grid grid-cols-12 gap-4 items-start">
|
|
2280
|
+
<!-- Drag Handle -->
|
|
2281
|
+
<div *ngIf="groups.length > 1"
|
|
2282
|
+
class="col-span-1 flex justify-center cursor-move text-gray-400 hover:text-gray-600 pt-2"
|
|
2317
2283
|
draggable="true"
|
|
2318
|
-
(dragstart)="onDragStart($event, i)"
|
|
2319
|
-
|
|
2320
|
-
|
|
2321
|
-
|
|
2322
|
-
|
|
2323
|
-
|
|
2324
|
-
|
|
2325
|
-
|
|
2326
|
-
|
|
2327
|
-
|
|
2328
|
-
|
|
2329
|
-
|
|
2330
|
-
|
|
2331
|
-
|
|
2284
|
+
(dragstart)="onDragStart($event, i)">
|
|
2285
|
+
<i class="pi pi-bars"></i>
|
|
2286
|
+
</div>
|
|
2287
|
+
|
|
2288
|
+
<!-- Group Content -->
|
|
2289
|
+
<div class="col-span-11">
|
|
2290
|
+
<div class="flex items-center justify-between mb-3">
|
|
2291
|
+
<div class="flex items-center gap-2">
|
|
2292
|
+
<i class="pi pi-sort-alt text-gray-500"></i>
|
|
2293
|
+
<span class="font-medium text-gray-700">{{ 'GROUP_LEVEL' | translate }} {{ i + 1 }}</span>
|
|
2294
|
+
</div>
|
|
2295
|
+
<div class="flex items-center gap-1">
|
|
2296
|
+
<button
|
|
2297
|
+
type="button"
|
|
2298
|
+
(click)="removeGroup(i)"
|
|
2299
|
+
class="p-1 text-red-500 hover:text-red-700 hover:bg-red-50 rounded transition-colors"
|
|
2300
|
+
[pTooltip]="'REMOVE' | translate"
|
|
2301
|
+
>
|
|
2302
|
+
<i class="pi pi-times"></i>
|
|
2303
|
+
</button>
|
|
2304
|
+
</div>
|
|
2305
|
+
</div>
|
|
2306
|
+
|
|
2307
|
+
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
|
2308
|
+
<!-- Field Selection -->
|
|
2309
|
+
<div>
|
|
2310
|
+
<label class="block text-sm font-medium text-gray-700 mb-2">{{ 'FIELD' | translate }}</label>
|
|
2311
|
+
<p-select
|
|
2312
|
+
[options]="availableFields"
|
|
2313
|
+
optionLabel="label"
|
|
2314
|
+
optionValue="key"
|
|
2315
|
+
[formControl]="getGroupControl(i, 'field')"
|
|
2316
|
+
[placeholder]="'SELECT_FIELD' | translate"
|
|
2317
|
+
[showClear]="true"
|
|
2318
|
+
(onChange)="onFieldChange(i, $event.value)"
|
|
2319
|
+
styleClass="w-full"
|
|
2320
|
+
>
|
|
2321
|
+
<ng-template pTemplate="selectedItem">
|
|
2322
|
+
<span *ngIf="getGroupControl(i, 'field').value" class="text-gray-900">
|
|
2323
|
+
{{ getFieldLabel(getGroupControl(i, 'field').value) }}
|
|
2324
|
+
</span>
|
|
2325
|
+
<span *ngIf="!getGroupControl(i, 'field').value" class="text-gray-500">{{ 'SELECT_FIELD' | translate }}</span>
|
|
2326
|
+
</ng-template>
|
|
2327
|
+
</p-select>
|
|
2332
2328
|
</div>
|
|
2333
2329
|
|
|
2334
|
-
<!--
|
|
2335
|
-
<div
|
|
2336
|
-
<
|
|
2337
|
-
|
|
2338
|
-
|
|
2339
|
-
|
|
2340
|
-
|
|
2341
|
-
|
|
2342
|
-
|
|
2343
|
-
|
|
2344
|
-
|
|
2345
|
-
class="p-1 text-red-500 hover:text-red-700 hover:bg-red-50 rounded transition-colors"
|
|
2346
|
-
[pTooltip]="'Remove'"
|
|
2347
|
-
>
|
|
2348
|
-
<i class="pi pi-times"></i>
|
|
2349
|
-
</button>
|
|
2350
|
-
</div>
|
|
2351
|
-
</div>
|
|
2352
|
-
|
|
2353
|
-
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
|
2354
|
-
<!-- Field Selection -->
|
|
2355
|
-
<div>
|
|
2356
|
-
<label class="block text-sm font-medium text-gray-700 mb-2">Field</label>
|
|
2357
|
-
<p-select
|
|
2358
|
-
[options]="availableFields"
|
|
2359
|
-
optionLabel="label"
|
|
2360
|
-
optionValue="key"
|
|
2361
|
-
[formControl]="getGroupControl(i, 'field')"
|
|
2362
|
-
placeholder="Select field"
|
|
2363
|
-
[showClear]="true"
|
|
2364
|
-
(onChange)="onFieldChange(i, $event.value)"
|
|
2365
|
-
styleClass="w-full"
|
|
2366
|
-
>
|
|
2367
|
-
<ng-template pTemplate="selectedItem">
|
|
2368
|
-
<span *ngIf="getGroupControl(i, 'field').value" class="text-gray-900">
|
|
2369
|
-
{{ getFieldLabel(getGroupControl(i, 'field').value) }}
|
|
2370
|
-
</span>
|
|
2371
|
-
<span *ngIf="!getGroupControl(i, 'field').value" class="text-gray-500">Select field</span>
|
|
2372
|
-
</ng-template>
|
|
2373
|
-
</p-select>
|
|
2374
|
-
</div>
|
|
2375
|
-
|
|
2376
|
-
<!-- Display Name -->
|
|
2377
|
-
<div>
|
|
2378
|
-
<label class="block text-sm font-medium text-gray-700 mb-2">Display Name</label>
|
|
2379
|
-
<input
|
|
2380
|
-
type="text"
|
|
2381
|
-
pInputText
|
|
2382
|
-
[formControl]="getGroupControl(i, 'displayName')"
|
|
2383
|
-
placeholder="Display name (optional)"
|
|
2384
|
-
class="w-full text-gray-900"
|
|
2385
|
-
(blur)="onFormChange()"
|
|
2386
|
-
>
|
|
2387
|
-
</div>
|
|
2388
|
-
</div>
|
|
2389
|
-
|
|
2390
|
-
<!-- Show Total Toggle -->
|
|
2391
|
-
<div class="flex items-center gap-2 mt-3">
|
|
2392
|
-
<p-checkbox
|
|
2393
|
-
[binary]="true"
|
|
2394
|
-
[formControl]="getGroupControl(i, 'showTotal')"
|
|
2395
|
-
[inputId]="'showTotal' + i"
|
|
2396
|
-
styleClass="[&>div]:border-gray-300 [&>div]:hover:border-gray-400"
|
|
2397
|
-
(onChange)="onFormChange()"
|
|
2398
|
-
>
|
|
2399
|
-
</p-checkbox>
|
|
2400
|
-
<label [for]="'showTotal' + i" class="text-sm text-gray-700 cursor-pointer hover:text-gray-900">
|
|
2401
|
-
Show total for this group level
|
|
2402
|
-
</label>
|
|
2403
|
-
</div>
|
|
2330
|
+
<!-- Display Name -->
|
|
2331
|
+
<div>
|
|
2332
|
+
<label class="block text-sm font-medium text-gray-700 mb-2">{{ 'DISPLAY_NAME' | translate }}</label>
|
|
2333
|
+
<input
|
|
2334
|
+
type="text"
|
|
2335
|
+
pInputText
|
|
2336
|
+
[formControl]="getGroupControl(i, 'displayName')"
|
|
2337
|
+
[placeholder]="'DISPLAY_NAME_PLACEHOLDER' | translate"
|
|
2338
|
+
class="w-full text-gray-900"
|
|
2339
|
+
(blur)="onFormChange()"
|
|
2340
|
+
>
|
|
2404
2341
|
</div>
|
|
2405
2342
|
</div>
|
|
2406
|
-
</div>
|
|
2407
|
-
</div>
|
|
2408
|
-
</div>
|
|
2409
2343
|
|
|
2410
|
-
|
|
2411
|
-
|
|
2412
|
-
|
|
2413
|
-
|
|
2414
|
-
|
|
2415
|
-
|
|
2416
|
-
|
|
2417
|
-
|
|
2418
|
-
|
|
2344
|
+
<!-- Show Total Toggle -->
|
|
2345
|
+
<div class="flex items-center gap-2 mt-3">
|
|
2346
|
+
<p-checkbox
|
|
2347
|
+
[binary]="true"
|
|
2348
|
+
[formControl]="getGroupControl(i, 'showTotal')"
|
|
2349
|
+
[inputId]="'showTotal' + i"
|
|
2350
|
+
styleClass="[&>div]:border-gray-300 [&>div]:hover:border-gray-400"
|
|
2351
|
+
(onChange)="onFormChange()"
|
|
2352
|
+
>
|
|
2353
|
+
</p-checkbox>
|
|
2354
|
+
<label [for]="'showTotal' + i" class="text-sm text-gray-700 cursor-pointer hover:text-gray-900">
|
|
2355
|
+
{{ 'SHOW_TOTAL' | translate }}
|
|
2356
|
+
</label>
|
|
2357
|
+
</div>
|
|
2419
2358
|
</div>
|
|
2420
2359
|
</div>
|
|
2421
2360
|
</div>
|
|
2422
2361
|
</div>
|
|
2423
|
-
|
|
2362
|
+
</div>
|
|
2363
|
+
|
|
2364
|
+
<!-- Grouping Tips -->
|
|
2365
|
+
<div *ngIf="groups.length > 0" class="mt-4 p-4 bg-blue-50 border border-blue-200 rounded-lg">
|
|
2366
|
+
<div class="flex items-center gap-3">
|
|
2367
|
+
<i class="pi pi-info-circle text-blue-500"></i>
|
|
2368
|
+
<div>
|
|
2369
|
+
<p class="text-sm text-blue-800">
|
|
2370
|
+
{{ 'GROUPING_TIPS' | translate }}
|
|
2371
|
+
{{ groups.length }} {{ 'LEVELS_DEFINED' | translate:{count: groups.length} }}
|
|
2372
|
+
</p>
|
|
2373
|
+
</div>
|
|
2374
|
+
</div>
|
|
2375
|
+
</div>
|
|
2376
|
+
</div>`, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { 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$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: i2$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i2$1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: SelectModule }, { kind: "component", type: i3.Select, selector: "p-select", inputs: ["id", "scrollHeight", "filter", "panelStyle", "styleClass", "panelStyleClass", "readonly", "editable", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "filterValue", "options", "appendTo"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }, { kind: "directive", type: i2.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "ngmodule", type: InputTextModule }, { kind: "directive", type: i5.InputText, selector: "[pInputText]", inputs: ["pSize", "variant", "fluid", "invalid"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "ngmodule", type: DatePickerModule }, { kind: "ngmodule", type: CheckboxModule }, { kind: "component", type: i4$1.Checkbox, selector: "p-checkbox, p-checkBox, p-check-box", inputs: ["value", "binary", "ariaLabelledBy", "ariaLabel", "tabindex", "inputId", "inputStyle", "styleClass", "inputClass", "indeterminate", "formControl", "checkboxIcon", "readonly", "autofocus", "trueValue", "falseValue", "variant", "size"], outputs: ["onChange", "onFocus", "onBlur"] }, { kind: "ngmodule", type: RadioButtonModule }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i6$1.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions", "appendTo"] }, { kind: "ngmodule", type: MenuModule }, { kind: "ngmodule", type: TranslateModule }, { kind: "ngmodule", type: InputGroupModule }, { kind: "ngmodule", type: InputGroupAddonModule }, { kind: "ngmodule", type: PopoverModule }, { kind: "ngmodule", type: ListboxModule }, { kind: "pipe", type: i8$1.TranslatePipe, name: "translate" }] });
|
|
2424
2377
|
}
|
|
2425
2378
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: GroupBuilderComponent, decorators: [{
|
|
2426
2379
|
type: Component,
|
|
2427
2380
|
args: [{
|
|
2428
2381
|
selector: 'formly-group-builder',
|
|
2429
|
-
template:
|
|
2430
|
-
|
|
2431
|
-
|
|
2432
|
-
|
|
2433
|
-
|
|
2434
|
-
|
|
2435
|
-
|
|
2436
|
-
|
|
2437
|
-
|
|
2438
|
-
|
|
2439
|
-
|
|
2440
|
-
|
|
2441
|
-
|
|
2442
|
-
|
|
2443
|
-
|
|
2444
|
-
|
|
2445
|
-
|
|
2446
|
-
|
|
2447
|
-
|
|
2448
|
-
|
|
2449
|
-
|
|
2450
|
-
|
|
2451
|
-
</div>
|
|
2382
|
+
template: `<div>
|
|
2383
|
+
<!-- Header -->
|
|
2384
|
+
<div class="mb-6">
|
|
2385
|
+
<h5 class="text-lg font-semibold text-gray-900 mb-2">{{ props.label || ('DATA_GROUPING' | translate) }}</h5>
|
|
2386
|
+
<p class="text-gray-600 text-sm">{{ props.description || ('GROUP_DESCRIPTION' | translate) }}</p>
|
|
2387
|
+
</div>
|
|
2388
|
+
|
|
2389
|
+
<!-- Group Configuration -->
|
|
2390
|
+
<div class="space-y-4">
|
|
2391
|
+
<div class="flex items-center justify-between">
|
|
2392
|
+
<span class="font-medium text-gray-700">{{ 'GROUP_LEVELS' | translate }}</span>
|
|
2393
|
+
<button
|
|
2394
|
+
type="button"
|
|
2395
|
+
*ngIf="canAddMoreGroups()"
|
|
2396
|
+
(click)="addGroup()"
|
|
2397
|
+
[disabled]="!canAddMoreGroups()"
|
|
2398
|
+
class="inline-flex items-center gap-2 px-3 py-2 text-sm font-medium text-blue-700 bg-blue-50 rounded-lg hover:bg-blue-100 disabled:opacity-50 disabled:cursor-not-allowed transition-colors"
|
|
2399
|
+
>
|
|
2400
|
+
<i class="pi pi-plus"></i>
|
|
2401
|
+
{{ 'ADD_GROUP_LEVEL' | translate }}
|
|
2402
|
+
</button>
|
|
2403
|
+
</div>
|
|
2452
2404
|
|
|
2453
|
-
|
|
2454
|
-
|
|
2455
|
-
|
|
2456
|
-
|
|
2457
|
-
|
|
2405
|
+
<!-- Drag Info -->
|
|
2406
|
+
<div *ngIf="groups.length > 1" class="mb-4 p-2 bg-blue-50 border border-blue-200 rounded text-sm text-blue-700">
|
|
2407
|
+
<i class="pi pi-info-circle mr-2"></i>
|
|
2408
|
+
{{ 'DRAG_INFO' | translate }}
|
|
2409
|
+
</div>
|
|
2458
2410
|
|
|
2459
|
-
|
|
2460
|
-
|
|
2461
|
-
|
|
2462
|
-
|
|
2463
|
-
|
|
2464
|
-
|
|
2465
|
-
|
|
2466
|
-
|
|
2467
|
-
|
|
2468
|
-
|
|
2469
|
-
|
|
2470
|
-
|
|
2471
|
-
|
|
2411
|
+
<!-- Empty State -->
|
|
2412
|
+
<div *ngIf="groups.length === 0" class="text-center py-8 px-4 border-2 border-dashed border-gray-300 rounded-lg bg-gray-50">
|
|
2413
|
+
<i class="pi pi-layer-group text-4xl text-gray-400 mb-3"></i>
|
|
2414
|
+
<p class="text-gray-500 mb-4">{{ 'NO_GROUPING_LEVELS' | translate }}</p>
|
|
2415
|
+
<button
|
|
2416
|
+
type="button"
|
|
2417
|
+
(click)="addGroup()"
|
|
2418
|
+
class="inline-flex items-center gap-2 px-4 py-2 text-sm font-medium text-white bg-blue-600 rounded-lg hover:bg-blue-700 transition-colors"
|
|
2419
|
+
>
|
|
2420
|
+
<i class="pi pi-plus"></i>
|
|
2421
|
+
{{ 'ADD_FIRST_GROUP_LEVEL' | translate }}
|
|
2422
|
+
</button>
|
|
2423
|
+
</div>
|
|
2472
2424
|
|
|
2473
|
-
|
|
2474
|
-
|
|
2475
|
-
|
|
2476
|
-
|
|
2425
|
+
<!-- Groups List with Drag & Drop -->
|
|
2426
|
+
<div class="space-y-3">
|
|
2427
|
+
<div *ngFor="let group of groups.controls; let i = index"
|
|
2428
|
+
class="bg-gray-50 rounded-lg border border-gray-200 p-4 transition-colors hover:bg-gray-100"
|
|
2429
|
+
draggable="true"
|
|
2430
|
+
(dragstart)="onDragStart($event, i)"
|
|
2431
|
+
(dragover)="onDragOver($event)"
|
|
2432
|
+
(drop)="onDrop($event, i)"
|
|
2433
|
+
(dragenter)="onDragEnter($event)"
|
|
2434
|
+
(dragleave)="onDragLeave($event)"
|
|
2435
|
+
(dragend)="onDragEnd($event)">
|
|
2436
|
+
|
|
2437
|
+
<div class="grid grid-cols-12 gap-4 items-start">
|
|
2438
|
+
<!-- Drag Handle -->
|
|
2439
|
+
<div *ngIf="groups.length > 1"
|
|
2440
|
+
class="col-span-1 flex justify-center cursor-move text-gray-400 hover:text-gray-600 pt-2"
|
|
2477
2441
|
draggable="true"
|
|
2478
|
-
(dragstart)="onDragStart($event, i)"
|
|
2479
|
-
|
|
2480
|
-
|
|
2481
|
-
|
|
2482
|
-
|
|
2483
|
-
|
|
2484
|
-
|
|
2485
|
-
|
|
2486
|
-
|
|
2487
|
-
|
|
2488
|
-
|
|
2489
|
-
|
|
2490
|
-
|
|
2491
|
-
|
|
2442
|
+
(dragstart)="onDragStart($event, i)">
|
|
2443
|
+
<i class="pi pi-bars"></i>
|
|
2444
|
+
</div>
|
|
2445
|
+
|
|
2446
|
+
<!-- Group Content -->
|
|
2447
|
+
<div class="col-span-11">
|
|
2448
|
+
<div class="flex items-center justify-between mb-3">
|
|
2449
|
+
<div class="flex items-center gap-2">
|
|
2450
|
+
<i class="pi pi-sort-alt text-gray-500"></i>
|
|
2451
|
+
<span class="font-medium text-gray-700">{{ 'GROUP_LEVEL' | translate }} {{ i + 1 }}</span>
|
|
2452
|
+
</div>
|
|
2453
|
+
<div class="flex items-center gap-1">
|
|
2454
|
+
<button
|
|
2455
|
+
type="button"
|
|
2456
|
+
(click)="removeGroup(i)"
|
|
2457
|
+
class="p-1 text-red-500 hover:text-red-700 hover:bg-red-50 rounded transition-colors"
|
|
2458
|
+
[pTooltip]="'REMOVE' | translate"
|
|
2459
|
+
>
|
|
2460
|
+
<i class="pi pi-times"></i>
|
|
2461
|
+
</button>
|
|
2462
|
+
</div>
|
|
2463
|
+
</div>
|
|
2464
|
+
|
|
2465
|
+
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
|
2466
|
+
<!-- Field Selection -->
|
|
2467
|
+
<div>
|
|
2468
|
+
<label class="block text-sm font-medium text-gray-700 mb-2">{{ 'FIELD' | translate }}</label>
|
|
2469
|
+
<p-select
|
|
2470
|
+
[options]="availableFields"
|
|
2471
|
+
optionLabel="label"
|
|
2472
|
+
optionValue="key"
|
|
2473
|
+
[formControl]="getGroupControl(i, 'field')"
|
|
2474
|
+
[placeholder]="'SELECT_FIELD' | translate"
|
|
2475
|
+
[showClear]="true"
|
|
2476
|
+
(onChange)="onFieldChange(i, $event.value)"
|
|
2477
|
+
styleClass="w-full"
|
|
2478
|
+
>
|
|
2479
|
+
<ng-template pTemplate="selectedItem">
|
|
2480
|
+
<span *ngIf="getGroupControl(i, 'field').value" class="text-gray-900">
|
|
2481
|
+
{{ getFieldLabel(getGroupControl(i, 'field').value) }}
|
|
2482
|
+
</span>
|
|
2483
|
+
<span *ngIf="!getGroupControl(i, 'field').value" class="text-gray-500">{{ 'SELECT_FIELD' | translate }}</span>
|
|
2484
|
+
</ng-template>
|
|
2485
|
+
</p-select>
|
|
2492
2486
|
</div>
|
|
2493
2487
|
|
|
2494
|
-
<!--
|
|
2495
|
-
<div
|
|
2496
|
-
<
|
|
2497
|
-
|
|
2498
|
-
|
|
2499
|
-
|
|
2500
|
-
|
|
2501
|
-
|
|
2502
|
-
|
|
2503
|
-
|
|
2504
|
-
|
|
2505
|
-
class="p-1 text-red-500 hover:text-red-700 hover:bg-red-50 rounded transition-colors"
|
|
2506
|
-
[pTooltip]="'Remove'"
|
|
2507
|
-
>
|
|
2508
|
-
<i class="pi pi-times"></i>
|
|
2509
|
-
</button>
|
|
2510
|
-
</div>
|
|
2511
|
-
</div>
|
|
2512
|
-
|
|
2513
|
-
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
|
2514
|
-
<!-- Field Selection -->
|
|
2515
|
-
<div>
|
|
2516
|
-
<label class="block text-sm font-medium text-gray-700 mb-2">Field</label>
|
|
2517
|
-
<p-select
|
|
2518
|
-
[options]="availableFields"
|
|
2519
|
-
optionLabel="label"
|
|
2520
|
-
optionValue="key"
|
|
2521
|
-
[formControl]="getGroupControl(i, 'field')"
|
|
2522
|
-
placeholder="Select field"
|
|
2523
|
-
[showClear]="true"
|
|
2524
|
-
(onChange)="onFieldChange(i, $event.value)"
|
|
2525
|
-
styleClass="w-full"
|
|
2526
|
-
>
|
|
2527
|
-
<ng-template pTemplate="selectedItem">
|
|
2528
|
-
<span *ngIf="getGroupControl(i, 'field').value" class="text-gray-900">
|
|
2529
|
-
{{ getFieldLabel(getGroupControl(i, 'field').value) }}
|
|
2530
|
-
</span>
|
|
2531
|
-
<span *ngIf="!getGroupControl(i, 'field').value" class="text-gray-500">Select field</span>
|
|
2532
|
-
</ng-template>
|
|
2533
|
-
</p-select>
|
|
2534
|
-
</div>
|
|
2535
|
-
|
|
2536
|
-
<!-- Display Name -->
|
|
2537
|
-
<div>
|
|
2538
|
-
<label class="block text-sm font-medium text-gray-700 mb-2">Display Name</label>
|
|
2539
|
-
<input
|
|
2540
|
-
type="text"
|
|
2541
|
-
pInputText
|
|
2542
|
-
[formControl]="getGroupControl(i, 'displayName')"
|
|
2543
|
-
placeholder="Display name (optional)"
|
|
2544
|
-
class="w-full text-gray-900"
|
|
2545
|
-
(blur)="onFormChange()"
|
|
2546
|
-
>
|
|
2547
|
-
</div>
|
|
2548
|
-
</div>
|
|
2549
|
-
|
|
2550
|
-
<!-- Show Total Toggle -->
|
|
2551
|
-
<div class="flex items-center gap-2 mt-3">
|
|
2552
|
-
<p-checkbox
|
|
2553
|
-
[binary]="true"
|
|
2554
|
-
[formControl]="getGroupControl(i, 'showTotal')"
|
|
2555
|
-
[inputId]="'showTotal' + i"
|
|
2556
|
-
styleClass="[&>div]:border-gray-300 [&>div]:hover:border-gray-400"
|
|
2557
|
-
(onChange)="onFormChange()"
|
|
2558
|
-
>
|
|
2559
|
-
</p-checkbox>
|
|
2560
|
-
<label [for]="'showTotal' + i" class="text-sm text-gray-700 cursor-pointer hover:text-gray-900">
|
|
2561
|
-
Show total for this group level
|
|
2562
|
-
</label>
|
|
2563
|
-
</div>
|
|
2488
|
+
<!-- Display Name -->
|
|
2489
|
+
<div>
|
|
2490
|
+
<label class="block text-sm font-medium text-gray-700 mb-2">{{ 'DISPLAY_NAME' | translate }}</label>
|
|
2491
|
+
<input
|
|
2492
|
+
type="text"
|
|
2493
|
+
pInputText
|
|
2494
|
+
[formControl]="getGroupControl(i, 'displayName')"
|
|
2495
|
+
[placeholder]="'DISPLAY_NAME_PLACEHOLDER' | translate"
|
|
2496
|
+
class="w-full text-gray-900"
|
|
2497
|
+
(blur)="onFormChange()"
|
|
2498
|
+
>
|
|
2564
2499
|
</div>
|
|
2565
2500
|
</div>
|
|
2566
|
-
</div>
|
|
2567
|
-
</div>
|
|
2568
|
-
</div>
|
|
2569
2501
|
|
|
2570
|
-
|
|
2571
|
-
|
|
2572
|
-
|
|
2573
|
-
|
|
2574
|
-
|
|
2575
|
-
|
|
2576
|
-
|
|
2577
|
-
|
|
2578
|
-
|
|
2502
|
+
<!-- Show Total Toggle -->
|
|
2503
|
+
<div class="flex items-center gap-2 mt-3">
|
|
2504
|
+
<p-checkbox
|
|
2505
|
+
[binary]="true"
|
|
2506
|
+
[formControl]="getGroupControl(i, 'showTotal')"
|
|
2507
|
+
[inputId]="'showTotal' + i"
|
|
2508
|
+
styleClass="[&>div]:border-gray-300 [&>div]:hover:border-gray-400"
|
|
2509
|
+
(onChange)="onFormChange()"
|
|
2510
|
+
>
|
|
2511
|
+
</p-checkbox>
|
|
2512
|
+
<label [for]="'showTotal' + i" class="text-sm text-gray-700 cursor-pointer hover:text-gray-900">
|
|
2513
|
+
{{ 'SHOW_TOTAL' | translate }}
|
|
2514
|
+
</label>
|
|
2515
|
+
</div>
|
|
2579
2516
|
</div>
|
|
2580
2517
|
</div>
|
|
2581
2518
|
</div>
|
|
2582
2519
|
</div>
|
|
2583
|
-
|
|
2520
|
+
</div>
|
|
2521
|
+
|
|
2522
|
+
<!-- Grouping Tips -->
|
|
2523
|
+
<div *ngIf="groups.length > 0" class="mt-4 p-4 bg-blue-50 border border-blue-200 rounded-lg">
|
|
2524
|
+
<div class="flex items-center gap-3">
|
|
2525
|
+
<i class="pi pi-info-circle text-blue-500"></i>
|
|
2526
|
+
<div>
|
|
2527
|
+
<p class="text-sm text-blue-800">
|
|
2528
|
+
{{ 'GROUPING_TIPS' | translate }}
|
|
2529
|
+
{{ groups.length }} {{ 'LEVELS_DEFINED' | translate:{count: groups.length} }}
|
|
2530
|
+
</p>
|
|
2531
|
+
</div>
|
|
2532
|
+
</div>
|
|
2533
|
+
</div>
|
|
2534
|
+
</div>`,
|
|
2584
2535
|
imports: [
|
|
2585
2536
|
CommonModule,
|
|
2586
2537
|
FormsModule,
|