@one-paragon/angular-utilities 2.8.3 → 2.8.4

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 (203) hide show
  1. package/karma.conf.js +43 -0
  2. package/ng-package.json +7 -0
  3. package/package.json +15 -27
  4. package/src/action-state/action-state-spinner/action-state-spinner.component.css +16 -0
  5. package/src/action-state/action-state-spinner/action-state-spinner.component.html +7 -0
  6. package/src/action-state/action-state-spinner/action-state-spinner.component.spec.ts +25 -0
  7. package/src/action-state/action-state-spinner/action-state-spinner.component.ts +26 -0
  8. package/src/action-state/action-state-ui/action-state-ui.module.ts +13 -0
  9. package/src/action-state/index.ts +8 -0
  10. package/src/action-state/ngrx-ext/ngrx-ext.module.ts +14 -0
  11. package/src/action-state/ngrx.ts +69 -0
  12. package/src/http-request-state/RequestStateFactory.ts +56 -0
  13. package/src/http-request-state/RequestStateStore.ts +360 -0
  14. package/src/http-request-state/deprecated.ts +20 -0
  15. package/src/http-request-state/directives/HttpStateDirectiveBase.ts +29 -0
  16. package/src/http-request-state/directives/http-error-state-directive.ts +21 -0
  17. package/src/http-request-state/directives/http-inProgress-state-directive.ts +19 -0
  18. package/src/http-request-state/directives/http-notStarted-state-directive.ts +19 -0
  19. package/src/http-request-state/directives/http-success-state-directive.ts +29 -0
  20. package/src/http-request-state/directives/index.ts +5 -0
  21. package/src/http-request-state/directives/request-state-directive.spec.ts +73 -0
  22. package/src/http-request-state/directives/request-state-directive.ts +78 -0
  23. package/src/http-request-state/documentation/CREATE-REQUESTOR.md +667 -0
  24. package/src/http-request-state/documentation/README.md +191 -0
  25. package/src/http-request-state/documentation/REQUEST-STATE-STORE-CONFIG.md +648 -0
  26. package/src/http-request-state/documentation/REQUESTOR.md +616 -0
  27. package/src/http-request-state/helpers.ts +30 -0
  28. package/src/http-request-state/http-state-module.ts +23 -0
  29. package/src/http-request-state/index.ts +7 -0
  30. package/src/http-request-state/models/view-context.ts +18 -0
  31. package/src/http-request-state/observable.spec.ts +43 -0
  32. package/src/http-request-state/request-state.ts +66 -0
  33. package/src/http-request-state/rxjs/getRequestorBody.ts +10 -0
  34. package/src/http-request-state/rxjs/getRequestorState.ts +8 -0
  35. package/src/http-request-state/rxjs/index.ts +4 -0
  36. package/src/http-request-state/rxjs/tapError.ts +16 -0
  37. package/src/http-request-state/rxjs/tapSuccess.ts +16 -0
  38. package/src/http-request-state/strategies.spec.ts +42 -0
  39. package/src/http-request-state/types.ts +54 -0
  40. package/src/ngrx/actionable-selector.ts +189 -0
  41. package/src/ngrx/index.ts +1 -0
  42. package/src/public-api.ts +40 -0
  43. package/src/rxjs/defaultShareReplay.ts +8 -0
  44. package/src/rxjs/index.ts +5 -0
  45. package/src/rxjs/mapError.ts +8 -0
  46. package/src/rxjs/rxjs-operators.ts +130 -0
  47. package/src/rxjs/subjectifier.ts +17 -0
  48. package/src/rxjs/subscriber.directive.ts +57 -0
  49. package/src/specs/clickSubject.spec.ts +99 -0
  50. package/src/specs/dialog.spec.ts +101 -0
  51. package/src/specs/toggleGroupDirective.spec.ts +229 -0
  52. package/src/table-builder/classes/DefaultSettings.ts +11 -0
  53. package/src/table-builder/classes/MatTableObservableDataSource.ts +23 -0
  54. package/src/table-builder/classes/TableBuilderConfig.ts +49 -0
  55. package/src/table-builder/classes/TableBuilderDataSource.ts +64 -0
  56. package/src/table-builder/classes/TableState.ts +96 -0
  57. package/src/table-builder/classes/data-store.ts +10 -0
  58. package/src/table-builder/classes/display-col.ts +5 -0
  59. package/src/table-builder/classes/filter-info.ts +129 -0
  60. package/src/table-builder/classes/table-builder-general-settings.ts +233 -0
  61. package/src/table-builder/classes/table-builder.ts +105 -0
  62. package/src/table-builder/classes/table-store.helpers.ts +109 -0
  63. package/src/table-builder/classes/table-store.ts +540 -0
  64. package/src/table-builder/components/array-column.component.ts +34 -0
  65. package/src/table-builder/components/column-builder/column-builder.component.html +109 -0
  66. package/src/table-builder/components/column-builder/column-builder.component.scss +43 -0
  67. package/src/table-builder/components/column-builder/column-builder.component.spec.ts +49 -0
  68. package/src/table-builder/components/column-builder/column-builder.component.ts +130 -0
  69. package/src/table-builder/components/column-builder/column-helpers.ts +54 -0
  70. package/src/table-builder/components/column-header-menu/column-header-menu.component.html +128 -0
  71. package/src/table-builder/components/column-header-menu/column-header-menu.component.scss +97 -0
  72. package/src/table-builder/components/column-header-menu/column-header-menu.component.ts +113 -0
  73. package/src/table-builder/components/date-filter/date-filter.component.html +39 -0
  74. package/src/table-builder/components/date-filter/date-filter.component.ts +33 -0
  75. package/src/table-builder/components/date-time-filter/date-time-filter.component.html +25 -0
  76. package/src/table-builder/components/date-time-filter/date-time-filter.component.ts +33 -0
  77. package/src/table-builder/components/filter/filter.component.html +120 -0
  78. package/src/table-builder/components/filter/filter.component.scss +60 -0
  79. package/src/table-builder/components/filter/filter.component.spec.ts +86 -0
  80. package/src/table-builder/components/filter/filter.component.ts +73 -0
  81. package/src/table-builder/components/filter/in-list/in-list-filter.component.ts +171 -0
  82. package/src/table-builder/components/gen-col-displayer/gen-col-displayer.component.html +60 -0
  83. package/src/table-builder/components/gen-col-displayer/gen-col-displayer.component.scss +57 -0
  84. package/src/table-builder/components/gen-col-displayer/gen-col-displayer.component.ts +44 -0
  85. package/src/table-builder/components/generic-table/generic-table.component.html +140 -0
  86. package/src/table-builder/components/generic-table/generic-table.component.scss +45 -0
  87. package/src/table-builder/components/generic-table/generic-table.component.ts +531 -0
  88. package/src/table-builder/components/generic-table/paginator.component.ts +125 -0
  89. package/src/table-builder/components/group-by-list/group-by-list.component.css +24 -0
  90. package/src/table-builder/components/group-by-list/group-by-list.component.html +21 -0
  91. package/src/table-builder/components/group-by-list/group-by-list.component.spec.ts +23 -0
  92. package/src/table-builder/components/group-by-list/group-by-list.component.ts +26 -0
  93. package/src/table-builder/components/in-filter/in-filter.component.css +22 -0
  94. package/src/table-builder/components/in-filter/in-filter.component.html +38 -0
  95. package/src/table-builder/components/in-filter/in-filter.component.ts +66 -0
  96. package/src/table-builder/components/index.ts +9 -0
  97. package/src/table-builder/components/initialization-component/initialization.component.html +78 -0
  98. package/src/table-builder/components/initialization-component/initialization.component.ts +28 -0
  99. package/src/table-builder/components/link-column.component.ts +42 -0
  100. package/src/table-builder/components/number-filter/number-filter.component.css +10 -0
  101. package/src/table-builder/components/number-filter/number-filter.component.html +32 -0
  102. package/src/table-builder/components/number-filter/number-filter.component.spec.ts +30 -0
  103. package/src/table-builder/components/number-filter/number-filter.component.ts +34 -0
  104. package/src/table-builder/components/profiles-menu/profiles-menu.component.html +77 -0
  105. package/src/table-builder/components/profiles-menu/profiles-menu.component.scss +126 -0
  106. package/src/table-builder/components/profiles-menu/profiles-menu.component.spec.ts +23 -0
  107. package/src/table-builder/components/profiles-menu/profiles-menu.component.ts +64 -0
  108. package/src/table-builder/components/reset-menu/reset-menu.component.css +3 -0
  109. package/src/table-builder/components/reset-menu/reset-menu.component.html +10 -0
  110. package/src/table-builder/components/reset-menu/reset-menu.component.ts +87 -0
  111. package/src/table-builder/components/scroll-strategy.ts +139 -0
  112. package/src/table-builder/components/sort-menu/sort-menu.component-store.ts +57 -0
  113. package/src/table-builder/components/sort-menu/sort-menu.component.html +115 -0
  114. package/src/table-builder/components/sort-menu/sort-menu.component.scss +119 -0
  115. package/src/table-builder/components/sort-menu/sort-menu.component.ts +88 -0
  116. package/src/table-builder/components/table-container/table-container.component.html +94 -0
  117. package/src/table-builder/components/table-container/table-container.component.scss +60 -0
  118. package/src/table-builder/components/table-container/table-container.component.ts +467 -0
  119. package/src/table-builder/components/table-container/table-container.helpers/data-state.helpers.ts +113 -0
  120. package/src/table-builder/components/table-container/table-container.helpers/filter-state.helpers.ts +125 -0
  121. package/src/table-builder/components/table-container/table-container.helpers/groupBy.helpers.ts +172 -0
  122. package/src/table-builder/components/table-container/table-container.helpers/meta-data.helpers.ts +19 -0
  123. package/src/table-builder/components/table-container/table-container.helpers/sort-state.helpers.ts +47 -0
  124. package/src/table-builder/components/table-container/tableProps.ts +21 -0
  125. package/src/table-builder/components/table-container/virtual-scroll-container.ts +216 -0
  126. package/src/table-builder/components/table-container-filter/filter-list/filter-list.component.html +42 -0
  127. package/src/table-builder/components/table-container-filter/filter-list/filter-list.component.ts +47 -0
  128. package/src/table-builder/components/table-container-filter/gen-filter-displayer/gen-filter-displayer.component.css +40 -0
  129. package/src/table-builder/components/table-container-filter/gen-filter-displayer/gen-filter-displayer.component.html +11 -0
  130. package/src/table-builder/components/table-container-filter/gen-filter-displayer/gen-filter-displayer.component.spec.ts +85 -0
  131. package/src/table-builder/components/table-container-filter/gen-filter-displayer/gen-filter-displayer.component.ts +35 -0
  132. package/src/table-builder/components/table-container-filter/table-wrapper-filter-store.ts +13 -0
  133. package/src/table-builder/components/table-header-menu/table-header-menu.component.css +21 -0
  134. package/src/table-builder/components/table-header-menu/table-header-menu.component.html +48 -0
  135. package/src/table-builder/components/table-header-menu/table-header-menu.component.ts +36 -0
  136. package/src/table-builder/directives/custom-cell-directive.ts +63 -0
  137. package/src/table-builder/directives/custom-header-directive.ts +16 -0
  138. package/src/table-builder/directives/group-row-directive.ts +91 -0
  139. package/src/table-builder/directives/index.ts +8 -0
  140. package/src/table-builder/directives/multi-sort.directive.spec.ts +124 -0
  141. package/src/table-builder/directives/multi-sort.directive.ts +58 -0
  142. package/src/table-builder/directives/resize-column.directive.ts +107 -0
  143. package/src/table-builder/directives/table-wrapper.directive.ts +13 -0
  144. package/src/table-builder/directives/tb-filter.directive.ts +376 -0
  145. package/src/table-builder/documentation/table-builder/CUSTOM-CELL.md +568 -0
  146. package/src/table-builder/documentation/table-builder/CUSTOM-GROUP-ROW.md +356 -0
  147. package/src/table-builder/documentation/table-builder/METADATA-DOCUMENTATION.md +517 -0
  148. package/src/table-builder/documentation/table-builder/STYLER-STYLE.md +228 -0
  149. package/src/table-builder/documentation/table-builder/TABLE-BUILDER-CONFIG.md +325 -0
  150. package/src/table-builder/documentation/table-builder/TABLE-BUILDER-SETTINGS.md +515 -0
  151. package/src/table-builder/documentation/table-builder/TABLE-BUILDER.md +430 -0
  152. package/src/table-builder/documentation/table-builder/TABLE-CONTAINER.md +628 -0
  153. package/src/table-builder/enums/filterTypes.ts +39 -0
  154. package/src/table-builder/functions/boolean-filter-function.ts +12 -0
  155. package/src/table-builder/functions/date-filter-function.ts +85 -0
  156. package/src/table-builder/functions/download-data.ts +11 -0
  157. package/src/table-builder/functions/null-filter-function.ts +9 -0
  158. package/src/table-builder/functions/number-filter-function.ts +47 -0
  159. package/src/table-builder/functions/sort-data-function.ts +80 -0
  160. package/src/table-builder/functions/string-filter-function.ts +59 -0
  161. package/src/table-builder/interfaces/ColumnInfo.ts +9 -0
  162. package/src/table-builder/interfaces/dictionary.ts +3 -0
  163. package/src/table-builder/interfaces/meta-data.ts +279 -0
  164. package/src/table-builder/ngrx/tableBuilderStateStore.ts +203 -0
  165. package/src/table-builder/pipes/column-total.pipe.ts +16 -0
  166. package/src/table-builder/pipes/format-filter-type.pipe.ts +12 -0
  167. package/src/table-builder/pipes/format-filter-value.pipe.ts +71 -0
  168. package/src/table-builder/pipes/key-display.ts +13 -0
  169. package/src/table-builder/services/all-values-filter-creator.service.ts +92 -0
  170. package/src/table-builder/services/export-to-csv.service.ts +117 -0
  171. package/src/table-builder/services/link-creator.service.ts +98 -0
  172. package/src/table-builder/services/table-template-service.ts +47 -0
  173. package/src/table-builder/services/transform-creator.ts +90 -0
  174. package/src/table-builder/specs/table-custom-filters.spec.ts +262 -0
  175. package/src/table-builder/styles/collapser.styles.scss +16 -0
  176. package/src/table-builder/table-builder.module.ts +42 -0
  177. package/src/table-builder/types/group-types.ts +42 -0
  178. package/src/table-builder/types/index.ts +1 -0
  179. package/src/test.ts +17 -0
  180. package/src/utilities/array-helpers.ts +13 -0
  181. package/src/utilities/directives/auto-focus.directive.ts +20 -0
  182. package/src/utilities/directives/clickEmitterDirective.ts +15 -0
  183. package/src/utilities/directives/clickSubject.ts +19 -0
  184. package/src/utilities/directives/conditional-classes.directive.ts +36 -0
  185. package/src/utilities/directives/dialog-service.ts +19 -0
  186. package/src/utilities/directives/dialog.ts +174 -0
  187. package/src/utilities/directives/mat-toggle-group-directive.ts +60 -0
  188. package/src/utilities/directives/prevent-enter.directive.ts +12 -0
  189. package/src/utilities/directives/stop-propagation.directive.ts +19 -0
  190. package/src/utilities/directives/styler.ts +45 -0
  191. package/src/utilities/directives/trim-whitespace.directive.ts +20 -0
  192. package/src/utilities/index.ts +22 -0
  193. package/src/utilities/module.ts +53 -0
  194. package/src/utilities/pipes/function.pipe.ts +21 -0
  195. package/src/utilities/pipes/phone.pipe.ts +20 -0
  196. package/src/utilities/pipes/space-case.pipes.spec.ts +47 -0
  197. package/src/utilities/pipes/space-case.pipes.ts +29 -0
  198. package/tsconfig.lib.json +20 -0
  199. package/tsconfig.lib.prod.json +10 -0
  200. package/tsconfig.spec.json +17 -0
  201. package/fesm2022/one-paragon-angular-utilities.mjs +0 -7328
  202. package/fesm2022/one-paragon-angular-utilities.mjs.map +0 -1
  203. package/types/one-paragon-angular-utilities.d.ts +0 -2197
