@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.
Files changed (127) hide show
  1. package/fesm2022/elite.framework-ng.core-src-lib-components-attachments.mjs +204 -0
  2. package/fesm2022/elite.framework-ng.core-src-lib-components-attachments.mjs.map +1 -0
  3. package/fesm2022/elite.framework-ng.core-src-lib-components-breadcrumb.mjs +132 -0
  4. package/fesm2022/elite.framework-ng.core-src-lib-components-breadcrumb.mjs.map +1 -0
  5. package/fesm2022/elite.framework-ng.core-src-lib-components-color-picker.mjs +76 -0
  6. package/fesm2022/elite.framework-ng.core-src-lib-components-color-picker.mjs.map +1 -0
  7. package/fesm2022/elite.framework-ng.core-src-lib-components-column-settings-popover.mjs +172 -0
  8. package/fesm2022/elite.framework-ng.core-src-lib-components-column-settings-popover.mjs.map +1 -0
  9. package/fesm2022/elite.framework-ng.core-src-lib-components-condition-editor.mjs +794 -0
  10. package/fesm2022/elite.framework-ng.core-src-lib-components-condition-editor.mjs.map +1 -0
  11. package/fesm2022/elite.framework-ng.core-src-lib-components-custom-switch.mjs +110 -0
  12. package/fesm2022/elite.framework-ng.core-src-lib-components-custom-switch.mjs.map +1 -0
  13. package/fesm2022/elite.framework-ng.core-src-lib-components-deactivation-reason.mjs +130 -0
  14. package/fesm2022/elite.framework-ng.core-src-lib-components-deactivation-reason.mjs.map +1 -0
  15. package/fesm2022/elite.framework-ng.core-src-lib-components-form-button.mjs +50 -0
  16. package/fesm2022/elite.framework-ng.core-src-lib-components-form-button.mjs.map +1 -0
  17. package/fesm2022/elite.framework-ng.core-src-lib-components-form-field.mjs +154 -0
  18. package/fesm2022/elite.framework-ng.core-src-lib-components-form-field.mjs.map +1 -0
  19. package/fesm2022/elite.framework-ng.core-src-lib-components-form-template.mjs +24 -0
  20. package/fesm2022/elite.framework-ng.core-src-lib-components-form-template.mjs.map +1 -0
  21. package/fesm2022/elite.framework-ng.core-src-lib-components-formly-avatar-image.mjs +100 -0
  22. package/fesm2022/elite.framework-ng.core-src-lib-components-formly-avatar-image.mjs.map +1 -0
  23. package/fesm2022/elite.framework-ng.core-src-lib-components-formly-avatar-label.mjs +78 -0
  24. package/fesm2022/elite.framework-ng.core-src-lib-components-formly-avatar-label.mjs.map +1 -0
  25. package/fesm2022/elite.framework-ng.core-src-lib-components-formly-button-selector.mjs +167 -0
  26. package/fesm2022/elite.framework-ng.core-src-lib-components-formly-button-selector.mjs.map +1 -0
  27. package/fesm2022/elite.framework-ng.core-src-lib-components-formly-button.mjs +62 -0
  28. package/fesm2022/elite.framework-ng.core-src-lib-components-formly-button.mjs.map +1 -0
  29. package/fesm2022/elite.framework-ng.core-src-lib-components-formly-split-button.mjs +50 -0
  30. package/fesm2022/elite.framework-ng.core-src-lib-components-formly-split-button.mjs.map +1 -0
  31. package/fesm2022/elite.framework-ng.core-src-lib-components-formly-username-with-domain.mjs +76 -0
  32. package/fesm2022/elite.framework-ng.core-src-lib-components-formly-username-with-domain.mjs.map +1 -0
  33. package/fesm2022/elite.framework-ng.core-src-lib-components-generic-autocomplete.mjs +163 -0
  34. package/fesm2022/elite.framework-ng.core-src-lib-components-generic-autocomplete.mjs.map +1 -0
  35. package/fesm2022/elite.framework-ng.core-src-lib-components-generic-button.mjs +133 -0
  36. package/fesm2022/elite.framework-ng.core-src-lib-components-generic-button.mjs.map +1 -0
  37. package/fesm2022/elite.framework-ng.core-src-lib-components-generic-card.mjs +214 -0
  38. package/fesm2022/elite.framework-ng.core-src-lib-components-generic-card.mjs.map +1 -0
  39. package/fesm2022/elite.framework-ng.core-src-lib-components-generic-crud-table.mjs +385 -0
  40. package/fesm2022/elite.framework-ng.core-src-lib-components-generic-crud-table.mjs.map +1 -0
  41. package/fesm2022/elite.framework-ng.core-src-lib-components-generic-errormessage.mjs +23 -0
  42. package/fesm2022/elite.framework-ng.core-src-lib-components-generic-errormessage.mjs.map +1 -0
  43. package/fesm2022/elite.framework-ng.core-src-lib-components-generic-formly-fields.mjs +53 -0
  44. package/fesm2022/elite.framework-ng.core-src-lib-components-generic-formly-fields.mjs.map +1 -0
  45. package/fesm2022/elite.framework-ng.core-src-lib-components-generic-loadingspinner.mjs +23 -0
  46. package/fesm2022/elite.framework-ng.core-src-lib-components-generic-loadingspinner.mjs.map +1 -0
  47. package/fesm2022/elite.framework-ng.core-src-lib-components-generic-search.mjs +85 -0
  48. package/fesm2022/elite.framework-ng.core-src-lib-components-generic-search.mjs.map +1 -0
  49. package/fesm2022/elite.framework-ng.core-src-lib-components-generic-selector.mjs +430 -0
  50. package/fesm2022/elite.framework-ng.core-src-lib-components-generic-selector.mjs.map +1 -0
  51. package/fesm2022/elite.framework-ng.core-src-lib-components-generic-table.mjs +216 -0
  52. package/fesm2022/elite.framework-ng.core-src-lib-components-generic-table.mjs.map +1 -0
  53. package/fesm2022/elite.framework-ng.core-src-lib-components-header-wrapper.mjs +18 -0
  54. package/fesm2022/elite.framework-ng.core-src-lib-components-header-wrapper.mjs.map +1 -0
  55. package/fesm2022/elite.framework-ng.core-src-lib-components-icon-picker.mjs +195 -0
  56. package/fesm2022/elite.framework-ng.core-src-lib-components-icon-picker.mjs.map +1 -0
  57. package/fesm2022/elite.framework-ng.core-src-lib-components-input-switch.mjs +94 -0
  58. package/fesm2022/elite.framework-ng.core-src-lib-components-input-switch.mjs.map +1 -0
  59. package/fesm2022/elite.framework-ng.core-src-lib-components-input-with-icon.mjs +55 -0
  60. package/fesm2022/elite.framework-ng.core-src-lib-components-input-with-icon.mjs.map +1 -0
  61. package/fesm2022/elite.framework-ng.core-src-lib-components-label-type.mjs +112 -0
  62. package/fesm2022/elite.framework-ng.core-src-lib-components-label-type.mjs.map +1 -0
  63. package/fesm2022/elite.framework-ng.core-src-lib-components-odata-query-builder.mjs +297 -0
  64. package/fesm2022/elite.framework-ng.core-src-lib-components-odata-query-builder.mjs.map +1 -0
  65. package/fesm2022/elite.framework-ng.core-src-lib-components-repeat.mjs +135 -0
  66. package/fesm2022/elite.framework-ng.core-src-lib-components-repeat.mjs.map +1 -0
  67. package/fesm2022/elite.framework-ng.core-src-lib-components-sidebar-cards.mjs +40 -0
  68. package/fesm2022/elite.framework-ng.core-src-lib-components-sidebar-cards.mjs.map +1 -0
  69. package/fesm2022/elite.framework-ng.core-src-lib-components-sidebar-toggles.mjs +41 -0
  70. package/fesm2022/elite.framework-ng.core-src-lib-components-sidebar-toggles.mjs.map +1 -0
  71. package/fesm2022/elite.framework-ng.core-src-lib-components-tabs.mjs +45 -0
  72. package/fesm2022/elite.framework-ng.core-src-lib-components-tabs.mjs.map +1 -0
  73. package/fesm2022/elite.framework-ng.core-src-lib-components-tag-type.mjs +192 -0
  74. package/fesm2022/elite.framework-ng.core-src-lib-components-tag-type.mjs.map +1 -0
  75. package/fesm2022/elite.framework-ng.core-src-lib-components-text-editor.mjs +44 -0
  76. package/fesm2022/elite.framework-ng.core-src-lib-components-text-editor.mjs.map +1 -0
  77. package/fesm2022/elite.framework-ng.core-src-lib-components-wrappers.mjs +174 -0
  78. package/fesm2022/elite.framework-ng.core-src-lib-components-wrappers.mjs.map +1 -0
  79. package/fesm2022/elite.framework-ng.core-src-lib-directives.mjs +59 -0
  80. package/fesm2022/elite.framework-ng.core-src-lib-directives.mjs.map +1 -0
  81. package/fesm2022/elite.framework-ng.core-src-lib-pipes.mjs +135 -0
  82. package/fesm2022/elite.framework-ng.core-src-lib-pipes.mjs.map +1 -0
  83. package/fesm2022/elite.framework-ng.core.mjs +1643 -384
  84. package/fesm2022/elite.framework-ng.core.mjs.map +1 -1
  85. package/index.d.ts +493 -24
  86. package/package.json +14 -62
  87. package/src/lib/components/attachments/index.d.ts +31 -0
  88. package/src/lib/components/breadcrumb/index.d.ts +10 -0
  89. package/src/lib/components/color-picker/index.d.ts +9 -0
  90. package/src/lib/components/column-settings-popover/index.d.ts +39 -0
  91. package/src/lib/components/condition-editor/index.d.ts +73 -0
  92. package/src/lib/components/custom-switch/index.d.ts +12 -0
  93. package/src/lib/components/deactivation-reason/index.d.ts +24 -0
  94. package/src/lib/components/form-button/index.d.ts +10 -0
  95. package/src/lib/components/form-field/index.d.ts +30 -0
  96. package/src/lib/components/form-template/index.d.ts +9 -0
  97. package/src/lib/components/formly-avatar-image/index.d.ts +11 -0
  98. package/src/lib/components/formly-avatar-label/index.d.ts +29 -0
  99. package/src/lib/components/formly-button/index.d.ts +13 -0
  100. package/src/lib/components/formly-button-selector/index.d.ts +28 -0
  101. package/src/lib/components/formly-split-button/index.d.ts +16 -0
  102. package/src/lib/components/formly-username-with-domain/index.d.ts +12 -0
  103. package/src/lib/components/generic-autocomplete/index.d.ts +34 -0
  104. package/src/lib/components/generic-button/index.d.ts +35 -0
  105. package/src/lib/components/generic-card/index.d.ts +90 -0
  106. package/src/lib/components/generic-crud-table/index.d.ts +120 -0
  107. package/src/lib/components/generic-errormessage/index.d.ts +10 -0
  108. package/src/lib/components/generic-formly-fields/index.d.ts +22 -0
  109. package/src/lib/components/generic-loadingspinner/index.d.ts +9 -0
  110. package/src/lib/components/generic-search/index.d.ts +29 -0
  111. package/src/lib/components/generic-selector/index.d.ts +66 -0
  112. package/src/lib/components/generic-table/index.d.ts +60 -0
  113. package/src/lib/components/header-wrapper/index.d.ts +8 -0
  114. package/src/lib/components/icon-picker/index.d.ts +23 -0
  115. package/src/lib/components/input-switch/index.d.ts +9 -0
  116. package/src/lib/components/input-with-icon/index.d.ts +10 -0
  117. package/src/lib/components/label-type/index.d.ts +19 -0
  118. package/src/lib/components/odata-query-builder/index.d.ts +81 -0
  119. package/src/lib/components/repeat/index.d.ts +17 -0
  120. package/src/lib/components/sidebar-cards/index.d.ts +18 -0
  121. package/src/lib/components/sidebar-toggles/index.d.ts +18 -0
  122. package/src/lib/components/tabs/index.d.ts +10 -0
  123. package/src/lib/components/tag-type/index.d.ts +27 -0
  124. package/src/lib/components/text-editor/index.d.ts +9 -0
  125. package/src/lib/components/wrappers/index.d.ts +24 -0
  126. package/src/lib/directives/index.d.ts +23 -0
  127. package/src/lib/pipes/index.d.ts +20 -0
