@elite.framework/ng.core 1.0.63 → 1.0.65
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/fesm2022/elite.framework-ng.core-src-lib-components-attachments.mjs +204 -0
- package/fesm2022/elite.framework-ng.core-src-lib-components-attachments.mjs.map +1 -0
- package/fesm2022/elite.framework-ng.core-src-lib-components-breadcrumb.mjs +132 -0
- package/fesm2022/elite.framework-ng.core-src-lib-components-breadcrumb.mjs.map +1 -0
- package/fesm2022/elite.framework-ng.core-src-lib-components-color-picker.mjs +76 -0
- package/fesm2022/elite.framework-ng.core-src-lib-components-color-picker.mjs.map +1 -0
- package/fesm2022/elite.framework-ng.core-src-lib-components-column-settings-popover.mjs +172 -0
- package/fesm2022/elite.framework-ng.core-src-lib-components-column-settings-popover.mjs.map +1 -0
- package/fesm2022/elite.framework-ng.core-src-lib-components-condition-editor.mjs +794 -0
- package/fesm2022/elite.framework-ng.core-src-lib-components-condition-editor.mjs.map +1 -0
- package/fesm2022/elite.framework-ng.core-src-lib-components-custom-switch.mjs +110 -0
- package/fesm2022/elite.framework-ng.core-src-lib-components-custom-switch.mjs.map +1 -0
- package/fesm2022/elite.framework-ng.core-src-lib-components-deactivation-reason.mjs +130 -0
- package/fesm2022/elite.framework-ng.core-src-lib-components-deactivation-reason.mjs.map +1 -0
- package/fesm2022/elite.framework-ng.core-src-lib-components-form-button.mjs +50 -0
- package/fesm2022/elite.framework-ng.core-src-lib-components-form-button.mjs.map +1 -0
- package/fesm2022/elite.framework-ng.core-src-lib-components-form-field.mjs +154 -0
- package/fesm2022/elite.framework-ng.core-src-lib-components-form-field.mjs.map +1 -0
- package/fesm2022/elite.framework-ng.core-src-lib-components-form-template.mjs +24 -0
- package/fesm2022/elite.framework-ng.core-src-lib-components-form-template.mjs.map +1 -0
- package/fesm2022/elite.framework-ng.core-src-lib-components-formly-avatar-image.mjs +100 -0
- package/fesm2022/elite.framework-ng.core-src-lib-components-formly-avatar-image.mjs.map +1 -0
- package/fesm2022/elite.framework-ng.core-src-lib-components-formly-avatar-label.mjs +78 -0
- package/fesm2022/elite.framework-ng.core-src-lib-components-formly-avatar-label.mjs.map +1 -0
- package/fesm2022/elite.framework-ng.core-src-lib-components-formly-button-selector.mjs +167 -0
- package/fesm2022/elite.framework-ng.core-src-lib-components-formly-button-selector.mjs.map +1 -0
- package/fesm2022/elite.framework-ng.core-src-lib-components-formly-button.mjs +62 -0
- package/fesm2022/elite.framework-ng.core-src-lib-components-formly-button.mjs.map +1 -0
- package/fesm2022/elite.framework-ng.core-src-lib-components-formly-split-button.mjs +50 -0
- package/fesm2022/elite.framework-ng.core-src-lib-components-formly-split-button.mjs.map +1 -0
- package/fesm2022/elite.framework-ng.core-src-lib-components-formly-username-with-domain.mjs +76 -0
- package/fesm2022/elite.framework-ng.core-src-lib-components-formly-username-with-domain.mjs.map +1 -0
- package/fesm2022/elite.framework-ng.core-src-lib-components-generic-autocomplete.mjs +163 -0
- package/fesm2022/elite.framework-ng.core-src-lib-components-generic-autocomplete.mjs.map +1 -0
- package/fesm2022/elite.framework-ng.core-src-lib-components-generic-button.mjs +133 -0
- package/fesm2022/elite.framework-ng.core-src-lib-components-generic-button.mjs.map +1 -0
- package/fesm2022/elite.framework-ng.core-src-lib-components-generic-card.mjs +214 -0
- package/fesm2022/elite.framework-ng.core-src-lib-components-generic-card.mjs.map +1 -0
- package/fesm2022/elite.framework-ng.core-src-lib-components-generic-crud-table.mjs +385 -0
- package/fesm2022/elite.framework-ng.core-src-lib-components-generic-crud-table.mjs.map +1 -0
- package/fesm2022/elite.framework-ng.core-src-lib-components-generic-errormessage.mjs +23 -0
- package/fesm2022/elite.framework-ng.core-src-lib-components-generic-errormessage.mjs.map +1 -0
- package/fesm2022/elite.framework-ng.core-src-lib-components-generic-formly-fields.mjs +53 -0
- package/fesm2022/elite.framework-ng.core-src-lib-components-generic-formly-fields.mjs.map +1 -0
- package/fesm2022/elite.framework-ng.core-src-lib-components-generic-loadingspinner.mjs +23 -0
- package/fesm2022/elite.framework-ng.core-src-lib-components-generic-loadingspinner.mjs.map +1 -0
- package/fesm2022/elite.framework-ng.core-src-lib-components-generic-search.mjs +85 -0
- package/fesm2022/elite.framework-ng.core-src-lib-components-generic-search.mjs.map +1 -0
- package/fesm2022/elite.framework-ng.core-src-lib-components-generic-selector.mjs +430 -0
- package/fesm2022/elite.framework-ng.core-src-lib-components-generic-selector.mjs.map +1 -0
- package/fesm2022/elite.framework-ng.core-src-lib-components-generic-table.mjs +216 -0
- package/fesm2022/elite.framework-ng.core-src-lib-components-generic-table.mjs.map +1 -0
- package/fesm2022/elite.framework-ng.core-src-lib-components-header-wrapper.mjs +18 -0
- package/fesm2022/elite.framework-ng.core-src-lib-components-header-wrapper.mjs.map +1 -0
- package/fesm2022/elite.framework-ng.core-src-lib-components-icon-picker.mjs +195 -0
- package/fesm2022/elite.framework-ng.core-src-lib-components-icon-picker.mjs.map +1 -0
- package/fesm2022/elite.framework-ng.core-src-lib-components-input-switch.mjs +94 -0
- package/fesm2022/elite.framework-ng.core-src-lib-components-input-switch.mjs.map +1 -0
- package/fesm2022/elite.framework-ng.core-src-lib-components-input-with-icon.mjs +55 -0
- package/fesm2022/elite.framework-ng.core-src-lib-components-input-with-icon.mjs.map +1 -0
- package/fesm2022/elite.framework-ng.core-src-lib-components-label-type.mjs +112 -0
- package/fesm2022/elite.framework-ng.core-src-lib-components-label-type.mjs.map +1 -0
- package/fesm2022/elite.framework-ng.core-src-lib-components-odata-query-builder.mjs +297 -0
- package/fesm2022/elite.framework-ng.core-src-lib-components-odata-query-builder.mjs.map +1 -0
- package/fesm2022/elite.framework-ng.core-src-lib-components-repeat.mjs +135 -0
- package/fesm2022/elite.framework-ng.core-src-lib-components-repeat.mjs.map +1 -0
- package/fesm2022/elite.framework-ng.core-src-lib-components-sidebar-cards.mjs +40 -0
- package/fesm2022/elite.framework-ng.core-src-lib-components-sidebar-cards.mjs.map +1 -0
- package/fesm2022/elite.framework-ng.core-src-lib-components-sidebar-toggles.mjs +41 -0
- package/fesm2022/elite.framework-ng.core-src-lib-components-sidebar-toggles.mjs.map +1 -0
- package/fesm2022/elite.framework-ng.core-src-lib-components-tabs.mjs +45 -0
- package/fesm2022/elite.framework-ng.core-src-lib-components-tabs.mjs.map +1 -0
- package/fesm2022/elite.framework-ng.core-src-lib-components-tag-type.mjs +192 -0
- package/fesm2022/elite.framework-ng.core-src-lib-components-tag-type.mjs.map +1 -0
- package/fesm2022/elite.framework-ng.core-src-lib-components-text-editor.mjs +44 -0
- package/fesm2022/elite.framework-ng.core-src-lib-components-text-editor.mjs.map +1 -0
- package/fesm2022/elite.framework-ng.core-src-lib-components-wrappers.mjs +174 -0
- package/fesm2022/elite.framework-ng.core-src-lib-components-wrappers.mjs.map +1 -0
- package/fesm2022/elite.framework-ng.core-src-lib-directives.mjs +59 -0
- package/fesm2022/elite.framework-ng.core-src-lib-directives.mjs.map +1 -0
- package/fesm2022/elite.framework-ng.core-src-lib-pipes.mjs +135 -0
- package/fesm2022/elite.framework-ng.core-src-lib-pipes.mjs.map +1 -0
- package/fesm2022/elite.framework-ng.core.mjs +1643 -384
- package/fesm2022/elite.framework-ng.core.mjs.map +1 -1
- package/index.d.ts +493 -24
- package/package.json +14 -62
- package/src/lib/components/attachments/index.d.ts +31 -0
- package/src/lib/components/breadcrumb/index.d.ts +10 -0
- package/src/lib/components/color-picker/index.d.ts +9 -0
- package/src/lib/components/column-settings-popover/index.d.ts +39 -0
- package/src/lib/components/condition-editor/index.d.ts +73 -0
- package/src/lib/components/custom-switch/index.d.ts +12 -0
- package/src/lib/components/deactivation-reason/index.d.ts +24 -0
- package/src/lib/components/form-button/index.d.ts +10 -0
- package/src/lib/components/form-field/index.d.ts +30 -0
- package/src/lib/components/form-template/index.d.ts +9 -0
- package/src/lib/components/formly-avatar-image/index.d.ts +11 -0
- package/src/lib/components/formly-avatar-label/index.d.ts +29 -0
- package/src/lib/components/formly-button/index.d.ts +13 -0
- package/src/lib/components/formly-button-selector/index.d.ts +28 -0
- package/src/lib/components/formly-split-button/index.d.ts +16 -0
- package/src/lib/components/formly-username-with-domain/index.d.ts +12 -0
- package/src/lib/components/generic-autocomplete/index.d.ts +34 -0
- package/src/lib/components/generic-button/index.d.ts +35 -0
- package/src/lib/components/generic-card/index.d.ts +90 -0
- package/src/lib/components/generic-crud-table/index.d.ts +120 -0
- package/src/lib/components/generic-errormessage/index.d.ts +10 -0
- package/src/lib/components/generic-formly-fields/index.d.ts +22 -0
- package/src/lib/components/generic-loadingspinner/index.d.ts +9 -0
- package/src/lib/components/generic-search/index.d.ts +29 -0
- package/src/lib/components/generic-selector/index.d.ts +66 -0
- package/src/lib/components/generic-table/index.d.ts +60 -0
- package/src/lib/components/header-wrapper/index.d.ts +8 -0
- package/src/lib/components/icon-picker/index.d.ts +23 -0
- package/src/lib/components/input-switch/index.d.ts +9 -0
- package/src/lib/components/input-with-icon/index.d.ts +10 -0
- package/src/lib/components/label-type/index.d.ts +19 -0
- package/src/lib/components/odata-query-builder/index.d.ts +81 -0
- package/src/lib/components/repeat/index.d.ts +17 -0
- package/src/lib/components/sidebar-cards/index.d.ts +18 -0
- package/src/lib/components/sidebar-toggles/index.d.ts +18 -0
- package/src/lib/components/tabs/index.d.ts +10 -0
- package/src/lib/components/tag-type/index.d.ts +27 -0
- package/src/lib/components/text-editor/index.d.ts +9 -0
- package/src/lib/components/wrappers/index.d.ts +24 -0
- package/src/lib/directives/index.d.ts +23 -0
- package/src/lib/pipes/index.d.ts +20 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"elite.framework-ng.core-src-lib-components-generic-selector.mjs","sources":["../../../projects/core/src/lib/components/generic-selector/generic-selector.component.ts","../../../projects/core/src/lib/components/generic-selector/elite.framework-ng.core-src-lib-components-generic-selector.ts"],"sourcesContent":["import { ChangeDetectorRef, Component, Injector, OnDestroy, OnInit, ViewChild } from '@angular/core';\r\nimport { FormlyFieldConfig, FieldType, FormlyAttributes, FieldTypeConfig } from '@ngx-formly/core';\r\nimport { DialogService } from 'primeng/dynamicdialog';\r\nimport { forkJoin, Observable, Subscription } from 'rxjs';\r\nimport { finalize, tap } from 'rxjs/operators';\r\nimport { CommonModule } from '@angular/common';\r\nimport { FormsModule, ReactiveFormsModule } from '@angular/forms';\r\nimport { AutoCompleteModule, AutoComplete } from 'primeng/autocomplete';\r\nimport { InputGroupModule } from 'primeng/inputgroup';\r\nimport { InputGroupAddonModule } from 'primeng/inputgroupaddon';\r\nimport { TranslateModule } from '@ngx-translate/core';\r\nimport { FormlyFieldProps } from '@ngx-formly/primeng/form-field';\r\nimport { CheckboxModule } from 'primeng/checkbox';\r\nimport { ButtonModule } from 'primeng/button';\r\nimport { BaseService } from '@elite.framework/ng.core';\r\n\r\ninterface GenericSelectorProps extends FormlyFieldProps/* , FormlyFieldSelectProps */ {\r\n // appendTo?: Select['appendTo'];\r\n serviceName: string;\r\n listEndpoint?: string | ((model: any) => string);\r\n loadDefaultField?: string;\r\n loadDefaultValue?: string;\r\n\r\n labelField?: string;\r\n valueField?: string;\r\n multiple?: boolean;\r\n loadDefault?: boolean;\r\n\r\n offline?: boolean;\r\n\r\n loadSaved?: boolean;\r\n loadSavedField?: string;\r\n\r\n\r\n /** Static offline items (array of objects) */\r\n offlineItems?: any[];\r\n\r\n /** Async offline items (observable) */\r\n offlineItems$?: Observable<any[]>;\r\n\r\n /** Function-based filter for offline items */\r\n onSelect?: (field: FormlyFieldConfig, event?: any) => void;\r\n\r\n offlineDataFn?: (query?: string) => any[];\r\n fixedFilters?: Record<string, any>;\r\n defaultValue?: any; // id أو array of ids\r\n defaultItem?: any; // الكائن كامل (object) إذا عندك جاهز\r\n}\r\n\r\n@Component({\r\n selector: 'formly-generic-selector',\r\n template: `\r\n <!-- (ngModelChange)=\"onSelectionChange($event)\" -->\r\n <p-inputGroup class=\"w-full\">\r\n <p-autoComplete\r\n #autoComp\r\n [ngModel]=\"selectedItem\"\r\n (ngModelChange)=\"onSelectionChange($event)\"\r\n [formlyAttributes]=\"field\"\r\n [suggestions]=\"options_\"\r\n (completeMethod)=\"search($event)\"\r\n [multiple]=\"to['multiple']\"\r\n [optionLabel]=\"to['labelField'] || 'name'\"\r\n [dropdown]=\"false\"\r\n [forceSelection]=\"true\"\r\n [placeholder]=\"(props['placeholder'] ?? '') | translate\"\r\n [disabled]=\"!!props.disabled\"\r\n dropdownMode=\"current\"\r\n appendTo=\"body\"\r\n class=\"w-full rounded-none\"\r\n [showEmptyMessage]=\"true\"\r\n (onSelect)=\"onSelect($event)\"\r\n emptyMessage=\"{{ getEmptyMessage() | translate }}\"\r\n [showTransitionOptions]=\"'0ms'\">\r\n </p-autoComplete>\r\n\r\n <!-- 🔘 Custom dropdown addon -->\r\n <p-inputGroupAddon>\r\n <p-button icon=\"pi pi-chevron-down\" (click)=\"onDropdownButtonClick()\" severity=\"secondary\" />\r\n </p-inputGroupAddon>\r\n</p-inputGroup>\r\n\r\n\r\n `,\r\n providers: [DialogService,BaseService],\r\n imports:[\r\n FormsModule,\r\n ReactiveFormsModule,\r\n AutoCompleteModule,\r\n CommonModule,\r\n InputGroupModule,\r\n InputGroupAddonModule,\r\n FormlyAttributes,\r\n TranslateModule,\r\n AutoComplete,\r\n CheckboxModule,\r\n ButtonModule\r\n]\r\n})\r\nexport class GenericSelectorTypeComponent extends FieldType<FieldTypeConfig<GenericSelectorProps>> implements OnInit,OnDestroy {\r\n @ViewChild('autoComp') autoComp!: AutoComplete;\r\n options_: any[] = [];\r\n selectedItem: any;\r\n\r\n loading = false;\r\n private _offlineList: any[] = [];\r\n\r\n api: BaseService|any;\r\n dialog: DialogService|any;\r\n private valueChangeSubscription!: Subscription; // Add a subscription to manage the observable\r\n constructor(private svc: BaseService,private injector: Injector,private cdr: ChangeDetectorRef) {\r\n super();\r\n\r\n }\r\n\r\n ngOnInit() {\r\n this.api = this.svc;\r\n this.dialog = this.injector.get(DialogService);\r\n const to = this.props;\r\n this.api.apiName = to['serviceName'];\r\n\r\n if (to['offline']) {\r\n if (to['offlineDataFn']) {\r\n this._offlineList = to['offlineDataFn']();\r\n this.initOfflineSelection();\r\n } else if (to['offlineItems$']) {\r\n to['offlineItems$'].subscribe((list: any[]) => {\r\n this._offlineList = list;\r\n this.initOfflineSelection();\r\n });\r\n } else {\r\n this._offlineList = to['offlineItems'] || [];\r\n this.initOfflineSelection();\r\n }\r\n } else {\r\n\r\n if (this.props.loadSaved && !this.props.multiple && this.props.loadSavedField && this.props.valueField) {\r\n const vf = this.to['valueField'] || 'id';\r\n const lf = this.to['labelField'] || 'name';\r\n this.selectedItem =\r\n {\r\n [vf]:this.formControl.value,\r\n [lf]:this.model[this.props.loadSavedField],\r\n };\r\n if (this.props.change) {\r\n this.props.change(this.field, { item: this.selectedItem });\r\n this.cdr.detectChanges();\r\n }\r\n }\r\n else{\r\n\r\n this.initOnlineSelection();\r\n }\r\n }\r\n\r\n // Subscribe to formControl value changes\r\n this.valueChangeSubscription = this.formControl.valueChanges\r\n .subscribe(() => {\r\n // This tap operator is a good place to run side effects\r\n // like calling your change handler after a value changes.\r\n // this.selectedItem = this.formControl.value;\r\n if (this.props.change) {\r\n if (to['offline']) {\r\n if (to['offlineDataFn']) {\r\n this._offlineList = to['offlineDataFn']();\r\n this.initOfflineSelection(false);\r\n } else if (to['offlineItems$']) {\r\n to['offlineItems$'].subscribe((list: any[]) => {\r\n this._offlineList = list;\r\n this.initOfflineSelection(false);\r\n });\r\n } else {\r\n this._offlineList = to['offlineItems'] || [];\r\n this.initOfflineSelection(false);\r\n }\r\n } else {\r\n this.initOnlineSelection(false);\r\n }\r\n }\r\n })\r\n ;\r\n }\r\n\r\n // Remember to unsubscribe to prevent memory leaks!\r\n ngOnDestroy() {\r\n if (this.valueChangeSubscription) {\r\n this.valueChangeSubscription.unsubscribe();\r\n }\r\n }\r\nprivate loadDefaultValue() {\r\n this.loading = true;\r\n const vf = this.to['valueField'] || 'id';\r\n const fixedFilters = this.getFixedFilters();\r\n const lf = this.to['loadDefaultField'] || 'isDefault';\r\n const lfValue = this.to['loadDefaultValue'] || true;\r\nconst searchParams = {\r\n [lf]: lfValue,\r\n ...fixedFilters,\r\n };\r\n this.api.getList(searchParams)\r\n .subscribe({\r\n next: (res: any) => {\r\n // Assuming the API returns a list and you want to select the first one\r\n if (res && res.items && res.items.length > 0) {\r\n if (this.to['multiple']){\r\n this.formControl.setValue(res.items.map((c: any) => c[vf]));\r\n }\r\n else{\r\n const defaultValue = res.items[0];\r\n this.formControl.setValue(defaultValue?.[vf]);\r\n }\r\n }\r\n this.loading = false;\r\n // this.initOnlineSelection(); // Proceed with online selection after setting the value\r\n },\r\n error: (err: any) => {\r\n console.error(\"Failed to load default value from API:\", err);\r\n this.loading = false;\r\n // this.initOnlineSelection(); // Fallback to local selection if API fails\r\n }\r\n });\r\n}\r\n // New method to handle loading the default value from the API\r\n\r\n onSelect(event: any) {\r\n\r\n if (this.props.onSelect) {\r\n this.props.onSelect(this.field, { item: event.value });\r\n this.cdr.detectChanges();\r\n }\r\n}\r\n\r\n onSelectionChange(val: any) {\r\n this.selectedItem = val;\r\n\r\n const vf = this.to['valueField'] || 'id';\r\n\r\n if (this.to['multiple']) {\r\n this.formControl.setValue(\r\n Array.isArray(val) ? val.map((c: any) => c[vf]) : []\r\n );\r\n } else {\r\n this.formControl.setValue(val?.[vf] ?? null);\r\n }\r\n}\r\n private initOfflineSelection(withSetValue:boolean=true) {\r\n const val = this.formControl.value;\r\n const vf = this.to['valueField'] || 'id';\r\n\r\n if (val == null) return;\r\n\r\n if (this.to['multiple'] && Array.isArray(val)) {\r\n this.selectedItem = this._offlineList.filter(item =>\r\n val.includes(item[vf])\r\n );\r\n } else {\r\n this.selectedItem = this._offlineList.find(item => item[vf] === val);\r\n }\r\n\r\n if(withSetValue == true){\r\n\r\n this.formControl.setValue(\r\n this.to['multiple']\r\n ? this.selectedItem.map((c: any) => c[vf])\r\n : this.selectedItem?.[vf]\r\n );\r\n }\r\n else{\r\n if (this.props.change) {\r\n this.props.change(this.field, { item: this.selectedItem });\r\n this.cdr.detectChanges();\r\n }\r\n }\r\n }\r\n\r\n private initOnlineSelection(withSetValue:boolean=true) {\r\n\r\n var d = this.selectedItem;\r\n const fullModel = this.model;\r\n const val = this.formControl.value;\r\n const vf = this.to['valueField'] || 'id';\r\n if (val == null || (Array.isArray(val) && val.length === 0)) {\r\n this.selectedItem = this.to['multiple'] ? [] : null;\r\n\r\n if (this.props['loadDefault'] == true) {\r\n this.loadDefaultValue();\r\n }\r\n else{\r\n\r\n return;\r\n }\r\n\r\n }\r\n\r\n\r\n if (this.to['multiple'] && Array.isArray(val) && val.length) {\r\n const calls = val.map((id: any) => this.api.get(id));\r\n forkJoin(calls)\r\n .pipe(finalize(() => (this.loading = false)))\r\n .subscribe(items => {\r\n this.selectedItem = items;\r\n if(withSetValue == true){\r\n\r\n this.formControl.setValue(items.map((c: any) => c[vf]));\r\n this.cdr.detectChanges();\r\n }\r\n else{\r\n if (this.props.change) {\r\n this.props.change(this.field, { item: this.selectedItem });\r\n this.cdr.detectChanges();\r\n }\r\n }\r\n });\r\n } else {\r\n this.loading = true;\r\n\r\n this.api.get(val)\r\n .pipe(finalize(() => (this.loading = false)))\r\n .subscribe((item: any) => {\r\n this.selectedItem = item;\r\n // debugger\r\n if(withSetValue == true){\r\n this.formControl.setValue(item?.[vf]);\r\n this.cdr.detectChanges();\r\n }\r\n else{\r\n if (this.props.change) {\r\n this.props.change(this.field, { item: this.selectedItem });\r\n this.cdr.detectChanges();\r\n }\r\n }\r\n });\r\n }\r\n }\r\n\r\ngetFixedFilters(): any {\r\n const fixedFilters = this.to['fixedFilters'];\r\n\r\n if (typeof fixedFilters === 'function') {\r\n // Call with current model (and optionally field)\r\n return fixedFilters(this.model);\r\n }\r\n\r\n return fixedFilters || {};\r\n}\r\nonDropdownButtonClick() {\r\n console.log('Custom dropdown button clicked!');\r\n this.search({ query: '' }); // trigger your own search\r\n setTimeout(() => this.autoComp.show(), 0); // force dropdown to open\r\n}\r\n// Called when dropdown button clicked\r\n onDropdownClick(event: any) {\r\n // 🚫 stop the default dropdown behavior\r\n event.originalEvent.preventDefault();\r\n event.originalEvent.stopPropagation();\r\n\r\n console.log('Dropdown clicked!', event);\r\n // ✅ your custom code here\r\n // e.g., force trigger search for empty query\r\n this.search({ query: '' });\r\n }\r\n\r\nsearch(event: { query: string }) {\r\n const q = event.query?.toString().toLowerCase() || '';\r\n const lf = this.to['labelField'] || 'name';\r\n const fixedFilters = this.getFixedFilters();\r\n\r\n\r\n if (this.to['offline']) {\r\n this.options_ = this.to['offlineDataFn']\r\n ? this.to['offlineDataFn'](q)\r\n : this._offlineList.filter(item =>\r\n item[lf]?.toString().toLowerCase().includes(q)\r\n );\r\n\r\n setTimeout(() => this.autoComp?.show(), 0);\r\n } else {\r\n this.loading = true;\r\n this.options_ = [];\r\n\r\n const searchParams = {\r\n [lf]: q,\r\n ...fixedFilters,\r\n };\r\n\r\n // ✅ استخدام listEndpoint إذا كان موجودًا، وإلا العودة إلى الافتراضي\r\n let listEndpoint = this.props.listEndpoint;\r\n if (typeof listEndpoint === 'function') {\r\n listEndpoint = listEndpoint(this.model);\r\n }\r\n\r\n this.api.getList(searchParams , listEndpoint)\r\n .pipe(finalize(() => (this.loading = false)))\r\n .subscribe({\r\n next: (res: any) => {\r\n this.options_ = res.items ?? res ?? [];\r\n setTimeout(() => this.autoComp?.show(), 0);\r\n },\r\n error: () => {\r\n this.options_ = [];\r\n\r\n },\r\n });\r\n }\r\n}\r\n\r\n openCrud(mode: 'add' | 'edit' | 'info') {\r\n const payload = mode === 'add' ? null : this.selectedItem;\r\n\r\n // Example integration:\r\n // const ref = this.dialog.open(CrudComponent, {\r\n // data: {\r\n // serviceName: this.to.serviceName,\r\n // mode,\r\n // record: payload\r\n // }\r\n // });\r\n // ref.onClose.subscribe((updated: any) => {\r\n // if (!this.to.multiple && updated?.[this.to.valueField]) {\r\n // this.api.get(updated[this.to.valueField])\r\n // .subscribe(item => {\r\n // this.selectedItem = item;\r\n // this.formControl.setValue(item?.[this.to.valueField]);\r\n // });\r\n // }\r\n // });\r\n\r\n }\r\n\r\n getEmptyMessage(): string {\r\n if (this.loading) {\r\n return 'LOADING_DATA_MESSAGE'; // مفتاح ترجمة لـ \"جاري تحميل البيانات...\"\r\n } else if (this.options_.length === 0) {\r\n return 'NO_RESULTS_FOUND'; // مفتاح ترجمة لـ \"لا توجد نتائج مطابقة.\"\r\n }\r\n return ''; // لا تُعرض رسالة إذا كانت هناك نتائج\r\n }\r\n\r\nisItemSelected(item: any): boolean {\r\n const vf = this.to['valueField'] || 'id';\r\n return Array.isArray(this.selectedItem) &&\r\n this.selectedItem.some((sel: any) => sel[vf] === item[vf]);\r\n}\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n}\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { EventEmitter, Input, Output, ViewChild, Component } from '@angular/core';
|
|
3
|
+
import * as i1 from '@angular/common';
|
|
4
|
+
import { CommonModule, NgForOf, NgIf } from '@angular/common';
|
|
5
|
+
import * as i2 from 'primeng/table';
|
|
6
|
+
import { TableModule } from 'primeng/table';
|
|
7
|
+
import * as i4 from 'primeng/button';
|
|
8
|
+
import { ButtonModule, Button } from 'primeng/button';
|
|
9
|
+
import * as i5 from 'primeng/menu';
|
|
10
|
+
import { MenuModule, Menu } from 'primeng/menu';
|
|
11
|
+
import * as i6 from '@ngx-translate/core';
|
|
12
|
+
import { TranslateModule, TranslatePipe } from '@ngx-translate/core';
|
|
13
|
+
import { FormlyForm, FormlyField } from '@ngx-formly/core';
|
|
14
|
+
import { FormGroup } from '@angular/forms';
|
|
15
|
+
import * as i3 from 'primeng/api';
|
|
16
|
+
|
|
17
|
+
class GenericTable {
|
|
18
|
+
dt;
|
|
19
|
+
data = [];
|
|
20
|
+
columns = [];
|
|
21
|
+
columns_ = [];
|
|
22
|
+
loading = false;
|
|
23
|
+
actions = [];
|
|
24
|
+
actionsMode = 'buttons';
|
|
25
|
+
first = 0;
|
|
26
|
+
rows = 10;
|
|
27
|
+
totalRecords = 0;
|
|
28
|
+
sortField;
|
|
29
|
+
sortOrder = 1;
|
|
30
|
+
globalFilterFields = [];
|
|
31
|
+
action = new EventEmitter();
|
|
32
|
+
pageChange = new EventEmitter();
|
|
33
|
+
scrollHeight = '400px';
|
|
34
|
+
// **جديد**: تمكين اختيار الصفوف
|
|
35
|
+
/** فعّل اختيار الصفين single/multiple */
|
|
36
|
+
rowSelectable = true;
|
|
37
|
+
/** يحتفظ بالصف المحدد */
|
|
38
|
+
//@Input() selection: T | T[] | null = null;
|
|
39
|
+
// هذا سيكون مرتبطًا بـ [(selection)] في p-table
|
|
40
|
+
_selection = null;
|
|
41
|
+
get selection() {
|
|
42
|
+
return this._selection;
|
|
43
|
+
}
|
|
44
|
+
set selection(val) {
|
|
45
|
+
this._selection = val;
|
|
46
|
+
// لا تُصدر الحدث هنا، بل في onInternalSelectionChange فقط
|
|
47
|
+
}
|
|
48
|
+
/** يصدر الصف المحدد عند النقر */
|
|
49
|
+
rowSelect = new EventEmitter();
|
|
50
|
+
/** يصدر الصفوف المحددة عند التغيير (للربط الثنائي) */
|
|
51
|
+
selectionChange = new EventEmitter();
|
|
52
|
+
/** جديد: التحكم بظهور الـ paginator */
|
|
53
|
+
paginator = true;
|
|
54
|
+
form = new FormGroup({});
|
|
55
|
+
options = {};
|
|
56
|
+
// **جديد**: يتحكم بإظهار عمود اختيار الصفوف (checkboxes)
|
|
57
|
+
/** يتحكم في إظهار عمود اختيار الصفوف المتعددة بواسطة checkboxes */
|
|
58
|
+
showRowSelectionCheckbox = false;
|
|
59
|
+
onAddNew() {
|
|
60
|
+
}
|
|
61
|
+
onInternalSelectionChange(event) {
|
|
62
|
+
if ('data' in event) {
|
|
63
|
+
// Row select/unselect (single أو multiple)
|
|
64
|
+
if (Array.isArray(this._selection)) {
|
|
65
|
+
this._selection = [...this._selection]; // تحديث نسخة المصفوفة عند متعدد
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
this._selection = event.data; // اختيار فردي
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
else if ('checked' in event) {
|
|
72
|
+
// Header checkbox toggle
|
|
73
|
+
this._selection = event.checked ? [...this.data] : [];
|
|
74
|
+
}
|
|
75
|
+
this.selectionChange.emit(this._selection);
|
|
76
|
+
}
|
|
77
|
+
customSort(event) {
|
|
78
|
+
event.data?.sort((data1, data2) => {
|
|
79
|
+
const value1 = this.resolveFieldData(data1, event.field ?? '');
|
|
80
|
+
const value2 = this.resolveFieldData(data2, event.field ?? '');
|
|
81
|
+
let result = 0;
|
|
82
|
+
if (value1 == null && value2 != null)
|
|
83
|
+
result = -1;
|
|
84
|
+
else if (value1 != null && value2 == null)
|
|
85
|
+
result = 1;
|
|
86
|
+
else if (value1 == null && value2 == null)
|
|
87
|
+
result = 0;
|
|
88
|
+
else if (typeof value1 === 'string' && typeof value2 === 'string')
|
|
89
|
+
result = value1.localeCompare(value2);
|
|
90
|
+
else
|
|
91
|
+
result = value1 < value2 ? -1 : value1 > value2 ? 1 : 0;
|
|
92
|
+
return (event.order ?? 1) * result;
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
resolveFieldData(data, field) {
|
|
96
|
+
if (!field)
|
|
97
|
+
return null;
|
|
98
|
+
if (field.indexOf('.') === -1)
|
|
99
|
+
return data[field];
|
|
100
|
+
return field.split('.').reduce((obj, prop) => (obj ? obj[prop] : null), data);
|
|
101
|
+
}
|
|
102
|
+
onAction(act, row) {
|
|
103
|
+
if (act.action) {
|
|
104
|
+
act.action(row);
|
|
105
|
+
}
|
|
106
|
+
else {
|
|
107
|
+
this.action.emit({ name: act.name, row });
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
cloneField(field) {
|
|
111
|
+
if (field === null || typeof field !== 'object') {
|
|
112
|
+
return field;
|
|
113
|
+
}
|
|
114
|
+
if (Array.isArray(field)) {
|
|
115
|
+
// preserve `this` context
|
|
116
|
+
return field.map((item) => this.cloneField(item));
|
|
117
|
+
}
|
|
118
|
+
const cloned = {};
|
|
119
|
+
for (const key of Object.keys(field)) {
|
|
120
|
+
cloned[key] = this.cloneField(field[key]);
|
|
121
|
+
}
|
|
122
|
+
return cloned;
|
|
123
|
+
}
|
|
124
|
+
getForm(rowIndex, colIndex) {
|
|
125
|
+
var cellForms = {};
|
|
126
|
+
const key = `${rowIndex}_${colIndex}`;
|
|
127
|
+
if (!cellForms[key]) {
|
|
128
|
+
cellForms[key] = new FormGroup({});
|
|
129
|
+
}
|
|
130
|
+
return cellForms[key];
|
|
131
|
+
}
|
|
132
|
+
onLazyLoad(event) {
|
|
133
|
+
this.columns_ = this.columns;
|
|
134
|
+
// // debugger
|
|
135
|
+
this.pageChange.emit(event);
|
|
136
|
+
}
|
|
137
|
+
applyFilter(filters) {
|
|
138
|
+
// if (field) {
|
|
139
|
+
// this.dt.filter(global, field, 'contains');
|
|
140
|
+
// } else {
|
|
141
|
+
// this.dt.filterGlobal(global, 'contains');
|
|
142
|
+
// }
|
|
143
|
+
}
|
|
144
|
+
getMenuItems(row) {
|
|
145
|
+
return this.actions.map(act => ({
|
|
146
|
+
label: act.label,
|
|
147
|
+
icon: act.icon,
|
|
148
|
+
command: () => this.onAction(act, row),
|
|
149
|
+
styleClass: act.styleClass
|
|
150
|
+
}));
|
|
151
|
+
}
|
|
152
|
+
// **جديد**: يتم إطلاق هذا عند اختيار صف
|
|
153
|
+
onRowSelect(event) {
|
|
154
|
+
// debugger
|
|
155
|
+
console.log('GenericTable.onRowSelect:', event.data);
|
|
156
|
+
if (event.data) {
|
|
157
|
+
this.rowSelect.emit(event.data);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: GenericTable, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
161
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.4", type: GenericTable, isStandalone: true, selector: "lib-generic-table", inputs: { data: "data", columns: "columns", loading: "loading", actions: "actions", actionsMode: "actionsMode", first: "first", rows: "rows", totalRecords: "totalRecords", sortField: "sortField", sortOrder: "sortOrder", globalFilterFields: "globalFilterFields", scrollHeight: "scrollHeight", rowSelectable: "rowSelectable", selection: "selection", paginator: "paginator", showRowSelectionCheckbox: "showRowSelectionCheckbox" }, outputs: { action: "action", pageChange: "pageChange", rowSelect: "rowSelect", selectionChange: "selectionChange" }, viewQueries: [{ propertyName: "dt", first: true, predicate: ["dt"], descendants: true }], ngImport: i0, template: "\r\n<div class=\"flex-1 last:[&>td]:border-0 rounded-lg border border-surface w-full overflow-auto\">\r\n <p-table #dt\r\n [value]=\"data\"\r\n [columns]=\"columns\"\r\n [lazy]=\"true\"\r\n [paginator]=\"paginator\"\r\n [rows]=\"rows\"\r\n [first]=\"first\"\r\n [totalRecords]=\"totalRecords\"\r\n [sortField]=\"sortField\"\r\n [sortOrder]=\"sortOrder\" (onLazyLoad)=\"onLazyLoad($event)\"\r\n [globalFilterFields]=\"globalFilterFields\"\r\n [loading]=\"loading\"\r\n [scrollable]=\"true\"\r\n [scrollHeight]=\"scrollHeight\"\r\n [selectionMode]=\"showRowSelectionCheckbox ? 'multiple' : (rowSelectable ? 'single' : undefined)\"\r\n [(selection)]=\"_selection\"\r\n (onRowSelect)=\"onInternalSelectionChange($event)\"\r\n (onRowUnselect)=\"onInternalSelectionChange($event)\"\r\n (onHeaderCheckboxToggle)=\"onInternalSelectionChange($event)\"\r\n tableLayout=\"fixed\"\r\n [customSort]=\"false\"\r\n (sortFunction)=\"customSort($event)\"\r\n >\r\n\r\n <ng-template pTemplate=\"emptymessage\">\r\n <div class=\"flex flex-col items-center justify-center py-10 text-center w-full\">\r\n <i class=\"pi pi-inbox text-4xl text-gray-400 mb-4\"></i>\r\n <p class=\"text-gray-500 mb-4\">{{ 'NO_DATA_FOUND' | translate }}</p>\r\n <button\r\n pButton\r\n type=\"button\"\r\n icon=\"pi pi-plus\"\r\n label=\"{{ 'ADD_NEW' | translate }}\"\r\n class=\"p-button-rounded p-button-success\"\r\n (click)=\"onAddNew()\"\r\n ></button>\r\n </div>\r\n </ng-template>\r\n <!-- <ng-template pTemplate=\"emptymessage\">\r\n <div class=\"flex flex-col items-center justify-center py-20 w-full\">\r\n <i class=\"pi pi-users text-6xl text-gray-400 mb-6\"></i>\r\n <button\r\n pButton\r\n type=\"button\"\r\n label=\"\u0625\u0636\u0627\u0641\u0629 \u0646\u0648\u0639 \u062C\u062F\u064A\u062F\"\r\n icon=\"pi pi-plus\"\r\n iconPos=\"right\"\r\n class=\"p-button-rounded p-button-outlined p-button-secondary text-sm\"\r\n (click)=\"onAddNew()\"\r\n ></button>\r\n </div>\r\n</ng-template> -->\r\n\r\n <ng-template pTemplate=\"header\" let-columns>\r\n <tr>\r\n <th *ngIf=\"showRowSelectionCheckbox\" style=\"width: 2rem\">\r\n <p-tableHeaderCheckbox></p-tableHeaderCheckbox>\r\n </th>\r\n <!-- <th style=\"width: 1rem\">\r\n <p-tableHeaderCheckbox />\r\n </th> -->\r\n\r\n <ng-container *ngFor=\"let col of columns\" >\r\n <th *ngIf=\"col.props?.table?.props?.width; else templateName\" [pSortableColumn]=\"col.key\"\r\n class=\"px-4 py-2 text-sm font-medium text-white text-center\"\r\n [style.min-width]=\"col.props?.table?.props?.width\">\r\n {{ col.props?.label | translate }}\r\n <p-sortIcon [field]=\"col.key\"></p-sortIcon>\r\n </th>\r\n\r\n <ng-template #templateName>\r\n <th class=\"px-4 py-2 text-sm font-medium text-white text-center\">\r\n {{ col.props?.label | translate }}\r\n <p-sortIcon [field]=\"col.key\"></p-sortIcon>\r\n </th>\r\n </ng-template>\r\n</ng-container>\r\n\r\n\r\n <th class=\"px-4 py-2 text-sm font-medium text-white text-center\"> {{ 'OPERATIONS' | translate }}</th>\r\n </tr>\r\n </ng-template>\r\n\r\n <ng-template pTemplate=\"body\" let-rowData let-columns=\"columns\" let-i=\"rowIndex\">\r\n <tr class=\"even:bg-gray-50 hover:bg-gray-100\" (click)=\"rowSelect.emit(rowData)\">\r\n <!-- <td style=\"width: 1rem\">\r\n <p-tableCheckbox [value]=\"rowData\" />\r\n </td> -->\r\n <td *ngIf=\"showRowSelectionCheckbox\" style=\"width: 2rem\">\r\n <p-tableCheckbox [value]=\"rowData\"></p-tableCheckbox>\r\n </td>\r\n <td *ngFor=\"let col of columns_ ; let colIndex = index\"\r\n class=\"border-t border-gray-200 px-4 py-2 text-center text-sm text-gray-700\"\r\n [style.width]=\"col.props && col.props['table']\r\n && col.props['table']['props'] && col.props['table']['props']['width'] \"\r\n\r\n >\r\n\r\n\r\n <!-- \u0625\u0630\u0627 \u0627\u0644\u0639\u0645\u0648\u062F \u0642\u0627\u0628\u0644 \u0644\u0644\u0646\u0642\u0631 -->\r\n\r\n <formly-form\r\n [model]=\"rowData\"\r\n [form]=\"getForm(i, colIndex)\"\r\n [fields]=\"[cloneField(col)]\"\r\n [options]=\"options\">\r\n </formly-form>\r\n\r\n </td>\r\n <td class=\"border-t border-gray-200 px-4 py-2 text-center align-middle\">\r\n <ng-container [ngSwitch]=\"actionsMode\">\r\n <!-- Render buttons -->\r\n <ng-container *ngSwitchCase=\"'buttons'\">\r\n <ng-container *ngFor=\"let act of actions\">\r\n <button\r\n *ngIf=\"act.icon || act.label\"\r\n pButton\r\n [icon]=\"act.icon || ''\"\r\n [label]=\"(act.label || '') | translate\"\r\n [class]=\"act.styleClass || ''\"\r\n class=\"p-button-sm mx-1\"\r\n (click)=\"onAction(act, rowData)\"\r\n ></button>\r\n </ng-container>\r\n </ng-container>\r\n\r\n <!-- Render menu -->\r\n <ng-container *ngSwitchCase=\"'menu'\">\r\n <p-menu #menu [model]=\"getMenuItems(rowData)\" [popup]=\"true\" appendTo=\"body\">\r\n <ng-template let-item pTemplate=\"item\">\r\n <div class=\"flex items-center gap-2 px-2 py-1\">\r\n <i [ngClass]=\"item.icon\" class=\"text-primary-600\" *ngIf=\"item.icon\"></i>\r\n <span class=\"font-medium\">{{ (item.label || '') | translate }}</span>\r\n\r\n <span *ngIf=\"item.badge\" class=\"ml-auto text-xs bg-red-500 text-white px-2 py-1 rounded\">\r\n {{ item.badge }}\r\n </span>\r\n\r\n <!-- <p-inputSwitch *ngIf=\"item.toggle\" [(ngModel)]=\"item.toggleValue\" class=\"ml-auto\" /> -->\r\n </div>\r\n </ng-template>\r\n </p-menu>\r\n\r\n <p-button\r\n outlined\r\n icon=\"pi pi-ellipsis-v\"\r\n class=\"p-button-text p-button-sm\"\r\n (onClick)=\"menu.toggle($event)\"\r\n ></p-button>\r\n </ng-container>\r\n </ng-container>\r\n\r\n </td>\r\n </tr>\r\n </ng-template>\r\n </p-table>\r\n\r\n</div>\r\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.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: i1.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { 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: ["iconPos", "loadingIcon", "loading", "severity", "raised", "rounded", "text", "outlined", "size", "plain", "fluid", "label", "icon", "buttonProps"] }, { kind: "component", type: i4.Button, selector: "p-button", inputs: ["type", "iconPos", "icon", "badge", "label", "disabled", "loading", "loadingIcon", "raised", "rounded", "text", "plain", "severity", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "buttonProps", "autofocus", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: MenuModule }, { kind: "component", type: i5.Menu, selector: "p-menu", inputs: ["model", "popup", "style", "styleClass", "autoZIndex", "baseZIndex", "showTransitionOptions", "hideTransitionOptions", "ariaLabel", "ariaLabelledBy", "id", "tabindex", "appendTo"], outputs: ["onShow", "onHide", "onBlur", "onFocus"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "component", type: FormlyForm, selector: "formly-form", inputs: ["form", "model", "fields", "options"], outputs: ["modelChange"] }, { kind: "pipe", type: i6.TranslatePipe, name: "translate" }] });
|
|
162
|
+
}
|
|
163
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: GenericTable, decorators: [{
|
|
164
|
+
type: Component,
|
|
165
|
+
args: [{ selector: 'lib-generic-table', imports: [CommonModule, TableModule, ButtonModule, MenuModule, NgForOf, TranslateModule, FormlyField, FormlyForm, NgIf, TranslatePipe, Menu, Button], template: "\r\n<div class=\"flex-1 last:[&>td]:border-0 rounded-lg border border-surface w-full overflow-auto\">\r\n <p-table #dt\r\n [value]=\"data\"\r\n [columns]=\"columns\"\r\n [lazy]=\"true\"\r\n [paginator]=\"paginator\"\r\n [rows]=\"rows\"\r\n [first]=\"first\"\r\n [totalRecords]=\"totalRecords\"\r\n [sortField]=\"sortField\"\r\n [sortOrder]=\"sortOrder\" (onLazyLoad)=\"onLazyLoad($event)\"\r\n [globalFilterFields]=\"globalFilterFields\"\r\n [loading]=\"loading\"\r\n [scrollable]=\"true\"\r\n [scrollHeight]=\"scrollHeight\"\r\n [selectionMode]=\"showRowSelectionCheckbox ? 'multiple' : (rowSelectable ? 'single' : undefined)\"\r\n [(selection)]=\"_selection\"\r\n (onRowSelect)=\"onInternalSelectionChange($event)\"\r\n (onRowUnselect)=\"onInternalSelectionChange($event)\"\r\n (onHeaderCheckboxToggle)=\"onInternalSelectionChange($event)\"\r\n tableLayout=\"fixed\"\r\n [customSort]=\"false\"\r\n (sortFunction)=\"customSort($event)\"\r\n >\r\n\r\n <ng-template pTemplate=\"emptymessage\">\r\n <div class=\"flex flex-col items-center justify-center py-10 text-center w-full\">\r\n <i class=\"pi pi-inbox text-4xl text-gray-400 mb-4\"></i>\r\n <p class=\"text-gray-500 mb-4\">{{ 'NO_DATA_FOUND' | translate }}</p>\r\n <button\r\n pButton\r\n type=\"button\"\r\n icon=\"pi pi-plus\"\r\n label=\"{{ 'ADD_NEW' | translate }}\"\r\n class=\"p-button-rounded p-button-success\"\r\n (click)=\"onAddNew()\"\r\n ></button>\r\n </div>\r\n </ng-template>\r\n <!-- <ng-template pTemplate=\"emptymessage\">\r\n <div class=\"flex flex-col items-center justify-center py-20 w-full\">\r\n <i class=\"pi pi-users text-6xl text-gray-400 mb-6\"></i>\r\n <button\r\n pButton\r\n type=\"button\"\r\n label=\"\u0625\u0636\u0627\u0641\u0629 \u0646\u0648\u0639 \u062C\u062F\u064A\u062F\"\r\n icon=\"pi pi-plus\"\r\n iconPos=\"right\"\r\n class=\"p-button-rounded p-button-outlined p-button-secondary text-sm\"\r\n (click)=\"onAddNew()\"\r\n ></button>\r\n </div>\r\n</ng-template> -->\r\n\r\n <ng-template pTemplate=\"header\" let-columns>\r\n <tr>\r\n <th *ngIf=\"showRowSelectionCheckbox\" style=\"width: 2rem\">\r\n <p-tableHeaderCheckbox></p-tableHeaderCheckbox>\r\n </th>\r\n <!-- <th style=\"width: 1rem\">\r\n <p-tableHeaderCheckbox />\r\n </th> -->\r\n\r\n <ng-container *ngFor=\"let col of columns\" >\r\n <th *ngIf=\"col.props?.table?.props?.width; else templateName\" [pSortableColumn]=\"col.key\"\r\n class=\"px-4 py-2 text-sm font-medium text-white text-center\"\r\n [style.min-width]=\"col.props?.table?.props?.width\">\r\n {{ col.props?.label | translate }}\r\n <p-sortIcon [field]=\"col.key\"></p-sortIcon>\r\n </th>\r\n\r\n <ng-template #templateName>\r\n <th class=\"px-4 py-2 text-sm font-medium text-white text-center\">\r\n {{ col.props?.label | translate }}\r\n <p-sortIcon [field]=\"col.key\"></p-sortIcon>\r\n </th>\r\n </ng-template>\r\n</ng-container>\r\n\r\n\r\n <th class=\"px-4 py-2 text-sm font-medium text-white text-center\"> {{ 'OPERATIONS' | translate }}</th>\r\n </tr>\r\n </ng-template>\r\n\r\n <ng-template pTemplate=\"body\" let-rowData let-columns=\"columns\" let-i=\"rowIndex\">\r\n <tr class=\"even:bg-gray-50 hover:bg-gray-100\" (click)=\"rowSelect.emit(rowData)\">\r\n <!-- <td style=\"width: 1rem\">\r\n <p-tableCheckbox [value]=\"rowData\" />\r\n </td> -->\r\n <td *ngIf=\"showRowSelectionCheckbox\" style=\"width: 2rem\">\r\n <p-tableCheckbox [value]=\"rowData\"></p-tableCheckbox>\r\n </td>\r\n <td *ngFor=\"let col of columns_ ; let colIndex = index\"\r\n class=\"border-t border-gray-200 px-4 py-2 text-center text-sm text-gray-700\"\r\n [style.width]=\"col.props && col.props['table']\r\n && col.props['table']['props'] && col.props['table']['props']['width'] \"\r\n\r\n >\r\n\r\n\r\n <!-- \u0625\u0630\u0627 \u0627\u0644\u0639\u0645\u0648\u062F \u0642\u0627\u0628\u0644 \u0644\u0644\u0646\u0642\u0631 -->\r\n\r\n <formly-form\r\n [model]=\"rowData\"\r\n [form]=\"getForm(i, colIndex)\"\r\n [fields]=\"[cloneField(col)]\"\r\n [options]=\"options\">\r\n </formly-form>\r\n\r\n </td>\r\n <td class=\"border-t border-gray-200 px-4 py-2 text-center align-middle\">\r\n <ng-container [ngSwitch]=\"actionsMode\">\r\n <!-- Render buttons -->\r\n <ng-container *ngSwitchCase=\"'buttons'\">\r\n <ng-container *ngFor=\"let act of actions\">\r\n <button\r\n *ngIf=\"act.icon || act.label\"\r\n pButton\r\n [icon]=\"act.icon || ''\"\r\n [label]=\"(act.label || '') | translate\"\r\n [class]=\"act.styleClass || ''\"\r\n class=\"p-button-sm mx-1\"\r\n (click)=\"onAction(act, rowData)\"\r\n ></button>\r\n </ng-container>\r\n </ng-container>\r\n\r\n <!-- Render menu -->\r\n <ng-container *ngSwitchCase=\"'menu'\">\r\n <p-menu #menu [model]=\"getMenuItems(rowData)\" [popup]=\"true\" appendTo=\"body\">\r\n <ng-template let-item pTemplate=\"item\">\r\n <div class=\"flex items-center gap-2 px-2 py-1\">\r\n <i [ngClass]=\"item.icon\" class=\"text-primary-600\" *ngIf=\"item.icon\"></i>\r\n <span class=\"font-medium\">{{ (item.label || '') | translate }}</span>\r\n\r\n <span *ngIf=\"item.badge\" class=\"ml-auto text-xs bg-red-500 text-white px-2 py-1 rounded\">\r\n {{ item.badge }}\r\n </span>\r\n\r\n <!-- <p-inputSwitch *ngIf=\"item.toggle\" [(ngModel)]=\"item.toggleValue\" class=\"ml-auto\" /> -->\r\n </div>\r\n </ng-template>\r\n </p-menu>\r\n\r\n <p-button\r\n outlined\r\n icon=\"pi pi-ellipsis-v\"\r\n class=\"p-button-text p-button-sm\"\r\n (onClick)=\"menu.toggle($event)\"\r\n ></p-button>\r\n </ng-container>\r\n </ng-container>\r\n\r\n </td>\r\n </tr>\r\n </ng-template>\r\n </p-table>\r\n\r\n</div>\r\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"] }]
|
|
166
|
+
}], propDecorators: { dt: [{
|
|
167
|
+
type: ViewChild,
|
|
168
|
+
args: ['dt']
|
|
169
|
+
}], data: [{
|
|
170
|
+
type: Input
|
|
171
|
+
}], columns: [{
|
|
172
|
+
type: Input
|
|
173
|
+
}], loading: [{
|
|
174
|
+
type: Input
|
|
175
|
+
}], actions: [{
|
|
176
|
+
type: Input
|
|
177
|
+
}], actionsMode: [{
|
|
178
|
+
type: Input
|
|
179
|
+
}], first: [{
|
|
180
|
+
type: Input
|
|
181
|
+
}], rows: [{
|
|
182
|
+
type: Input
|
|
183
|
+
}], totalRecords: [{
|
|
184
|
+
type: Input
|
|
185
|
+
}], sortField: [{
|
|
186
|
+
type: Input
|
|
187
|
+
}], sortOrder: [{
|
|
188
|
+
type: Input
|
|
189
|
+
}], globalFilterFields: [{
|
|
190
|
+
type: Input
|
|
191
|
+
}], action: [{
|
|
192
|
+
type: Output
|
|
193
|
+
}], pageChange: [{
|
|
194
|
+
type: Output
|
|
195
|
+
}], scrollHeight: [{
|
|
196
|
+
type: Input
|
|
197
|
+
}], rowSelectable: [{
|
|
198
|
+
type: Input
|
|
199
|
+
}], selection: [{
|
|
200
|
+
type: Input
|
|
201
|
+
}], rowSelect: [{
|
|
202
|
+
type: Output
|
|
203
|
+
}], selectionChange: [{
|
|
204
|
+
type: Output
|
|
205
|
+
}], paginator: [{
|
|
206
|
+
type: Input
|
|
207
|
+
}], showRowSelectionCheckbox: [{
|
|
208
|
+
type: Input
|
|
209
|
+
}] } });
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* Generated bundle index. Do not edit.
|
|
213
|
+
*/
|
|
214
|
+
|
|
215
|
+
export { GenericTable };
|
|
216
|
+
//# sourceMappingURL=elite.framework-ng.core-src-lib-components-generic-table.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"elite.framework-ng.core-src-lib-components-generic-table.mjs","sources":["../../../projects/core/src/lib/components/generic-table/generic-table.ts","../../../projects/core/src/lib/components/generic-table/generic-table.html","../../../projects/core/src/lib/components/generic-table/elite.framework-ng.core-src-lib-components-generic-table.ts"],"sourcesContent":["import { Component, Input, Output, EventEmitter, ViewChild } from '@angular/core';\r\nimport { MenuItem, SortEvent } from 'primeng/api';\r\nimport { Table, TableHeaderCheckboxToggleEvent, TableLazyLoadEvent, TableRowSelectEvent } from 'primeng/table';\r\nimport { CommonModule, NgForOf, NgIf } 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 { TranslateModule, TranslatePipe } from '@ngx-translate/core';\r\nimport { FormlyField, FormlyFieldConfig, FormlyForm, FormlyFormOptions } from '@ngx-formly/core';\r\nimport { FormGroup } from '@angular/forms';\r\nimport { ActionDef } from '@elite.framework/ng.core';\r\n\r\n@Component({\r\n selector: 'lib-generic-table',\r\n imports: [CommonModule, TableModule, ButtonModule, MenuModule, NgForOf,TranslateModule,FormlyField,FormlyForm, NgIf, TranslatePipe, Menu, Button],\r\n templateUrl: './generic-table.html',\r\n styleUrl: './generic-table.css'\r\n})\r\nexport class GenericTable<T> {\r\n@ViewChild('dt') dt!: Table;\r\n\r\n @Input() data: T[] = [];\r\n @Input() columns: FormlyFieldConfig[] = [];\r\n columns_: FormlyFieldConfig[] = [];\r\n @Input() loading = false;\r\n @Input() actions: ActionDef<T>[] = [];\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\r\n @Input() scrollHeight: string = '400px';\r\n\r\n // **جديد**: تمكين اختيار الصفوف\r\n /** فعّل اختيار الصفين single/multiple */\r\n @Input() rowSelectable: boolean = 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 /** يصدر الصف المحدد عند النقر */\r\n @Output() rowSelect = new EventEmitter<T>();\r\n\r\n /** يصدر الصفوف المحددة عند التغيير (للربط الثنائي) */\r\n @Output() selectionChange = new EventEmitter<T | T[] | null>();\r\n\r\n\r\n /** جديد: التحكم بظهور الـ paginator */\r\n @Input() paginator: boolean = true;\r\nform = new FormGroup({});\r\noptions: FormlyFormOptions = {};\r\n\r\n\r\n // **جديد**: يتحكم بإظهار عمود اختيار الصفوف (checkboxes)\r\n /** يتحكم في إظهار عمود اختيار الصفوف المتعددة بواسطة checkboxes */\r\n @Input() showRowSelectionCheckbox: boolean = false;\r\n\r\nonAddNew(){\r\n\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\n\r\n\r\n\r\ncustomSort(event: SortEvent) {\r\n event.data?.sort((data1, data2) => {\r\n const value1 = this.resolveFieldData(data1, event.field ?? '');\r\n const value2 = this.resolveFieldData(data2, event.field ?? '');\r\n\r\n let result = 0;\r\n if (value1 == null && value2 != null) result = -1;\r\n else if (value1 != null && value2 == null) result = 1;\r\n else if (value1 == null && value2 == null) result = 0;\r\n else if (typeof value1 === 'string' && typeof value2 === 'string')\r\n result = value1.localeCompare(value2);\r\n else result = value1 < value2 ? -1 : value1 > value2 ? 1 : 0;\r\n\r\n return (event.order ?? 1) * result;\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 cloneField(field: any): any {\r\n if (field === null || typeof field !== 'object') {\r\n return field;\r\n }\r\n\r\n if (Array.isArray(field)) {\r\n // preserve `this` context\r\n return field.map((item) => this.cloneField(item));\r\n }\r\n const cloned: any = {};\r\n for (const key of Object.keys(field)) {\r\n cloned[key] = this.cloneField(field[key]);\r\n }\r\n\r\n return cloned;\r\n}\r\n\r\n getForm(rowIndex: number, colIndex: number): FormGroup {\r\n var cellForms: { [key: string]: FormGroup } = {};\r\n const key = `${rowIndex}_${colIndex}`;\r\n if (!cellForms[key]) {\r\n cellForms[key] = new FormGroup({});\r\n }\r\n return cellForms[key];\r\n }\r\n\r\n onLazyLoad(event: TableLazyLoadEvent): void {\r\n this.columns_ = this.columns;\r\n // // debugger\r\n this.pageChange.emit(event);\r\n }\r\n\r\n\r\n applyFilter(filters: any): void {\r\n // if (field) {\r\n // this.dt.filter(global, field, 'contains');\r\n // } else {\r\n // this.dt.filterGlobal(global, 'contains');\r\n // }\r\n\r\n }\r\n\r\n getMenuItems(row: T): MenuItem[] {\r\n return this.actions.map(act => ({\r\n label: act.label,\r\n icon: act.icon,\r\n command: () => this.onAction(act, row ),\r\n styleClass: act.styleClass\r\n }));\r\n }\r\n\r\n // **جديد**: يتم إطلاق هذا عند اختيار صف\r\n onRowSelect(event: TableRowSelectEvent<T>) {\r\n // debugger\r\n console.log('GenericTable.onRowSelect:', event.data);\r\n if (event.data) {\r\n this.rowSelect.emit(event.data as T);\r\n }\r\n }\r\n\r\n}\r\n","\r\n<div class=\"flex-1 last:[&>td]:border-0 rounded-lg border border-surface w-full overflow-auto\">\r\n <p-table #dt\r\n [value]=\"data\"\r\n [columns]=\"columns\"\r\n [lazy]=\"true\"\r\n [paginator]=\"paginator\"\r\n [rows]=\"rows\"\r\n [first]=\"first\"\r\n [totalRecords]=\"totalRecords\"\r\n [sortField]=\"sortField\"\r\n [sortOrder]=\"sortOrder\" (onLazyLoad)=\"onLazyLoad($event)\"\r\n [globalFilterFields]=\"globalFilterFields\"\r\n [loading]=\"loading\"\r\n [scrollable]=\"true\"\r\n [scrollHeight]=\"scrollHeight\"\r\n [selectionMode]=\"showRowSelectionCheckbox ? 'multiple' : (rowSelectable ? 'single' : undefined)\"\r\n [(selection)]=\"_selection\"\r\n (onRowSelect)=\"onInternalSelectionChange($event)\"\r\n (onRowUnselect)=\"onInternalSelectionChange($event)\"\r\n (onHeaderCheckboxToggle)=\"onInternalSelectionChange($event)\"\r\n tableLayout=\"fixed\"\r\n [customSort]=\"false\"\r\n (sortFunction)=\"customSort($event)\"\r\n >\r\n\r\n <ng-template pTemplate=\"emptymessage\">\r\n <div class=\"flex flex-col items-center justify-center py-10 text-center w-full\">\r\n <i class=\"pi pi-inbox text-4xl text-gray-400 mb-4\"></i>\r\n <p class=\"text-gray-500 mb-4\">{{ 'NO_DATA_FOUND' | translate }}</p>\r\n <button\r\n pButton\r\n type=\"button\"\r\n icon=\"pi pi-plus\"\r\n label=\"{{ 'ADD_NEW' | translate }}\"\r\n class=\"p-button-rounded p-button-success\"\r\n (click)=\"onAddNew()\"\r\n ></button>\r\n </div>\r\n </ng-template>\r\n <!-- <ng-template pTemplate=\"emptymessage\">\r\n <div class=\"flex flex-col items-center justify-center py-20 w-full\">\r\n <i class=\"pi pi-users text-6xl text-gray-400 mb-6\"></i>\r\n <button\r\n pButton\r\n type=\"button\"\r\n label=\"إضافة نوع جديد\"\r\n icon=\"pi pi-plus\"\r\n iconPos=\"right\"\r\n class=\"p-button-rounded p-button-outlined p-button-secondary text-sm\"\r\n (click)=\"onAddNew()\"\r\n ></button>\r\n </div>\r\n</ng-template> -->\r\n\r\n <ng-template pTemplate=\"header\" let-columns>\r\n <tr>\r\n <th *ngIf=\"showRowSelectionCheckbox\" style=\"width: 2rem\">\r\n <p-tableHeaderCheckbox></p-tableHeaderCheckbox>\r\n </th>\r\n <!-- <th style=\"width: 1rem\">\r\n <p-tableHeaderCheckbox />\r\n </th> -->\r\n\r\n <ng-container *ngFor=\"let col of columns\" >\r\n <th *ngIf=\"col.props?.table?.props?.width; else templateName\" [pSortableColumn]=\"col.key\"\r\n class=\"px-4 py-2 text-sm font-medium text-white text-center\"\r\n [style.min-width]=\"col.props?.table?.props?.width\">\r\n {{ col.props?.label | translate }}\r\n <p-sortIcon [field]=\"col.key\"></p-sortIcon>\r\n </th>\r\n\r\n <ng-template #templateName>\r\n <th class=\"px-4 py-2 text-sm font-medium text-white text-center\">\r\n {{ col.props?.label | translate }}\r\n <p-sortIcon [field]=\"col.key\"></p-sortIcon>\r\n </th>\r\n </ng-template>\r\n</ng-container>\r\n\r\n\r\n <th class=\"px-4 py-2 text-sm font-medium text-white text-center\"> {{ 'OPERATIONS' | translate }}</th>\r\n </tr>\r\n </ng-template>\r\n\r\n <ng-template pTemplate=\"body\" let-rowData let-columns=\"columns\" let-i=\"rowIndex\">\r\n <tr class=\"even:bg-gray-50 hover:bg-gray-100\" (click)=\"rowSelect.emit(rowData)\">\r\n <!-- <td style=\"width: 1rem\">\r\n <p-tableCheckbox [value]=\"rowData\" />\r\n </td> -->\r\n <td *ngIf=\"showRowSelectionCheckbox\" style=\"width: 2rem\">\r\n <p-tableCheckbox [value]=\"rowData\"></p-tableCheckbox>\r\n </td>\r\n <td *ngFor=\"let col of columns_ ; let colIndex = index\"\r\n class=\"border-t border-gray-200 px-4 py-2 text-center text-sm text-gray-700\"\r\n [style.width]=\"col.props && col.props['table']\r\n && col.props['table']['props'] && col.props['table']['props']['width'] \"\r\n\r\n >\r\n\r\n\r\n <!-- إذا العمود قابل للنقر -->\r\n\r\n <formly-form\r\n [model]=\"rowData\"\r\n [form]=\"getForm(i, colIndex)\"\r\n [fields]=\"[cloneField(col)]\"\r\n [options]=\"options\">\r\n </formly-form>\r\n\r\n </td>\r\n <td class=\"border-t border-gray-200 px-4 py-2 text-center align-middle\">\r\n <ng-container [ngSwitch]=\"actionsMode\">\r\n <!-- Render buttons -->\r\n <ng-container *ngSwitchCase=\"'buttons'\">\r\n <ng-container *ngFor=\"let act of actions\">\r\n <button\r\n *ngIf=\"act.icon || act.label\"\r\n pButton\r\n [icon]=\"act.icon || ''\"\r\n [label]=\"(act.label || '') | translate\"\r\n [class]=\"act.styleClass || ''\"\r\n class=\"p-button-sm mx-1\"\r\n (click)=\"onAction(act, rowData)\"\r\n ></button>\r\n </ng-container>\r\n </ng-container>\r\n\r\n <!-- Render menu -->\r\n <ng-container *ngSwitchCase=\"'menu'\">\r\n <p-menu #menu [model]=\"getMenuItems(rowData)\" [popup]=\"true\" appendTo=\"body\">\r\n <ng-template let-item pTemplate=\"item\">\r\n <div class=\"flex items-center gap-2 px-2 py-1\">\r\n <i [ngClass]=\"item.icon\" class=\"text-primary-600\" *ngIf=\"item.icon\"></i>\r\n <span class=\"font-medium\">{{ (item.label || '') | translate }}</span>\r\n\r\n <span *ngIf=\"item.badge\" class=\"ml-auto text-xs bg-red-500 text-white px-2 py-1 rounded\">\r\n {{ item.badge }}\r\n </span>\r\n\r\n <!-- <p-inputSwitch *ngIf=\"item.toggle\" [(ngModel)]=\"item.toggleValue\" class=\"ml-auto\" /> -->\r\n </div>\r\n </ng-template>\r\n </p-menu>\r\n\r\n <p-button\r\n outlined\r\n icon=\"pi pi-ellipsis-v\"\r\n class=\"p-button-text p-button-sm\"\r\n (onClick)=\"menu.toggle($event)\"\r\n ></p-button>\r\n </ng-container>\r\n </ng-container>\r\n\r\n </td>\r\n </tr>\r\n </ng-template>\r\n </p-table>\r\n\r\n</div>\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { Component } from '@angular/core';
|
|
3
|
+
|
|
4
|
+
class HeaderWrapper {
|
|
5
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: HeaderWrapper, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
6
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.4", type: HeaderWrapper, isStandalone: true, selector: "lib-header-wrapper", ngImport: i0, template: "<p>header-wrapper works!</p>\n", styles: [""] });
|
|
7
|
+
}
|
|
8
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: HeaderWrapper, decorators: [{
|
|
9
|
+
type: Component,
|
|
10
|
+
args: [{ selector: 'lib-header-wrapper', imports: [], template: "<p>header-wrapper works!</p>\n" }]
|
|
11
|
+
}] });
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Generated bundle index. Do not edit.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
export { HeaderWrapper };
|
|
18
|
+
//# sourceMappingURL=elite.framework-ng.core-src-lib-components-header-wrapper.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"elite.framework-ng.core-src-lib-components-header-wrapper.mjs","sources":["../../../projects/core/src/lib/components/header-wrapper/header-wrapper.ts","../../../projects/core/src/lib/components/header-wrapper/header-wrapper.html","../../../projects/core/src/lib/components/header-wrapper/elite.framework-ng.core-src-lib-components-header-wrapper.ts"],"sourcesContent":["import { Component } from '@angular/core';\n\n@Component({\n selector: 'lib-header-wrapper',\n imports: [],\n templateUrl: './header-wrapper.html',\n styleUrl: './header-wrapper.css'\n})\nexport class HeaderWrapper {\n\n}\n","<p>header-wrapper works!</p>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":";;;MAQa,aAAa,CAAA;uGAAb,aAAa,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAb,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,aAAa,8ECR1B,gCACA,EAAA,MAAA,EAAA,CAAA,EAAA,CAAA,EAAA,CAAA;;2FDOa,aAAa,EAAA,UAAA,EAAA,CAAA;kBANzB,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,oBAAoB,WACrB,EAAE,EAAA,QAAA,EAAA,gCAAA,EAAA;;;AEJb;;AAEG;;;;"}
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
import * as i2 from '@angular/common';
|
|
2
|
+
import { CommonModule } from '@angular/common';
|
|
3
|
+
import * as i0 from '@angular/core';
|
|
4
|
+
import { Component } from '@angular/core';
|
|
5
|
+
import * as i1 from '@angular/forms';
|
|
6
|
+
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
|
7
|
+
import { FieldType } from '@ngx-formly/core';
|
|
8
|
+
import { ButtonModule } from 'primeng/button';
|
|
9
|
+
import { DialogModule } from 'primeng/dialog';
|
|
10
|
+
|
|
11
|
+
class IconPickerComponent extends FieldType {
|
|
12
|
+
dropdownOpen = false;
|
|
13
|
+
searchQuery = '';
|
|
14
|
+
page = 1;
|
|
15
|
+
pageSize = 16;
|
|
16
|
+
icons = [
|
|
17
|
+
'fa-solid fa-box',
|
|
18
|
+
'fa-solid fa-layer-group',
|
|
19
|
+
'fa-solid fa-table-columns',
|
|
20
|
+
'fa-solid fa-database',
|
|
21
|
+
'fa-solid fa-arrow-left',
|
|
22
|
+
'fa-solid fa-arrow-right',
|
|
23
|
+
'fa-solid fa-arrow-down',
|
|
24
|
+
'fa-solid fa-arrow-up',
|
|
25
|
+
'fa-solid fa-trash',
|
|
26
|
+
'fa-solid fa-gear',
|
|
27
|
+
'fa-solid fa-circle-check',
|
|
28
|
+
'fa-solid fa-circle-xmark',
|
|
29
|
+
'fa-solid fa-pen',
|
|
30
|
+
'fa-solid fa-copy',
|
|
31
|
+
'fa-solid fa-share',
|
|
32
|
+
'fa-solid fa-upload',
|
|
33
|
+
'fa-solid fa-download',
|
|
34
|
+
'fa-solid fa-image',
|
|
35
|
+
'fa-solid fa-chart-pie',
|
|
36
|
+
// Add more FontAwesome Pro icons
|
|
37
|
+
];
|
|
38
|
+
get filteredIcons() {
|
|
39
|
+
if (!this.searchQuery)
|
|
40
|
+
return this.icons;
|
|
41
|
+
return this.icons.filter(icon => icon.toLowerCase().includes(this.searchQuery.toLowerCase()));
|
|
42
|
+
}
|
|
43
|
+
get totalPages() {
|
|
44
|
+
return Math.ceil(this.filteredIcons.length / this.pageSize);
|
|
45
|
+
}
|
|
46
|
+
get start() {
|
|
47
|
+
return (this.page - 1) * this.pageSize;
|
|
48
|
+
}
|
|
49
|
+
get end() {
|
|
50
|
+
return Math.min(this.start + this.pageSize, this.filteredIcons.length);
|
|
51
|
+
}
|
|
52
|
+
get pagedIcons() {
|
|
53
|
+
return this.filteredIcons.slice(this.start, this.end);
|
|
54
|
+
}
|
|
55
|
+
onSearch() {
|
|
56
|
+
this.page = 1;
|
|
57
|
+
}
|
|
58
|
+
selectIcon(icon) {
|
|
59
|
+
this.formControl.setValue(icon);
|
|
60
|
+
this.dropdownOpen = false;
|
|
61
|
+
}
|
|
62
|
+
nextPage() {
|
|
63
|
+
if (this.page < this.totalPages)
|
|
64
|
+
this.page++;
|
|
65
|
+
}
|
|
66
|
+
prevPage() {
|
|
67
|
+
if (this.page > 1)
|
|
68
|
+
this.page--;
|
|
69
|
+
}
|
|
70
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: IconPickerComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
|
|
71
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.4", type: IconPickerComponent, isStandalone: true, selector: "formly-field-icon-picker", usesInheritance: true, ngImport: i0, template: `
|
|
72
|
+
<div class="relative inline-block">
|
|
73
|
+
<!-- Toggle Button -->
|
|
74
|
+
<button type="button" class="px-2 py-1 border rounded shadow-sm bg-white dark:bg-gray-800 dark:border-gray-600"
|
|
75
|
+
(click)="dropdownOpen = !dropdownOpen">
|
|
76
|
+
<i [class]="formControl.value || 'fa-solid fa-circle-half-stroke'" class="text-lg"></i>
|
|
77
|
+
<i class="fas fa-caret-down ml-1 text-xs"></i>
|
|
78
|
+
</button>
|
|
79
|
+
|
|
80
|
+
<!-- Dropdown -->
|
|
81
|
+
<div *ngIf="dropdownOpen"
|
|
82
|
+
class="absolute z-50 mt-2 w-72 rounded-md border border-gray-300 shadow-lg bg-white dark:bg-gray-800 dark:border-gray-600">
|
|
83
|
+
|
|
84
|
+
<!-- Header -->
|
|
85
|
+
<div class="flex items-center justify-between px-2 py-1 border-b dark:border-gray-600">
|
|
86
|
+
<button (click)="prevPage()" class="p-1 hover:text-blue-600" [disabled]="page === 1">
|
|
87
|
+
<i class="fas fa-arrow-left"></i>
|
|
88
|
+
</button>
|
|
89
|
+
<span class="text-xs text-gray-600 dark:text-gray-300">Page {{ page }} / {{ totalPages }}</span>
|
|
90
|
+
<button (click)="nextPage()" class="p-1 hover:text-blue-600" [disabled]="page === totalPages">
|
|
91
|
+
<i class="fas fa-arrow-right"></i>
|
|
92
|
+
</button>
|
|
93
|
+
</div>
|
|
94
|
+
|
|
95
|
+
<!-- Search -->
|
|
96
|
+
<div class="p-2">
|
|
97
|
+
<input
|
|
98
|
+
type="text"
|
|
99
|
+
placeholder="Search icon"
|
|
100
|
+
[(ngModel)]="searchQuery"
|
|
101
|
+
(ngModelChange)="onSearch()"
|
|
102
|
+
class="w-full px-2 py-1 text-sm border border-gray-300 rounded focus:outline-none focus:ring-1 focus:ring-blue-500 dark:bg-gray-700 dark:border-gray-600 dark:text-white"
|
|
103
|
+
/>
|
|
104
|
+
</div>
|
|
105
|
+
|
|
106
|
+
<!-- Icon Grid -->
|
|
107
|
+
<div class="grid grid-cols-4 gap-2 p-2 max-h-56 overflow-y-auto">
|
|
108
|
+
<button
|
|
109
|
+
*ngFor="let icon of pagedIcons"
|
|
110
|
+
(click)="selectIcon(icon)"
|
|
111
|
+
class="flex items-center justify-center h-10 w-10 border rounded hover:bg-gray-100 dark:hover:bg-gray-700"
|
|
112
|
+
[ngClass]="{ 'ring-2 ring-blue-500': formControl.value === icon }"
|
|
113
|
+
>
|
|
114
|
+
<i [class]="icon" class="text-lg"></i>
|
|
115
|
+
</button>
|
|
116
|
+
</div>
|
|
117
|
+
|
|
118
|
+
<!-- Footer -->
|
|
119
|
+
<div class="px-2 py-1 text-xs text-gray-500 dark:text-gray-400 border-t dark:border-gray-600">
|
|
120
|
+
{{ start + 1 }} - {{ end }} of {{ filteredIcons.length }}
|
|
121
|
+
</div>
|
|
122
|
+
</div>
|
|
123
|
+
</div>
|
|
124
|
+
|
|
125
|
+
`, isInline: true, dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: DialogModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "ngmodule", type: ButtonModule }] });
|
|
126
|
+
}
|
|
127
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: IconPickerComponent, decorators: [{
|
|
128
|
+
type: Component,
|
|
129
|
+
args: [{
|
|
130
|
+
selector: 'formly-field-icon-picker',
|
|
131
|
+
imports: [FormsModule, CommonModule, DialogModule, ReactiveFormsModule, ButtonModule],
|
|
132
|
+
template: `
|
|
133
|
+
<div class="relative inline-block">
|
|
134
|
+
<!-- Toggle Button -->
|
|
135
|
+
<button type="button" class="px-2 py-1 border rounded shadow-sm bg-white dark:bg-gray-800 dark:border-gray-600"
|
|
136
|
+
(click)="dropdownOpen = !dropdownOpen">
|
|
137
|
+
<i [class]="formControl.value || 'fa-solid fa-circle-half-stroke'" class="text-lg"></i>
|
|
138
|
+
<i class="fas fa-caret-down ml-1 text-xs"></i>
|
|
139
|
+
</button>
|
|
140
|
+
|
|
141
|
+
<!-- Dropdown -->
|
|
142
|
+
<div *ngIf="dropdownOpen"
|
|
143
|
+
class="absolute z-50 mt-2 w-72 rounded-md border border-gray-300 shadow-lg bg-white dark:bg-gray-800 dark:border-gray-600">
|
|
144
|
+
|
|
145
|
+
<!-- Header -->
|
|
146
|
+
<div class="flex items-center justify-between px-2 py-1 border-b dark:border-gray-600">
|
|
147
|
+
<button (click)="prevPage()" class="p-1 hover:text-blue-600" [disabled]="page === 1">
|
|
148
|
+
<i class="fas fa-arrow-left"></i>
|
|
149
|
+
</button>
|
|
150
|
+
<span class="text-xs text-gray-600 dark:text-gray-300">Page {{ page }} / {{ totalPages }}</span>
|
|
151
|
+
<button (click)="nextPage()" class="p-1 hover:text-blue-600" [disabled]="page === totalPages">
|
|
152
|
+
<i class="fas fa-arrow-right"></i>
|
|
153
|
+
</button>
|
|
154
|
+
</div>
|
|
155
|
+
|
|
156
|
+
<!-- Search -->
|
|
157
|
+
<div class="p-2">
|
|
158
|
+
<input
|
|
159
|
+
type="text"
|
|
160
|
+
placeholder="Search icon"
|
|
161
|
+
[(ngModel)]="searchQuery"
|
|
162
|
+
(ngModelChange)="onSearch()"
|
|
163
|
+
class="w-full px-2 py-1 text-sm border border-gray-300 rounded focus:outline-none focus:ring-1 focus:ring-blue-500 dark:bg-gray-700 dark:border-gray-600 dark:text-white"
|
|
164
|
+
/>
|
|
165
|
+
</div>
|
|
166
|
+
|
|
167
|
+
<!-- Icon Grid -->
|
|
168
|
+
<div class="grid grid-cols-4 gap-2 p-2 max-h-56 overflow-y-auto">
|
|
169
|
+
<button
|
|
170
|
+
*ngFor="let icon of pagedIcons"
|
|
171
|
+
(click)="selectIcon(icon)"
|
|
172
|
+
class="flex items-center justify-center h-10 w-10 border rounded hover:bg-gray-100 dark:hover:bg-gray-700"
|
|
173
|
+
[ngClass]="{ 'ring-2 ring-blue-500': formControl.value === icon }"
|
|
174
|
+
>
|
|
175
|
+
<i [class]="icon" class="text-lg"></i>
|
|
176
|
+
</button>
|
|
177
|
+
</div>
|
|
178
|
+
|
|
179
|
+
<!-- Footer -->
|
|
180
|
+
<div class="px-2 py-1 text-xs text-gray-500 dark:text-gray-400 border-t dark:border-gray-600">
|
|
181
|
+
{{ start + 1 }} - {{ end }} of {{ filteredIcons.length }}
|
|
182
|
+
</div>
|
|
183
|
+
</div>
|
|
184
|
+
</div>
|
|
185
|
+
|
|
186
|
+
`
|
|
187
|
+
}]
|
|
188
|
+
}] });
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* Generated bundle index. Do not edit.
|
|
192
|
+
*/
|
|
193
|
+
|
|
194
|
+
export { IconPickerComponent };
|
|
195
|
+
//# sourceMappingURL=elite.framework-ng.core-src-lib-components-icon-picker.mjs.map
|