@@ -0,0 +1,90 @@
1
+ import { PipeTransform } from '@angular/core';
2
+ import { FieldType, MappedMetaData, MetaData } from '../interfaces/meta-data';
3
+ import { formatDate, formatCurrency } from '@angular/common';
4
+ import { phoneFormatter } from '../../utilities/pipes/phone.pipe';
5
+ import { TableBuilderConfig } from '../classes/TableBuilderConfig';
6
+ import { spaceCase } from '../../utilities';
7
+ import { getFactory } from '../functions/sort-data-function';
8
+
9
+ export function isPipe(o : any ): o is PipeTransform {
10
+ return typeof ((o as PipeTransform).transform ) === 'function';
11
+ }
12
+
13
+ export function createTransformer(metaData: MetaData<any, any>, config: TableBuilderConfig, noIcons = false, forItem = false): ((value: any, ...args: any[]) => any) {
14
+ const defaultFunc = getFactory(metaData.key);
15
+ if(metaData.map && !forItem){
16
+ return (value: any) => {
17
+ return metaData.map!(value)};
18
+ }
19
+ if((metaData as MappedMetaData).mapItem){
20
+ return (value: any) => {
21
+ return (metaData as MappedMetaData).mapItem!(defaultFunc(value))};
22
+ }
23
+ if(config.transformers && config.transformers[metaData.fieldType]) {
24
+ var transformer = config.transformers![metaData.fieldType]!;
25
+ return (value: any) => transformer(defaultFunc(value));
26
+ }
27
+ const defaultDateFormat = config.dateFormats?.dateFormat ?? 'shortDate';
28
+ const defaultDateTimeFormat = config.dateFormats?.dateTimeFormat ?? 'short';
29
+ switch (metaData.fieldType) {
30
+ case FieldType.Date:
31
+ const dateFormat = metaData.additional?.dateFormat ?? defaultDateFormat;
32
+ return (value: any) => dateFormatter(defaultFunc(value), dateFormat);
33
+ case FieldType.DateTime:
34
+ const dateTimeFormat = metaData.additional?.dateTimeOptions?.format ?? defaultDateTimeFormat;
35
+ return (value: any) => dateFormatter(defaultFunc(value), dateTimeFormat);
36
+ case FieldType.Currency:
37
+ return (value: any) => currencyFormatter(defaultFunc(value));
38
+ case FieldType.PhoneNumber:
39
+ return (value: any) => phoneFormatter(defaultFunc(value));
40
+ case FieldType.Enum:
41
+ return (value: any) => spaceCase(metaData.additional?.enumMap![defaultFunc(value)] as string) ;
42
+ case FieldType.Boolean:
43
+ if(noIcons) {
44
+ return defaultFunc
45
+ }
46
+ let forTrue = 'check'
47
+ let forFalse = '';
48
+ if(metaData.additional?.boolean?.forTrue) {
49
+ forTrue = metaData?.additional.boolean.forTrue.icon;
50
+ }
51
+ if(metaData.additional?.boolean?.showForFalse === true) {
52
+ forFalse = 'clear';
53
+ } else if(metaData.additional?.boolean?.showForFalse?.icon) {
54
+ forFalse = metaData.additional?.boolean?.showForFalse?.icon;
55
+ }
56
+ return (value: any) => defaultFunc(value) ? forTrue : forFalse ;
57
+ }
58
+ return defaultFunc;
59
+ }
60
+
61
+ export function createItemTransformer<T = any, AdditionalFields extends string[] = []>(metaData: MetaData<T, AdditionalFields>, config: TableBuilderConfig, noIcons = false, mutate = false){
62
+ const transform = createTransformer(metaData, config, noIcons);
63
+ return (t: T) => {
64
+ if(!mutate){
65
+ t = { ...t }
66
+ }
67
+ t[metaData.key as string] = transform(t)
68
+ }
69
+ }
70
+
71
+ export function createItemTransformers<T = any, AdditionalFields extends string[] = []>(metaDatas: MetaData<T, AdditionalFields>[], config: TableBuilderConfig, noIcons = false, mutate = false){
72
+ const transformers = metaDatas.map(meta => createItemTransformer(meta, config, noIcons, true));
73
+ return (t: T) => {
74
+ if(!t) return t;
75
+ if(!mutate){
76
+ t = { ... t }
77
+ }
78
+ transformers.forEach(m => m(t));
79
+ return t;
80
+ }
81
+ }
82
+
83
+ export function dateFormatter(date: string | Date | number, format: string){
84
+ if(!date) return;
85
+ return formatDate(date, format, 'en-US');
86
+ }
87
+
88
+ export function currencyFormatter(amt: number) {
89
+ return formatCurrency(amt, 'en-US', '$');
90
+ }
@@ -0,0 +1,262 @@
1
+ // import { HarnessLoader } from "@angular/cdk/testing";
2
+ // import { TestbedHarnessEnvironment } from "@angular/cdk/testing/testbed";
3
+ // import { Component, DebugElement, Type } from "@angular/core";
4
+ // import { ComponentFixture, TestBed, waitForAsync } from "@angular/core/testing";
5
+ // import { MatButtonToggleModule } from "@angular/material/button-toggle";
6
+ // import { MatButtonToggleHarness } from "@angular/material/button-toggle/testing";
7
+ // import { MatCheckbox, MatCheckboxModule } from "@angular/material/checkbox";
8
+ // import { MatLegacyRadioModule as MatRadioModule } from "@angular/material/legacy-radio";
9
+ // import { MatLegacySelectModule as MatSelectModule } from "@angular/material/legacy-select";
10
+ // import { MatSlideToggleModule } from "@angular/material/slide-toggle";
11
+ // import { MatSlideToggleHarness } from "@angular/material/slide-toggle/testing";
12
+ // import { MatLegacyRadioButtonHarness as MatRadioButtonHarness } from '@angular/material/legacy-radio/testing';
13
+ // import { MatCheckboxHarness } from '@angular/material/checkbox/testing';
14
+ // import { MatLegacySelectHarness as MatSelectHarness, } from "@angular/material/legacy-select/testing";
15
+ // import { MatLegacyOptionHarness as MatOptionHarness } from "@angular/material/legacy-core/testing";
16
+ // import { By } from "@angular/platform-browser";
17
+ // import { firstValueFrom, lastValueFrom, Observable, skip, Subject, take, takeUntil } from "rxjs";
18
+ // import { MatButtonToggleFilterDirective, MatCheckboxTbFilterDirective, MatOptionTbFilterDirective, MatRadioButtonTbFilterDirective, MatSlideToggleTbFilterDirective, TableCustomFilterDirective } from "../directives/tb-filter.directive";
19
+ // import { NoopAnimationsModule } from "@angular/platform-browser/animations";
20
+
21
+ // abstract class ToggleTestComponent {
22
+
23
+ // }
24
+
25
+
26
+ // const takeItem = <T>(src:Observable<T>, itemNumber: number, until: Observable<any>) : Promise<T | null> => {
27
+ // return firstValueFrom(src.pipe( skip(itemNumber - 1),takeUntil(until) ), {defaultValue: null});
28
+ // }
29
+
30
+ // @Component({
31
+ // template: `
32
+ // <mat-slide-toggle tbCustomFilter > Slide me! </mat-slide-toggle>
33
+ // <mat-checkbox tbCustomFilter > Check me! </mat-checkbox>
34
+ // <mat-radio-button tbCustomFilter > Click me! </mat-radio-button>
35
+ // <mat-select>
36
+ // <mat-option tbCustomFilter > Click me! </mat-option>
37
+ // <mat-option [value]='"other"' >Other</mat-option>
38
+ // </mat-select>
39
+ // <mat-button-toggle tbCustomFilter > Click me! </mat-button-toggle>
40
+ // <div class='optionGroup' tbCustomFilterGroup >
41
+ // <mat-checkbox tbCustomFilter class="child-1-checkbox" >1</mat-checkbox>
42
+ // </div>
43
+ // `
44
+ // }) export class SingleToggleTestComponent extends ToggleTestComponent {
45
+
46
+ // }
47
+
48
+
49
+ // let fixture: ComponentFixture<ToggleTestComponent>;
50
+ // let loader: HarnessLoader;
51
+
52
+
53
+ // const setupTest = (): void => {
54
+
55
+
56
+ // TestBed.configureTestingModule({
57
+ // imports: [
58
+ // NoopAnimationsModule,
59
+ // MatSlideToggleModule,
60
+ // MatCheckboxModule,
61
+ // MatRadioModule,
62
+ // MatButtonToggleModule,
63
+ // MatSelectModule
64
+ // ],
65
+ // declarations: [
66
+ // TableCustomFilterDirective,
67
+ // SingleToggleTestComponent,
68
+ // MatSlideToggleTbFilterDirective,
69
+ // MatButtonToggleFilterDirective,
70
+ // MatOptionTbFilterDirective,
71
+ // MatRadioButtonTbFilterDirective,
72
+ // MatCheckboxTbFilterDirective,
73
+ // TablebFilterGroupDirective,
74
+
75
+ // ],
76
+ // providers: [ ]
77
+ // });
78
+ // fixture = TestBed.createComponent(SingleToggleTestComponent);
79
+ // fixture.detectChanges();
80
+ // loader = TestbedHarnessEnvironment.documentRootLoader(fixture);
81
+ // };
82
+
83
+
84
+ // describe("Custom Table Filters", () => {
85
+
86
+ // describe("mat slide toggle filter", () => {
87
+ // let toggleHarnesses: MatSlideToggleHarness[];
88
+ // let dElement: DebugElement;
89
+ // beforeEach(async () => {
90
+ // setupTest();
91
+ // dElement = fixture.debugElement.query(By.directive(MatSlideToggleTbFilterDirective) );
92
+ // toggleHarnesses = await loader.getAllHarnesses(MatSlideToggleHarness);
93
+ // } );
94
+
95
+ // it('should create', () : void => {
96
+ // expect(dElement).toBeTruthy();
97
+ // });
98
+
99
+ // it('should emit on toggle', async () => {
100
+ // var filterDirective = dElement.injector.get(TableCustomFilterDirective);
101
+ // const dunzo = new Subject();
102
+ // var val = takeItem(filterDirective.filter$, 2, dunzo);
103
+ // await toggleHarnesses[0].toggle();
104
+ // dunzo.next(null);
105
+ // var i = await val;
106
+ // expect(i).toBeTruthy();
107
+ // expect(i?.active).toBeTrue();
108
+ // expect(filterDirective.active).toBeTrue();
109
+ // })
110
+ // })
111
+
112
+ // describe("check box filter", () => {
113
+ // let checkBoxHarnesses: MatCheckboxHarness;
114
+ // let dElement: DebugElement;
115
+ // beforeEach( async () => {
116
+ // setupTest();
117
+ // dElement = fixture.debugElement.query(By.directive(MatCheckboxTbFilterDirective) );
118
+ // checkBoxHarnesses = await loader.getHarness(MatCheckboxHarness);
119
+
120
+ // });
121
+
122
+ // it('should create', async () : Promise<void> => {
123
+ // expect(dElement).not.toBeNull();
124
+ // });
125
+
126
+ // it('should emit on check', async () => {
127
+ // var filterDirective = dElement.injector.get(TableCustomFilterDirective);
128
+ // var val = firstValueFrom(filterDirective.filter$);
129
+ // await checkBoxHarnesses.check();
130
+ // var i = await val;
131
+ // expect(i).toBeTruthy();
132
+ // expect(filterDirective.active).toBeTrue();
133
+ // });
134
+
135
+
136
+ // });
137
+
138
+
139
+ // describe("radio button filter", () => {
140
+ // let radioHarnesses: MatRadioButtonHarness;
141
+ // let dElement: DebugElement;
142
+ // beforeEach( async () => {
143
+ // setupTest();
144
+ // dElement = fixture.debugElement.query(By.directive(MatRadioButtonTbFilterDirective) );
145
+ // radioHarnesses = await loader.getHarness(MatRadioButtonHarness);
146
+
147
+ // });
148
+
149
+ // it('should create', async () : Promise<void> => {
150
+ // expect(dElement).not.toBeNull();
151
+ // });
152
+
153
+ // it('should emit on check', async () => {
154
+ // var filterDirective = dElement.injector.get(TableCustomFilterDirective);
155
+ // var val = firstValueFrom(filterDirective.filter$);
156
+ // await radioHarnesses.check();
157
+ // var i = await val;
158
+ // expect(i).toBeTruthy();
159
+ // expect(filterDirective.active).toBeTrue();
160
+ // });
161
+ // });
162
+
163
+ // describe("button toggle filter", () => {
164
+ // let buttonToggleHarness: MatButtonToggleHarness;
165
+ // let dElement: DebugElement;
166
+ // beforeEach( async () => {
167
+ // setupTest();
168
+ // dElement = fixture.debugElement.query(By.directive(MatButtonToggleFilterDirective) );
169
+ // buttonToggleHarness = await loader.getHarness(MatButtonToggleHarness);
170
+
171
+ // });
172
+
173
+ // it('should create', () : void => {
174
+ // expect(dElement).not.toBeNull();
175
+ // });
176
+
177
+ // it('should emit on toggle', async () => {
178
+ // var filterDirective = dElement.injector.get(TableCustomFilterDirective);
179
+ // var val = firstValueFrom(filterDirective.filter$);
180
+ // await buttonToggleHarness.check();
181
+ // var i = await val;
182
+ // expect(i).toBeTruthy();
183
+ // expect(filterDirective.active).toBeTrue();
184
+ // });
185
+ // });
186
+
187
+ // describe("option filter", () => {
188
+ // let optionHarness: MatOptionHarness;
189
+ // let optionHarness2: MatOptionHarness;
190
+ // let selectHarness: MatSelectHarness;
191
+ // let dElement: DebugElement;
192
+ // beforeEach(async () => {
193
+ // setupTest();
194
+ // selectHarness = await loader.getHarness(MatSelectHarness);
195
+ // await selectHarness.open();
196
+ // var h = await loader.getAllHarnesses(MatOptionHarness);
197
+ // optionHarness = h[0];
198
+ // optionHarness2 = h[1];
199
+ // dElement = fixture.debugElement.query(By.directive(MatOptionTbFilterDirective) );
200
+ // });
201
+
202
+ // it('should create', async () : Promise<void> => {
203
+ // expect(dElement).toBeTruthy();
204
+ // });
205
+
206
+ // it('should emit on select', async () => {
207
+ // let doneSubject = new Subject<void>();
208
+
209
+ // var filterDirective = dElement.injector.get(TableCustomFilterDirective);
210
+
211
+ // let val = takeItem(filterDirective.filter$, 2, doneSubject);
212
+ // await optionHarness.click();
213
+ // doneSubject.next();
214
+ // let i = await val;
215
+
216
+ // expect(i).toBeTruthy();
217
+ // expect(i?.active).toBeTrue();
218
+ // expect(filterDirective.active).toBeTrue();
219
+
220
+
221
+ // val = takeItem(filterDirective.filter$, 2, doneSubject);
222
+ // await optionHarness2.click();
223
+
224
+ // i = await val;
225
+ // expect(i).toBeTruthy();
226
+ // expect(i?.active).toBeFalse();
227
+ // expect(filterDirective.active).toBeFalse();
228
+
229
+ // });
230
+ // });
231
+
232
+ // describe("group filter", () => {
233
+ // let checkboxHarness: MatCheckboxHarness;
234
+ // let dElement: DebugElement;
235
+ // beforeEach(async () => {
236
+ // setupTest();
237
+
238
+ // dElement = fixture.debugElement.query(By.directive(TablebFilterGroupDirective) );
239
+ // const childLoader = await loader.getChildLoader('.optionGroup');
240
+ // checkboxHarness = await childLoader.getHarness(MatCheckboxHarness);
241
+ // });
242
+
243
+ // it('should create', () : void => {
244
+ // expect(dElement).toBeTruthy();
245
+ // });
246
+
247
+ // it('should emit on child select', async () => {
248
+
249
+ // var directive = dElement.injector.get(TablebFilterGroupDirective);
250
+ // var doneSubject = new Subject<void>();
251
+ // var resultPromise = takeItem(directive.filter$, 2, doneSubject);
252
+
253
+ // await checkboxHarness.check();
254
+ // doneSubject.next();
255
+
256
+ // var result = await resultPromise;
257
+ // expect(result).toBeTruthy();
258
+
259
+ // });
260
+ // });
261
+
262
+ // });
@@ -0,0 +1,16 @@
1
+ .collapse-icon{
2
+ font-size: 16px;
3
+ height: 16px;
4
+ color:#3f51b5;
5
+ align-self: flex-start;
6
+ }
7
+ .collapse-icon:hover{
8
+ cursor: pointer;
9
+ }
10
+ .hide{
11
+ display: none;
12
+ }
13
+ .paginator-row{
14
+ display: flex;
15
+ align-items: center;
16
+ }
@@ -0,0 +1,42 @@
1
+
2
+ import { NgModule } from '@angular/core';
3
+ import { MultiSortDirective } from './directives/multi-sort.directive';
4
+ import { ModuleWithProviders } from '@angular/core';
5
+ import { TableBuilderConfig, TableBuilderConfigToken } from './classes/TableBuilderConfig';
6
+ import { TableContainerComponent } from './components';
7
+ import { CustomCellDirective, CustomGroupRowDirective, CustomHeaderDirective, TableFilterDirective, TableFilterStringContainsDirective, TableWrapperDirective } from './directives';
8
+ import { UtilitiesModule } from '../utilities';
9
+
10
+ @NgModule({
11
+ imports: [
12
+ TableContainerComponent,
13
+ CustomCellDirective,
14
+ CustomHeaderDirective,
15
+ CustomGroupRowDirective,
16
+ TableFilterDirective,
17
+ TableFilterStringContainsDirective,
18
+ TableWrapperDirective,
19
+ ],
20
+ exports: [
21
+ TableContainerComponent,
22
+ CustomCellDirective,
23
+ CustomHeaderDirective,
24
+ CustomGroupRowDirective,
25
+ TableFilterStringContainsDirective,
26
+ TableWrapperDirective,
27
+ UtilitiesModule,
28
+ ],
29
+ providers: [
30
+ MultiSortDirective,
31
+ ]
32
+ })
33
+ export class TableBuilderModule {
34
+ static forRoot(config: TableBuilderConfig): ModuleWithProviders<TableBuilderModule> {
35
+ return {
36
+ ngModule: TableBuilderModule,
37
+ providers: [
38
+ { provide: TableBuilderConfigToken, useValue: config }
39
+ ]
40
+ };
41
+ }
42
+ }
@@ -0,0 +1,42 @@
1
+ import { SortDirection } from '@angular/material/sort';
2
+
3
+ export type NoneGroupHeader = any;
4
+
5
+ export interface BaseGroup {
6
+ key: string;
7
+ groupName: string;
8
+ groupHeaderDisplay: string;
9
+ uniqueName: string;
10
+ isGroupHeader: true;
11
+ padding: number;
12
+ length: number;
13
+ hasTheData: boolean;
14
+ level: number;
15
+ parent?: BaseGroup;
16
+ }
17
+
18
+ export interface DataGroup<T extends NoneGroupHeader = any> extends BaseGroup {
19
+ children: T[];
20
+ hasTheData: true;
21
+ }
22
+
23
+ export interface GroupGroup<T extends NoneGroupHeader = any> extends BaseGroup {
24
+ groups: (DataGroup<T> | GroupGroup<T>)[];
25
+ hasTheData: false;
26
+ }
27
+
28
+ export type Group<T extends NoneGroupHeader = any> = GroupGroup<T> | DataGroup<T>;
29
+
30
+ export interface GroupedData {
31
+ key: string;
32
+ expandedHeaders: string[] | 'all';
33
+ sort: SortDirection;
34
+ }
35
+
36
+ export function isGroupHeader(data: any): data is Group {
37
+ return !!data?.isGroupHeader;
38
+ }
39
+
40
+ export function isDataGroup<T extends NoneGroupHeader = any>(group: Group<T>): group is DataGroup<T> {
41
+ return group.hasTheData === true;
42
+ }
@@ -0,0 +1 @@
1
+ export * from './group-types';
package/src/test.ts ADDED
@@ -0,0 +1,17 @@
1
+ // This file is required by karma.conf.js and loads recursively all the .spec and framework files
2
+
3
+ import 'zone.js';
4
+ import 'zone.js/testing';
5
+ import { getTestBed } from '@angular/core/testing';
6
+ import {
7
+ BrowserDynamicTestingModule,
8
+ platformBrowserDynamicTesting
9
+ } from '@angular/platform-browser-dynamic/testing';
10
+
11
+ // First, initialize the Angular testing environment.
12
+ getTestBed().initTestEnvironment(
13
+ BrowserDynamicTestingModule,
14
+ platformBrowserDynamicTesting(), {
15
+ teardown: { destroyAfterEach: false }
16
+ }
17
+ );
@@ -0,0 +1,13 @@
1
+ export const replaceInArrayWithClone = <T = any>(arr: T[], findMeth: (t: T) => boolean, actionOnClone: (t: T) => any = ((t: T) => {})): T[] => {
2
+ const index = arr.findIndex(findMeth);
3
+ const clonedArray = [...arr];
4
+ const t = clonedArray[index];
5
+ clonedArray[index] =
6
+ t != null && typeof t === 'object' ?
7
+ Array.isArray(t) ?
8
+ [...t] as any
9
+ : { ...t }
10
+ : t;
11
+ actionOnClone(clonedArray[index]);
12
+ return clonedArray;
13
+ }
@@ -0,0 +1,20 @@
1
+ import { Directive, ElementRef, AfterViewInit, Input, inject } from '@angular/core';
2
+
3
+ @Directive({
4
+ selector: '[autoFocus]',
5
+ })
6
+ export class AutoFocusDirective implements AfterViewInit {
7
+ private elementRef = inject(ElementRef);
8
+
9
+
10
+ @Input() autoFocus = true;
11
+
12
+ ngAfterViewInit() {
13
+ if(this.autoFocus){
14
+ setTimeout(() => {
15
+ this.elementRef.nativeElement.focus();
16
+ });
17
+ }
18
+ }
19
+
20
+ }
@@ -0,0 +1,15 @@
1
+ import { Directive } from '@angular/core';
2
+ import { Subject } from 'rxjs';
3
+
4
+
5
+ @Directive({
6
+ selector: '[clickEmitter]',
7
+ exportAs: 'clickEmitter',
8
+ host: {
9
+ '(click)': 'next(true)'
10
+ },
11
+ }) export class ClickEmitterDirective extends Subject<boolean> {
12
+ constructor() {
13
+ super();
14
+ }
15
+ }
@@ -0,0 +1,19 @@
1
+ import { Directive, Input } from '@angular/core';
2
+ import { Subject } from 'rxjs';
3
+
4
+ @Directive({
5
+ selector: '[clickSubject]',
6
+ exportAs: 'clickSubject',
7
+ host: {
8
+ '(click)': 'next(this._val)'
9
+ },
10
+ }) export class ClickSubjectDirective<T = boolean> extends Subject<T> {
11
+ constructor( ) {
12
+ super();
13
+ }
14
+ _val!: T;
15
+
16
+ @Input('clickSubject') set clickSubject( val: T) {
17
+ this._val = val;
18
+ }
19
+ }
@@ -0,0 +1,36 @@
1
+ import { Directive, ElementRef, Renderer2, effect, inject, input, untracked } from '@angular/core';
2
+ import { Dictionary, Predicate } from '@ngrx/entity';
3
+
4
+ @Directive({
5
+ selector: '[conditionalClasses]',
6
+ })
7
+ export class ConditionalClassesDirective {
8
+ private el = inject(ElementRef);
9
+ private renderer = inject(Renderer2);
10
+
11
+ $element = input.required<any>({ alias: 'element' });
12
+ $classes = input<Dictionary<Predicate<any> | true>>(undefined, { alias: 'conditionalClasses' });
13
+
14
+ classesApplied: string[] = [];
15
+
16
+ #onClasses = effect(() => {
17
+ const classes = this.$classes();
18
+ untracked(() => {
19
+ const element = this.$element();
20
+ let toApply: string [] = [];
21
+ if(classes) {
22
+ toApply = Object.keys(classes)
23
+ .filter( key => (classes![key] === true) || classes![key]!(element) );
24
+ }
25
+
26
+ var classesNotYetApplied = toApply.filter( c => !this.classesApplied.includes(c) );
27
+ var classesToRemove = this.classesApplied.filter( c => !toApply.includes(c));
28
+
29
+ classesToRemove.forEach( c => this.renderer.removeClass( this.el.nativeElement, c ) );
30
+
31
+ classesNotYetApplied.forEach( c => this.renderer.addClass( this.el.nativeElement, c ) );
32
+
33
+ this.classesApplied = toApply;
34
+ })
35
+ });
36
+ }
@@ -0,0 +1,19 @@
1
+ import { Injectable } from '@angular/core';
2
+ import { MatDialogRef } from '@angular/material/dialog';
3
+
4
+ @Injectable({ providedIn: 'root' })
5
+ export class DialogService {
6
+ allOpenOpDialogs: MatDialogRef<any>[] = [];
7
+
8
+ addDialogRef(ref: MatDialogRef<any>) {
9
+ this.allOpenOpDialogs.push(ref);
10
+ }
11
+
12
+ removeDialogRef(ref: MatDialogRef<any>) {
13
+ this.allOpenOpDialogs = this.allOpenOpDialogs.filter(rf => ref.id !== rf.id);
14
+ }
15
+
16
+ closeAllOpDialogs() {
17
+ this.allOpenOpDialogs.forEach(ref => ref.close());
18
+ }
19
+ }