@es.framework/ng.ui.core 2.0.65 → 2.0.67

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.
@@ -195,7 +195,7 @@ class GenericTable {
195
195
  // }
196
196
  // this.selectionChange.emit(this._selection);
197
197
  // }
198
- onInternalSelectionChange(event) {
198
+ onInternalSelectionChange(event, selected) {
199
199
  // ───────────── Header checkbox ─────────────
200
200
  if ('checked' in event) {
201
201
  this._selection = event.checked ? [...this.data] : [];
@@ -206,7 +206,10 @@ class GenericTable {
206
206
  // ───────────── MULTI SELECTION ─────────────
207
207
  if (Array.isArray(this._selection)) {
208
208
  const index = this._selection.findIndex(r => this.isSameRow(r, row));
209
- if (index === -1) {
209
+ if (selected === false) {
210
+ this._selection = this._selection.filter(r => !this.isSameRow(r, row));
211
+ }
212
+ else if (index === -1) {
210
213
  // Not selected → add
211
214
  this._selection = [...this._selection, row];
212
215
  }
@@ -217,12 +220,17 @@ class GenericTable {
217
220
  }
218
221
  // ───────────── SINGLE SELECTION ─────────────
219
222
  else {
220
- this._selection = row;
223
+ this._selection = selected === false ? null : row;
221
224
  }
222
225
  this.selectionChange.emit(this._selection);
223
226
  }
224
227
  isSameRow(a, b) {
225
- return a.id === b.id;
228
+ const aKey = this.resolveFieldData(a, this.dataKey);
229
+ const bKey = this.resolveFieldData(b, this.dataKey);
230
+ if (aKey != null && bKey != null) {
231
+ return aKey === bKey;
232
+ }
233
+ return a === b;
226
234
  }
227
235
  resolveFieldData(data, field) {
228
236
  if (!field)
@@ -318,11 +326,11 @@ class GenericTable {
318
326
  }
319
327
  }
320
328
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: GenericTable, deps: [], target: i0.ɵɵFactoryTarget.Component });
321
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.3", type: GenericTable, isStandalone: true, selector: "lib-generic-table", inputs: { data: "data", columns: "columns", columnFormFields: "columnFormFields", loading: "loading", actions: "actions", actionsPosition: "actionsPosition", actionsMode: "actionsMode", first: "first", rows: "rows", totalRecords: "totalRecords", sortField: "sortField", sortOrder: "sortOrder", globalFilterFields: "globalFilterFields", addButtonConfigs: "addButtonConfigs", scrollHeight: "scrollHeight", rowEditable: "rowEditable", rowSelectable: "rowSelectable", selection: "selection", dataKey: "dataKey", paginator: "paginator", showRowSelectionCheckbox: "showRowSelectionCheckbox" }, outputs: { action: "action", pageChange: "pageChange", onAddNew: "onAddNew", rowSelect: "rowSelect", selectionChange: "selectionChange" }, viewQueries: [{ propertyName: "dt", first: true, predicate: ["dt"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div class=\"flex flex-col h-screen\" style=\" height: 60vh;\">\n <div class=\"flex-1 border rounded-lg overflow-hidden flex flex-col\">\n\n <!-- PrimeNG Table -->\n <p-table #dt\n [value]=\"data_\"\n [dataKey]=\"dataKey\"\n [columns]=\"columns\"\n [lazy]=\"true\"\n [paginator]=\"false\"\n [rows]=\"rows\"\n [first]=\"first\"\n [totalRecords]=\"totalRecords\"\n (onLazyLoad)=\"onLazyLoad($event)\"\n [globalFilterFields]=\"globalFilterFields\"\n [loading]=\"loading\"\n [scrollable]=\"true\"\n scrollHeight=\"flex\"\n [selectionMode]=\"showRowSelectionCheckbox ? 'multiple' : (rowSelectable ? 'single' : undefined)\"\n [(selection)]=\"_selection\"\n (onRowSelect)=\"onInternalSelectionChange($event)\"\n (onRowUnselect)=\"onInternalSelectionChange($event)\"\n (onHeaderCheckboxToggle)=\"onInternalSelectionChange($event)\"\n tableLayout=\"fixed\"\n [customSort]=\"false\"\n class=\"flex-1 overflow-auto\"\n >\n\n <!-- Empty message -->\n <ng-template pTemplate=\"emptymessage\">\n <tr>\n <td colspan=\"10\">\n <div class=\"flex flex-col items-center justify-center py-10 text-center w-full\">\n <i class=\"pi pi-inbox text-4xl text-gray-400 mb-4\"></i>\n <p class=\"text-gray-500 mb-4\">{{ 'NO_DATA_FOUND' | translate }}</p>\n\n @for (btn of addButtonConfigs; track trackByIdx($index, btn)) {\n @if (!btn.visible || btn.visible === true) {\n <lib-generic-button\n [icon]=\"btn.icon\"\n [label]=\"btn.label | translate\"\n [variant]=\"btn.variant\"\n [size]=\"btn.size\"\n [model]=\"btn.splitActions\"\n [permission]=\"btn.permission\"\n (clicked)=\"onAddNew.emit({ name: btn.actionName, row: null! })\"\n class=\"mb-2\"\n ></lib-generic-button>\n }\n }\n </div>\n </td>\n </tr>\n </ng-template>\n\n <!-- Table header -->\n <ng-template pTemplate=\"header\" let-columns>\n <tr class=\"bg-gray-200 sticky top-0 z-10\">\n @if (showRowSelectionCheckbox) {\n <th style=\"width: 2rem\">\n <p-tableHeaderCheckbox></p-tableHeaderCheckbox>\n </th>\n }\n @if (actions.length > 0 && actionsPosition === 'start') {\n <th class=\"px-4 py-2 text-sm font-medium text-center sticky right-0\">\n {{ '*' | translate }}\n </th>\n }\n @for (col of columns; track trackByFn($index, col)) {\n <th\n [pSortableColumn]=\"col.props.entityKey || col.key\"\n class=\"px-4 py-2 text-sm font-medium text-center\"\n [style.min-width]=\"col.props?.table?.props?.width || '150px'\"\n >\n {{ col.props?.label | translate }}\n <p-sortIcon [field]=\"col.props.entityKey || col.key\"></p-sortIcon>\n </th>\n }\n\n @if (actions.length > 0 && actionsPosition === 'end') {\n <th class=\"px-4 py-2 text-sm font-medium text-center sticky left-0\">\n {{ '*' | translate }}\n </th>\n }\n </tr>\n </ng-template>\n\n <!-- Table body -->\n <ng-template pTemplate=\"body\" let-rowData let-columns=\"columns\" let-i=\"rowIndex\">\n <tr class=\"even:bg-gray-50 hover:bg-gray-100 cursor-pointer\" (click)=\"rowSelect.emit(rowData)\">\n @if (showRowSelectionCheckbox) {\n <td style=\"width: 2rem\">\n <p-tableCheckbox [value]=\"rowData\"></p-tableCheckbox>\n </td>\n }\n @if (actions.length > 0 && actionsPosition === 'start') {\n <td class=\"border-t border-gray-200 px-4 py-2 text-center sticky right-0 bg-gray-50\">\n <ng-container\n *ngTemplateOutlet=\"actionsTemplate; context: {$implicit: rowData}\">\n </ng-container>\n </td>\n }\n\n @for (col of rowData.rowFields; track trackByFn(colIndex, col); let colIndex = $index) {\n <td\n class=\"border-t border-gray-200 px-4 py-2 text-center text-sm text-gray-700\"\n [style.width]=\"col.props?.table?.props?.width\"\n >\n <formly-form\n [model]=\"rowData\"\n [form]=\"getForm(i, colIndex)\"\n [fields]=\"[col]\"\n [options]=\"options\"\n (modelChange)=\"onRowModelChange(rowData)\"\n ></formly-form>\n </td>\n }\n\n @if (actions.length > 0 && actionsPosition === 'end') {\n <td class=\"border-t border-gray-200 px-4 py-2 text-center sticky left-0\">\n <ng-container\n *ngTemplateOutlet=\"actionsTemplate; context: {$implicit: rowData}\">\n </ng-container>\n </td>\n }\n </tr>\n\n </ng-template>\n\n\n </p-table>\n </div>\n</div>\n\n<ng-template #actionsTemplate let-rowData>\n @switch (actionsMode) {\n @case ('buttons') {\n @for (act of sortedActions; track act) {\n @if ((act.icon || act.label) && (!act.visible || act.visible(rowData))) {\n <button\n pButton\n [icon]=\"act.icon || ''\"\n [label]=\"(act.label ?? '') | translate\"\n [class]=\"act.styleClass || ''\"\n class=\"p-button-sm mx-1\"\n (click)=\"onAction(act, rowData)\">\n </button>\n }\n }\n }\n @case ('menu') {\n <app-action-menu [items]=\"getMenuItems(rowData) || []\"></app-action-menu>\n <!-- <p-menu #menu [model]=\"getMenuItems(rowData)\" [popup]=\"true\" appendTo=\"body\"></p-menu>\n <p-button\n outlined\n icon=\"pi pi-ellipsis-v\"\n class=\"p-button-text p-button-sm\"\n (onClick)=\"menu.toggle($event)\"\n ></p-button> -->\n }\n }\n</ng-template>\n\n", styles: [".custom-button-medium{font-size:1.1rem;width:2.5rem;height:2.5rem;line-height:2.5rem;padding:0}.custom-button-gray{color:#333;background-color:transparent;border:none}.custom-button-gray:hover{background-color:#eee;color:#000}.icon-delete{color:red!important}.icon-edit{color:#333}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: TableModule }, { kind: "component", type: i2.Table, selector: "p-table", inputs: ["frozenColumns", "frozenValue", "styleClass", "tableStyle", "tableStyleClass", "paginator", "pageLinks", "rowsPerPageOptions", "alwaysShowPaginator", "paginatorPosition", "paginatorStyleClass", "paginatorDropdownAppendTo", "paginatorDropdownScrollHeight", "currentPageReportTemplate", "showCurrentPageReport", "showJumpToPageDropdown", "showJumpToPageInput", "showFirstLastIcon", "showPageLinks", "defaultSortOrder", "sortMode", "resetPageOnSort", "selectionMode", "selectionPageOnly", "contextMenuSelection", "contextMenuSelectionMode", "dataKey", "metaKeySelection", "rowSelectable", "rowTrackBy", "lazy", "lazyLoadOnInit", "compareSelectionBy", "csvSeparator", "exportFilename", "filters", "globalFilterFields", "filterDelay", "filterLocale", "expandedRowKeys", "editingRowKeys", "rowExpandMode", "scrollable", "rowGroupMode", "scrollHeight", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "virtualScrollDelay", "frozenWidth", "contextMenu", "resizableColumns", "columnResizeMode", "reorderableColumns", "loading", "loadingIcon", "showLoader", "rowHover", "customSort", "showInitialSortBadge", "exportFunction", "exportHeader", "stateKey", "stateStorage", "editMode", "groupRowsBy", "size", "showGridlines", "stripedRows", "groupRowsByOrder", "responsiveLayout", "breakpoint", "paginatorLocale", "value", "columns", "first", "rows", "totalRecords", "sortField", "sortOrder", "multiSortMeta", "selection", "selectAll"], outputs: ["contextMenuSelectionChange", "selectAllChange", "selectionChange", "onRowSelect", "onRowUnselect", "onPage", "onSort", "onFilter", "onLazyLoad", "onRowExpand", "onRowCollapse", "onContextMenuSelect", "onColResize", "onColReorder", "onRowReorder", "onEditInit", "onEditComplete", "onEditCancel", "onHeaderCheckboxToggle", "sortFunction", "firstChange", "rowsChange", "onStateSave", "onStateRestore"] }, { kind: "directive", type: i3.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "directive", type: i2.SortableColumn, selector: "[pSortableColumn]", inputs: ["pSortableColumn", "pSortableColumnDisabled"] }, { kind: "component", type: i2.SortIcon, selector: "p-sortIcon", inputs: ["field"] }, { kind: "component", type: i2.TableCheckbox, selector: "p-tableCheckbox", inputs: ["value", "disabled", "required", "index", "inputId", "name", "ariaLabel"] }, { kind: "component", type: i2.TableHeaderCheckbox, selector: "p-tableHeaderCheckbox", inputs: ["disabled", "inputId", "name", "ariaLabel"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "directive", type: i4.ButtonDirective, selector: "[pButton]", inputs: ["ptButtonDirective", "hostName", "text", "plain", "raised", "size", "outlined", "rounded", "iconPos", "loadingIcon", "fluid", "label", "icon", "loading", "buttonProps", "severity"] }, { kind: "ngmodule", type: MenuModule }, { kind: "component", type: FormlyForm, selector: "formly-form", inputs: ["form", "model", "fields", "options"], outputs: ["modelChange"] }, { kind: "component", type: GenericButton, selector: "lib-generic-button", inputs: ["model", "type", "icon", "label", "variant", "severity", "size", "iconPosition", "disabled", "loading", "ariaLabel", "extraClasses", "permission"], outputs: ["clicked", "itemClick"] }, { kind: "ngmodule", type: PaginatorModule }, { kind: "component", type: ActionMenuComponent, selector: "app-action-menu", inputs: ["items"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] });
329
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.3", type: GenericTable, isStandalone: true, selector: "lib-generic-table", inputs: { data: "data", columns: "columns", columnFormFields: "columnFormFields", loading: "loading", actions: "actions", actionsPosition: "actionsPosition", actionsMode: "actionsMode", first: "first", rows: "rows", totalRecords: "totalRecords", sortField: "sortField", sortOrder: "sortOrder", globalFilterFields: "globalFilterFields", addButtonConfigs: "addButtonConfigs", scrollHeight: "scrollHeight", rowEditable: "rowEditable", rowSelectable: "rowSelectable", selection: "selection", dataKey: "dataKey", paginator: "paginator", showRowSelectionCheckbox: "showRowSelectionCheckbox" }, outputs: { action: "action", pageChange: "pageChange", onAddNew: "onAddNew", rowSelect: "rowSelect", selectionChange: "selectionChange" }, viewQueries: [{ propertyName: "dt", first: true, predicate: ["dt"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div class=\"flex flex-col h-screen\" style=\" height: 60vh;\">\n <div class=\"flex-1 border rounded-lg overflow-hidden flex flex-col\">\n\n <!-- PrimeNG Table -->\n <p-table #dt\n [value]=\"data_\"\n [dataKey]=\"dataKey\"\n [columns]=\"columns\"\n [lazy]=\"true\"\n [paginator]=\"false\"\n [rows]=\"rows\"\n [first]=\"first\"\n [totalRecords]=\"totalRecords\"\n (onLazyLoad)=\"onLazyLoad($event)\"\n [globalFilterFields]=\"globalFilterFields\"\n [loading]=\"loading\"\n [scrollable]=\"true\"\n scrollHeight=\"flex\"\n [selectionMode]=\"showRowSelectionCheckbox ? 'multiple' : (rowSelectable ? 'single' : undefined)\"\n [(selection)]=\"_selection\"\n (onRowSelect)=\"onInternalSelectionChange($event, true)\"\n (onRowUnselect)=\"onInternalSelectionChange($event, false)\"\n (onHeaderCheckboxToggle)=\"onInternalSelectionChange($event)\"\n tableLayout=\"fixed\"\n [customSort]=\"false\"\n class=\"flex-1 overflow-auto\"\n >\n\n <!-- Empty message -->\n <ng-template pTemplate=\"emptymessage\">\n <tr>\n <td colspan=\"10\">\n <div class=\"flex flex-col items-center justify-center py-10 text-center w-full\">\n <i class=\"pi pi-inbox text-4xl text-gray-400 mb-4\"></i>\n <p class=\"text-gray-500 mb-4\">{{ 'NO_DATA_FOUND' | translate }}</p>\n\n @for (btn of addButtonConfigs; track trackByIdx($index, btn)) {\n @if (!btn.visible || btn.visible === true) {\n <lib-generic-button\n [icon]=\"btn.icon\"\n [label]=\"btn.label | translate\"\n [variant]=\"btn.variant\"\n [size]=\"btn.size\"\n [model]=\"btn.splitActions\"\n [permission]=\"btn.permission\"\n (clicked)=\"onAddNew.emit({ name: btn.actionName, row: null! })\"\n class=\"mb-2\"\n ></lib-generic-button>\n }\n }\n </div>\n </td>\n </tr>\n </ng-template>\n\n <!-- Table header -->\n <ng-template pTemplate=\"header\" let-columns>\n <tr class=\"bg-gray-200 sticky top-0 z-10\">\n @if (showRowSelectionCheckbox) {\n <th style=\"width: 2rem\">\n <p-tableHeaderCheckbox></p-tableHeaderCheckbox>\n </th>\n }\n @if (actions.length > 0 && actionsPosition === 'start') {\n <th class=\"px-4 py-2 text-sm font-medium text-center sticky right-0\">\n {{ '*' | translate }}\n </th>\n }\n @for (col of columns; track trackByFn($index, col)) {\n <th\n [pSortableColumn]=\"col.props.entityKey || col.key\"\n class=\"px-4 py-2 text-sm font-medium text-center\"\n [style.min-width]=\"col.props?.table?.props?.width || '150px'\"\n >\n {{ col.props?.label | translate }}\n <p-sortIcon [field]=\"col.props.entityKey || col.key\"></p-sortIcon>\n </th>\n }\n\n @if (actions.length > 0 && actionsPosition === 'end') {\n <th class=\"px-4 py-2 text-sm font-medium text-center sticky left-0\">\n {{ '*' | translate }}\n </th>\n }\n </tr>\n </ng-template>\n\n <!-- Table body -->\n <ng-template pTemplate=\"body\" let-rowData let-columns=\"columns\" let-i=\"rowIndex\">\n <tr class=\"even:bg-gray-50 hover:bg-gray-100 cursor-pointer\" (click)=\"rowSelect.emit(rowData)\">\n @if (showRowSelectionCheckbox) {\n <td style=\"width: 2rem\">\n <p-tableCheckbox [value]=\"rowData\"></p-tableCheckbox>\n </td>\n }\n @if (actions.length > 0 && actionsPosition === 'start') {\n <td class=\"border-t border-gray-200 px-4 py-2 text-center sticky right-0 bg-gray-50\">\n <ng-container\n *ngTemplateOutlet=\"actionsTemplate; context: {$implicit: rowData}\">\n </ng-container>\n </td>\n }\n\n @for (col of rowData.rowFields; track trackByFn(colIndex, col); let colIndex = $index) {\n <td\n class=\"border-t border-gray-200 px-4 py-2 text-center text-sm text-gray-700\"\n [style.width]=\"col.props?.table?.props?.width\"\n >\n <formly-form\n [model]=\"rowData\"\n [form]=\"getForm(i, colIndex)\"\n [fields]=\"[col]\"\n [options]=\"options\"\n (modelChange)=\"onRowModelChange(rowData)\"\n ></formly-form>\n </td>\n }\n\n @if (actions.length > 0 && actionsPosition === 'end') {\n <td class=\"border-t border-gray-200 px-4 py-2 text-center sticky left-0\">\n <ng-container\n *ngTemplateOutlet=\"actionsTemplate; context: {$implicit: rowData}\">\n </ng-container>\n </td>\n }\n </tr>\n\n </ng-template>\n\n\n </p-table>\n </div>\n</div>\n\n<ng-template #actionsTemplate let-rowData>\n @switch (actionsMode) {\n @case ('buttons') {\n @for (act of sortedActions; track act) {\n @if ((act.icon || act.label) && (!act.visible || act.visible(rowData))) {\n <button\n pButton\n [icon]=\"act.icon || ''\"\n [label]=\"(act.label ?? '') | translate\"\n [class]=\"act.styleClass || ''\"\n class=\"p-button-sm mx-1\"\n (click)=\"onAction(act, rowData)\">\n </button>\n }\n }\n }\n @case ('menu') {\n <app-action-menu [items]=\"getMenuItems(rowData) || []\"></app-action-menu>\n <!-- <p-menu #menu [model]=\"getMenuItems(rowData)\" [popup]=\"true\" appendTo=\"body\"></p-menu>\n <p-button\n outlined\n icon=\"pi pi-ellipsis-v\"\n class=\"p-button-text p-button-sm\"\n (onClick)=\"menu.toggle($event)\"\n ></p-button> -->\n }\n }\n</ng-template>\n\n", styles: [".custom-button-medium{font-size:1.1rem;width:2.5rem;height:2.5rem;line-height:2.5rem;padding:0}.custom-button-gray{color:#333;background-color:transparent;border:none}.custom-button-gray:hover{background-color:#eee;color:#000}.icon-delete{color:red!important}.icon-edit{color:#333}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: TableModule }, { kind: "component", type: i2.Table, selector: "p-table", inputs: ["frozenColumns", "frozenValue", "styleClass", "tableStyle", "tableStyleClass", "paginator", "pageLinks", "rowsPerPageOptions", "alwaysShowPaginator", "paginatorPosition", "paginatorStyleClass", "paginatorDropdownAppendTo", "paginatorDropdownScrollHeight", "currentPageReportTemplate", "showCurrentPageReport", "showJumpToPageDropdown", "showJumpToPageInput", "showFirstLastIcon", "showPageLinks", "defaultSortOrder", "sortMode", "resetPageOnSort", "selectionMode", "selectionPageOnly", "contextMenuSelection", "contextMenuSelectionMode", "dataKey", "metaKeySelection", "rowSelectable", "rowTrackBy", "lazy", "lazyLoadOnInit", "compareSelectionBy", "csvSeparator", "exportFilename", "filters", "globalFilterFields", "filterDelay", "filterLocale", "expandedRowKeys", "editingRowKeys", "rowExpandMode", "scrollable", "rowGroupMode", "scrollHeight", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "virtualScrollDelay", "frozenWidth", "contextMenu", "resizableColumns", "columnResizeMode", "reorderableColumns", "loading", "loadingIcon", "showLoader", "rowHover", "customSort", "showInitialSortBadge", "exportFunction", "exportHeader", "stateKey", "stateStorage", "editMode", "groupRowsBy", "size", "showGridlines", "stripedRows", "groupRowsByOrder", "responsiveLayout", "breakpoint", "paginatorLocale", "value", "columns", "first", "rows", "totalRecords", "sortField", "sortOrder", "multiSortMeta", "selection", "selectAll"], outputs: ["contextMenuSelectionChange", "selectAllChange", "selectionChange", "onRowSelect", "onRowUnselect", "onPage", "onSort", "onFilter", "onLazyLoad", "onRowExpand", "onRowCollapse", "onContextMenuSelect", "onColResize", "onColReorder", "onRowReorder", "onEditInit", "onEditComplete", "onEditCancel", "onHeaderCheckboxToggle", "sortFunction", "firstChange", "rowsChange", "onStateSave", "onStateRestore"] }, { kind: "directive", type: i3.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "directive", type: i2.SortableColumn, selector: "[pSortableColumn]", inputs: ["pSortableColumn", "pSortableColumnDisabled"] }, { kind: "component", type: i2.SortIcon, selector: "p-sortIcon", inputs: ["field"] }, { kind: "component", type: i2.TableCheckbox, selector: "p-tableCheckbox", inputs: ["value", "disabled", "required", "index", "inputId", "name", "ariaLabel"] }, { kind: "component", type: i2.TableHeaderCheckbox, selector: "p-tableHeaderCheckbox", inputs: ["disabled", "inputId", "name", "ariaLabel"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "directive", type: i4.ButtonDirective, selector: "[pButton]", inputs: ["ptButtonDirective", "hostName", "text", "plain", "raised", "size", "outlined", "rounded", "iconPos", "loadingIcon", "fluid", "label", "icon", "loading", "buttonProps", "severity"] }, { kind: "ngmodule", type: MenuModule }, { kind: "component", type: FormlyForm, selector: "formly-form", inputs: ["form", "model", "fields", "options"], outputs: ["modelChange"] }, { kind: "component", type: GenericButton, selector: "lib-generic-button", inputs: ["model", "type", "icon", "label", "tooltip", "tooltipPosition", "variant", "severity", "size", "iconPosition", "disabled", "loading", "ariaLabel", "extraClasses", "permission"], outputs: ["clicked", "itemClick"] }, { kind: "ngmodule", type: PaginatorModule }, { kind: "component", type: ActionMenuComponent, selector: "app-action-menu", inputs: ["items"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] });
322
330
  }
323
331
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: GenericTable, decorators: [{
324
332
  type: Component,
325
- args: [{ selector: 'lib-generic-table', imports: [CommonModule, TableModule, ButtonModule, MenuModule, TranslatePipe, FormlyField, FormlyForm, TranslatePipe, Menu, Button, GenericButton, PaginatorModule, ActionMenuComponent], template: "<div class=\"flex flex-col h-screen\" style=\" height: 60vh;\">\n <div class=\"flex-1 border rounded-lg overflow-hidden flex flex-col\">\n\n <!-- PrimeNG Table -->\n <p-table #dt\n [value]=\"data_\"\n [dataKey]=\"dataKey\"\n [columns]=\"columns\"\n [lazy]=\"true\"\n [paginator]=\"false\"\n [rows]=\"rows\"\n [first]=\"first\"\n [totalRecords]=\"totalRecords\"\n (onLazyLoad)=\"onLazyLoad($event)\"\n [globalFilterFields]=\"globalFilterFields\"\n [loading]=\"loading\"\n [scrollable]=\"true\"\n scrollHeight=\"flex\"\n [selectionMode]=\"showRowSelectionCheckbox ? 'multiple' : (rowSelectable ? 'single' : undefined)\"\n [(selection)]=\"_selection\"\n (onRowSelect)=\"onInternalSelectionChange($event)\"\n (onRowUnselect)=\"onInternalSelectionChange($event)\"\n (onHeaderCheckboxToggle)=\"onInternalSelectionChange($event)\"\n tableLayout=\"fixed\"\n [customSort]=\"false\"\n class=\"flex-1 overflow-auto\"\n >\n\n <!-- Empty message -->\n <ng-template pTemplate=\"emptymessage\">\n <tr>\n <td colspan=\"10\">\n <div class=\"flex flex-col items-center justify-center py-10 text-center w-full\">\n <i class=\"pi pi-inbox text-4xl text-gray-400 mb-4\"></i>\n <p class=\"text-gray-500 mb-4\">{{ 'NO_DATA_FOUND' | translate }}</p>\n\n @for (btn of addButtonConfigs; track trackByIdx($index, btn)) {\n @if (!btn.visible || btn.visible === true) {\n <lib-generic-button\n [icon]=\"btn.icon\"\n [label]=\"btn.label | translate\"\n [variant]=\"btn.variant\"\n [size]=\"btn.size\"\n [model]=\"btn.splitActions\"\n [permission]=\"btn.permission\"\n (clicked)=\"onAddNew.emit({ name: btn.actionName, row: null! })\"\n class=\"mb-2\"\n ></lib-generic-button>\n }\n }\n </div>\n </td>\n </tr>\n </ng-template>\n\n <!-- Table header -->\n <ng-template pTemplate=\"header\" let-columns>\n <tr class=\"bg-gray-200 sticky top-0 z-10\">\n @if (showRowSelectionCheckbox) {\n <th style=\"width: 2rem\">\n <p-tableHeaderCheckbox></p-tableHeaderCheckbox>\n </th>\n }\n @if (actions.length > 0 && actionsPosition === 'start') {\n <th class=\"px-4 py-2 text-sm font-medium text-center sticky right-0\">\n {{ '*' | translate }}\n </th>\n }\n @for (col of columns; track trackByFn($index, col)) {\n <th\n [pSortableColumn]=\"col.props.entityKey || col.key\"\n class=\"px-4 py-2 text-sm font-medium text-center\"\n [style.min-width]=\"col.props?.table?.props?.width || '150px'\"\n >\n {{ col.props?.label | translate }}\n <p-sortIcon [field]=\"col.props.entityKey || col.key\"></p-sortIcon>\n </th>\n }\n\n @if (actions.length > 0 && actionsPosition === 'end') {\n <th class=\"px-4 py-2 text-sm font-medium text-center sticky left-0\">\n {{ '*' | translate }}\n </th>\n }\n </tr>\n </ng-template>\n\n <!-- Table body -->\n <ng-template pTemplate=\"body\" let-rowData let-columns=\"columns\" let-i=\"rowIndex\">\n <tr class=\"even:bg-gray-50 hover:bg-gray-100 cursor-pointer\" (click)=\"rowSelect.emit(rowData)\">\n @if (showRowSelectionCheckbox) {\n <td style=\"width: 2rem\">\n <p-tableCheckbox [value]=\"rowData\"></p-tableCheckbox>\n </td>\n }\n @if (actions.length > 0 && actionsPosition === 'start') {\n <td class=\"border-t border-gray-200 px-4 py-2 text-center sticky right-0 bg-gray-50\">\n <ng-container\n *ngTemplateOutlet=\"actionsTemplate; context: {$implicit: rowData}\">\n </ng-container>\n </td>\n }\n\n @for (col of rowData.rowFields; track trackByFn(colIndex, col); let colIndex = $index) {\n <td\n class=\"border-t border-gray-200 px-4 py-2 text-center text-sm text-gray-700\"\n [style.width]=\"col.props?.table?.props?.width\"\n >\n <formly-form\n [model]=\"rowData\"\n [form]=\"getForm(i, colIndex)\"\n [fields]=\"[col]\"\n [options]=\"options\"\n (modelChange)=\"onRowModelChange(rowData)\"\n ></formly-form>\n </td>\n }\n\n @if (actions.length > 0 && actionsPosition === 'end') {\n <td class=\"border-t border-gray-200 px-4 py-2 text-center sticky left-0\">\n <ng-container\n *ngTemplateOutlet=\"actionsTemplate; context: {$implicit: rowData}\">\n </ng-container>\n </td>\n }\n </tr>\n\n </ng-template>\n\n\n </p-table>\n </div>\n</div>\n\n<ng-template #actionsTemplate let-rowData>\n @switch (actionsMode) {\n @case ('buttons') {\n @for (act of sortedActions; track act) {\n @if ((act.icon || act.label) && (!act.visible || act.visible(rowData))) {\n <button\n pButton\n [icon]=\"act.icon || ''\"\n [label]=\"(act.label ?? '') | translate\"\n [class]=\"act.styleClass || ''\"\n class=\"p-button-sm mx-1\"\n (click)=\"onAction(act, rowData)\">\n </button>\n }\n }\n }\n @case ('menu') {\n <app-action-menu [items]=\"getMenuItems(rowData) || []\"></app-action-menu>\n <!-- <p-menu #menu [model]=\"getMenuItems(rowData)\" [popup]=\"true\" appendTo=\"body\"></p-menu>\n <p-button\n outlined\n icon=\"pi pi-ellipsis-v\"\n class=\"p-button-text p-button-sm\"\n (onClick)=\"menu.toggle($event)\"\n ></p-button> -->\n }\n }\n</ng-template>\n\n", styles: [".custom-button-medium{font-size:1.1rem;width:2.5rem;height:2.5rem;line-height:2.5rem;padding:0}.custom-button-gray{color:#333;background-color:transparent;border:none}.custom-button-gray:hover{background-color:#eee;color:#000}.icon-delete{color:red!important}.icon-edit{color:#333}\n"] }]
333
+ args: [{ selector: 'lib-generic-table', imports: [CommonModule, TableModule, ButtonModule, MenuModule, TranslatePipe, FormlyField, FormlyForm, TranslatePipe, Menu, Button, GenericButton, PaginatorModule, ActionMenuComponent], template: "<div class=\"flex flex-col h-screen\" style=\" height: 60vh;\">\n <div class=\"flex-1 border rounded-lg overflow-hidden flex flex-col\">\n\n <!-- PrimeNG Table -->\n <p-table #dt\n [value]=\"data_\"\n [dataKey]=\"dataKey\"\n [columns]=\"columns\"\n [lazy]=\"true\"\n [paginator]=\"false\"\n [rows]=\"rows\"\n [first]=\"first\"\n [totalRecords]=\"totalRecords\"\n (onLazyLoad)=\"onLazyLoad($event)\"\n [globalFilterFields]=\"globalFilterFields\"\n [loading]=\"loading\"\n [scrollable]=\"true\"\n scrollHeight=\"flex\"\n [selectionMode]=\"showRowSelectionCheckbox ? 'multiple' : (rowSelectable ? 'single' : undefined)\"\n [(selection)]=\"_selection\"\n (onRowSelect)=\"onInternalSelectionChange($event, true)\"\n (onRowUnselect)=\"onInternalSelectionChange($event, false)\"\n (onHeaderCheckboxToggle)=\"onInternalSelectionChange($event)\"\n tableLayout=\"fixed\"\n [customSort]=\"false\"\n class=\"flex-1 overflow-auto\"\n >\n\n <!-- Empty message -->\n <ng-template pTemplate=\"emptymessage\">\n <tr>\n <td colspan=\"10\">\n <div class=\"flex flex-col items-center justify-center py-10 text-center w-full\">\n <i class=\"pi pi-inbox text-4xl text-gray-400 mb-4\"></i>\n <p class=\"text-gray-500 mb-4\">{{ 'NO_DATA_FOUND' | translate }}</p>\n\n @for (btn of addButtonConfigs; track trackByIdx($index, btn)) {\n @if (!btn.visible || btn.visible === true) {\n <lib-generic-button\n [icon]=\"btn.icon\"\n [label]=\"btn.label | translate\"\n [variant]=\"btn.variant\"\n [size]=\"btn.size\"\n [model]=\"btn.splitActions\"\n [permission]=\"btn.permission\"\n (clicked)=\"onAddNew.emit({ name: btn.actionName, row: null! })\"\n class=\"mb-2\"\n ></lib-generic-button>\n }\n }\n </div>\n </td>\n </tr>\n </ng-template>\n\n <!-- Table header -->\n <ng-template pTemplate=\"header\" let-columns>\n <tr class=\"bg-gray-200 sticky top-0 z-10\">\n @if (showRowSelectionCheckbox) {\n <th style=\"width: 2rem\">\n <p-tableHeaderCheckbox></p-tableHeaderCheckbox>\n </th>\n }\n @if (actions.length > 0 && actionsPosition === 'start') {\n <th class=\"px-4 py-2 text-sm font-medium text-center sticky right-0\">\n {{ '*' | translate }}\n </th>\n }\n @for (col of columns; track trackByFn($index, col)) {\n <th\n [pSortableColumn]=\"col.props.entityKey || col.key\"\n class=\"px-4 py-2 text-sm font-medium text-center\"\n [style.min-width]=\"col.props?.table?.props?.width || '150px'\"\n >\n {{ col.props?.label | translate }}\n <p-sortIcon [field]=\"col.props.entityKey || col.key\"></p-sortIcon>\n </th>\n }\n\n @if (actions.length > 0 && actionsPosition === 'end') {\n <th class=\"px-4 py-2 text-sm font-medium text-center sticky left-0\">\n {{ '*' | translate }}\n </th>\n }\n </tr>\n </ng-template>\n\n <!-- Table body -->\n <ng-template pTemplate=\"body\" let-rowData let-columns=\"columns\" let-i=\"rowIndex\">\n <tr class=\"even:bg-gray-50 hover:bg-gray-100 cursor-pointer\" (click)=\"rowSelect.emit(rowData)\">\n @if (showRowSelectionCheckbox) {\n <td style=\"width: 2rem\">\n <p-tableCheckbox [value]=\"rowData\"></p-tableCheckbox>\n </td>\n }\n @if (actions.length > 0 && actionsPosition === 'start') {\n <td class=\"border-t border-gray-200 px-4 py-2 text-center sticky right-0 bg-gray-50\">\n <ng-container\n *ngTemplateOutlet=\"actionsTemplate; context: {$implicit: rowData}\">\n </ng-container>\n </td>\n }\n\n @for (col of rowData.rowFields; track trackByFn(colIndex, col); let colIndex = $index) {\n <td\n class=\"border-t border-gray-200 px-4 py-2 text-center text-sm text-gray-700\"\n [style.width]=\"col.props?.table?.props?.width\"\n >\n <formly-form\n [model]=\"rowData\"\n [form]=\"getForm(i, colIndex)\"\n [fields]=\"[col]\"\n [options]=\"options\"\n (modelChange)=\"onRowModelChange(rowData)\"\n ></formly-form>\n </td>\n }\n\n @if (actions.length > 0 && actionsPosition === 'end') {\n <td class=\"border-t border-gray-200 px-4 py-2 text-center sticky left-0\">\n <ng-container\n *ngTemplateOutlet=\"actionsTemplate; context: {$implicit: rowData}\">\n </ng-container>\n </td>\n }\n </tr>\n\n </ng-template>\n\n\n </p-table>\n </div>\n</div>\n\n<ng-template #actionsTemplate let-rowData>\n @switch (actionsMode) {\n @case ('buttons') {\n @for (act of sortedActions; track act) {\n @if ((act.icon || act.label) && (!act.visible || act.visible(rowData))) {\n <button\n pButton\n [icon]=\"act.icon || ''\"\n [label]=\"(act.label ?? '') | translate\"\n [class]=\"act.styleClass || ''\"\n class=\"p-button-sm mx-1\"\n (click)=\"onAction(act, rowData)\">\n </button>\n }\n }\n }\n @case ('menu') {\n <app-action-menu [items]=\"getMenuItems(rowData) || []\"></app-action-menu>\n <!-- <p-menu #menu [model]=\"getMenuItems(rowData)\" [popup]=\"true\" appendTo=\"body\"></p-menu>\n <p-button\n outlined\n icon=\"pi pi-ellipsis-v\"\n class=\"p-button-text p-button-sm\"\n (onClick)=\"menu.toggle($event)\"\n ></p-button> -->\n }\n }\n</ng-template>\n\n", styles: [".custom-button-medium{font-size:1.1rem;width:2.5rem;height:2.5rem;line-height:2.5rem;padding:0}.custom-button-gray{color:#333;background-color:transparent;border:none}.custom-button-gray:hover{background-color:#eee;color:#000}.icon-delete{color:red!important}.icon-edit{color:#333}\n"] }]
326
334
  }], propDecorators: { dt: [{
327
335
  type: ViewChild,
328
336
  args: ['dt']
@@ -1 +1 @@
1
- {"version":3,"file":"es.framework-ng.ui.core-generic-table.mjs","sources":["../../../../libs/ng.ui.core/generic-table/src/lib/generic-table-module.ts","../../../../libs/ng.ui.core/generic-table/src/lib/action-menu.component.ts","../../../../libs/ng.ui.core/generic-table/src/lib/action-menu.component.html","../../../../libs/ng.ui.core/generic-table/src/lib/generic-table.ts","../../../../libs/ng.ui.core/generic-table/src/lib/generic-table.html","../../../../libs/ng.ui.core/generic-table/src/es.framework-ng.ui.core-generic-table.ts"],"sourcesContent":["import { NgModule } from '@angular/core';\nimport { CommonModule } from '@angular/common';\n\n@NgModule({\n imports: [CommonModule],\n})\nexport class GenericTableModule {}\n","\r\nimport { Component, Input, ViewChildren, QueryList, ElementRef } from '@angular/core';\r\nimport { MenuItem } from 'primeng/api';\r\nimport { ButtonModule } from 'primeng/button';\r\nimport { OverlayModule } from 'primeng/overlay';\r\n\r\n@Component({\r\n selector: 'app-action-menu',\r\n templateUrl: './action-menu.component.html',\r\n imports: [OverlayModule, ButtonModule],\r\n})\r\nexport class ActionMenuComponent {\r\n @Input() items: MenuItem[] = [];\r\n open = false;\r\n\r\n @ViewChildren('menuItem') menuItems!: QueryList<ElementRef<HTMLButtonElement>>;\r\n\r\n menuPositionClass = 'right-0';\r\n\r\n toggle() {\r\n this.open = !this.open;\r\n // Optional: adjust position when opening\r\n // if (this.open) setTimeout(() => this.adjustMenuPosition());\r\n }\r\n\r\n adjustMenuPosition() {\r\n const menu = document.querySelector('.absolute.mt-2') as HTMLElement;\r\n if (!menu) return;\r\n\r\n const rect = menu.getBoundingClientRect();\r\n const viewportWidth = window.innerWidth;\r\n\r\n this.menuPositionClass = rect.right > viewportWidth ? 'left-0' : 'right-0';\r\n }\r\n\r\n onClick(item: MenuItem, event: MouseEvent) {\r\n this.open = false;\r\n if (item.command) {\r\n item.command({ originalEvent: event, item });\r\n }\r\n }\r\n\r\n onOutsideClick(event: MouseEvent) {\r\n const target = event.target as HTMLElement;\r\n if (!target.closest('.inline-block')) {\r\n this.open = false;\r\n }\r\n }\r\n\r\n // ========================\r\n // Focus & Keyboard navigation\r\n // ========================\r\n focusFirst() {\r\n // Delay needed because overlay content is rendered asynchronously\r\n setTimeout(() => {\r\n this.menuItems.first?.nativeElement.focus();\r\n });\r\n }\r\n\r\n // -------------------\r\n // Keyboard on menu container\r\n // -------------------\r\n onMenuKeydown(event: KeyboardEvent) {\r\n // Convert QueryList to array of HTMLButtonElement\r\n const items: HTMLButtonElement[] = this.menuItems.toArray().map(i => i.nativeElement as HTMLButtonElement);\r\n\r\n let index = items.indexOf(document.activeElement as HTMLButtonElement);\r\n if (index === -1) return;\r\n\r\n switch (event.key) {\r\n case 'ArrowDown':\r\n event.preventDefault();\r\n index = (index + 1) % items.length;\r\n items[index].focus();\r\n break;\r\n\r\n case 'ArrowUp':\r\n event.preventDefault();\r\n index = (index - 1 + items.length) % items.length;\r\n items[index].focus();\r\n break;\r\n\r\n case 'Enter':\r\n case ' ':\r\n event.preventDefault();\r\n items[index].click();\r\n break;\r\n\r\n case 'Escape':\r\n this.open = false;\r\n break;\r\n }\r\n}\r\n\r\n\r\n\r\n onTriggerKeydown(event: KeyboardEvent) {\r\n // Open overlay via keyboard\r\n if (event.key === 'ArrowDown' || event.key === 'Enter' || event.key === ' ') {\r\n event.preventDefault();\r\n this.open = true;\r\n this.focusFirst();\r\n }\r\n }\r\n}\r\n","<div class=\"inline-block relative\">\n <button type=\"button\"\n class=\"p-ripple p-button p-button-icon-only p-button-outlined p-component\"\n #trigger\n (click)=\"toggle()\">\n <span class=\"pi pi-ellipsis-v\"></span>\n </button>\n\n <p-overlay [(visible)]=\"open\" [appendTo]=\"'body'\" (onShow)=\"focusFirst()\">\n <div class=\"w-48 rounded-lg shadow-lg bg-white border border-gray-200\"\n tabindex=\"0\"\n (keydown)=\"onMenuKeydown($event)\">\n @for (item of items; track item) {\n <button #menuItem\n (click)=\"onClick(item, $event)\"\n class=\"flex items-center w-full text-left px-4 py-2 text-sm hover:bg-gray-100 focus:bg-gray-100 focus:outline-none\">\n @if (item.icon) {\n <i [class]=\"item.icon + ' ml-2 mr-2 text-gray-500'\"></i>\n }\n <span>{{ item.label }}</span>\n </button>\n }\n </div>\n </p-overlay>\n</div>\n","import { Component, Input, Output, EventEmitter, ViewChild, OnChanges, SimpleChanges, inject, OnInit } from '@angular/core';\r\nimport { MenuItem, SortEvent } from 'primeng/api';\r\nimport { Table, TableHeaderCheckboxToggleEvent, TableLazyLoadEvent, TableRowSelectEvent } from 'primeng/table';\r\nimport { CommonModule } from '@angular/common';\r\nimport { TableModule } from 'primeng/table';\r\nimport { ButtonModule, Button } from 'primeng/button';\r\nimport { MenuModule, Menu } from 'primeng/menu';\r\nimport { TranslatePipe } from '@es.framework/ng.core/pipes';\r\nimport { FormlyField, FormlyFieldConfig, FormlyForm, FormlyFormOptions } from '@ngx-formly/core';\r\nimport { FormGroup } from '@angular/forms';\r\nimport { ActionDef, ButtonConfig } from '@es.framework/ng.core/models';\r\nimport { cloneDeep, forEach } from 'lodash';\r\nimport { GenericButton } from '@es.framework/ng.ui.core/generic-button';\r\nimport { PaginatorModule } from 'primeng/paginator';\r\nimport { ActionMenuComponent } from './action-menu.component';\r\nimport { LocalizationService, PermissionCheckerService } from '@es.framework/ng.core/services';\r\n\r\n@Component({\r\n selector: 'lib-generic-table',\r\n imports: [CommonModule, TableModule, ButtonModule, MenuModule, TranslatePipe, FormlyField, FormlyForm, TranslatePipe, Menu, Button, GenericButton, PaginatorModule, ActionMenuComponent],\r\n templateUrl: './generic-table.html',\r\n styleUrl: './generic-table.css'\r\n})\r\nexport class GenericTable<T> implements OnInit, OnChanges{\r\n\r\n\r\n translateService:LocalizationService = inject(LocalizationService);\r\n permissionsService:PermissionCheckerService = inject(PermissionCheckerService);\r\n\r\n@ViewChild('dt') dt!: Table;\r\n\r\n@Input() data: any[] = [];\r\n data_: any[] = [];\r\n @Input() columns: FormlyFieldConfig[] = [];\r\n processedFields: any[] = [];\r\n @Input() columnFormFields: FormlyFieldConfig[] = [];\r\n @Input() loading = false;\r\n @Input() actions: ActionDef<T>[] = [];\r\n @Input() actionsPosition: 'start' | 'end' = 'end';\r\n @Input() actionsMode: 'buttons' | 'menu' = 'buttons';\r\n @Input() first = 0;\r\n @Input() rows = 10;\r\n @Input() totalRecords = 0;\r\n @Input() sortField?: string;\r\n @Input() sortOrder: 1 | -1 = 1;\r\n @Input() globalFilterFields: string[] = [];\r\n\r\n @Output() action = new EventEmitter<{ name: string; row: T }>();\r\n @Output() pageChange = new EventEmitter<TableLazyLoadEvent>();\r\n\r\n // eslint-disable-next-line @angular-eslint/no-output-on-prefix\r\n @Output() onAddNew = new EventEmitter<any>();\r\n@Input() addButtonConfigs: ButtonConfig[] = [];\r\n @Input() scrollHeight = '400px';\r\n\r\n // **جديد**: تمكين تعديل الصفوف\r\n @Input() rowEditable = false;\r\n // **جديد**: تمكين اختيار الصفوف\r\n /** فعّل اختيار الصفين single/multiple */\r\n @Input() rowSelectable = true;\r\n /** يحتفظ بالصف المحدد */\r\n //@Input() selection: T | T[] | null = null;\r\n\r\n // هذا سيكون مرتبطًا بـ [(selection)] في p-table\r\n _selection: T | T[] | null = null;\r\n\r\n\r\n @Input()\r\n get selection(): T | T[] | null {\r\n return this._selection;\r\n }\r\n set selection(val: T | T[] | null) {\r\n this._selection = val;\r\n // لا تُصدر الحدث هنا، بل في onInternalSelectionChange فقط\r\n }\r\n\r\n trackByIdx(index: number, item: any): number {\r\n return index;\r\n }\r\n /** يصدر الصف المحدد عند النقر */\r\n @Output() rowSelect = new EventEmitter<T>();\r\n\r\n @Input() dataKey = 'id';\r\n\r\n /** يصدر الصفوف المحددة عند التغيير (للربط الثنائي) */\r\n @Output() selectionChange = new EventEmitter<T | T[] | null>();\r\n\r\n\r\n /** جديد: التحكم بظهور الـ paginator */\r\n @Input() paginator = true;\r\nform = new FormGroup({});\r\noptions: FormlyFormOptions = {};\r\n\r\n\r\n\r\n // **جديد**: يتحكم بإظهار عمود اختيار الصفوف (checkboxes)\r\n /** يتحكم في إظهار عمود اختيار الصفوف المتعددة بواسطة checkboxes */\r\n @Input() showRowSelectionCheckbox = false;\r\n\r\n\r\n menuItems : MenuItem[] = [];\r\n\r\n ngOnInit(): void {\r\n // this.menuItems = this.getMenuItems();\r\n }\r\n// onInternalSelectionChange(event: TableRowSelectEvent<T>\r\n// | TableHeaderCheckboxToggleEvent): void {\r\n// if ('data' in event) {\r\n// // Row select/unselect (single أو multiple)\r\n// if (Array.isArray(this._selection)) {\r\n// this._selection = [...this._selection]; // تحديث نسخة المصفوفة عند متعدد\r\n// } else {\r\n// this._selection = event.data as T; // اختيار فردي\r\n// }\r\n// } else if ('checked' in event) {\r\n// // Header checkbox toggle\r\n// this._selection = event.checked ? [...this.data] : [];\r\n// }\r\n\r\n// this.selectionChange.emit(this._selection);\r\n// }\r\nonInternalSelectionChange(\r\n event: TableRowSelectEvent<T> | TableHeaderCheckboxToggleEvent\r\n): void {\r\n\r\n // ───────────── Header checkbox ─────────────\r\n if ('checked' in event) {\r\n this._selection = event.checked ? [...this.data] : [];\r\n this.selectionChange.emit(this._selection);\r\n return;\r\n }\r\n\r\n const row = event.data as T;\r\n\r\n // ───────────── MULTI SELECTION ─────────────\r\n if (Array.isArray(this._selection)) {\r\n const index = this._selection.findIndex(\r\n r => this.isSameRow(r, row)\r\n );\r\n\r\n if (index === -1) {\r\n // Not selected → add\r\n this._selection = [...this._selection, row];\r\n } else {\r\n // Already selected → REPLACE with edited row\r\n this._selection = this._selection.map((r, i) =>\r\n i === index ? row : r\r\n );\r\n }\r\n }\r\n // ───────────── SINGLE SELECTION ─────────────\r\n else {\r\n this._selection = row;\r\n }\r\n\r\n this.selectionChange.emit(this._selection);\r\n}\r\n\r\n\r\nprivate isSameRow(a: T, b: T): boolean {\r\n return (a as any).id === (b as any).id;\r\n}\r\nresolveFieldData(data: any, field: string): any {\r\n if (!field) return null;\r\n if (field.indexOf('.') === -1) return data[field];\r\n return field.split('.').reduce((obj, prop) => (obj ? obj[prop] : null), data);\r\n}\r\n\r\n onAction(act: ActionDef<T>, row: T) {\r\n if (act.action) {\r\n act.action(row);\r\n } else {\r\n this.action.emit({ name: act.name, row });\r\n }\r\n }\r\n\r\n // Use a map to store form groups for each row and column\r\n private cellForms: Map<string, FormGroup> = new Map();\r\n forms: FormGroup = new FormGroup({}); // A main form for the table\r\n\r\n\r\n // Refactored getForm to return an existing form instance\r\n getForm(rowIndex: number, colIndex: number): FormGroup {\r\n const key = `${rowIndex}_${colIndex}`;\r\n let form = this.cellForms.get(key);\r\n\r\n if (!form) {\r\n form = new FormGroup({});\r\n this.cellForms.set(key, form);\r\n }\r\n return form;\r\n }\r\ntrackByFn(index: number, item: any) {\r\n return index; // or a unique identifier from your data\r\n}\r\n // This method is called whenever any @Input() property changes.\r\n ngOnChanges(changes: SimpleChanges): void {\r\n // Check if the 'data' property has changed.\r\n if (changes['data']) {\r\n const currentData = changes['data'].currentValue;\r\n const previousData = changes['data'].previousValue;\r\n\r\n\r\n // For example, you can call a method to re-render or process the data.\r\n this.refreshData();\r\n }\r\n }\r\n\r\n onLazyLoad(event: TableLazyLoadEvent): void {\r\n // Reinitialize forms on new data load\r\n // this.cellForms.clear();\r\n this.refreshData();\r\n this.pageChange.emit(event);\r\n }\r\n\r\n refreshData(){\r\n this.data_ = this.data.map(rowData => {\r\n // Create a new array of fields for each row\r\n const rowFields = (this.rowEditable ? this.columnFormFields :this.columns).map(col => {\r\n return cloneDeep(col);\r\n });\r\n // Attach the unique fields to the row data object\r\n return {\r\n ...rowData,\r\n rowFields: rowFields\r\n };\r\n });\r\n }\r\nonRowModelChange(rowData: any) {\r\n\r\n this.onInternalSelectionChange({\r\n data: rowData\r\n } as any);\r\n}\r\n get sortedActions(): ActionDef<T>[] {\r\n return this.actions\r\n .filter(action =>\r\n !action.permissions?.length || // no permissions → allow\r\n action.permissions.every(p => this.permissionsService.isGranted(p)) // all granted\r\n )\r\n .sort((a, b) => (a.order ?? 0) - (b.order ?? 0));\r\n}\r\n\r\n\r\ngetMenuItems(row: T): MenuItem[] {\r\n return this.sortedActions\r\n .filter(act => !act.visible || act.visible(row)) // فقط العناصر المرئية\r\n .map(act => ({\r\n label: this.translateService.instant(act.label ?? ''),\r\n icon: act.icon,\r\n styleClass: act.styleClass,\r\n command: (event: any) => {\r\n this.onAction(act, row);\r\n event.originalEvent.stopPropagation(); // لمنع تكرار الحدث\r\n event.item = act; // إذا احتجت للوصول للـ action\r\n }\r\n }));\r\n}\r\n\r\n\r\n // **جديد**: يتم إطلاق هذا عند اختيار صف\r\n onRowSelect(event: TableRowSelectEvent<T>) {\r\n //\r\n if (event.data) {\r\n this.rowSelect.emit(event.data as T);\r\n }\r\n }\r\n\r\n}\r\n","<div class=\"flex flex-col h-screen\" style=\" height: 60vh;\">\n <div class=\"flex-1 border rounded-lg overflow-hidden flex flex-col\">\n\n <!-- PrimeNG Table -->\n <p-table #dt\n [value]=\"data_\"\n [dataKey]=\"dataKey\"\n [columns]=\"columns\"\n [lazy]=\"true\"\n [paginator]=\"false\"\n [rows]=\"rows\"\n [first]=\"first\"\n [totalRecords]=\"totalRecords\"\n (onLazyLoad)=\"onLazyLoad($event)\"\n [globalFilterFields]=\"globalFilterFields\"\n [loading]=\"loading\"\n [scrollable]=\"true\"\n scrollHeight=\"flex\"\n [selectionMode]=\"showRowSelectionCheckbox ? 'multiple' : (rowSelectable ? 'single' : undefined)\"\n [(selection)]=\"_selection\"\n (onRowSelect)=\"onInternalSelectionChange($event)\"\n (onRowUnselect)=\"onInternalSelectionChange($event)\"\n (onHeaderCheckboxToggle)=\"onInternalSelectionChange($event)\"\n tableLayout=\"fixed\"\n [customSort]=\"false\"\n class=\"flex-1 overflow-auto\"\n >\n\n <!-- Empty message -->\n <ng-template pTemplate=\"emptymessage\">\n <tr>\n <td colspan=\"10\">\n <div class=\"flex flex-col items-center justify-center py-10 text-center w-full\">\n <i class=\"pi pi-inbox text-4xl text-gray-400 mb-4\"></i>\n <p class=\"text-gray-500 mb-4\">{{ 'NO_DATA_FOUND' | translate }}</p>\n\n @for (btn of addButtonConfigs; track trackByIdx($index, btn)) {\n @if (!btn.visible || btn.visible === true) {\n <lib-generic-button\n [icon]=\"btn.icon\"\n [label]=\"btn.label | translate\"\n [variant]=\"btn.variant\"\n [size]=\"btn.size\"\n [model]=\"btn.splitActions\"\n [permission]=\"btn.permission\"\n (clicked)=\"onAddNew.emit({ name: btn.actionName, row: null! })\"\n class=\"mb-2\"\n ></lib-generic-button>\n }\n }\n </div>\n </td>\n </tr>\n </ng-template>\n\n <!-- Table header -->\n <ng-template pTemplate=\"header\" let-columns>\n <tr class=\"bg-gray-200 sticky top-0 z-10\">\n @if (showRowSelectionCheckbox) {\n <th style=\"width: 2rem\">\n <p-tableHeaderCheckbox></p-tableHeaderCheckbox>\n </th>\n }\n @if (actions.length > 0 && actionsPosition === 'start') {\n <th class=\"px-4 py-2 text-sm font-medium text-center sticky right-0\">\n {{ '*' | translate }}\n </th>\n }\n @for (col of columns; track trackByFn($index, col)) {\n <th\n [pSortableColumn]=\"col.props.entityKey || col.key\"\n class=\"px-4 py-2 text-sm font-medium text-center\"\n [style.min-width]=\"col.props?.table?.props?.width || '150px'\"\n >\n {{ col.props?.label | translate }}\n <p-sortIcon [field]=\"col.props.entityKey || col.key\"></p-sortIcon>\n </th>\n }\n\n @if (actions.length > 0 && actionsPosition === 'end') {\n <th class=\"px-4 py-2 text-sm font-medium text-center sticky left-0\">\n {{ '*' | translate }}\n </th>\n }\n </tr>\n </ng-template>\n\n <!-- Table body -->\n <ng-template pTemplate=\"body\" let-rowData let-columns=\"columns\" let-i=\"rowIndex\">\n <tr class=\"even:bg-gray-50 hover:bg-gray-100 cursor-pointer\" (click)=\"rowSelect.emit(rowData)\">\n @if (showRowSelectionCheckbox) {\n <td style=\"width: 2rem\">\n <p-tableCheckbox [value]=\"rowData\"></p-tableCheckbox>\n </td>\n }\n @if (actions.length > 0 && actionsPosition === 'start') {\n <td class=\"border-t border-gray-200 px-4 py-2 text-center sticky right-0 bg-gray-50\">\n <ng-container\n *ngTemplateOutlet=\"actionsTemplate; context: {$implicit: rowData}\">\n </ng-container>\n </td>\n }\n\n @for (col of rowData.rowFields; track trackByFn(colIndex, col); let colIndex = $index) {\n <td\n class=\"border-t border-gray-200 px-4 py-2 text-center text-sm text-gray-700\"\n [style.width]=\"col.props?.table?.props?.width\"\n >\n <formly-form\n [model]=\"rowData\"\n [form]=\"getForm(i, colIndex)\"\n [fields]=\"[col]\"\n [options]=\"options\"\n (modelChange)=\"onRowModelChange(rowData)\"\n ></formly-form>\n </td>\n }\n\n @if (actions.length > 0 && actionsPosition === 'end') {\n <td class=\"border-t border-gray-200 px-4 py-2 text-center sticky left-0\">\n <ng-container\n *ngTemplateOutlet=\"actionsTemplate; context: {$implicit: rowData}\">\n </ng-container>\n </td>\n }\n </tr>\n\n </ng-template>\n\n\n </p-table>\n </div>\n</div>\n\n<ng-template #actionsTemplate let-rowData>\n @switch (actionsMode) {\n @case ('buttons') {\n @for (act of sortedActions; track act) {\n @if ((act.icon || act.label) && (!act.visible || act.visible(rowData))) {\n <button\n pButton\n [icon]=\"act.icon || ''\"\n [label]=\"(act.label ?? '') | translate\"\n [class]=\"act.styleClass || ''\"\n class=\"p-button-sm mx-1\"\n (click)=\"onAction(act, rowData)\">\n </button>\n }\n }\n }\n @case ('menu') {\n <app-action-menu [items]=\"getMenuItems(rowData) || []\"></app-action-menu>\n <!-- <p-menu #menu [model]=\"getMenuItems(rowData)\" [popup]=\"true\" appendTo=\"body\"></p-menu>\n <p-button\n outlined\n icon=\"pi pi-ellipsis-v\"\n class=\"p-button-text p-button-sm\"\n (onClick)=\"menu.toggle($event)\"\n ></p-button> -->\n }\n }\n</ng-template>\n\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":["i1"],"mappings":"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"}
1
+ {"version":3,"file":"es.framework-ng.ui.core-generic-table.mjs","sources":["../../../../libs/ng.ui.core/generic-table/src/lib/generic-table-module.ts","../../../../libs/ng.ui.core/generic-table/src/lib/action-menu.component.ts","../../../../libs/ng.ui.core/generic-table/src/lib/action-menu.component.html","../../../../libs/ng.ui.core/generic-table/src/lib/generic-table.ts","../../../../libs/ng.ui.core/generic-table/src/lib/generic-table.html","../../../../libs/ng.ui.core/generic-table/src/es.framework-ng.ui.core-generic-table.ts"],"sourcesContent":["import { NgModule } from '@angular/core';\nimport { CommonModule } from '@angular/common';\n\n@NgModule({\n imports: [CommonModule],\n})\nexport class GenericTableModule {}\n","\r\nimport { Component, Input, ViewChildren, QueryList, ElementRef } from '@angular/core';\r\nimport { MenuItem } from 'primeng/api';\r\nimport { ButtonModule } from 'primeng/button';\r\nimport { OverlayModule } from 'primeng/overlay';\r\n\r\n@Component({\r\n selector: 'app-action-menu',\r\n templateUrl: './action-menu.component.html',\r\n imports: [OverlayModule, ButtonModule],\r\n})\r\nexport class ActionMenuComponent {\r\n @Input() items: MenuItem[] = [];\r\n open = false;\r\n\r\n @ViewChildren('menuItem') menuItems!: QueryList<ElementRef<HTMLButtonElement>>;\r\n\r\n menuPositionClass = 'right-0';\r\n\r\n toggle() {\r\n this.open = !this.open;\r\n // Optional: adjust position when opening\r\n // if (this.open) setTimeout(() => this.adjustMenuPosition());\r\n }\r\n\r\n adjustMenuPosition() {\r\n const menu = document.querySelector('.absolute.mt-2') as HTMLElement;\r\n if (!menu) return;\r\n\r\n const rect = menu.getBoundingClientRect();\r\n const viewportWidth = window.innerWidth;\r\n\r\n this.menuPositionClass = rect.right > viewportWidth ? 'left-0' : 'right-0';\r\n }\r\n\r\n onClick(item: MenuItem, event: MouseEvent) {\r\n this.open = false;\r\n if (item.command) {\r\n item.command({ originalEvent: event, item });\r\n }\r\n }\r\n\r\n onOutsideClick(event: MouseEvent) {\r\n const target = event.target as HTMLElement;\r\n if (!target.closest('.inline-block')) {\r\n this.open = false;\r\n }\r\n }\r\n\r\n // ========================\r\n // Focus & Keyboard navigation\r\n // ========================\r\n focusFirst() {\r\n // Delay needed because overlay content is rendered asynchronously\r\n setTimeout(() => {\r\n this.menuItems.first?.nativeElement.focus();\r\n });\r\n }\r\n\r\n // -------------------\r\n // Keyboard on menu container\r\n // -------------------\r\n onMenuKeydown(event: KeyboardEvent) {\r\n // Convert QueryList to array of HTMLButtonElement\r\n const items: HTMLButtonElement[] = this.menuItems.toArray().map(i => i.nativeElement as HTMLButtonElement);\r\n\r\n let index = items.indexOf(document.activeElement as HTMLButtonElement);\r\n if (index === -1) return;\r\n\r\n switch (event.key) {\r\n case 'ArrowDown':\r\n event.preventDefault();\r\n index = (index + 1) % items.length;\r\n items[index].focus();\r\n break;\r\n\r\n case 'ArrowUp':\r\n event.preventDefault();\r\n index = (index - 1 + items.length) % items.length;\r\n items[index].focus();\r\n break;\r\n\r\n case 'Enter':\r\n case ' ':\r\n event.preventDefault();\r\n items[index].click();\r\n break;\r\n\r\n case 'Escape':\r\n this.open = false;\r\n break;\r\n }\r\n}\r\n\r\n\r\n\r\n onTriggerKeydown(event: KeyboardEvent) {\r\n // Open overlay via keyboard\r\n if (event.key === 'ArrowDown' || event.key === 'Enter' || event.key === ' ') {\r\n event.preventDefault();\r\n this.open = true;\r\n this.focusFirst();\r\n }\r\n }\r\n}\r\n","<div class=\"inline-block relative\">\n <button type=\"button\"\n class=\"p-ripple p-button p-button-icon-only p-button-outlined p-component\"\n #trigger\n (click)=\"toggle()\">\n <span class=\"pi pi-ellipsis-v\"></span>\n </button>\n\n <p-overlay [(visible)]=\"open\" [appendTo]=\"'body'\" (onShow)=\"focusFirst()\">\n <div class=\"w-48 rounded-lg shadow-lg bg-white border border-gray-200\"\n tabindex=\"0\"\n (keydown)=\"onMenuKeydown($event)\">\n @for (item of items; track item) {\n <button #menuItem\n (click)=\"onClick(item, $event)\"\n class=\"flex items-center w-full text-left px-4 py-2 text-sm hover:bg-gray-100 focus:bg-gray-100 focus:outline-none\">\n @if (item.icon) {\n <i [class]=\"item.icon + ' ml-2 mr-2 text-gray-500'\"></i>\n }\n <span>{{ item.label }}</span>\n </button>\n }\n </div>\n </p-overlay>\n</div>\n","import { Component, Input, Output, EventEmitter, ViewChild, OnChanges, SimpleChanges, inject, OnInit } from '@angular/core';\r\nimport { MenuItem, SortEvent } from 'primeng/api';\r\nimport { Table, TableHeaderCheckboxToggleEvent, TableLazyLoadEvent, TableRowSelectEvent } from 'primeng/table';\r\nimport { CommonModule } from '@angular/common';\r\nimport { TableModule } from 'primeng/table';\r\nimport { ButtonModule, Button } from 'primeng/button';\r\nimport { MenuModule, Menu } from 'primeng/menu';\r\nimport { TranslatePipe } from '@es.framework/ng.core/pipes';\r\nimport { FormlyField, FormlyFieldConfig, FormlyForm, FormlyFormOptions } from '@ngx-formly/core';\r\nimport { FormGroup } from '@angular/forms';\r\nimport { ActionDef, ButtonConfig } from '@es.framework/ng.core/models';\r\nimport { cloneDeep, forEach } from 'lodash';\r\nimport { GenericButton } from '@es.framework/ng.ui.core/generic-button';\r\nimport { PaginatorModule } from 'primeng/paginator';\r\nimport { ActionMenuComponent } from './action-menu.component';\r\nimport { LocalizationService, PermissionCheckerService } from '@es.framework/ng.core/services';\r\n\r\n@Component({\r\n selector: 'lib-generic-table',\r\n imports: [CommonModule, TableModule, ButtonModule, MenuModule, TranslatePipe, FormlyField, FormlyForm, TranslatePipe, Menu, Button, GenericButton, PaginatorModule, ActionMenuComponent],\r\n templateUrl: './generic-table.html',\r\n styleUrl: './generic-table.css'\r\n})\r\nexport class GenericTable<T> implements OnInit, OnChanges{\r\n\r\n\r\n translateService:LocalizationService = inject(LocalizationService);\r\n permissionsService:PermissionCheckerService = inject(PermissionCheckerService);\r\n\r\n@ViewChild('dt') dt!: Table;\r\n\r\n@Input() data: any[] = [];\r\n data_: any[] = [];\r\n @Input() columns: FormlyFieldConfig[] = [];\r\n processedFields: any[] = [];\r\n @Input() columnFormFields: FormlyFieldConfig[] = [];\r\n @Input() loading = false;\r\n @Input() actions: ActionDef<T>[] = [];\r\n @Input() actionsPosition: 'start' | 'end' = 'end';\r\n @Input() actionsMode: 'buttons' | 'menu' = 'buttons';\r\n @Input() first = 0;\r\n @Input() rows = 10;\r\n @Input() totalRecords = 0;\r\n @Input() sortField?: string;\r\n @Input() sortOrder: 1 | -1 = 1;\r\n @Input() globalFilterFields: string[] = [];\r\n\r\n @Output() action = new EventEmitter<{ name: string; row: T }>();\r\n @Output() pageChange = new EventEmitter<TableLazyLoadEvent>();\r\n\r\n // eslint-disable-next-line @angular-eslint/no-output-on-prefix\r\n @Output() onAddNew = new EventEmitter<any>();\r\n@Input() addButtonConfigs: ButtonConfig[] = [];\r\n @Input() scrollHeight = '400px';\r\n\r\n // **جديد**: تمكين تعديل الصفوف\r\n @Input() rowEditable = false;\r\n // **جديد**: تمكين اختيار الصفوف\r\n /** فعّل اختيار الصفين single/multiple */\r\n @Input() rowSelectable = true;\r\n /** يحتفظ بالصف المحدد */\r\n //@Input() selection: T | T[] | null = null;\r\n\r\n // هذا سيكون مرتبطًا بـ [(selection)] في p-table\r\n _selection: T | T[] | null = null;\r\n\r\n\r\n @Input()\r\n get selection(): T | T[] | null {\r\n return this._selection;\r\n }\r\n set selection(val: T | T[] | null) {\r\n this._selection = val;\r\n // لا تُصدر الحدث هنا، بل في onInternalSelectionChange فقط\r\n }\r\n\r\n trackByIdx(index: number, item: any): number {\r\n return index;\r\n }\r\n /** يصدر الصف المحدد عند النقر */\r\n @Output() rowSelect = new EventEmitter<T>();\r\n\r\n @Input() dataKey = 'id';\r\n\r\n /** يصدر الصفوف المحددة عند التغيير (للربط الثنائي) */\r\n @Output() selectionChange = new EventEmitter<T | T[] | null>();\r\n\r\n\r\n /** جديد: التحكم بظهور الـ paginator */\r\n @Input() paginator = true;\r\nform = new FormGroup({});\r\noptions: FormlyFormOptions = {};\r\n\r\n\r\n\r\n // **جديد**: يتحكم بإظهار عمود اختيار الصفوف (checkboxes)\r\n /** يتحكم في إظهار عمود اختيار الصفوف المتعددة بواسطة checkboxes */\r\n @Input() showRowSelectionCheckbox = false;\r\n\r\n\r\n menuItems : MenuItem[] = [];\r\n\r\n ngOnInit(): void {\r\n // this.menuItems = this.getMenuItems();\r\n }\r\n// onInternalSelectionChange(event: TableRowSelectEvent<T>\r\n// | TableHeaderCheckboxToggleEvent): void {\r\n// if ('data' in event) {\r\n// // Row select/unselect (single أو multiple)\r\n// if (Array.isArray(this._selection)) {\r\n// this._selection = [...this._selection]; // تحديث نسخة المصفوفة عند متعدد\r\n// } else {\r\n// this._selection = event.data as T; // اختيار فردي\r\n// }\r\n// } else if ('checked' in event) {\r\n// // Header checkbox toggle\r\n// this._selection = event.checked ? [...this.data] : [];\r\n// }\r\n\r\n// this.selectionChange.emit(this._selection);\r\n// }\r\nonInternalSelectionChange(\r\n event: TableRowSelectEvent<T> | TableHeaderCheckboxToggleEvent,\r\n selected?: boolean\r\n): void {\r\n\r\n // ───────────── Header checkbox ─────────────\r\n if ('checked' in event) {\r\n this._selection = event.checked ? [...this.data] : [];\r\n this.selectionChange.emit(this._selection);\r\n return;\r\n }\r\n\r\n const row = event.data as T;\r\n\r\n // ───────────── MULTI SELECTION ─────────────\r\n if (Array.isArray(this._selection)) {\r\n const index = this._selection.findIndex(\r\n r => this.isSameRow(r, row)\r\n );\r\n\r\n if (selected === false) {\r\n this._selection = this._selection.filter(\r\n r => !this.isSameRow(r, row)\r\n );\r\n } else if (index === -1) {\r\n // Not selected → add\r\n this._selection = [...this._selection, row];\r\n } else {\r\n // Already selected → REPLACE with edited row\r\n this._selection = this._selection.map((r, i) =>\r\n i === index ? row : r\r\n );\r\n }\r\n }\r\n // ───────────── SINGLE SELECTION ─────────────\r\n else {\r\n this._selection = selected === false ? null : row;\r\n }\r\n\r\n this.selectionChange.emit(this._selection);\r\n}\r\n\r\n\r\nprivate isSameRow(a: T, b: T): boolean {\r\n const aKey = this.resolveFieldData(a, this.dataKey);\r\n const bKey = this.resolveFieldData(b, this.dataKey);\r\n\r\n if (aKey != null && bKey != null) {\r\n return aKey === bKey;\r\n }\r\n\r\n return a === b;\r\n}\r\n\r\nresolveFieldData(data: any, field: string): any {\r\n if (!field) return null;\r\n if (field.indexOf('.') === -1) return data[field];\r\n return field.split('.').reduce((obj, prop) => (obj ? obj[prop] : null), data);\r\n}\r\n\r\n onAction(act: ActionDef<T>, row: T) {\r\n if (act.action) {\r\n act.action(row);\r\n } else {\r\n this.action.emit({ name: act.name, row });\r\n }\r\n }\r\n\r\n // Use a map to store form groups for each row and column\r\n private cellForms: Map<string, FormGroup> = new Map();\r\n forms: FormGroup = new FormGroup({}); // A main form for the table\r\n\r\n\r\n // Refactored getForm to return an existing form instance\r\n getForm(rowIndex: number, colIndex: number): FormGroup {\r\n const key = `${rowIndex}_${colIndex}`;\r\n let form = this.cellForms.get(key);\r\n\r\n if (!form) {\r\n form = new FormGroup({});\r\n this.cellForms.set(key, form);\r\n }\r\n return form;\r\n }\r\ntrackByFn(index: number, item: any) {\r\n return index; // or a unique identifier from your data\r\n}\r\n // This method is called whenever any @Input() property changes.\r\n ngOnChanges(changes: SimpleChanges): void {\r\n // Check if the 'data' property has changed.\r\n if (changes['data']) {\r\n const currentData = changes['data'].currentValue;\r\n const previousData = changes['data'].previousValue;\r\n\r\n\r\n // For example, you can call a method to re-render or process the data.\r\n this.refreshData();\r\n }\r\n }\r\n\r\n onLazyLoad(event: TableLazyLoadEvent): void {\r\n // Reinitialize forms on new data load\r\n // this.cellForms.clear();\r\n this.refreshData();\r\n this.pageChange.emit(event);\r\n }\r\n\r\n refreshData(){\r\n this.data_ = this.data.map(rowData => {\r\n // Create a new array of fields for each row\r\n const rowFields = (this.rowEditable ? this.columnFormFields :this.columns).map(col => {\r\n return cloneDeep(col);\r\n });\r\n // Attach the unique fields to the row data object\r\n return {\r\n ...rowData,\r\n rowFields: rowFields\r\n };\r\n });\r\n }\r\nonRowModelChange(rowData: any) {\r\n\r\n this.onInternalSelectionChange({\r\n data: rowData\r\n } as any);\r\n}\r\n get sortedActions(): ActionDef<T>[] {\r\n return this.actions\r\n .filter(action =>\r\n !action.permissions?.length || // no permissions → allow\r\n action.permissions.every(p => this.permissionsService.isGranted(p)) // all granted\r\n )\r\n .sort((a, b) => (a.order ?? 0) - (b.order ?? 0));\r\n}\r\n\r\n\r\ngetMenuItems(row: T): MenuItem[] {\r\n return this.sortedActions\r\n .filter(act => !act.visible || act.visible(row)) // فقط العناصر المرئية\r\n .map(act => ({\r\n label: this.translateService.instant(act.label ?? ''),\r\n icon: act.icon,\r\n styleClass: act.styleClass,\r\n command: (event: any) => {\r\n this.onAction(act, row);\r\n event.originalEvent.stopPropagation(); // لمنع تكرار الحدث\r\n event.item = act; // إذا احتجت للوصول للـ action\r\n }\r\n }));\r\n}\r\n\r\n\r\n // **جديد**: يتم إطلاق هذا عند اختيار صف\r\n onRowSelect(event: TableRowSelectEvent<T>) {\r\n //\r\n if (event.data) {\r\n this.rowSelect.emit(event.data as T);\r\n }\r\n }\r\n\r\n}\r\n","<div class=\"flex flex-col h-screen\" style=\" height: 60vh;\">\n <div class=\"flex-1 border rounded-lg overflow-hidden flex flex-col\">\n\n <!-- PrimeNG Table -->\n <p-table #dt\n [value]=\"data_\"\n [dataKey]=\"dataKey\"\n [columns]=\"columns\"\n [lazy]=\"true\"\n [paginator]=\"false\"\n [rows]=\"rows\"\n [first]=\"first\"\n [totalRecords]=\"totalRecords\"\n (onLazyLoad)=\"onLazyLoad($event)\"\n [globalFilterFields]=\"globalFilterFields\"\n [loading]=\"loading\"\n [scrollable]=\"true\"\n scrollHeight=\"flex\"\n [selectionMode]=\"showRowSelectionCheckbox ? 'multiple' : (rowSelectable ? 'single' : undefined)\"\n [(selection)]=\"_selection\"\n (onRowSelect)=\"onInternalSelectionChange($event, true)\"\n (onRowUnselect)=\"onInternalSelectionChange($event, false)\"\n (onHeaderCheckboxToggle)=\"onInternalSelectionChange($event)\"\n tableLayout=\"fixed\"\n [customSort]=\"false\"\n class=\"flex-1 overflow-auto\"\n >\n\n <!-- Empty message -->\n <ng-template pTemplate=\"emptymessage\">\n <tr>\n <td colspan=\"10\">\n <div class=\"flex flex-col items-center justify-center py-10 text-center w-full\">\n <i class=\"pi pi-inbox text-4xl text-gray-400 mb-4\"></i>\n <p class=\"text-gray-500 mb-4\">{{ 'NO_DATA_FOUND' | translate }}</p>\n\n @for (btn of addButtonConfigs; track trackByIdx($index, btn)) {\n @if (!btn.visible || btn.visible === true) {\n <lib-generic-button\n [icon]=\"btn.icon\"\n [label]=\"btn.label | translate\"\n [variant]=\"btn.variant\"\n [size]=\"btn.size\"\n [model]=\"btn.splitActions\"\n [permission]=\"btn.permission\"\n (clicked)=\"onAddNew.emit({ name: btn.actionName, row: null! })\"\n class=\"mb-2\"\n ></lib-generic-button>\n }\n }\n </div>\n </td>\n </tr>\n </ng-template>\n\n <!-- Table header -->\n <ng-template pTemplate=\"header\" let-columns>\n <tr class=\"bg-gray-200 sticky top-0 z-10\">\n @if (showRowSelectionCheckbox) {\n <th style=\"width: 2rem\">\n <p-tableHeaderCheckbox></p-tableHeaderCheckbox>\n </th>\n }\n @if (actions.length > 0 && actionsPosition === 'start') {\n <th class=\"px-4 py-2 text-sm font-medium text-center sticky right-0\">\n {{ '*' | translate }}\n </th>\n }\n @for (col of columns; track trackByFn($index, col)) {\n <th\n [pSortableColumn]=\"col.props.entityKey || col.key\"\n class=\"px-4 py-2 text-sm font-medium text-center\"\n [style.min-width]=\"col.props?.table?.props?.width || '150px'\"\n >\n {{ col.props?.label | translate }}\n <p-sortIcon [field]=\"col.props.entityKey || col.key\"></p-sortIcon>\n </th>\n }\n\n @if (actions.length > 0 && actionsPosition === 'end') {\n <th class=\"px-4 py-2 text-sm font-medium text-center sticky left-0\">\n {{ '*' | translate }}\n </th>\n }\n </tr>\n </ng-template>\n\n <!-- Table body -->\n <ng-template pTemplate=\"body\" let-rowData let-columns=\"columns\" let-i=\"rowIndex\">\n <tr class=\"even:bg-gray-50 hover:bg-gray-100 cursor-pointer\" (click)=\"rowSelect.emit(rowData)\">\n @if (showRowSelectionCheckbox) {\n <td style=\"width: 2rem\">\n <p-tableCheckbox [value]=\"rowData\"></p-tableCheckbox>\n </td>\n }\n @if (actions.length > 0 && actionsPosition === 'start') {\n <td class=\"border-t border-gray-200 px-4 py-2 text-center sticky right-0 bg-gray-50\">\n <ng-container\n *ngTemplateOutlet=\"actionsTemplate; context: {$implicit: rowData}\">\n </ng-container>\n </td>\n }\n\n @for (col of rowData.rowFields; track trackByFn(colIndex, col); let colIndex = $index) {\n <td\n class=\"border-t border-gray-200 px-4 py-2 text-center text-sm text-gray-700\"\n [style.width]=\"col.props?.table?.props?.width\"\n >\n <formly-form\n [model]=\"rowData\"\n [form]=\"getForm(i, colIndex)\"\n [fields]=\"[col]\"\n [options]=\"options\"\n (modelChange)=\"onRowModelChange(rowData)\"\n ></formly-form>\n </td>\n }\n\n @if (actions.length > 0 && actionsPosition === 'end') {\n <td class=\"border-t border-gray-200 px-4 py-2 text-center sticky left-0\">\n <ng-container\n *ngTemplateOutlet=\"actionsTemplate; context: {$implicit: rowData}\">\n </ng-container>\n </td>\n }\n </tr>\n\n </ng-template>\n\n\n </p-table>\n </div>\n</div>\n\n<ng-template #actionsTemplate let-rowData>\n @switch (actionsMode) {\n @case ('buttons') {\n @for (act of sortedActions; track act) {\n @if ((act.icon || act.label) && (!act.visible || act.visible(rowData))) {\n <button\n pButton\n [icon]=\"act.icon || ''\"\n [label]=\"(act.label ?? '') | translate\"\n [class]=\"act.styleClass || ''\"\n class=\"p-button-sm mx-1\"\n (click)=\"onAction(act, rowData)\">\n </button>\n }\n }\n }\n @case ('menu') {\n <app-action-menu [items]=\"getMenuItems(rowData) || []\"></app-action-menu>\n <!-- <p-menu #menu [model]=\"getMenuItems(rowData)\" [popup]=\"true\" appendTo=\"body\"></p-menu>\n <p-button\n outlined\n icon=\"pi pi-ellipsis-v\"\n class=\"p-button-text p-button-sm\"\n (onClick)=\"menu.toggle($event)\"\n ></p-button> -->\n }\n }\n</ng-template>\n\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":["i1"],"mappings":"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"}
@@ -342,7 +342,7 @@ class GenericViewComponent {
342
342
  // this.goToMode(currentMode);
343
343
  }
344
344
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: GenericViewComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: i1.DynamicDialogRef, optional: true }, { token: i1.DynamicDialogConfig, optional: true }], target: i0.ɵɵFactoryTarget.Component });
345
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.3", type: GenericViewComponent, isStandalone: true, selector: "app-detail-view", inputs: { title: "title", actions: "actions", createEditActions: "createEditActions", tabs: "tabs", viewMode: "viewMode", breadcrumb: "breadcrumb", service: "service", formFields: "formFields", apiName: "apiName", moduleName: "moduleName", idField: "idField", standaloneMode: "standaloneMode", useRouteParams: "useRouteParams", query: "query", currentId: "currentId", useTabs: "useTabs", isViewMode: "isViewMode", isCreateMode: "isCreateMode", isEditMode: "isEditMode", model: "model", displayMode: "displayMode", mode: "mode", loading: "loading", showToolbar: "showToolbar" }, outputs: { action: "action", afterDelete: "afterDelete" }, providers: [DialogService, BaseService, RestService], viewQueries: [{ propertyName: "dialog", first: true, predicate: ["dialog"], descendants: true }, { propertyName: "inlineForm", first: true, predicate: ["inlineForm"], descendants: true }], ngImport: i0, template: "@if (mode === 'detail') {\n<div class=\"w-full flex flex-col gap-3\">\n <!-- overlay -->\n @if (loading) {\n <div \n class=\"absolute inset-0 bg-white/70 flex items-center justify-center z-50\">\n <p-progress-spinner/>\n </div>\n}\n\n <!-- actual content -->\n <!-- Toolbar -->\n @if (showToolbar) {\n <!-- background: transparent; -->\n <p-toolbar style=\"border: 0px;box-shadow: none;\" class=\"toolbar-top bg-white shadow-none border-none rounded-md px-3\">\n <ng-template pTemplate=\"left\">\n <!-- <span class=\"font-semibold text-lg xs:hidden block\">{{ title }}</span> -->\n <app-breadcrumb class=\"xs:block\" [breadcrumb]=\"breadcrumb\"></app-breadcrumb> <!-- xs:block hidden -->\n </ng-template>\n <ng-template pTemplate=\"right\">\n <div class=\"flex gap-2\">\n\n <button\n pButton pRipple\n icon=\"pi pi-chevron-right\"\n class=\"p-button-text p-button-sm fd-btn\"\n pTooltip=\"\u0627\u0644\u062A\u0627\u0644\u064A\"\n (click)=\"next()\"\n ></button>\n <button\n pButton pRipple\n icon=\"pi pi-chevron-left\"\n class=\"p-button-text p-button-sm fd-btn\"\n pTooltip=\"\u0627\u0644\u0633\u0627\u0628\u0642\"\n (click)=\"previous()\"\n ></button>\n </div>\n </ng-template>\n </p-toolbar>\n\n <p-toolbar class=\"toolbar-bottom bg-white shadow rounded-md px-3\">\n\n <ng-template pTemplate=\"left\">\n @if (isViewMode) {\n <div class=\"flex gap-1\">\n @for (action of actions_; track $index) {\n <button\n pButton pRipple\n [icon]=\"action.icon ?? ''\"\n [label]=\"(action.label ?? '') | translate\"\n class=\"fd-btn\"\n (click)=\"onAction(action,model)\"\n ></button>\n }\n </div>\n }\n </ng-template>\n <ng-template pTemplate=\"right\">\n @if (isEditMode || isCreateMode) {\n <div class=\"flex gap-1\">\n @for (btn of createEditActions; track $index) {\n @if (!btn.visible || (btn.visible && btn.visible === true)) {\n @if (btn.type === 'submit' && inlineForm) {\n <lib-generic-button\n [type]=\"'submit'\"\n [loading]=\"inlineForm.loading\"\n [disabled]=\"inlineForm.loading || form.invalid\"\n [icon]=\"btn.icon\"\n [label]=\"btn.label | translate\"\n [variant]=\"btn.variant\"\n [severity]=\"btn.severity\"\n [size]=\"btn.size\"\n [model]=\"btn.splitActions\"\n [permission]=\"btn.permission\"\n (clicked)=\"inlineForm.onSubmit()\"\n ></lib-generic-button>\n }\n @else{\n <lib-generic-button\n [icon]=\"btn.icon\"\n [label]=\"btn.label | translate\"\n [variant]=\"btn.variant\"\n [severity]=\"btn.severity\"\n [size]=\"btn.size\"\n [model]=\"btn.splitActions\"\n [permission]=\"btn.permission\"\n (clicked)=\"handleCreateEditAction(btn)\"\n ></lib-generic-button>\n }\n }\n }\n </div>\n }\n </ng-template>\n\n </p-toolbar>\n}\n\n <!-- Tabs -->\n <ng-template #tabContent let-tab let-i=\"index\">\n <div>\n \n <!-- First tab special handling -->\n @if (tab.fields.length && i === 0) {\n @if(form){\n\n \n <form [formGroup]=\"form\">\n\n @if (isEditMode || isCreateMode) {\n <app-generic-dialog\n #inlineForm\n [form]=\"form\"\n [model]=\"model\"\n [formFields]=\"formFields ?? []\"\n [apiName]=\"apiName\"\n [idField]=\"idField ?? 'id'\"\n [moduleName]=\"moduleName\"\n [displayMode]=\"'inline'\"\n [mode]=\"'form-only'\"\n [forceState]=\"isCreateMode ? 'create':'edit'\"\n (afterSave)=\"afterSave($event)\">\n </app-generic-dialog>\n }\n @else if (isViewMode) {\n <formly-form\n [form]=\"form\"\n [fields]=\"tab.fields\"\n [model]=\"model\">\n </formly-form>\n }\n\n </form>\n }\n }\n\n <!-- \u0628\u0627\u0642\u064A \u0627\u0644\u062A\u0627\u0628\u0627\u062A -->\n @if (tab.fields.length && i > 0) {\n <formly-form\n [form]=\"getForm(i)\"\n [fields]=\"tab.fields\"\n [model]=\"tab.model || model\">\n </formly-form>\n }\n\n <!-- Custom template -->\n @if (tab.content) {\n <ng-container\n *ngTemplateOutlet=\"tab.content; context: { model: model }\">\n </ng-container>\n }\n\n </div>\n</ng-template>\n@if (useTabs) {\n <p-tabs value=\"0\">\n <p-tablist>\n @for (tab of tabs_; track $index) {\n <p-tab value=\"{{$index}}\">\n <i [class]=\"tab.icon\"></i>\n <span class=\"mr-1 ml-1\">{{ tab.header | translate }}</span>\n </p-tab>\n }\n </p-tablist>\n\n <p-tabpanels>\n @for (tab of tabs_; track $index) {\n <p-tabpanel value=\"{{$index}}\">\n <ng-container\n *ngTemplateOutlet=\"tabContent; context: { $implicit: tab, index: $index }\">\n </ng-container>\n </p-tabpanel>\n }\n </p-tabpanels>\n </p-tabs>\n}\n@else {\n <div class=\"flex flex-column gap-4\">\n @for (tab of tabs_; track $index) {\n\n <!-- Optional header -->\n <!-- <div class=\"font-bold text-lg\">\n <i [class]=\"tab.icon\"></i>\n <span class=\"ml-2\">{{ tab.header | translate }}</span>\n </div> -->\n\n <ng-container\n *ngTemplateOutlet=\"tabContent; context: { $implicit: tab, index: $index }\">\n </ng-container>\n\n }\n </div>\n}\n</div>\n\n<!-- [model]=\"model\" -->\n <app-generic-dialog\n #dialog\n [formFields]=\"formFields ?? []\"\n [apiName]=\"apiName\"\n [idField]=\"idField ??'id'\"\n [moduleName]=\"moduleName\"\n [displayMode]=\"displayMode ?? 'dialog'\"\n (afterSave)=\"afterSave($event)\"\n >\n </app-generic-dialog>\n}\n", styles: [".toolbar-top{position:sticky;top:0;z-index:1000}.toolbar-bottom{position:sticky;top:48px;z-index:999}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: ToolbarModule }, { kind: "component", type: i3.Toolbar, selector: "p-toolbar", inputs: ["styleClass", "ariaLabelledBy"] }, { kind: "directive", type: i4.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "directive", type: i5.ButtonDirective, selector: "[pButton]", inputs: ["ptButtonDirective", "hostName", "text", "plain", "raised", "size", "outlined", "rounded", "iconPos", "loadingIcon", "fluid", "label", "icon", "loading", "buttonProps", "severity"] }, { kind: "ngmodule", type: TabsModule }, { kind: "component", type: i6.Tabs, selector: "p-tabs", inputs: ["value", "scrollable", "lazy", "selectOnFocus", "showNavigators", "tabindex"], outputs: ["valueChange"] }, { kind: "component", type: i6.TabPanels, selector: "p-tabpanels" }, { kind: "component", type: i6.TabPanel, selector: "p-tabpanel", inputs: ["lazy", "value"], outputs: ["valueChange"] }, { kind: "component", type: i6.TabList, selector: "p-tablist" }, { kind: "component", type: i6.Tab, selector: "p-tab", inputs: ["value", "disabled"], outputs: ["valueChange"] }, { kind: "component", type: FormlyForm, selector: "formly-form", inputs: ["form", "model", "fields", "options"], outputs: ["modelChange"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i7.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i7.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i7.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: BreadcrumbComponent, selector: "app-breadcrumb", inputs: ["breadcrumb"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i8.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions", "appendTo", "ptTooltip"] }, { kind: "component", type: GenericDialogComponent, selector: "app-generic-dialog", inputs: ["form", "service", "formFields", "model", "apiName", "moduleName", "idField", "dialogMaxWidth", "displayMode", "mode", "forceState", "drawerVisible", "dialogVisible", "isViewMode", "isEditMode", "useConfirmOnSave", "loading", "errorMsg", "errorMessage", "beforeSaveTransform", "hideTable", "autoShowForm"], outputs: ["action", "afterSave", "afterDelete", "beforeSave", "beforeDelete", "formCancel", "formInit", "dataLoaded", "selectionChange", "error", "visibleChange"] }, { kind: "component", type: GenericButton, selector: "lib-generic-button", inputs: ["model", "type", "icon", "label", "variant", "severity", "size", "iconPosition", "disabled", "loading", "ariaLabel", "extraClasses", "permission"], outputs: ["clicked", "itemClick"] }, { kind: "ngmodule", type: ProgressSpinnerModule }, { kind: "component", type: i9.ProgressSpinner, selector: "p-progressSpinner, p-progress-spinner, p-progressspinner", inputs: ["styleClass", "strokeWidth", "fill", "animationDuration", "ariaLabel"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] });
345
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.3", type: GenericViewComponent, isStandalone: true, selector: "app-detail-view", inputs: { title: "title", actions: "actions", createEditActions: "createEditActions", tabs: "tabs", viewMode: "viewMode", breadcrumb: "breadcrumb", service: "service", formFields: "formFields", apiName: "apiName", moduleName: "moduleName", idField: "idField", standaloneMode: "standaloneMode", useRouteParams: "useRouteParams", query: "query", currentId: "currentId", useTabs: "useTabs", isViewMode: "isViewMode", isCreateMode: "isCreateMode", isEditMode: "isEditMode", model: "model", displayMode: "displayMode", mode: "mode", loading: "loading", showToolbar: "showToolbar" }, outputs: { action: "action", afterDelete: "afterDelete" }, providers: [DialogService, BaseService, RestService], viewQueries: [{ propertyName: "dialog", first: true, predicate: ["dialog"], descendants: true }, { propertyName: "inlineForm", first: true, predicate: ["inlineForm"], descendants: true }], ngImport: i0, template: "@if (mode === 'detail') {\n<div class=\"w-full flex flex-col gap-3\">\n <!-- overlay -->\n @if (loading) {\n <div \n class=\"absolute inset-0 bg-white/70 flex items-center justify-center z-50\">\n <p-progress-spinner/>\n </div>\n}\n\n <!-- actual content -->\n <!-- Toolbar -->\n @if (showToolbar) {\n <!-- background: transparent; -->\n <p-toolbar style=\"border: 0px;box-shadow: none;\" class=\"toolbar-top bg-white shadow-none border-none rounded-md px-3\">\n <ng-template pTemplate=\"left\">\n <!-- <span class=\"font-semibold text-lg xs:hidden block\">{{ title }}</span> -->\n <app-breadcrumb class=\"xs:block\" [breadcrumb]=\"breadcrumb\"></app-breadcrumb> <!-- xs:block hidden -->\n </ng-template>\n <ng-template pTemplate=\"right\">\n <div class=\"flex gap-2\">\n\n <button\n pButton pRipple\n icon=\"pi pi-chevron-right\"\n class=\"p-button-text p-button-sm fd-btn\"\n pTooltip=\"\u0627\u0644\u062A\u0627\u0644\u064A\"\n (click)=\"next()\"\n ></button>\n <button\n pButton pRipple\n icon=\"pi pi-chevron-left\"\n class=\"p-button-text p-button-sm fd-btn\"\n pTooltip=\"\u0627\u0644\u0633\u0627\u0628\u0642\"\n (click)=\"previous()\"\n ></button>\n </div>\n </ng-template>\n </p-toolbar>\n\n <p-toolbar class=\"toolbar-bottom bg-white shadow rounded-md px-3\">\n\n <ng-template pTemplate=\"left\">\n @if (isViewMode) {\n <div class=\"flex gap-1\">\n @for (action of actions_; track $index) {\n <button\n pButton pRipple\n [icon]=\"action.icon ?? ''\"\n [label]=\"(action.label ?? '') | translate\"\n class=\"fd-btn\"\n (click)=\"onAction(action,model)\"\n ></button>\n }\n </div>\n }\n </ng-template>\n <ng-template pTemplate=\"right\">\n @if (isEditMode || isCreateMode) {\n <div class=\"flex gap-1\">\n @for (btn of createEditActions; track $index) {\n @if (!btn.visible || (btn.visible && btn.visible === true)) {\n @if (btn.type === 'submit' && inlineForm) {\n <lib-generic-button\n [type]=\"'submit'\"\n [loading]=\"inlineForm.loading\"\n [disabled]=\"inlineForm.loading || form.invalid\"\n [icon]=\"btn.icon\"\n [label]=\"btn.label | translate\"\n [variant]=\"btn.variant\"\n [severity]=\"btn.severity\"\n [size]=\"btn.size\"\n [model]=\"btn.splitActions\"\n [permission]=\"btn.permission\"\n (clicked)=\"inlineForm.onSubmit()\"\n ></lib-generic-button>\n }\n @else{\n <lib-generic-button\n [icon]=\"btn.icon\"\n [label]=\"btn.label | translate\"\n [variant]=\"btn.variant\"\n [severity]=\"btn.severity\"\n [size]=\"btn.size\"\n [model]=\"btn.splitActions\"\n [permission]=\"btn.permission\"\n (clicked)=\"handleCreateEditAction(btn)\"\n ></lib-generic-button>\n }\n }\n }\n </div>\n }\n </ng-template>\n\n </p-toolbar>\n}\n\n <!-- Tabs -->\n <ng-template #tabContent let-tab let-i=\"index\">\n <div>\n \n <!-- First tab special handling -->\n @if (tab.fields.length && i === 0) {\n @if(form){\n\n \n <form [formGroup]=\"form\">\n\n @if (isEditMode || isCreateMode) {\n <app-generic-dialog\n #inlineForm\n [form]=\"form\"\n [model]=\"model\"\n [formFields]=\"formFields ?? []\"\n [apiName]=\"apiName\"\n [idField]=\"idField ?? 'id'\"\n [moduleName]=\"moduleName\"\n [displayMode]=\"'inline'\"\n [mode]=\"'form-only'\"\n [forceState]=\"isCreateMode ? 'create':'edit'\"\n (afterSave)=\"afterSave($event)\">\n </app-generic-dialog>\n }\n @else if (isViewMode) {\n <formly-form\n [form]=\"form\"\n [fields]=\"tab.fields\"\n [model]=\"model\">\n </formly-form>\n }\n\n </form>\n }\n }\n\n <!-- \u0628\u0627\u0642\u064A \u0627\u0644\u062A\u0627\u0628\u0627\u062A -->\n @if (tab.fields.length && i > 0) {\n <formly-form\n [form]=\"getForm(i)\"\n [fields]=\"tab.fields\"\n [model]=\"tab.model || model\">\n </formly-form>\n }\n\n <!-- Custom template -->\n @if (tab.content) {\n <ng-container\n *ngTemplateOutlet=\"tab.content; context: { model: model }\">\n </ng-container>\n }\n\n </div>\n</ng-template>\n@if (useTabs) {\n <p-tabs value=\"0\">\n <p-tablist>\n @for (tab of tabs_; track $index) {\n <p-tab value=\"{{$index}}\">\n <i [class]=\"tab.icon\"></i>\n <span class=\"mr-1 ml-1\">{{ tab.header | translate }}</span>\n </p-tab>\n }\n </p-tablist>\n\n <p-tabpanels>\n @for (tab of tabs_; track $index) {\n <p-tabpanel value=\"{{$index}}\">\n <ng-container\n *ngTemplateOutlet=\"tabContent; context: { $implicit: tab, index: $index }\">\n </ng-container>\n </p-tabpanel>\n }\n </p-tabpanels>\n </p-tabs>\n}\n@else {\n <div class=\"flex flex-column gap-4\">\n @for (tab of tabs_; track $index) {\n\n <!-- Optional header -->\n <!-- <div class=\"font-bold text-lg\">\n <i [class]=\"tab.icon\"></i>\n <span class=\"ml-2\">{{ tab.header | translate }}</span>\n </div> -->\n\n <ng-container\n *ngTemplateOutlet=\"tabContent; context: { $implicit: tab, index: $index }\">\n </ng-container>\n\n }\n </div>\n}\n</div>\n\n<!-- [model]=\"model\" -->\n <app-generic-dialog\n #dialog\n [formFields]=\"formFields ?? []\"\n [apiName]=\"apiName\"\n [idField]=\"idField ??'id'\"\n [moduleName]=\"moduleName\"\n [displayMode]=\"displayMode ?? 'dialog'\"\n (afterSave)=\"afterSave($event)\"\n >\n </app-generic-dialog>\n}\n", styles: [".toolbar-top{position:sticky;top:0;z-index:1000}.toolbar-bottom{position:sticky;top:48px;z-index:999}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: ToolbarModule }, { kind: "component", type: i3.Toolbar, selector: "p-toolbar", inputs: ["styleClass", "ariaLabelledBy"] }, { kind: "directive", type: i4.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "directive", type: i5.ButtonDirective, selector: "[pButton]", inputs: ["ptButtonDirective", "hostName", "text", "plain", "raised", "size", "outlined", "rounded", "iconPos", "loadingIcon", "fluid", "label", "icon", "loading", "buttonProps", "severity"] }, { kind: "ngmodule", type: TabsModule }, { kind: "component", type: i6.Tabs, selector: "p-tabs", inputs: ["value", "scrollable", "lazy", "selectOnFocus", "showNavigators", "tabindex"], outputs: ["valueChange"] }, { kind: "component", type: i6.TabPanels, selector: "p-tabpanels" }, { kind: "component", type: i6.TabPanel, selector: "p-tabpanel", inputs: ["lazy", "value"], outputs: ["valueChange"] }, { kind: "component", type: i6.TabList, selector: "p-tablist" }, { kind: "component", type: i6.Tab, selector: "p-tab", inputs: ["value", "disabled"], outputs: ["valueChange"] }, { kind: "component", type: FormlyForm, selector: "formly-form", inputs: ["form", "model", "fields", "options"], outputs: ["modelChange"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i7.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i7.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i7.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: BreadcrumbComponent, selector: "app-breadcrumb", inputs: ["breadcrumb"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i8.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions", "appendTo", "ptTooltip"] }, { kind: "component", type: GenericDialogComponent, selector: "app-generic-dialog", inputs: ["form", "service", "formFields", "model", "apiName", "moduleName", "idField", "dialogMaxWidth", "displayMode", "mode", "forceState", "drawerVisible", "dialogVisible", "isViewMode", "isEditMode", "useConfirmOnSave", "loading", "errorMsg", "errorMessage", "beforeSaveTransform", "hideTable", "autoShowForm"], outputs: ["action", "afterSave", "afterDelete", "beforeSave", "beforeDelete", "formCancel", "formInit", "dataLoaded", "selectionChange", "error", "visibleChange"] }, { kind: "component", type: GenericButton, selector: "lib-generic-button", inputs: ["model", "type", "icon", "label", "tooltip", "tooltipPosition", "variant", "severity", "size", "iconPosition", "disabled", "loading", "ariaLabel", "extraClasses", "permission"], outputs: ["clicked", "itemClick"] }, { kind: "ngmodule", type: ProgressSpinnerModule }, { kind: "component", type: i9.ProgressSpinner, selector: "p-progressSpinner, p-progress-spinner, p-progressspinner", inputs: ["styleClass", "strokeWidth", "fill", "animationDuration", "ariaLabel"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] });
346
346
  }
347
347
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: GenericViewComponent, decorators: [{
348
348
  type: Component,
@@ -1 +1 @@
1
- {"version":3,"file":"es.framework-ng.ui.core-generic-view.mjs","sources":["../../../../libs/ng.ui.core/generic-view/src/lib/generic-view.ts","../../../../libs/ng.ui.core/generic-view/src/lib/generic-view.html","../../../../libs/ng.ui.core/generic-view/src/lib/generic-view-module.ts","../../../../libs/ng.ui.core/generic-view/src/es.framework-ng.ui.core-generic-view.ts"],"sourcesContent":["import { TooltipModule } from 'primeng/tooltip';\r\nimport { ChangeDetectorRef, Component, EventEmitter, inject, Input, OnInit, Optional, Output, TemplateRef, ViewChild } from '@angular/core';\r\nimport { CommonModule, Location } from '@angular/common';\r\nimport { ToolbarModule } from 'primeng/toolbar';\r\nimport { ButtonModule } from 'primeng/button';\r\nimport { FormlyForm, FormlyFieldConfig } from '@ngx-formly/core';\r\nimport { FormGroup, FormsModule, ReactiveFormsModule, UntypedFormGroup } from '@angular/forms';\r\nimport { TabsModule } from 'primeng/tabs';\r\nimport { TranslatePipe } from '@es.framework/ng.core/pipes';\r\nimport { MenuItem } from 'primeng/api';\r\nimport { BreadcrumbComponent } from '@es.framework/ng.ui.core/breadcrumb';\r\nimport { BaseService, RestService, SchemaService, SwalService } from '@es.framework/ng.core/services';\r\nimport { ActivatedRoute, Router } from '@angular/router';\r\nimport { ActionDef, ButtonConfig, PaginatedResult } from '@es.framework/ng.core/models';\r\nimport { ProgressSpinnerModule } from 'primeng/progressspinner';\r\nimport { DialogService, DynamicDialogConfig, DynamicDialogRef } from 'primeng/dynamicdialog';\r\nimport { GenericDialogComponent } from '@es.framework/ng.ui.core/generic-dialog';\r\nimport { GenericButton } from '@es.framework/ng.ui.core/generic-button';\r\n\r\nexport interface DetailTab {\r\n header: string;\r\n icon?: string;\r\n fields: FormlyFieldConfig[];\r\n model?: any;\r\n content?: TemplateRef<any>;\r\n}\r\n\r\n@Component({\r\n selector: 'app-detail-view',\r\n standalone: true,\r\n imports: [\r\n CommonModule,\r\n ToolbarModule,\r\n ButtonModule,\r\n TabsModule,\r\n FormlyForm,\r\n FormsModule,\r\n ReactiveFormsModule,\r\n TranslatePipe,\r\n BreadcrumbComponent,\r\n TooltipModule,\r\n GenericDialogComponent,\r\n GenericButton,\r\n ProgressSpinnerModule\r\n ],\r\n providers: [DialogService,BaseService,RestService],\r\n templateUrl: './generic-view.html',\r\n styles:[\r\n `\r\n .toolbar-top {\r\n position: sticky;\r\n top: 0;\r\n z-index: 1000;\r\n}\r\n\r\n.toolbar-bottom {\r\n position: sticky;\r\n top: 48px; \r\n z-index: 999;\r\n}\r\n `\r\n ]\r\n})\r\nexport class GenericViewComponent implements OnInit {\r\n private route = inject(ActivatedRoute);\r\n private router = inject(Router);\r\n private schemaService = inject(SchemaService);\r\n\r\n form = new UntypedFormGroup({});\r\n\r\n @Input() title = '';\r\n @Input() actions: ActionDef<any>[] = [];\r\n @Input() createEditActions: ButtonConfig[] = [];\r\n actions_: ActionDef<any>[] = [];\r\n @Input() tabs: DetailTab[] = [];\r\n @Input() viewMode = true;\r\n @Input() breadcrumb: MenuItem[] | undefined;\r\n @Input() service: BaseService = inject(BaseService);\r\n @Input() formFields: FormlyFieldConfig[] = [];\r\n @Input() apiName = '';\r\n @Input() moduleName = '';\r\n @Input() idField = 'id';\r\n @Input() standaloneMode = false;\r\n @Input() useRouteParams = true;\r\n\r\n @Input() query?: string;\r\n @Input() currentId!: string | number;\r\n@Input() useTabs: boolean = true;\r\n @Input() isViewMode = true; // وضع المشاهدة فقط\r\n @Input() isCreateMode = false; // وضع الاضافة فقط\r\n @Input() isEditMode = false; // وضع التعديل\r\n @Input() model = {};\r\n @Input() displayMode:\r\n | 'drawer'\r\n | 'dialog'\r\n | 'route'\r\n | 'inline'\r\n | Partial<\r\n Record<\r\n 'add' | 'edit' | 'view',\r\n 'drawer' | 'dialog' | 'route' | 'inline'\r\n >\r\n > = 'drawer';\r\n@Input() mode: 'full' | 'form-only' | 'table-only' | 'detail' = 'detail';\r\n\r\n @Output() action = new EventEmitter<{ name: string; row: any }>();\r\n @Output() afterDelete = new EventEmitter<{ record: any; response?: any }>();\r\n\r\n @ViewChild('dialog') dialog!: GenericDialogComponent;\r\n @ViewChild('inlineForm') inlineForm!: GenericDialogComponent;\r\n\r\n tabs_: DetailTab[] = [];\r\n model_: any = {};\r\n\r\n list: any[] = [];\r\n totalRecords = 0;\r\n @Input() loading = false;\r\n @Input() showToolbar = true;\r\n\r\n\r\n // pagination state\r\n pageSize = 10;\r\n pageIndex = 0;\r\n sort = '';\r\n currentFilters: any = {};\r\n pageFilters: any = {};\r\n searchGlobal = '';\r\n private dialogService = inject(DialogService);\r\n private swalService = inject(SwalService);\r\n\r\n _location: Location = inject(Location);\r\n ngOnInit() {\r\n this.init();\r\n }\r\n constructor(\r\n private cdr: ChangeDetectorRef,\r\n @Optional() public ref: DynamicDialogRef,\r\n @Optional() public config: DynamicDialogConfig,\r\n ) {\r\nif (config && config.data) {\r\nconst data = config?.data ?? {};\r\n\r\n this.currentId = data.currentId ?? this.currentId;\r\n this.isViewMode = data.isViewMode ?? this.isViewMode;\r\n this.apiName = data.apiName ?? this.apiName;\r\n this.moduleName = data.moduleName ?? this.moduleName;\r\n this.useRouteParams = data.useRouteParams ?? this.useRouteParams;\r\n this.standaloneMode = data.standaloneMode ?? this.standaloneMode;\r\n this.useTabs = data.useTabs ?? this.useTabs;\r\n this.formFields = data.formFields ?? this.formFields;\r\n this.tabs = data.tabs ?? this.tabs;\r\n this.breadcrumb = data.breadcrumb ?? this.breadcrumb; \r\n this.showToolbar = data.showToolbar ?? this.showToolbar; \r\n this.mode = data.mode ?? this.mode; \r\n \r\n}\r\nthis.init();\r\n }\r\n \r\n init() {\r\n \r\n if (this.apiName) {\r\n this.service.moduleName = this.service.moduleName || this.moduleName;\r\n this.service.apiName = this.apiName;\r\n }\r\n\r\n\r\n this.actions_ = this.actions.filter(c=>c.name != 'view');\r\n\r\n if (this.useRouteParams) { \r\n\r\n this.route.paramMap.subscribe(params => {\r\n const id = params.get(this.idField);\r\n if (id) {\r\n this.currentId = id;\r\n if(this.standaloneMode){\r\n this.loadList();\r\n }\r\n }\r\n\r\n this.refresh();\r\n\r\n });\r\n }\r\n else{\r\n if(this.standaloneMode && (this.currentId || this.query)){\r\n this.loadList();\r\n this.initTabs();\r\n }\r\n }\r\n\r\n\r\n }\r\n\r\n refresh(){\r\n\r\n // detect mode based on route\r\n const url = this.router.url.toLowerCase();\r\n this.isViewMode = url.includes('/view');\r\n this.isEditMode = url.includes('/edit');\r\n this.isCreateMode = url.includes('/create') || url.endsWith('/new') || url.endsWith('/add');\r\n\r\n this.initTabs();\r\n }\r\n\r\n initTabs(){\r\n this.tabs_ = [];\r\n if(this.tabs.length == 0){\r\n this.tabs.push({\r\n header: 'Details',\r\n fields: []\r\n });\r\n }\r\nfor (let i = 0; i < this.tabs.length; i++) {\r\n const t = this.tabs[i];\r\n this.tabs_.push({\r\n ...t,\r\n fields: [\r\n {\r\n props: { label: '' },\r\n // fieldGroupClassName: 'grid grid-cols-1 md:grid-cols-2 gap-3', // TODO\r\n fieldGroupClassName: '',\r\n fieldGroup:\r\n this.isCreateMode || this.isEditMode\r\n ? this.schemaService.getCreateEditFields(i == 0 ? this.formFields: t.fields,this.isViewMode)\r\n : this.schemaService.getViewFields(i == 0 ? this.formFields : t.fields,this.isViewMode),\r\n },\r\n ],\r\n });\r\n}\r\n// this.loading = false;\r\n }\r\n \r\n private cellForms: Map<string, FormGroup> = new Map();\r\n getForm(rowIndex: number): FormGroup {\r\n const key = `${rowIndex}_`;\r\n let form = this.cellForms.get(key);\r\n\r\n if (!form) {\r\n form = new FormGroup({});\r\n this.cellForms.set(key, form);\r\n }\r\n return form;\r\n }\r\n\r\n\r\n async handleCreateEditAction(btn: ButtonConfig) {\r\n try {\r\n if (btn.action) {\r\n // Execute the provided action\r\n await btn.action(null); // You can pass row or context here\r\n } else {\r\n // Fallback to emitting event\r\n if(btn.actionName == 'cancel'){\r\n this.back();\r\n }\r\n else{\r\n this.action.emit({\r\n name: btn.actionName ?? 'cancel',\r\n row: null!, // provide row if available\r\n });\r\n }\r\n }\r\n } catch (err) {\r\n console.error('Button action error', err);\r\n }\r\n }\r\n\r\n\r\nonAction(act: ActionDef<any>, model: any) {\r\n if (act.action) {\r\n act.action(model);\r\n } else {\r\n // this.action.emit({ name: act.name, row:model });\r\n this.emitAction({ name: act.name, row:model });\r\n }\r\n \r\n }\r\n\r\n emitAction(event: { name: string; row: any | null }): void {\r\n switch (event.name) {\r\n case 'edit':\r\n // this.dialog.openForm(\"edit\",event.row);\r\n this.goToMode('edit');\r\n break;\r\n case 'delete':\r\n this.onDelete(event.row!);\r\n break;\r\n default :\r\n this.action.emit(event);\r\n break;\r\n }\r\n}\r\n\r\nonDelete(item: any): void {\r\n const id = item[this.idField];\r\n\r\n this.swalService.confirm(\r\n 'تأكيد الحذف',\r\n 'هل تريد حذف هذا السجل فعلاً؟',\r\n 'نعم، احذف',\r\n 'إلغاء'\r\n ).then((result) => {\r\n if (result.isConfirmed) {\r\n this.service.delete(id).subscribe({\r\n next: () => {\r\n this.swalService.success('تم الحذف بنجاح');\r\n this.back();\r\n },\r\n error: (err: any) => {\r\n this.loading = false;\r\n\r\n }\r\n });\r\n }\r\n });\r\n}\r\n afterSave(event: any) {\r\n this.model = event.response;\r\n\r\n // set the id from backend response\r\n this.currentId = event.response[this.idField];\r\n\r\n if (this.isCreateMode) {\r\n this.goToMode('view');\r\n } else if (this.isEditMode) {\r\n this.goToMode('view');\r\n }\r\n}\r\n\r\n\r\n\r\ngoToMode(mode: 'view' | 'edit' | 'create') {\r\n const tree = this.router.parseUrl(this.router.url);\r\n const segments = tree.root.children['primary']?.segments.map(s => s.path) ?? [];\r\n\r\n let newSegments: string[];\r\n\r\n if (mode === 'create') {\r\n // always navigate to \"add\"\r\n newSegments = [\r\n ...segments.filter(s => !['view', 'edit', 'add'].includes(s)),\r\n 'add',\r\n ];\r\n } else {\r\n // if in \"add\" mode, replace it with the new id\r\n if (segments.includes('add')) {\r\n newSegments = [\r\n ...segments.filter(s => s !== 'add'),\r\n String(this.currentId),\r\n mode,\r\n ];\r\n } else {\r\n const idIndex = segments.findIndex(s => s === String(this.currentId));\r\n if (idIndex === -1) {\r\n newSegments = [...segments, String(this.currentId), mode];\r\n } else {\r\n newSegments = segments.slice(0, idIndex + 1);\r\n newSegments.push(mode);\r\n }\r\n }\r\n }\r\n\r\n this.router.navigate(newSegments);\r\n this.refresh();\r\n}\r\n\r\n\r\nbackToList(){\r\n this.router.navigate(['../']);\r\n }\r\nback(){\r\n // this.router.navigate(['..']);\r\n this._location.back()\r\n }\r\n loadList() {\r\n this.loading = true;\r\n const filters = {\r\n maxResultCount: this.pageSize,\r\n skipCount: this.pageIndex * this.pageSize,\r\n sorting: this.sort,\r\n ...this.currentFilters,\r\n ...this.pageFilters,\r\n ...(this.searchGlobal ? { filter: this.searchGlobal } : {}),\r\n };\r\n if(this.query){\r\n filters['query'] = this.query;\r\n }\r\n if(this.currentId){\r\n filters[this.idField] = this.currentId;\r\n }\r\n this.service.getList(filters).subscribe({\r\n next: (res: PaginatedResult<any>) => {\r\n this.list = res.items;\r\n this.totalRecords = res.totalCount;\r\n this.loading = false;\r\n\r\n if(this.list.length > 0){\r\n this.model = this.list[0];\r\n this.model_ = this.list[0];\r\n }\r\n // set model_ to current id item\r\n // const found = this.list.find(x => x[this.idField] == this.currentId);\r\n // if (found) {\r\n // this.model_ = found;\r\n // }\r\n },\r\n error: err => {\r\n console.error('Error loading list', err);\r\n this.loading = false;\r\n }\r\n });\r\n }\r\n next() {\r\n if (!this.currentId) return;\r\n\r\n // increment currentId numerically\r\n // const newId = Number(this.currentId) + 1;\r\n // this.currentId = newId;\r\n // use goToMode to navigate and keep mode\r\n const currentMode = this.isEditMode ? 'edit' : 'view';\r\n // this.goToMode(currentMode);\r\n}\r\n\r\nprevious() {\r\n if (!this.currentId) return;\r\n\r\n // decrement currentId numerically\r\n // const newId = Number(this.currentId) - 1;\r\n // if (newId <= 0) return;\r\n\r\n // this.currentId = newId;\r\n\r\n // use goToMode to navigate and keep mode\r\n const currentMode = this.isEditMode ? 'edit' : 'view';\r\n // this.goToMode(currentMode);\r\n}\r\n\r\n\r\n // next() {\r\n // const idx = this.list.findIndex(x => x[this.idField] == this.currentId);\r\n // if (idx >= 0 && idx < this.list.length - 1) {\r\n // const newId = this.list[idx + 1][this.idField];\r\n // this.router.navigate(['../', newId], { relativeTo: this.route });\r\n // }\r\n // }\r\n\r\n // previous() {\r\n // const idx = this.list.findIndex(x => x[this.idField] == this.currentId);\r\n // if (idx > 0) {\r\n // const newId = this.list[idx - 1][this.idField];\r\n // this.router.navigate(['../', newId], { relativeTo: this.route });\r\n // }\r\n // }\r\n}\r\n\r\n","@if (mode === 'detail') {\n<div class=\"w-full flex flex-col gap-3\">\n <!-- overlay -->\n @if (loading) {\n <div \n class=\"absolute inset-0 bg-white/70 flex items-center justify-center z-50\">\n <p-progress-spinner/>\n </div>\n}\n\n <!-- actual content -->\n <!-- Toolbar -->\n @if (showToolbar) {\n <!-- background: transparent; -->\n <p-toolbar style=\"border: 0px;box-shadow: none;\" class=\"toolbar-top bg-white shadow-none border-none rounded-md px-3\">\n <ng-template pTemplate=\"left\">\n <!-- <span class=\"font-semibold text-lg xs:hidden block\">{{ title }}</span> -->\n <app-breadcrumb class=\"xs:block\" [breadcrumb]=\"breadcrumb\"></app-breadcrumb> <!-- xs:block hidden -->\n </ng-template>\n <ng-template pTemplate=\"right\">\n <div class=\"flex gap-2\">\n\n <button\n pButton pRipple\n icon=\"pi pi-chevron-right\"\n class=\"p-button-text p-button-sm fd-btn\"\n pTooltip=\"التالي\"\n (click)=\"next()\"\n ></button>\n <button\n pButton pRipple\n icon=\"pi pi-chevron-left\"\n class=\"p-button-text p-button-sm fd-btn\"\n pTooltip=\"السابق\"\n (click)=\"previous()\"\n ></button>\n </div>\n </ng-template>\n </p-toolbar>\n\n <p-toolbar class=\"toolbar-bottom bg-white shadow rounded-md px-3\">\n\n <ng-template pTemplate=\"left\">\n @if (isViewMode) {\n <div class=\"flex gap-1\">\n @for (action of actions_; track $index) {\n <button\n pButton pRipple\n [icon]=\"action.icon ?? ''\"\n [label]=\"(action.label ?? '') | translate\"\n class=\"fd-btn\"\n (click)=\"onAction(action,model)\"\n ></button>\n }\n </div>\n }\n </ng-template>\n <ng-template pTemplate=\"right\">\n @if (isEditMode || isCreateMode) {\n <div class=\"flex gap-1\">\n @for (btn of createEditActions; track $index) {\n @if (!btn.visible || (btn.visible && btn.visible === true)) {\n @if (btn.type === 'submit' && inlineForm) {\n <lib-generic-button\n [type]=\"'submit'\"\n [loading]=\"inlineForm.loading\"\n [disabled]=\"inlineForm.loading || form.invalid\"\n [icon]=\"btn.icon\"\n [label]=\"btn.label | translate\"\n [variant]=\"btn.variant\"\n [severity]=\"btn.severity\"\n [size]=\"btn.size\"\n [model]=\"btn.splitActions\"\n [permission]=\"btn.permission\"\n (clicked)=\"inlineForm.onSubmit()\"\n ></lib-generic-button>\n }\n @else{\n <lib-generic-button\n [icon]=\"btn.icon\"\n [label]=\"btn.label | translate\"\n [variant]=\"btn.variant\"\n [severity]=\"btn.severity\"\n [size]=\"btn.size\"\n [model]=\"btn.splitActions\"\n [permission]=\"btn.permission\"\n (clicked)=\"handleCreateEditAction(btn)\"\n ></lib-generic-button>\n }\n }\n }\n </div>\n }\n </ng-template>\n\n </p-toolbar>\n}\n\n <!-- Tabs -->\n <ng-template #tabContent let-tab let-i=\"index\">\n <div>\n \n <!-- First tab special handling -->\n @if (tab.fields.length && i === 0) {\n @if(form){\n\n \n <form [formGroup]=\"form\">\n\n @if (isEditMode || isCreateMode) {\n <app-generic-dialog\n #inlineForm\n [form]=\"form\"\n [model]=\"model\"\n [formFields]=\"formFields ?? []\"\n [apiName]=\"apiName\"\n [idField]=\"idField ?? 'id'\"\n [moduleName]=\"moduleName\"\n [displayMode]=\"'inline'\"\n [mode]=\"'form-only'\"\n [forceState]=\"isCreateMode ? 'create':'edit'\"\n (afterSave)=\"afterSave($event)\">\n </app-generic-dialog>\n }\n @else if (isViewMode) {\n <formly-form\n [form]=\"form\"\n [fields]=\"tab.fields\"\n [model]=\"model\">\n </formly-form>\n }\n\n </form>\n }\n }\n\n <!-- باقي التابات -->\n @if (tab.fields.length && i > 0) {\n <formly-form\n [form]=\"getForm(i)\"\n [fields]=\"tab.fields\"\n [model]=\"tab.model || model\">\n </formly-form>\n }\n\n <!-- Custom template -->\n @if (tab.content) {\n <ng-container\n *ngTemplateOutlet=\"tab.content; context: { model: model }\">\n </ng-container>\n }\n\n </div>\n</ng-template>\n@if (useTabs) {\n <p-tabs value=\"0\">\n <p-tablist>\n @for (tab of tabs_; track $index) {\n <p-tab value=\"{{$index}}\">\n <i [class]=\"tab.icon\"></i>\n <span class=\"mr-1 ml-1\">{{ tab.header | translate }}</span>\n </p-tab>\n }\n </p-tablist>\n\n <p-tabpanels>\n @for (tab of tabs_; track $index) {\n <p-tabpanel value=\"{{$index}}\">\n <ng-container\n *ngTemplateOutlet=\"tabContent; context: { $implicit: tab, index: $index }\">\n </ng-container>\n </p-tabpanel>\n }\n </p-tabpanels>\n </p-tabs>\n}\n@else {\n <div class=\"flex flex-column gap-4\">\n @for (tab of tabs_; track $index) {\n\n <!-- Optional header -->\n <!-- <div class=\"font-bold text-lg\">\n <i [class]=\"tab.icon\"></i>\n <span class=\"ml-2\">{{ tab.header | translate }}</span>\n </div> -->\n\n <ng-container\n *ngTemplateOutlet=\"tabContent; context: { $implicit: tab, index: $index }\">\n </ng-container>\n\n }\n </div>\n}\n</div>\n\n<!-- [model]=\"model\" -->\n <app-generic-dialog\n #dialog\n [formFields]=\"formFields ?? []\"\n [apiName]=\"apiName\"\n [idField]=\"idField ??'id'\"\n [moduleName]=\"moduleName\"\n [displayMode]=\"displayMode ?? 'dialog'\"\n (afterSave)=\"afterSave($event)\"\n >\n </app-generic-dialog>\n}\n","import { NgModule } from '@angular/core';\nimport { CommonModule } from '@angular/common';\n\n@NgModule({\n imports: [CommonModule],\n})\nexport class GenericViewModule {}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"es.framework-ng.ui.core-generic-view.mjs","sources":["../../../../libs/ng.ui.core/generic-view/src/lib/generic-view.ts","../../../../libs/ng.ui.core/generic-view/src/lib/generic-view.html","../../../../libs/ng.ui.core/generic-view/src/lib/generic-view-module.ts","../../../../libs/ng.ui.core/generic-view/src/es.framework-ng.ui.core-generic-view.ts"],"sourcesContent":["import { TooltipModule } from 'primeng/tooltip';\r\nimport { ChangeDetectorRef, Component, EventEmitter, inject, Input, OnInit, Optional, Output, TemplateRef, ViewChild } from '@angular/core';\r\nimport { CommonModule, Location } from '@angular/common';\r\nimport { ToolbarModule } from 'primeng/toolbar';\r\nimport { ButtonModule } from 'primeng/button';\r\nimport { FormlyForm, FormlyFieldConfig } from '@ngx-formly/core';\r\nimport { FormGroup, FormsModule, ReactiveFormsModule, UntypedFormGroup } from '@angular/forms';\r\nimport { TabsModule } from 'primeng/tabs';\r\nimport { TranslatePipe } from '@es.framework/ng.core/pipes';\r\nimport { MenuItem } from 'primeng/api';\r\nimport { BreadcrumbComponent } from '@es.framework/ng.ui.core/breadcrumb';\r\nimport { BaseService, RestService, SchemaService, SwalService } from '@es.framework/ng.core/services';\r\nimport { ActivatedRoute, Router } from '@angular/router';\r\nimport { ActionDef, ButtonConfig, PaginatedResult } from '@es.framework/ng.core/models';\r\nimport { ProgressSpinnerModule } from 'primeng/progressspinner';\r\nimport { DialogService, DynamicDialogConfig, DynamicDialogRef } from 'primeng/dynamicdialog';\r\nimport { GenericDialogComponent } from '@es.framework/ng.ui.core/generic-dialog';\r\nimport { GenericButton } from '@es.framework/ng.ui.core/generic-button';\r\n\r\nexport interface DetailTab {\r\n header: string;\r\n icon?: string;\r\n fields: FormlyFieldConfig[];\r\n model?: any;\r\n content?: TemplateRef<any>;\r\n}\r\n\r\n@Component({\r\n selector: 'app-detail-view',\r\n standalone: true,\r\n imports: [\r\n CommonModule,\r\n ToolbarModule,\r\n ButtonModule,\r\n TabsModule,\r\n FormlyForm,\r\n FormsModule,\r\n ReactiveFormsModule,\r\n TranslatePipe,\r\n BreadcrumbComponent,\r\n TooltipModule,\r\n GenericDialogComponent,\r\n GenericButton,\r\n ProgressSpinnerModule\r\n ],\r\n providers: [DialogService,BaseService,RestService],\r\n templateUrl: './generic-view.html',\r\n styles:[\r\n `\r\n .toolbar-top {\r\n position: sticky;\r\n top: 0;\r\n z-index: 1000;\r\n}\r\n\r\n.toolbar-bottom {\r\n position: sticky;\r\n top: 48px; \r\n z-index: 999;\r\n}\r\n `\r\n ]\r\n})\r\nexport class GenericViewComponent implements OnInit {\r\n private route = inject(ActivatedRoute);\r\n private router = inject(Router);\r\n private schemaService = inject(SchemaService);\r\n\r\n form = new UntypedFormGroup({});\r\n\r\n @Input() title = '';\r\n @Input() actions: ActionDef<any>[] = [];\r\n @Input() createEditActions: ButtonConfig[] = [];\r\n actions_: ActionDef<any>[] = [];\r\n @Input() tabs: DetailTab[] = [];\r\n @Input() viewMode = true;\r\n @Input() breadcrumb: MenuItem[] | undefined;\r\n @Input() service: BaseService = inject(BaseService);\r\n @Input() formFields: FormlyFieldConfig[] = [];\r\n @Input() apiName = '';\r\n @Input() moduleName = '';\r\n @Input() idField = 'id';\r\n @Input() standaloneMode = false;\r\n @Input() useRouteParams = true;\r\n\r\n @Input() query?: string;\r\n @Input() currentId!: string | number;\r\n@Input() useTabs: boolean = true;\r\n @Input() isViewMode = true; // وضع المشاهدة فقط\r\n @Input() isCreateMode = false; // وضع الاضافة فقط\r\n @Input() isEditMode = false; // وضع التعديل\r\n @Input() model = {};\r\n @Input() displayMode:\r\n | 'drawer'\r\n | 'dialog'\r\n | 'route'\r\n | 'inline'\r\n | Partial<\r\n Record<\r\n 'add' | 'edit' | 'view',\r\n 'drawer' | 'dialog' | 'route' | 'inline'\r\n >\r\n > = 'drawer';\r\n@Input() mode: 'full' | 'form-only' | 'table-only' | 'detail' = 'detail';\r\n\r\n @Output() action = new EventEmitter<{ name: string; row: any }>();\r\n @Output() afterDelete = new EventEmitter<{ record: any; response?: any }>();\r\n\r\n @ViewChild('dialog') dialog!: GenericDialogComponent;\r\n @ViewChild('inlineForm') inlineForm!: GenericDialogComponent;\r\n\r\n tabs_: DetailTab[] = [];\r\n model_: any = {};\r\n\r\n list: any[] = [];\r\n totalRecords = 0;\r\n @Input() loading = false;\r\n @Input() showToolbar = true;\r\n\r\n\r\n // pagination state\r\n pageSize = 10;\r\n pageIndex = 0;\r\n sort = '';\r\n currentFilters: any = {};\r\n pageFilters: any = {};\r\n searchGlobal = '';\r\n private dialogService = inject(DialogService);\r\n private swalService = inject(SwalService);\r\n\r\n _location: Location = inject(Location);\r\n ngOnInit() {\r\n this.init();\r\n }\r\n constructor(\r\n private cdr: ChangeDetectorRef,\r\n @Optional() public ref: DynamicDialogRef,\r\n @Optional() public config: DynamicDialogConfig,\r\n ) {\r\nif (config && config.data) {\r\nconst data = config?.data ?? {};\r\n\r\n this.currentId = data.currentId ?? this.currentId;\r\n this.isViewMode = data.isViewMode ?? this.isViewMode;\r\n this.apiName = data.apiName ?? this.apiName;\r\n this.moduleName = data.moduleName ?? this.moduleName;\r\n this.useRouteParams = data.useRouteParams ?? this.useRouteParams;\r\n this.standaloneMode = data.standaloneMode ?? this.standaloneMode;\r\n this.useTabs = data.useTabs ?? this.useTabs;\r\n this.formFields = data.formFields ?? this.formFields;\r\n this.tabs = data.tabs ?? this.tabs;\r\n this.breadcrumb = data.breadcrumb ?? this.breadcrumb; \r\n this.showToolbar = data.showToolbar ?? this.showToolbar; \r\n this.mode = data.mode ?? this.mode; \r\n \r\n}\r\nthis.init();\r\n }\r\n \r\n init() {\r\n \r\n if (this.apiName) {\r\n this.service.moduleName = this.service.moduleName || this.moduleName;\r\n this.service.apiName = this.apiName;\r\n }\r\n\r\n\r\n this.actions_ = this.actions.filter(c=>c.name != 'view');\r\n\r\n if (this.useRouteParams) { \r\n\r\n this.route.paramMap.subscribe(params => {\r\n const id = params.get(this.idField);\r\n if (id) {\r\n this.currentId = id;\r\n if(this.standaloneMode){\r\n this.loadList();\r\n }\r\n }\r\n\r\n this.refresh();\r\n\r\n });\r\n }\r\n else{\r\n if(this.standaloneMode && (this.currentId || this.query)){\r\n this.loadList();\r\n this.initTabs();\r\n }\r\n }\r\n\r\n\r\n }\r\n\r\n refresh(){\r\n\r\n // detect mode based on route\r\n const url = this.router.url.toLowerCase();\r\n this.isViewMode = url.includes('/view');\r\n this.isEditMode = url.includes('/edit');\r\n this.isCreateMode = url.includes('/create') || url.endsWith('/new') || url.endsWith('/add');\r\n\r\n this.initTabs();\r\n }\r\n\r\n initTabs(){\r\n this.tabs_ = [];\r\n if(this.tabs.length == 0){\r\n this.tabs.push({\r\n header: 'Details',\r\n fields: []\r\n });\r\n }\r\nfor (let i = 0; i < this.tabs.length; i++) {\r\n const t = this.tabs[i];\r\n this.tabs_.push({\r\n ...t,\r\n fields: [\r\n {\r\n props: { label: '' },\r\n // fieldGroupClassName: 'grid grid-cols-1 md:grid-cols-2 gap-3', // TODO\r\n fieldGroupClassName: '',\r\n fieldGroup:\r\n this.isCreateMode || this.isEditMode\r\n ? this.schemaService.getCreateEditFields(i == 0 ? this.formFields: t.fields,this.isViewMode)\r\n : this.schemaService.getViewFields(i == 0 ? this.formFields : t.fields,this.isViewMode),\r\n },\r\n ],\r\n });\r\n}\r\n// this.loading = false;\r\n }\r\n \r\n private cellForms: Map<string, FormGroup> = new Map();\r\n getForm(rowIndex: number): FormGroup {\r\n const key = `${rowIndex}_`;\r\n let form = this.cellForms.get(key);\r\n\r\n if (!form) {\r\n form = new FormGroup({});\r\n this.cellForms.set(key, form);\r\n }\r\n return form;\r\n }\r\n\r\n\r\n async handleCreateEditAction(btn: ButtonConfig) {\r\n try {\r\n if (btn.action) {\r\n // Execute the provided action\r\n await btn.action(null); // You can pass row or context here\r\n } else {\r\n // Fallback to emitting event\r\n if(btn.actionName == 'cancel'){\r\n this.back();\r\n }\r\n else{\r\n this.action.emit({\r\n name: btn.actionName ?? 'cancel',\r\n row: null!, // provide row if available\r\n });\r\n }\r\n }\r\n } catch (err) {\r\n console.error('Button action error', err);\r\n }\r\n }\r\n\r\n\r\nonAction(act: ActionDef<any>, model: any) {\r\n if (act.action) {\r\n act.action(model);\r\n } else {\r\n // this.action.emit({ name: act.name, row:model });\r\n this.emitAction({ name: act.name, row:model });\r\n }\r\n \r\n }\r\n\r\n emitAction(event: { name: string; row: any | null }): void {\r\n switch (event.name) {\r\n case 'edit':\r\n // this.dialog.openForm(\"edit\",event.row);\r\n this.goToMode('edit');\r\n break;\r\n case 'delete':\r\n this.onDelete(event.row!);\r\n break;\r\n default :\r\n this.action.emit(event);\r\n break;\r\n }\r\n}\r\n\r\nonDelete(item: any): void {\r\n const id = item[this.idField];\r\n\r\n this.swalService.confirm(\r\n 'تأكيد الحذف',\r\n 'هل تريد حذف هذا السجل فعلاً؟',\r\n 'نعم، احذف',\r\n 'إلغاء'\r\n ).then((result) => {\r\n if (result.isConfirmed) {\r\n this.service.delete(id).subscribe({\r\n next: () => {\r\n this.swalService.success('تم الحذف بنجاح');\r\n this.back();\r\n },\r\n error: (err: any) => {\r\n this.loading = false;\r\n\r\n }\r\n });\r\n }\r\n });\r\n}\r\n afterSave(event: any) {\r\n this.model = event.response;\r\n\r\n // set the id from backend response\r\n this.currentId = event.response[this.idField];\r\n\r\n if (this.isCreateMode) {\r\n this.goToMode('view');\r\n } else if (this.isEditMode) {\r\n this.goToMode('view');\r\n }\r\n}\r\n\r\n\r\n\r\ngoToMode(mode: 'view' | 'edit' | 'create') {\r\n const tree = this.router.parseUrl(this.router.url);\r\n const segments = tree.root.children['primary']?.segments.map(s => s.path) ?? [];\r\n\r\n let newSegments: string[];\r\n\r\n if (mode === 'create') {\r\n // always navigate to \"add\"\r\n newSegments = [\r\n ...segments.filter(s => !['view', 'edit', 'add'].includes(s)),\r\n 'add',\r\n ];\r\n } else {\r\n // if in \"add\" mode, replace it with the new id\r\n if (segments.includes('add')) {\r\n newSegments = [\r\n ...segments.filter(s => s !== 'add'),\r\n String(this.currentId),\r\n mode,\r\n ];\r\n } else {\r\n const idIndex = segments.findIndex(s => s === String(this.currentId));\r\n if (idIndex === -1) {\r\n newSegments = [...segments, String(this.currentId), mode];\r\n } else {\r\n newSegments = segments.slice(0, idIndex + 1);\r\n newSegments.push(mode);\r\n }\r\n }\r\n }\r\n\r\n this.router.navigate(newSegments);\r\n this.refresh();\r\n}\r\n\r\n\r\nbackToList(){\r\n this.router.navigate(['../']);\r\n }\r\nback(){\r\n // this.router.navigate(['..']);\r\n this._location.back()\r\n }\r\n loadList() {\r\n this.loading = true;\r\n const filters = {\r\n maxResultCount: this.pageSize,\r\n skipCount: this.pageIndex * this.pageSize,\r\n sorting: this.sort,\r\n ...this.currentFilters,\r\n ...this.pageFilters,\r\n ...(this.searchGlobal ? { filter: this.searchGlobal } : {}),\r\n };\r\n if(this.query){\r\n filters['query'] = this.query;\r\n }\r\n if(this.currentId){\r\n filters[this.idField] = this.currentId;\r\n }\r\n this.service.getList(filters).subscribe({\r\n next: (res: PaginatedResult<any>) => {\r\n this.list = res.items;\r\n this.totalRecords = res.totalCount;\r\n this.loading = false;\r\n\r\n if(this.list.length > 0){\r\n this.model = this.list[0];\r\n this.model_ = this.list[0];\r\n }\r\n // set model_ to current id item\r\n // const found = this.list.find(x => x[this.idField] == this.currentId);\r\n // if (found) {\r\n // this.model_ = found;\r\n // }\r\n },\r\n error: err => {\r\n console.error('Error loading list', err);\r\n this.loading = false;\r\n }\r\n });\r\n }\r\n next() {\r\n if (!this.currentId) return;\r\n\r\n // increment currentId numerically\r\n // const newId = Number(this.currentId) + 1;\r\n // this.currentId = newId;\r\n // use goToMode to navigate and keep mode\r\n const currentMode = this.isEditMode ? 'edit' : 'view';\r\n // this.goToMode(currentMode);\r\n}\r\n\r\nprevious() {\r\n if (!this.currentId) return;\r\n\r\n // decrement currentId numerically\r\n // const newId = Number(this.currentId) - 1;\r\n // if (newId <= 0) return;\r\n\r\n // this.currentId = newId;\r\n\r\n // use goToMode to navigate and keep mode\r\n const currentMode = this.isEditMode ? 'edit' : 'view';\r\n // this.goToMode(currentMode);\r\n}\r\n\r\n\r\n // next() {\r\n // const idx = this.list.findIndex(x => x[this.idField] == this.currentId);\r\n // if (idx >= 0 && idx < this.list.length - 1) {\r\n // const newId = this.list[idx + 1][this.idField];\r\n // this.router.navigate(['../', newId], { relativeTo: this.route });\r\n // }\r\n // }\r\n\r\n // previous() {\r\n // const idx = this.list.findIndex(x => x[this.idField] == this.currentId);\r\n // if (idx > 0) {\r\n // const newId = this.list[idx - 1][this.idField];\r\n // this.router.navigate(['../', newId], { relativeTo: this.route });\r\n // }\r\n // }\r\n}\r\n\r\n","@if (mode === 'detail') {\n<div class=\"w-full flex flex-col gap-3\">\n <!-- overlay -->\n @if (loading) {\n <div \n class=\"absolute inset-0 bg-white/70 flex items-center justify-center z-50\">\n <p-progress-spinner/>\n </div>\n}\n\n <!-- actual content -->\n <!-- Toolbar -->\n @if (showToolbar) {\n <!-- background: transparent; -->\n <p-toolbar style=\"border: 0px;box-shadow: none;\" class=\"toolbar-top bg-white shadow-none border-none rounded-md px-3\">\n <ng-template pTemplate=\"left\">\n <!-- <span class=\"font-semibold text-lg xs:hidden block\">{{ title }}</span> -->\n <app-breadcrumb class=\"xs:block\" [breadcrumb]=\"breadcrumb\"></app-breadcrumb> <!-- xs:block hidden -->\n </ng-template>\n <ng-template pTemplate=\"right\">\n <div class=\"flex gap-2\">\n\n <button\n pButton pRipple\n icon=\"pi pi-chevron-right\"\n class=\"p-button-text p-button-sm fd-btn\"\n pTooltip=\"التالي\"\n (click)=\"next()\"\n ></button>\n <button\n pButton pRipple\n icon=\"pi pi-chevron-left\"\n class=\"p-button-text p-button-sm fd-btn\"\n pTooltip=\"السابق\"\n (click)=\"previous()\"\n ></button>\n </div>\n </ng-template>\n </p-toolbar>\n\n <p-toolbar class=\"toolbar-bottom bg-white shadow rounded-md px-3\">\n\n <ng-template pTemplate=\"left\">\n @if (isViewMode) {\n <div class=\"flex gap-1\">\n @for (action of actions_; track $index) {\n <button\n pButton pRipple\n [icon]=\"action.icon ?? ''\"\n [label]=\"(action.label ?? '') | translate\"\n class=\"fd-btn\"\n (click)=\"onAction(action,model)\"\n ></button>\n }\n </div>\n }\n </ng-template>\n <ng-template pTemplate=\"right\">\n @if (isEditMode || isCreateMode) {\n <div class=\"flex gap-1\">\n @for (btn of createEditActions; track $index) {\n @if (!btn.visible || (btn.visible && btn.visible === true)) {\n @if (btn.type === 'submit' && inlineForm) {\n <lib-generic-button\n [type]=\"'submit'\"\n [loading]=\"inlineForm.loading\"\n [disabled]=\"inlineForm.loading || form.invalid\"\n [icon]=\"btn.icon\"\n [label]=\"btn.label | translate\"\n [variant]=\"btn.variant\"\n [severity]=\"btn.severity\"\n [size]=\"btn.size\"\n [model]=\"btn.splitActions\"\n [permission]=\"btn.permission\"\n (clicked)=\"inlineForm.onSubmit()\"\n ></lib-generic-button>\n }\n @else{\n <lib-generic-button\n [icon]=\"btn.icon\"\n [label]=\"btn.label | translate\"\n [variant]=\"btn.variant\"\n [severity]=\"btn.severity\"\n [size]=\"btn.size\"\n [model]=\"btn.splitActions\"\n [permission]=\"btn.permission\"\n (clicked)=\"handleCreateEditAction(btn)\"\n ></lib-generic-button>\n }\n }\n }\n </div>\n }\n </ng-template>\n\n </p-toolbar>\n}\n\n <!-- Tabs -->\n <ng-template #tabContent let-tab let-i=\"index\">\n <div>\n \n <!-- First tab special handling -->\n @if (tab.fields.length && i === 0) {\n @if(form){\n\n \n <form [formGroup]=\"form\">\n\n @if (isEditMode || isCreateMode) {\n <app-generic-dialog\n #inlineForm\n [form]=\"form\"\n [model]=\"model\"\n [formFields]=\"formFields ?? []\"\n [apiName]=\"apiName\"\n [idField]=\"idField ?? 'id'\"\n [moduleName]=\"moduleName\"\n [displayMode]=\"'inline'\"\n [mode]=\"'form-only'\"\n [forceState]=\"isCreateMode ? 'create':'edit'\"\n (afterSave)=\"afterSave($event)\">\n </app-generic-dialog>\n }\n @else if (isViewMode) {\n <formly-form\n [form]=\"form\"\n [fields]=\"tab.fields\"\n [model]=\"model\">\n </formly-form>\n }\n\n </form>\n }\n }\n\n <!-- باقي التابات -->\n @if (tab.fields.length && i > 0) {\n <formly-form\n [form]=\"getForm(i)\"\n [fields]=\"tab.fields\"\n [model]=\"tab.model || model\">\n </formly-form>\n }\n\n <!-- Custom template -->\n @if (tab.content) {\n <ng-container\n *ngTemplateOutlet=\"tab.content; context: { model: model }\">\n </ng-container>\n }\n\n </div>\n</ng-template>\n@if (useTabs) {\n <p-tabs value=\"0\">\n <p-tablist>\n @for (tab of tabs_; track $index) {\n <p-tab value=\"{{$index}}\">\n <i [class]=\"tab.icon\"></i>\n <span class=\"mr-1 ml-1\">{{ tab.header | translate }}</span>\n </p-tab>\n }\n </p-tablist>\n\n <p-tabpanels>\n @for (tab of tabs_; track $index) {\n <p-tabpanel value=\"{{$index}}\">\n <ng-container\n *ngTemplateOutlet=\"tabContent; context: { $implicit: tab, index: $index }\">\n </ng-container>\n </p-tabpanel>\n }\n </p-tabpanels>\n </p-tabs>\n}\n@else {\n <div class=\"flex flex-column gap-4\">\n @for (tab of tabs_; track $index) {\n\n <!-- Optional header -->\n <!-- <div class=\"font-bold text-lg\">\n <i [class]=\"tab.icon\"></i>\n <span class=\"ml-2\">{{ tab.header | translate }}</span>\n </div> -->\n\n <ng-container\n *ngTemplateOutlet=\"tabContent; context: { $implicit: tab, index: $index }\">\n </ng-container>\n\n }\n </div>\n}\n</div>\n\n<!-- [model]=\"model\" -->\n <app-generic-dialog\n #dialog\n [formFields]=\"formFields ?? []\"\n [apiName]=\"apiName\"\n [idField]=\"idField ??'id'\"\n [moduleName]=\"moduleName\"\n [displayMode]=\"displayMode ?? 'dialog'\"\n (afterSave)=\"afterSave($event)\"\n >\n </app-generic-dialog>\n}\n","import { NgModule } from '@angular/core';\nimport { CommonModule } from '@angular/common';\n\n@NgModule({\n imports: [CommonModule],\n})\nexport class GenericViewModule {}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@es.framework/ng.ui.core",
3
- "version": "2.0.65",
3
+ "version": "2.0.67",
4
4
  "peerDependencies": {
5
5
  "@angular/common": "^20.1.0",
6
6
  "@angular/core": "^20.1.0"