@@ -0,0 +1,23 @@
1
+ import * as i0 from '@angular/core';
2
+ import { Input, Component } from '@angular/core';
3
+ import * as i1 from '@angular/common';
4
+ import { CommonModule } from '@angular/common';
5
+
6
+ class GenericLoadingspinner {
7
+ loading = false;
8
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: GenericLoadingspinner, deps: [], target: i0.ɵɵFactoryTarget.Component });
9
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.4", type: GenericLoadingspinner, isStandalone: true, selector: "lib-generic-loadingspinner", inputs: { loading: "loading" }, ngImport: i0, template: " <ng-container *ngIf=\"loading\"> \n <div class=\"flex justify-center items-center my-6\"> \n <svg class=\"w-8 h-8 animate-spin text-blue-500\" viewBox=\"0 0 24 24\" fill=\"none\"> \n <circle class=\"opacity-25\" cx=\"12\" cy=\"12\" r=\"10\" stroke=\"currentColor\" stroke-width=\"4\"></circle> \n <path class=\"opacity-75\" fill=\"currentColor\" d=\"M4 12a8 8 0 018-8v8H4z\"></path> \n </svg> \n <span class=\"ml-2 text-gray-700\">\u062C\u0627\u0631\u064A \u0627\u0644\u062A\u062D\u0645\u064A\u0644...</span> \n </div> \n </ng-container>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] });
10
+ }
11
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: GenericLoadingspinner, decorators: [{
12
+ type: Component,
13
+ args: [{ selector: 'lib-generic-loadingspinner', imports: [CommonModule], template: " <ng-container *ngIf=\"loading\"> \n <div class=\"flex justify-center items-center my-6\"> \n <svg class=\"w-8 h-8 animate-spin text-blue-500\" viewBox=\"0 0 24 24\" fill=\"none\"> \n <circle class=\"opacity-25\" cx=\"12\" cy=\"12\" r=\"10\" stroke=\"currentColor\" stroke-width=\"4\"></circle> \n <path class=\"opacity-75\" fill=\"currentColor\" d=\"M4 12a8 8 0 018-8v8H4z\"></path> \n </svg> \n <span class=\"ml-2 text-gray-700\">\u062C\u0627\u0631\u064A \u0627\u0644\u062A\u062D\u0645\u064A\u0644...</span> \n </div> \n </ng-container>\n" }]
14
+ }], propDecorators: { loading: [{
15
+ type: Input
16
+ }] } });
17
+
18
+ /**
19
+ * Generated bundle index. Do not edit.
20
+ */
21
+
22
+ export { GenericLoadingspinner };
23
+ //# sourceMappingURL=elite.framework-ng.core-src-lib-components-generic-loadingspinner.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"elite.framework-ng.core-src-lib-components-generic-loadingspinner.mjs","sources":["../../../projects/core/src/lib/components/generic-loadingspinner/generic-loadingspinner.ts","../../../projects/core/src/lib/components/generic-loadingspinner/generic-loadingspinner.html","../../../projects/core/src/lib/components/generic-loadingspinner/elite.framework-ng.core-src-lib-components-generic-loadingspinner.ts"],"sourcesContent":["import { Component, Input } from '@angular/core';\nimport { CommonModule } from '@angular/common';\n\n@Component({\n selector: 'lib-generic-loadingspinner',\n imports: [CommonModule],\n templateUrl: './generic-loadingspinner.html',\n styleUrl: './generic-loadingspinner.css'\n})\nexport class GenericLoadingspinner {\n@Input() loading: boolean = false;\n}\n\n\n\n\n"," <ng-container *ngIf=\"loading\"> \n <div class=\"flex justify-center items-center my-6\"> \n <svg class=\"w-8 h-8 animate-spin text-blue-500\" viewBox=\"0 0 24 24\" fill=\"none\"> \n <circle class=\"opacity-25\" cx=\"12\" cy=\"12\" r=\"10\" stroke=\"currentColor\" stroke-width=\"4\"></circle> \n <path class=\"opacity-75\" fill=\"currentColor\" d=\"M4 12a8 8 0 018-8v8H4z\"></path> \n </svg> \n <span class=\"ml-2 text-gray-700\">جاري التحميل...</span> \n </div> \n </ng-container>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":";;;;;MASa,qBAAqB,CAAA;IACzB,OAAO,GAAY,KAAK;uGADpB,qBAAqB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;2FAArB,qBAAqB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,4BAAA,EAAA,MAAA,EAAA,EAAA,OAAA,EAAA,SAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,ECTlC,6sBASA,EAAA,MAAA,EAAA,CAAA,EAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EDJY,YAAY,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,IAAA,EAAA,QAAA,EAAA,QAAA,EAAA,MAAA,EAAA,CAAA,MAAA,EAAA,UAAA,EAAA,UAAA,CAAA,EAAA,CAAA,EAAA,CAAA;;2FAIX,qBAAqB,EAAA,UAAA,EAAA,CAAA;kBANjC,SAAS;+BACE,4BAA4B,EAAA,OAAA,EAC7B,CAAC,YAAY,CAAC,EAAA,QAAA,EAAA,6sBAAA,EAAA;8BAKhB,OAAO,EAAA,CAAA;sBAAf;;;AEVD;;AAEG;;;;"}
@@ -0,0 +1,85 @@
1
+ import * as i0 from '@angular/core';
2
+ import { inject, EventEmitter, Input, Output, ViewChild, Component } from '@angular/core';
3
+ import { CommonModule } from '@angular/common';
4
+ import * as i2 from '@angular/forms';
5
+ import { FormGroup, ReactiveFormsModule, FormsModule } from '@angular/forms';
6
+ import { FormlyForm } from '@ngx-formly/core';
7
+ import * as i7 from '@ngx-translate/core';
8
+ import { TranslateService, TranslateModule } from '@ngx-translate/core';
9
+ import { ToolbarModule } from 'primeng/toolbar';
10
+ import * as i1 from 'primeng/button';
11
+ import { ButtonModule } from 'primeng/button';
12
+ import * as i3 from 'primeng/popover';
13
+ import { PopoverModule } from 'primeng/popover';
14
+ import * as i4 from 'primeng/inputicon';
15
+ import { InputIconModule } from 'primeng/inputicon';
16
+ import * as i5 from 'primeng/iconfield';
17
+ import { IconFieldModule } from 'primeng/iconfield';
18
+ import * as i6 from 'primeng/inputtext';
19
+ import { InputTextModule } from 'primeng/inputtext';
20
+
21
+ class GenericSearch {
22
+ overlay;
23
+ translate = inject(TranslateService);
24
+ placeholder = 'بحث...';
25
+ /**
26
+ * List of fields to search by
27
+ * Example: [{ label: 'Name', value: 'name' }, { label: 'Email', value: 'email' }]
28
+ */
29
+ search = new EventEmitter();
30
+ form = new FormGroup({});
31
+ model = {};
32
+ options = {};
33
+ fields = [];
34
+ fields_ = [];
35
+ // onTogglePopover(event: any) {
36
+ // debugger
37
+ // this.overlay.toggle(event);
38
+ // }
39
+ ngOnInit() {
40
+ this.fields_ = this.fields;
41
+ }
42
+ onSubmit() {
43
+ this.search.emit(this.model);
44
+ }
45
+ onReset() {
46
+ this.model = {};
47
+ this.search.emit(this.model);
48
+ }
49
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: GenericSearch, deps: [], target: i0.ɵɵFactoryTarget.Component });
50
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.4", type: GenericSearch, isStandalone: true, selector: "lib-generic-search", inputs: { placeholder: "placeholder", model: "model", fields: "fields" }, outputs: { search: "search" }, viewQueries: [{ propertyName: "overlay", first: true, predicate: ["overlay"], descendants: true }], ngImport: i0, template: "<div class=\"flex items-center gap-3\">\r\n<p-iconfield iconPosition=\"left\">\r\n\r\n <p-inputicon class=\"pi pi-search\"> </p-inputicon>\r\n <input pInputText type=\"text\" (keyup.enter)=\"onSubmit()\" [(ngModel)]=\"model['filter']\" placeholder=\"{{ 'SEARCH' | translate }}\" />\r\n <!-- 2) Search Button that toggles the popover -->\r\n\r\n</p-iconfield>\r\n<p-button icon=\"pi pi-filter\" outlined severity=\"secondary\" (onClick)=\"overlay.toggle($event)\" />\r\n</div>\r\n<!-- 4) Popover for Advanced Multi-field Search -->\r\n<p-popover #overlay [dismissable]=\"true\" styleClass=\"p-4 w-80 max-h-96 flex flex-col\">\r\n\r\n <div class=\"flex-1 overflow-auto\">\r\n <form [formGroup]=\"form\" (ngSubmit)=\"onSubmit(); overlay.hide()\">\r\n <formly-form\r\n [form]=\"form\"\r\n [fields]=\"fields_\"\r\n [model]=\"model\"\r\n [options]=\"options\">\r\n </formly-form>\r\n </form>\r\n </div>\r\n\r\n <div class=\"flex justify-end mt-2 space-x-2 flex-none\">\r\n <button type=\"submit\" pButton size=\"small\" label=\"{{ 'SEARCH' | translate }}\"></button>\r\n <button type=\"button\" pButton size=\"small\" class=\"p-button-text\" (click)=\"onReset(); overlay.hide()\">\r\n {{ 'CLEAR' | translate }}\r\n </button>\r\n </div>\r\n\r\n\r\n</p-popover>\r\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: FormlyForm, selector: "formly-form", inputs: ["form", "model", "fields", "options"], outputs: ["modelChange"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "ngmodule", type: ToolbarModule }, { kind: "ngmodule", type: ButtonModule }, { kind: "directive", type: i1.ButtonDirective, selector: "[pButton]", inputs: ["iconPos", "loadingIcon", "loading", "severity", "raised", "rounded", "text", "outlined", "size", "plain", "fluid", "label", "icon", "buttonProps"] }, { kind: "component", type: i1.Button, selector: "p-button", inputs: ["type", "iconPos", "icon", "badge", "label", "disabled", "loading", "loadingIcon", "raised", "rounded", "text", "plain", "severity", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "buttonProps", "autofocus", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: PopoverModule }, { kind: "component", type: i3.Popover, selector: "p-popover", inputs: ["ariaLabel", "ariaLabelledBy", "dismissable", "style", "styleClass", "appendTo", "autoZIndex", "ariaCloseLabel", "baseZIndex", "focusOnShow", "showTransitionOptions", "hideTransitionOptions"], outputs: ["onShow", "onHide"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: InputIconModule }, { kind: "component", type: i4.InputIcon, selector: "p-inputicon, p-inputIcon", inputs: ["styleClass"] }, { kind: "ngmodule", type: IconFieldModule }, { kind: "component", type: i5.IconField, selector: "p-iconfield, p-iconField, p-icon-field", inputs: ["iconPosition", "styleClass"] }, { kind: "ngmodule", type: InputTextModule }, { kind: "directive", type: i6.InputText, selector: "[pInputText]", inputs: ["pSize", "variant", "fluid", "invalid"] }, { kind: "pipe", type: i7.TranslatePipe, name: "translate" }] });
51
+ }
52
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: GenericSearch, decorators: [{
53
+ type: Component,
54
+ args: [{ selector: 'lib-generic-search', standalone: true, imports: [
55
+ CommonModule,
56
+ FormlyForm,
57
+ TranslateModule,
58
+ ToolbarModule,
59
+ ButtonModule,
60
+ ReactiveFormsModule,
61
+ PopoverModule,
62
+ FormsModule,
63
+ InputIconModule,
64
+ IconFieldModule,
65
+ InputTextModule,
66
+ ], template: "<div class=\"flex items-center gap-3\">\r\n<p-iconfield iconPosition=\"left\">\r\n\r\n <p-inputicon class=\"pi pi-search\"> </p-inputicon>\r\n <input pInputText type=\"text\" (keyup.enter)=\"onSubmit()\" [(ngModel)]=\"model['filter']\" placeholder=\"{{ 'SEARCH' | translate }}\" />\r\n <!-- 2) Search Button that toggles the popover -->\r\n\r\n</p-iconfield>\r\n<p-button icon=\"pi pi-filter\" outlined severity=\"secondary\" (onClick)=\"overlay.toggle($event)\" />\r\n</div>\r\n<!-- 4) Popover for Advanced Multi-field Search -->\r\n<p-popover #overlay [dismissable]=\"true\" styleClass=\"p-4 w-80 max-h-96 flex flex-col\">\r\n\r\n <div class=\"flex-1 overflow-auto\">\r\n <form [formGroup]=\"form\" (ngSubmit)=\"onSubmit(); overlay.hide()\">\r\n <formly-form\r\n [form]=\"form\"\r\n [fields]=\"fields_\"\r\n [model]=\"model\"\r\n [options]=\"options\">\r\n </formly-form>\r\n </form>\r\n </div>\r\n\r\n <div class=\"flex justify-end mt-2 space-x-2 flex-none\">\r\n <button type=\"submit\" pButton size=\"small\" label=\"{{ 'SEARCH' | translate }}\"></button>\r\n <button type=\"button\" pButton size=\"small\" class=\"p-button-text\" (click)=\"onReset(); overlay.hide()\">\r\n {{ 'CLEAR' | translate }}\r\n </button>\r\n </div>\r\n\r\n\r\n</p-popover>\r\n" }]
67
+ }], propDecorators: { overlay: [{
68
+ type: ViewChild,
69
+ args: ['overlay']
70
+ }], placeholder: [{
71
+ type: Input
72
+ }], search: [{
73
+ type: Output
74
+ }], model: [{
75
+ type: Input
76
+ }], fields: [{
77
+ type: Input
78
+ }] } });
79
+
80
+ /**
81
+ * Generated bundle index. Do not edit.
82
+ */
83
+
84
+ export { GenericSearch };
85
+ //# sourceMappingURL=elite.framework-ng.core-src-lib-components-generic-search.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"elite.framework-ng.core-src-lib-components-generic-search.mjs","sources":["../../../projects/core/src/lib/components/generic-search/generic-search.ts","../../../projects/core/src/lib/components/generic-search/generic-search.html","../../../projects/core/src/lib/components/generic-search/elite.framework-ng.core-src-lib-components-generic-search.ts"],"sourcesContent":["import { Component, EventEmitter, Input, OnInit, Output, ViewChild, inject } from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { FormGroup, FormsModule, ReactiveFormsModule } from '@angular/forms';\nimport { FormlyFieldConfig, FormlyForm, FormlyFormOptions } from '@ngx-formly/core';\nimport { TranslateModule, TranslateService } from '@ngx-translate/core';\nimport { ToolbarModule } from 'primeng/toolbar';\nimport { ButtonModule } from 'primeng/button';\nimport { Popover, PopoverModule } from 'primeng/popover';\nimport { InputIconModule } from 'primeng/inputicon';\nimport { IconFieldModule } from 'primeng/iconfield';\nimport { InputTextModule } from 'primeng/inputtext';\n\n@Component({\n selector: 'lib-generic-search',\n standalone: true,\n imports: [\n CommonModule,\n FormlyForm,\n TranslateModule,\n ToolbarModule,\n ButtonModule,\n ReactiveFormsModule,\n PopoverModule,\n FormsModule,\n InputIconModule,\n IconFieldModule,\n InputTextModule,\n ],\n templateUrl: './generic-search.html',\n})\nexport class GenericSearch implements OnInit {\n @ViewChild('overlay') overlay!: Popover;\n translate = inject(TranslateService);\n\n @Input() placeholder = 'بحث...';\n\n /**\n * List of fields to search by\n * Example: [{ label: 'Name', value: 'name' }, { label: 'Email', value: 'email' }]\n */\n\n\n @Output() search = new EventEmitter<any>();\n\n form = new FormGroup({});\n @Input() model: any = {};\n options: FormlyFormOptions = {};\n @Input() fields: FormlyFieldConfig[] = [];\n fields_: FormlyFieldConfig[] = [];\n\n// onTogglePopover(event: any) {\n// debugger\n// this.overlay.toggle(event);\n// }\n ngOnInit() {\n this.fields_ = this.fields;\n }\n\n onSubmit() {\n this.search.emit(this.model);\n }\n\n onReset() {\n this.model = {};\n this.search.emit(this.model);\n }\n}\n","<div class=\"flex items-center gap-3\">\r\n<p-iconfield iconPosition=\"left\">\r\n\r\n <p-inputicon class=\"pi pi-search\"> </p-inputicon>\r\n <input pInputText type=\"text\" (keyup.enter)=\"onSubmit()\" [(ngModel)]=\"model['filter']\" placeholder=\"{{ 'SEARCH' | translate }}\" />\r\n <!-- 2) Search Button that toggles the popover -->\r\n\r\n</p-iconfield>\r\n<p-button icon=\"pi pi-filter\" outlined severity=\"secondary\" (onClick)=\"overlay.toggle($event)\" />\r\n</div>\r\n<!-- 4) Popover for Advanced Multi-field Search -->\r\n<p-popover #overlay [dismissable]=\"true\" styleClass=\"p-4 w-80 max-h-96 flex flex-col\">\r\n\r\n <div class=\"flex-1 overflow-auto\">\r\n <form [formGroup]=\"form\" (ngSubmit)=\"onSubmit(); overlay.hide()\">\r\n <formly-form\r\n [form]=\"form\"\r\n [fields]=\"fields_\"\r\n [model]=\"model\"\r\n [options]=\"options\">\r\n </formly-form>\r\n </form>\r\n </div>\r\n\r\n <div class=\"flex justify-end mt-2 space-x-2 flex-none\">\r\n <button type=\"submit\" pButton size=\"small\" label=\"{{ 'SEARCH' | translate }}\"></button>\r\n <button type=\"button\" pButton size=\"small\" class=\"p-button-text\" (click)=\"onReset(); overlay.hide()\">\r\n {{ 'CLEAR' | translate }}\r\n </button>\r\n </div>\r\n\r\n\r\n</p-popover>\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,430 @@
1
+ import * as i0 from '@angular/core';
2
+ import { ViewChild, Component } from '@angular/core';
3
+ import { FieldType, FormlyAttributes } from '@ngx-formly/core';
4
+ import { DialogService } from 'primeng/dynamicdialog';
5
+ import { forkJoin } from 'rxjs';
6
+ import { finalize } from 'rxjs/operators';
7
+ import { CommonModule } from '@angular/common';
8
+ import * as i2 from '@angular/forms';
9
+ import { FormsModule, ReactiveFormsModule } from '@angular/forms';
10
+ import * as i3 from 'primeng/autocomplete';
11
+ import { AutoCompleteModule, AutoComplete } from 'primeng/autocomplete';
12
+ import * as i4 from 'primeng/inputgroup';
13
+ import { InputGroupModule } from 'primeng/inputgroup';
14
+ import * as i5 from 'primeng/inputgroupaddon';
15
+ import { InputGroupAddonModule } from 'primeng/inputgroupaddon';
16
+ import * as i7 from '@ngx-translate/core';
17
+ import { TranslateModule } from '@ngx-translate/core';
18
+ import { CheckboxModule } from 'primeng/checkbox';
19
+ import * as i6 from 'primeng/button';
20
+ import { ButtonModule } from 'primeng/button';
21
+ import * as i1 from '@elite.framework/ng.core';
22
+ import { BaseService } from '@elite.framework/ng.core';
23
+
24
+ class GenericSelectorTypeComponent extends FieldType {
25
+ svc;
26
+ injector;
27
+ cdr;
28
+ autoComp;
29
+ options_ = [];
30
+ selectedItem;
31
+ loading = false;
32
+ _offlineList = [];
33
+ api;
34
+ dialog;
35
+ valueChangeSubscription; // Add a subscription to manage the observable
36
+ constructor(svc, injector, cdr) {
37
+ super();
38
+ this.svc = svc;
39
+ this.injector = injector;
40
+ this.cdr = cdr;
41
+ }
42
+ ngOnInit() {
43
+ this.api = this.svc;
44
+ this.dialog = this.injector.get(DialogService);
45
+ const to = this.props;
46
+ this.api.apiName = to['serviceName'];
47
+ if (to['offline']) {
48
+ if (to['offlineDataFn']) {
49
+ this._offlineList = to['offlineDataFn']();
50
+ this.initOfflineSelection();
51
+ }
52
+ else if (to['offlineItems$']) {
53
+ to['offlineItems$'].subscribe((list) => {
54
+ this._offlineList = list;
55
+ this.initOfflineSelection();
56
+ });
57
+ }
58
+ else {
59
+ this._offlineList = to['offlineItems'] || [];
60
+ this.initOfflineSelection();
61
+ }
62
+ }
63
+ else {
64
+ if (this.props.loadSaved && !this.props.multiple && this.props.loadSavedField && this.props.valueField) {
65
+ const vf = this.to['valueField'] || 'id';
66
+ const lf = this.to['labelField'] || 'name';
67
+ this.selectedItem =
68
+ {
69
+ [vf]: this.formControl.value,
70
+ [lf]: this.model[this.props.loadSavedField],
71
+ };
72
+ if (this.props.change) {
73
+ this.props.change(this.field, { item: this.selectedItem });
74
+ this.cdr.detectChanges();
75
+ }
76
+ }
77
+ else {
78
+ this.initOnlineSelection();
79
+ }
80
+ }
81
+ // Subscribe to formControl value changes
82
+ this.valueChangeSubscription = this.formControl.valueChanges
83
+ .subscribe(() => {
84
+ // This tap operator is a good place to run side effects
85
+ // like calling your change handler after a value changes.
86
+ // this.selectedItem = this.formControl.value;
87
+ if (this.props.change) {
88
+ if (to['offline']) {
89
+ if (to['offlineDataFn']) {
90
+ this._offlineList = to['offlineDataFn']();
91
+ this.initOfflineSelection(false);
92
+ }
93
+ else if (to['offlineItems$']) {
94
+ to['offlineItems$'].subscribe((list) => {
95
+ this._offlineList = list;
96
+ this.initOfflineSelection(false);
97
+ });
98
+ }
99
+ else {
100
+ this._offlineList = to['offlineItems'] || [];
101
+ this.initOfflineSelection(false);
102
+ }
103
+ }
104
+ else {
105
+ this.initOnlineSelection(false);
106
+ }
107
+ }
108
+ });
109
+ }
110
+ // Remember to unsubscribe to prevent memory leaks!
111
+ ngOnDestroy() {
112
+ if (this.valueChangeSubscription) {
113
+ this.valueChangeSubscription.unsubscribe();
114
+ }
115
+ }
116
+ loadDefaultValue() {
117
+ this.loading = true;
118
+ const vf = this.to['valueField'] || 'id';
119
+ const fixedFilters = this.getFixedFilters();
120
+ const lf = this.to['loadDefaultField'] || 'isDefault';
121
+ const lfValue = this.to['loadDefaultValue'] || true;
122
+ const searchParams = {
123
+ [lf]: lfValue,
124
+ ...fixedFilters,
125
+ };
126
+ this.api.getList(searchParams)
127
+ .subscribe({
128
+ next: (res) => {
129
+ // Assuming the API returns a list and you want to select the first one
130
+ if (res && res.items && res.items.length > 0) {
131
+ if (this.to['multiple']) {
132
+ this.formControl.setValue(res.items.map((c) => c[vf]));
133
+ }
134
+ else {
135
+ const defaultValue = res.items[0];
136
+ this.formControl.setValue(defaultValue?.[vf]);
137
+ }
138
+ }
139
+ this.loading = false;
140
+ // this.initOnlineSelection(); // Proceed with online selection after setting the value
141
+ },
142
+ error: (err) => {
143
+ console.error("Failed to load default value from API:", err);
144
+ this.loading = false;
145
+ // this.initOnlineSelection(); // Fallback to local selection if API fails
146
+ }
147
+ });
148
+ }
149
+ // New method to handle loading the default value from the API
150
+ onSelect(event) {
151
+ if (this.props.onSelect) {
152
+ this.props.onSelect(this.field, { item: event.value });
153
+ this.cdr.detectChanges();
154
+ }
155
+ }
156
+ onSelectionChange(val) {
157
+ this.selectedItem = val;
158
+ const vf = this.to['valueField'] || 'id';
159
+ if (this.to['multiple']) {
160
+ this.formControl.setValue(Array.isArray(val) ? val.map((c) => c[vf]) : []);
161
+ }
162
+ else {
163
+ this.formControl.setValue(val?.[vf] ?? null);
164
+ }
165
+ }
166
+ initOfflineSelection(withSetValue = true) {
167
+ const val = this.formControl.value;
168
+ const vf = this.to['valueField'] || 'id';
169
+ if (val == null)
170
+ return;
171
+ if (this.to['multiple'] && Array.isArray(val)) {
172
+ this.selectedItem = this._offlineList.filter(item => val.includes(item[vf]));
173
+ }
174
+ else {
175
+ this.selectedItem = this._offlineList.find(item => item[vf] === val);
176
+ }
177
+ if (withSetValue == true) {
178
+ this.formControl.setValue(this.to['multiple']
179
+ ? this.selectedItem.map((c) => c[vf])
180
+ : this.selectedItem?.[vf]);
181
+ }
182
+ else {
183
+ if (this.props.change) {
184
+ this.props.change(this.field, { item: this.selectedItem });
185
+ this.cdr.detectChanges();
186
+ }
187
+ }
188
+ }
189
+ initOnlineSelection(withSetValue = true) {
190
+ var d = this.selectedItem;
191
+ const fullModel = this.model;
192
+ const val = this.formControl.value;
193
+ const vf = this.to['valueField'] || 'id';
194
+ if (val == null || (Array.isArray(val) && val.length === 0)) {
195
+ this.selectedItem = this.to['multiple'] ? [] : null;
196
+ if (this.props['loadDefault'] == true) {
197
+ this.loadDefaultValue();
198
+ }
199
+ else {
200
+ return;
201
+ }
202
+ }
203
+ if (this.to['multiple'] && Array.isArray(val) && val.length) {
204
+ const calls = val.map((id) => this.api.get(id));
205
+ forkJoin(calls)
206
+ .pipe(finalize(() => (this.loading = false)))
207
+ .subscribe(items => {
208
+ this.selectedItem = items;
209
+ if (withSetValue == true) {
210
+ this.formControl.setValue(items.map((c) => c[vf]));
211
+ this.cdr.detectChanges();
212
+ }
213
+ else {
214
+ if (this.props.change) {
215
+ this.props.change(this.field, { item: this.selectedItem });
216
+ this.cdr.detectChanges();
217
+ }
218
+ }
219
+ });
220
+ }
221
+ else {
222
+ this.loading = true;
223
+ this.api.get(val)
224
+ .pipe(finalize(() => (this.loading = false)))
225
+ .subscribe((item) => {
226
+ this.selectedItem = item;
227
+ // debugger
228
+ if (withSetValue == true) {
229
+ this.formControl.setValue(item?.[vf]);
230
+ this.cdr.detectChanges();
231
+ }
232
+ else {
233
+ if (this.props.change) {
234
+ this.props.change(this.field, { item: this.selectedItem });
235
+ this.cdr.detectChanges();
236
+ }
237
+ }
238
+ });
239
+ }
240
+ }
241
+ getFixedFilters() {
242
+ const fixedFilters = this.to['fixedFilters'];
243
+ if (typeof fixedFilters === 'function') {
244
+ // Call with current model (and optionally field)
245
+ return fixedFilters(this.model);
246
+ }
247
+ return fixedFilters || {};
248
+ }
249
+ onDropdownButtonClick() {
250
+ console.log('Custom dropdown button clicked!');
251
+ this.search({ query: '' }); // trigger your own search
252
+ setTimeout(() => this.autoComp.show(), 0); // force dropdown to open
253
+ }
254
+ // Called when dropdown button clicked
255
+ onDropdownClick(event) {
256
+ // 🚫 stop the default dropdown behavior
257
+ event.originalEvent.preventDefault();
258
+ event.originalEvent.stopPropagation();
259
+ console.log('Dropdown clicked!', event);
260
+ // ✅ your custom code here
261
+ // e.g., force trigger search for empty query
262
+ this.search({ query: '' });
263
+ }
264
+ search(event) {
265
+ const q = event.query?.toString().toLowerCase() || '';
266
+ const lf = this.to['labelField'] || 'name';
267
+ const fixedFilters = this.getFixedFilters();
268
+ if (this.to['offline']) {
269
+ this.options_ = this.to['offlineDataFn']
270
+ ? this.to['offlineDataFn'](q)
271
+ : this._offlineList.filter(item => item[lf]?.toString().toLowerCase().includes(q));
272
+ setTimeout(() => this.autoComp?.show(), 0);
273
+ }
274
+ else {
275
+ this.loading = true;
276
+ this.options_ = [];
277
+ const searchParams = {
278
+ [lf]: q,
279
+ ...fixedFilters,
280
+ };
281
+ // ✅ استخدام listEndpoint إذا كان موجودًا، وإلا العودة إلى الافتراضي
282
+ let listEndpoint = this.props.listEndpoint;
283
+ if (typeof listEndpoint === 'function') {
284
+ listEndpoint = listEndpoint(this.model);
285
+ }
286
+ this.api.getList(searchParams, listEndpoint)
287
+ .pipe(finalize(() => (this.loading = false)))
288
+ .subscribe({
289
+ next: (res) => {
290
+ this.options_ = res.items ?? res ?? [];
291
+ setTimeout(() => this.autoComp?.show(), 0);
292
+ },
293
+ error: () => {
294
+ this.options_ = [];
295
+ },
296
+ });
297
+ }
298
+ }
299
+ openCrud(mode) {
300
+ const payload = mode === 'add' ? null : this.selectedItem;
301
+ // Example integration:
302
+ // const ref = this.dialog.open(CrudComponent, {
303
+ // data: {
304
+ // serviceName: this.to.serviceName,
305
+ // mode,
306
+ // record: payload
307
+ // }
308
+ // });
309
+ // ref.onClose.subscribe((updated: any) => {
310
+ // if (!this.to.multiple && updated?.[this.to.valueField]) {
311
+ // this.api.get(updated[this.to.valueField])
312
+ // .subscribe(item => {
313
+ // this.selectedItem = item;
314
+ // this.formControl.setValue(item?.[this.to.valueField]);
315
+ // });
316
+ // }
317
+ // });
318
+ }
319
+ getEmptyMessage() {
320
+ if (this.loading) {
321
+ return 'LOADING_DATA_MESSAGE'; // مفتاح ترجمة لـ "جاري تحميل البيانات..."
322
+ }
323
+ else if (this.options_.length === 0) {
324
+ return 'NO_RESULTS_FOUND'; // مفتاح ترجمة لـ "لا توجد نتائج مطابقة."
325
+ }
326
+ return ''; // لا تُعرض رسالة إذا كانت هناك نتائج
327
+ }
328
+ isItemSelected(item) {
329
+ const vf = this.to['valueField'] || 'id';
330
+ return Array.isArray(this.selectedItem) &&
331
+ this.selectedItem.some((sel) => sel[vf] === item[vf]);
332
+ }
333
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: GenericSelectorTypeComponent, deps: [{ token: i1.BaseService }, { token: i0.Injector }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
334
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.4", type: GenericSelectorTypeComponent, isStandalone: true, selector: "formly-generic-selector", providers: [DialogService, BaseService], viewQueries: [{ propertyName: "autoComp", first: true, predicate: ["autoComp"], descendants: true }], usesInheritance: true, ngImport: i0, template: `
335
+ <!-- (ngModelChange)="onSelectionChange($event)" -->
336
+ <p-inputGroup class="w-full">
337
+ <p-autoComplete
338
+ #autoComp
339
+ [ngModel]="selectedItem"
340
+ (ngModelChange)="onSelectionChange($event)"
341
+ [formlyAttributes]="field"
342
+ [suggestions]="options_"
343
+ (completeMethod)="search($event)"
344
+ [multiple]="to['multiple']"
345
+ [optionLabel]="to['labelField'] || 'name'"
346
+ [dropdown]="false"
347
+ [forceSelection]="true"
348
+ [placeholder]="(props['placeholder'] ?? '') | translate"
349
+ [disabled]="!!props.disabled"
350
+ dropdownMode="current"
351
+ appendTo="body"
352
+ class="w-full rounded-none"
353
+ [showEmptyMessage]="true"
354
+ (onSelect)="onSelect($event)"
355
+ emptyMessage="{{ getEmptyMessage() | translate }}"
356
+ [showTransitionOptions]="'0ms'">
357
+ </p-autoComplete>
358
+
359
+ <!-- 🔘 Custom dropdown addon -->
360
+ <p-inputGroupAddon>
361
+ <p-button icon="pi pi-chevron-down" (click)="onDropdownButtonClick()" severity="secondary" />
362
+ </p-inputGroupAddon>
363
+ </p-inputGroup>
364
+
365
+
366
+ `, isInline: true, dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "ngmodule", type: AutoCompleteModule }, { kind: "component", type: i3.AutoComplete, selector: "p-autoComplete, p-autocomplete, p-auto-complete", inputs: ["minLength", "minQueryLength", "delay", "panelStyle", "styleClass", "panelStyleClass", "inputStyle", "inputId", "inputStyleClass", "placeholder", "readonly", "scrollHeight", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "autoHighlight", "forceSelection", "type", "autoZIndex", "baseZIndex", "ariaLabel", "dropdownAriaLabel", "ariaLabelledBy", "dropdownIcon", "unique", "group", "completeOnFocus", "showClear", "dropdown", "showEmptyMessage", "dropdownMode", "multiple", "tabindex", "dataKey", "emptyMessage", "showTransitionOptions", "hideTransitionOptions", "autofocus", "autocomplete", "optionGroupChildren", "optionGroupLabel", "overlayOptions", "suggestions", "optionLabel", "optionValue", "id", "searchMessage", "emptySelectionMessage", "selectionMessage", "autoOptionFocus", "selectOnFocus", "searchLocale", "optionDisabled", "focusOnHover", "typeahead", "appendTo"], outputs: ["completeMethod", "onSelect", "onUnselect", "onFocus", "onBlur", "onDropdownClick", "onClear", "onKeyUp", "onShow", "onHide", "onLazyLoad"] }, { kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: InputGroupModule }, { kind: "component", type: i4.InputGroup, selector: "p-inputgroup, p-inputGroup, p-input-group", inputs: ["styleClass"] }, { kind: "ngmodule", type: InputGroupAddonModule }, { kind: "component", type: i5.InputGroupAddon, selector: "p-inputgroup-addon, p-inputGroupAddon", inputs: ["style", "styleClass"] }, { kind: "directive", type: FormlyAttributes, selector: "[formlyAttributes]", inputs: ["formlyAttributes", "id"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "ngmodule", type: CheckboxModule }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i6.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: "pipe", type: i7.TranslatePipe, name: "translate" }] });
367
+ }
368
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: GenericSelectorTypeComponent, decorators: [{
369
+ type: Component,
370
+ args: [{
371
+ selector: 'formly-generic-selector',
372
+ template: `
373
+ <!-- (ngModelChange)="onSelectionChange($event)" -->
374
+ <p-inputGroup class="w-full">
375
+ <p-autoComplete
376
+ #autoComp
377
+ [ngModel]="selectedItem"
378
+ (ngModelChange)="onSelectionChange($event)"
379
+ [formlyAttributes]="field"
380
+ [suggestions]="options_"
381
+ (completeMethod)="search($event)"
382
+ [multiple]="to['multiple']"
383
+ [optionLabel]="to['labelField'] || 'name'"
384
+ [dropdown]="false"
385
+ [forceSelection]="true"
386
+ [placeholder]="(props['placeholder'] ?? '') | translate"
387
+ [disabled]="!!props.disabled"
388
+ dropdownMode="current"
389
+ appendTo="body"
390
+ class="w-full rounded-none"
391
+ [showEmptyMessage]="true"
392
+ (onSelect)="onSelect($event)"
393
+ emptyMessage="{{ getEmptyMessage() | translate }}"
394
+ [showTransitionOptions]="'0ms'">
395
+ </p-autoComplete>
396
+
397
+ <!-- 🔘 Custom dropdown addon -->
398
+ <p-inputGroupAddon>
399
+ <p-button icon="pi pi-chevron-down" (click)="onDropdownButtonClick()" severity="secondary" />
400
+ </p-inputGroupAddon>
401
+ </p-inputGroup>
402
+
403
+
404
+ `,
405
+ providers: [DialogService, BaseService],
406
+ imports: [
407
+ FormsModule,
408
+ ReactiveFormsModule,
409
+ AutoCompleteModule,
410
+ CommonModule,
411
+ InputGroupModule,
412
+ InputGroupAddonModule,
413
+ FormlyAttributes,
414
+ TranslateModule,
415
+ AutoComplete,
416
+ CheckboxModule,
417
+ ButtonModule
418
+ ]
419
+ }]
420
+ }], ctorParameters: () => [{ type: i1.BaseService }, { type: i0.Injector }, { type: i0.ChangeDetectorRef }], propDecorators: { autoComp: [{
421
+ type: ViewChild,
422
+ args: ['autoComp']
423
+ }] } });
424
+
425
+ /**
426
+ * Generated bundle index. Do not edit.
427
+ */
428
+
429
+ export { GenericSelectorTypeComponent };
430
+ //# sourceMappingURL=elite.framework-ng.core-src-lib-components-generic-selector.mjs.map