@ecodev/natural 62.1.2 → 63.0.0

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 (183) hide show
  1. package/fesm2022/ecodev-natural-vanilla.mjs +1193 -0
  2. package/fesm2022/ecodev-natural-vanilla.mjs.map +1 -0
  3. package/fesm2022/ecodev-natural.mjs +436 -425
  4. package/fesm2022/ecodev-natural.mjs.map +1 -1
  5. package/lib/classes/network-activity.service.d.ts +54 -0
  6. package/lib/classes/validators.d.ts +1 -1
  7. package/lib/modules/columns-picker/columns-picker.component.d.ts +2 -2
  8. package/lib/modules/common/services/seo.provider.d.ts +2 -2
  9. package/lib/modules/dropdown-components/type-select/type-select.component.d.ts +1 -1
  10. package/lib/modules/file/abstract-file.d.ts +6 -3
  11. package/lib/modules/file/component/file.component.d.ts +2 -2
  12. package/lib/modules/file/file-drop.directive.d.ts +2 -3
  13. package/lib/modules/fixed-button-detail/fixed-button-detail.component.d.ts +2 -3
  14. package/lib/modules/hierarchic-selector/hierarchic-selector/hierarchic-selector.component.d.ts +3 -3
  15. package/lib/modules/icon/icon.module.d.ts +2 -2
  16. package/lib/modules/panels/panels.service.d.ts +1 -2
  17. package/lib/modules/relations/relations.component.d.ts +3 -3
  18. package/lib/modules/search/dropdown-container/dropdown-container.component.d.ts +2 -3
  19. package/lib/modules/search/group/group.component.d.ts +2 -3
  20. package/lib/modules/search/input/input.component.d.ts +5 -5
  21. package/lib/modules/search/search/search.component.d.ts +2 -2
  22. package/lib/modules/select/abstract-select.component.d.ts +3 -3
  23. package/lib/modules/select/select/select.component.d.ts +1 -1
  24. package/lib/modules/sidenav/sidenav-container/sidenav-container.component.d.ts +1 -1
  25. package/lib/modules/table-button/table-button.component.d.ts +4 -2
  26. package/package.json +16 -14
  27. package/public-api.d.ts +1 -0
  28. package/src/lib/_natural.theme.scss +1 -2
  29. package/vanilla/index.d.ts +5 -0
  30. package/vanilla/package.json +3 -0
  31. package/vanilla/public-api.d.ts +11 -0
  32. package/vanilla/src/lib/classes/crypto.d.ts +8 -0
  33. package/vanilla/src/lib/classes/data-source.d.ts +32 -0
  34. package/vanilla/src/lib/classes/query-variable-manager-utils.d.ts +2 -0
  35. package/vanilla/src/lib/classes/query-variable-manager.d.ts +91 -0
  36. package/vanilla/src/lib/classes/signing.d.ts +7 -0
  37. package/vanilla/src/lib/classes/utility.d.ts +77 -0
  38. package/vanilla/src/lib/modules/search/classes/graphql-doctrine.types.d.ts +83 -0
  39. package/vanilla/src/lib/modules/search/classes/utils.d.ts +17 -0
  40. package/vanilla/src/lib/modules/search/types/dropdown-component.d.ts +20 -0
  41. package/vanilla/src/lib/modules/search/types/facet.d.ts +75 -0
  42. package/vanilla/src/lib/modules/search/types/values.d.ts +32 -0
  43. package/vanilla/src/lib/services/abstract-model.service.d.ts +244 -0
  44. package/vanilla/src/lib/services/debounce.service.d.ts +52 -0
  45. package/vanilla/src/lib/types/types.d.ts +100 -0
  46. package/esm2022/ecodev-natural.mjs +0 -5
  47. package/esm2022/lib/classes/abstract-detail.mjs +0 -229
  48. package/esm2022/lib/classes/abstract-editable-list.mjs +0 -99
  49. package/esm2022/lib/classes/abstract-list.mjs +0 -461
  50. package/esm2022/lib/classes/abstract-navigable-list.mjs +0 -133
  51. package/esm2022/lib/classes/apollo-utils.mjs +0 -59
  52. package/esm2022/lib/classes/crypto.mjs +0 -23
  53. package/esm2022/lib/classes/cumulative-changes.mjs +0 -50
  54. package/esm2022/lib/classes/data-source.mjs +0 -71
  55. package/esm2022/lib/classes/providers.mjs +0 -13
  56. package/esm2022/lib/classes/query-variable-manager-utils.mjs +0 -14
  57. package/esm2022/lib/classes/query-variable-manager.mjs +0 -172
  58. package/esm2022/lib/classes/rxjs.mjs +0 -54
  59. package/esm2022/lib/classes/signing.mjs +0 -38
  60. package/esm2022/lib/classes/tld.mjs +0 -1476
  61. package/esm2022/lib/classes/utility.mjs +0 -234
  62. package/esm2022/lib/classes/validators.mjs +0 -179
  63. package/esm2022/lib/directives/http-prefix.directive.mjs +0 -47
  64. package/esm2022/lib/modules/alert/alert.service.mjs +0 -53
  65. package/esm2022/lib/modules/alert/confirm.component.mjs +0 -16
  66. package/esm2022/lib/modules/alert/public-api.mjs +0 -6
  67. package/esm2022/lib/modules/avatar/component/avatar.component.mjs +0 -203
  68. package/esm2022/lib/modules/avatar/public-api.mjs +0 -6
  69. package/esm2022/lib/modules/avatar/service/avatar.service.mjs +0 -63
  70. package/esm2022/lib/modules/avatar/sources/gravatar.mjs +0 -29
  71. package/esm2022/lib/modules/avatar/sources/image.mjs +0 -13
  72. package/esm2022/lib/modules/avatar/sources/initials.mjs +0 -39
  73. package/esm2022/lib/modules/avatar/sources/source.mjs +0 -16
  74. package/esm2022/lib/modules/columns-picker/columns-picker.component.mjs +0 -145
  75. package/esm2022/lib/modules/columns-picker/public-api.mjs +0 -5
  76. package/esm2022/lib/modules/columns-picker/types.mjs +0 -2
  77. package/esm2022/lib/modules/common/directives/background-density.directive.mjs +0 -63
  78. package/esm2022/lib/modules/common/directives/linkable-tab.directive.mjs +0 -93
  79. package/esm2022/lib/modules/common/directives/src-density.directive.mjs +0 -72
  80. package/esm2022/lib/modules/common/pipes/capitalize.pipe.mjs +0 -24
  81. package/esm2022/lib/modules/common/pipes/ellipsis.pipe.mjs +0 -17
  82. package/esm2022/lib/modules/common/pipes/enum.pipe.mjs +0 -24
  83. package/esm2022/lib/modules/common/pipes/time-ago.pipe.mjs +0 -140
  84. package/esm2022/lib/modules/common/public-api.mjs +0 -14
  85. package/esm2022/lib/modules/common/services/memory-storage.mjs +0 -110
  86. package/esm2022/lib/modules/common/services/seo.provider.mjs +0 -23
  87. package/esm2022/lib/modules/common/services/seo.service.mjs +0 -235
  88. package/esm2022/lib/modules/detail-header/detail-header.component.mjs +0 -84
  89. package/esm2022/lib/modules/detail-header/public-api.mjs +0 -5
  90. package/esm2022/lib/modules/dialog-trigger/dialog-trigger.component.mjs +0 -72
  91. package/esm2022/lib/modules/dialog-trigger/public-api.mjs +0 -5
  92. package/esm2022/lib/modules/dropdown-components/abstract-association-select-component.directive.mjs +0 -100
  93. package/esm2022/lib/modules/dropdown-components/public-api.mjs +0 -14
  94. package/esm2022/lib/modules/dropdown-components/type-boolean/type-boolean.component.mjs +0 -39
  95. package/esm2022/lib/modules/dropdown-components/type-date/type-date.component.mjs +0 -173
  96. package/esm2022/lib/modules/dropdown-components/type-date-range/type-date-range.component.mjs +0 -134
  97. package/esm2022/lib/modules/dropdown-components/type-hierarchic-selector/type-hierarchic-selector.component.mjs +0 -80
  98. package/esm2022/lib/modules/dropdown-components/type-natural-select/type-natural-select.component.mjs +0 -48
  99. package/esm2022/lib/modules/dropdown-components/type-number/type-number.component.mjs +0 -110
  100. package/esm2022/lib/modules/dropdown-components/type-options/type-options.component.mjs +0 -64
  101. package/esm2022/lib/modules/dropdown-components/type-select/type-select.component.mjs +0 -175
  102. package/esm2022/lib/modules/dropdown-components/type-text/type-text.component.mjs +0 -62
  103. package/esm2022/lib/modules/dropdown-components/types.mjs +0 -41
  104. package/esm2022/lib/modules/dropdown-components/utils.mjs +0 -35
  105. package/esm2022/lib/modules/file/abstract-file.mjs +0 -230
  106. package/esm2022/lib/modules/file/component/file.component.mjs +0 -172
  107. package/esm2022/lib/modules/file/file-drop.directive.mjs +0 -111
  108. package/esm2022/lib/modules/file/file-select.directive.mjs +0 -26
  109. package/esm2022/lib/modules/file/file.service.mjs +0 -43
  110. package/esm2022/lib/modules/file/public-api.mjs +0 -9
  111. package/esm2022/lib/modules/file/types.mjs +0 -2
  112. package/esm2022/lib/modules/file/utils.mjs +0 -129
  113. package/esm2022/lib/modules/fixed-button/fixed-button.component.mjs +0 -30
  114. package/esm2022/lib/modules/fixed-button/public-api.mjs +0 -5
  115. package/esm2022/lib/modules/fixed-button-detail/fixed-button-detail.component.mjs +0 -56
  116. package/esm2022/lib/modules/fixed-button-detail/public-api.mjs +0 -5
  117. package/esm2022/lib/modules/hierarchic-selector/classes/flat-node.mjs +0 -18
  118. package/esm2022/lib/modules/hierarchic-selector/classes/hierarchic-configuration.mjs +0 -2
  119. package/esm2022/lib/modules/hierarchic-selector/classes/hierarchic-filters-configuration.mjs +0 -2
  120. package/esm2022/lib/modules/hierarchic-selector/classes/model-node.mjs +0 -14
  121. package/esm2022/lib/modules/hierarchic-selector/hierarchic-selector/hierarchic-selector.component.mjs +0 -398
  122. package/esm2022/lib/modules/hierarchic-selector/hierarchic-selector/hierarchic-selector.service.mjs +0 -243
  123. package/esm2022/lib/modules/hierarchic-selector/hierarchic-selector-dialog/hierarchic-selector-dialog.component.mjs +0 -38
  124. package/esm2022/lib/modules/hierarchic-selector/hierarchic-selector-dialog/hierarchic-selector-dialog.service.mjs +0 -22
  125. package/esm2022/lib/modules/hierarchic-selector/public-api.mjs +0 -10
  126. package/esm2022/lib/modules/icon/icon.directive.mjs +0 -96
  127. package/esm2022/lib/modules/icon/icon.module.mjs +0 -33
  128. package/esm2022/lib/modules/icon/public-api.mjs +0 -6
  129. package/esm2022/lib/modules/logger/error-handler.mjs +0 -87
  130. package/esm2022/lib/modules/logger/error.module.mjs +0 -22
  131. package/esm2022/lib/modules/logger/public-api.mjs +0 -6
  132. package/esm2022/lib/modules/matomo/matomo.service.mjs +0 -96
  133. package/esm2022/lib/modules/matomo/public-api.mjs +0 -5
  134. package/esm2022/lib/modules/panels/abstract-panel.mjs +0 -76
  135. package/esm2022/lib/modules/panels/fallback-if-no-opened-panels.urlmatcher.mjs +0 -12
  136. package/esm2022/lib/modules/panels/panels.component.mjs +0 -27
  137. package/esm2022/lib/modules/panels/panels.module.mjs +0 -10
  138. package/esm2022/lib/modules/panels/panels.service.mjs +0 -329
  139. package/esm2022/lib/modules/panels/panels.urlmatcher.mjs +0 -75
  140. package/esm2022/lib/modules/panels/public-api.mjs +0 -11
  141. package/esm2022/lib/modules/panels/types.mjs +0 -3
  142. package/esm2022/lib/modules/relations/public-api.mjs +0 -5
  143. package/esm2022/lib/modules/relations/relations.component.mjs +0 -254
  144. package/esm2022/lib/modules/search/classes/graphql-doctrine.mjs +0 -111
  145. package/esm2022/lib/modules/search/classes/graphql-doctrine.types.mjs +0 -14
  146. package/esm2022/lib/modules/search/classes/transformers.mjs +0 -142
  147. package/esm2022/lib/modules/search/classes/url.mjs +0 -53
  148. package/esm2022/lib/modules/search/classes/utils.mjs +0 -25
  149. package/esm2022/lib/modules/search/dropdown-container/dropdown-container-animations.mjs +0 -44
  150. package/esm2022/lib/modules/search/dropdown-container/dropdown-container.component.mjs +0 -87
  151. package/esm2022/lib/modules/search/dropdown-container/dropdown-ref.mjs +0 -24
  152. package/esm2022/lib/modules/search/dropdown-container/dropdown.service.mjs +0 -90
  153. package/esm2022/lib/modules/search/facet-selector/facet-selector.component.mjs +0 -45
  154. package/esm2022/lib/modules/search/group/group.component.mjs +0 -53
  155. package/esm2022/lib/modules/search/input/input.component.mjs +0 -365
  156. package/esm2022/lib/modules/search/public-api.mjs +0 -7
  157. package/esm2022/lib/modules/search/search/search.component.mjs +0 -102
  158. package/esm2022/lib/modules/search/types/dropdown-component.mjs +0 -2
  159. package/esm2022/lib/modules/search/types/facet.mjs +0 -2
  160. package/esm2022/lib/modules/search/types/values.mjs +0 -2
  161. package/esm2022/lib/modules/select/abstract-select.component.mjs +0 -232
  162. package/esm2022/lib/modules/select/public-api.mjs +0 -7
  163. package/esm2022/lib/modules/select/select/select.component.mjs +0 -310
  164. package/esm2022/lib/modules/select/select-enum/select-enum.component.mjs +0 -57
  165. package/esm2022/lib/modules/select/select-hierarchic/select-hierarchic.component.mjs +0 -155
  166. package/esm2022/lib/modules/sidenav/public-api.mjs +0 -9
  167. package/esm2022/lib/modules/sidenav/sidenav/sidenav.component.mjs +0 -15
  168. package/esm2022/lib/modules/sidenav/sidenav-container/sidenav-container.component.mjs +0 -90
  169. package/esm2022/lib/modules/sidenav/sidenav-content/sidenav-content.component.mjs +0 -11
  170. package/esm2022/lib/modules/sidenav/sidenav-stack.service.mjs +0 -50
  171. package/esm2022/lib/modules/sidenav/sidenav.service.mjs +0 -196
  172. package/esm2022/lib/modules/stamp/public-api.mjs +0 -5
  173. package/esm2022/lib/modules/stamp/stamp.component.mjs +0 -23
  174. package/esm2022/lib/modules/table-button/public-api.mjs +0 -5
  175. package/esm2022/lib/modules/table-button/table-button.component.mjs +0 -78
  176. package/esm2022/lib/services/abstract-model.service.mjs +0 -526
  177. package/esm2022/lib/services/debounce.service.mjs +0 -149
  178. package/esm2022/lib/services/enum.service.mjs +0 -64
  179. package/esm2022/lib/services/link-mutation.service.mjs +0 -154
  180. package/esm2022/lib/services/persistence.service.mjs +0 -115
  181. package/esm2022/lib/services/swiss-parsing-date-adapter.service.mjs +0 -63
  182. package/esm2022/lib/types/types.mjs +0 -2
  183. package/esm2022/public-api.mjs +0 -46
@@ -0,0 +1,91 @@
1
+ import { BehaviorSubject } from 'rxjs';
2
+ export type QueryVariables = {
3
+ filter?: any | null;
4
+ pagination?: PaginationInput | null;
5
+ sorting?: Sorting[] | null;
6
+ };
7
+ export type PaginationInput = {
8
+ offset?: number | null;
9
+ pageIndex?: number | null;
10
+ pageSize?: number | null;
11
+ };
12
+ export type Sorting = {
13
+ field: any;
14
+ order?: SortingOrder | null;
15
+ nullAsHighest?: boolean | null;
16
+ emptyStringAsHighest?: boolean | null;
17
+ };
18
+ export declare enum SortingOrder {
19
+ ASC = "ASC",
20
+ DESC = "DESC"
21
+ }
22
+ /**
23
+ * Filter manager stores a set of channels that contain a variable object and exposes an observable "variables" that updates with the result
24
+ * of all channels merged together.
25
+ *
26
+ * A channel is supposed to be used by a given aspect of the GUI (pagination, sorting, search, others ?).
27
+ *
28
+ * ```ts
29
+ * const fm = new QueryVariablesManager();
30
+ * fm.merge('componentA-variables', {a : [1, 2, 3]});
31
+ * ```
32
+ *
33
+ * Variables attributes is a BehaviorSubject. That mean it's not mandatory to subscribe, we can just call getValue or value attributes on
34
+ * it :
35
+ *
36
+ * ```ts
37
+ * console.log(fm.variables.value); // {a : [1, 2, 3]}
38
+ * ```
39
+ *
40
+ * Set new variables for 'componentA-variables':
41
+ *
42
+ * ```ts
43
+ * fm.merge('componentA-variables', {a : [1, 2]});
44
+ * console.log(fm.variables.value); // {a : [1, 2, 3]}
45
+ * ```
46
+ *
47
+ * Set new variables for new channel:
48
+ *
49
+ * ```ts
50
+ * fm.merge('componentB-variables', {a : [3, 4]});
51
+ * console.log(fm.variables.value); // {a : [1, 2, 3, 4]}
52
+ * ```
53
+ */
54
+ export declare class NaturalQueryVariablesManager<T extends QueryVariables = QueryVariables> {
55
+ readonly variables: BehaviorSubject<T | undefined>;
56
+ private readonly channels;
57
+ constructor(queryVariablesManager?: NaturalQueryVariablesManager<T>);
58
+ /**
59
+ * Set or override all the variables that may exist in the given channel
60
+ */
61
+ set(channelName: string, variables: Partial<T> | null | undefined): void;
62
+ /**
63
+ * Return a deep clone of the variables for the given channel name.
64
+ *
65
+ * Avoid returning the same reference to prevent an attribute change, then another channel update that would
66
+ * used this changed attribute without having explicitly asked QueryVariablesManager to update it.
67
+ */
68
+ get(channelName: string): Partial<T> | undefined;
69
+ /**
70
+ * Merge variable into a channel, overriding arrays in same channel / key
71
+ */
72
+ merge(channelName: string, newVariables: Partial<T>): void;
73
+ /**
74
+ * Apply default values to a channel
75
+ * Note : lodash defaults only defines values on destinations keys that are undefined
76
+ */
77
+ defaults(channelName: string, newVariables: Partial<T>): void;
78
+ private getChannelsCopy;
79
+ /**
80
+ * Merge channels in a single object
81
+ * Arrays are concatenated
82
+ * Filter groups are combined smartly (see mergeGroupList)
83
+ */
84
+ private updateVariables;
85
+ /**
86
+ * Cross merge two filters
87
+ * Only accepts groups with same groupLogic (ignores the first one, because there is no groupLogic in this one)
88
+ * @throws In case two non-empty lists of groups are given and at one of them mix groupLogic value, throws an error
89
+ */
90
+ private mergeGroupList;
91
+ }
@@ -0,0 +1,7 @@
1
+ import { HttpInterceptorFn } from '@angular/common/http';
2
+ /**
3
+ * Sign all HTTP POST requests that are GraphQL queries against `/graphql` endpoint with a custom signature.
4
+ *
5
+ * The server will validate the signature before executing the GraphQL query.
6
+ */
7
+ export declare function graphqlQuerySigner(key: string): HttpInterceptorFn;
@@ -0,0 +1,77 @@
1
+ import { Literal } from '../types/types';
2
+ import type { ReadonlyDeep } from 'type-fest';
3
+ import { PaginationInput, Sorting } from './query-variable-manager';
4
+ /**
5
+ * Very basic formatting to get only date, without time and ignoring entirely the timezone
6
+ *
7
+ * So something like: "2021-09-23"
8
+ */
9
+ export declare function formatIsoDate(date: null): null;
10
+ export declare function formatIsoDate(date: Date): string;
11
+ export declare function formatIsoDate(date: Date | null): string | null;
12
+ /**
13
+ * Format a date and time in a way that will preserve the local time zone.
14
+ * This allows the server side to know the day (without time) that was selected on client side.
15
+ *
16
+ * So something like: "2021-09-23T17:57:16+09:00"
17
+ */
18
+ export declare function formatIsoDateTime(date: Date): string;
19
+ /**
20
+ * Relations to full objects are converted to their IDs only.
21
+ *
22
+ * So {user: {id: 123}} becomes {user: 123}
23
+ */
24
+ export declare function relationsToIds(object: Literal): Literal;
25
+ /**
26
+ * Returns the plural form of the given name
27
+ *
28
+ * This is **not** necessarily valid english grammar. Its only purpose is for internal usage, not for humans.
29
+ *
30
+ * This **MUST** be kept in sync with `\Ecodev\Felix\Api\Plural:make()`.
31
+ *
32
+ * This is a bit performance-sensitive, so we should keep it fast and only cover cases that we actually need.
33
+ */
34
+ export declare function makePlural(name: string): string;
35
+ /**
36
+ * Returns the string with the first letter as capital
37
+ */
38
+ export declare function upperCaseFirstLetter(term: string): string;
39
+ /**
40
+ * Replace all attributes of first object with the ones provided by the second, but keeps the reference
41
+ */
42
+ export declare function replaceObjectKeepingReference(obj: Literal | null, newObj: Literal | null): void;
43
+ /**
44
+ * Get contrasted color for text in the slider thumb
45
+ * @param hexBgColor string in hexadecimals representing the background color
46
+ */
47
+ export declare function getForegroundColor(hexBgColor: string): 'black' | 'white';
48
+ /**
49
+ * Convert RGB color to hexadecimal color
50
+ *
51
+ * ```ts
52
+ * rgbToHex('rgb(255, 00, 255)'); // '#FF00FF'
53
+ * ```
54
+ */
55
+ export declare function rgbToHex(rgb: string): string;
56
+ /**
57
+ * During lodash.mergeWith, overrides arrays
58
+ */
59
+ export declare function mergeOverrideArray(destValue: unknown, source: unknown): unknown;
60
+ /**
61
+ * Copy text to clipboard.
62
+ * Accepts line breaks `\n` as textarea do.
63
+ */
64
+ export declare function copyToClipboard(document: Document, text: string): void;
65
+ export declare function deepFreeze<T extends Literal>(o: T): ReadonlyDeep<T>;
66
+ /**
67
+ * Return a valid PaginationInput from whatever is available from data. Invalid properties/types will be dropped.
68
+ */
69
+ export declare function validatePagination(data: unknown): PaginationInput | null;
70
+ /**
71
+ * Return a valid Sortings from whatever is available from data. Invalid properties/types will be dropped.
72
+ */
73
+ export declare function validateSorting(data: unknown): Sorting[] | null;
74
+ /**
75
+ * Return valid columns from whatever is available from data. Invalid properties/types will be dropped.
76
+ */
77
+ export declare function validateColumns(data: unknown): string[] | null;
@@ -0,0 +1,83 @@
1
+ import { Literal } from '../../../types/types';
2
+ export type Filter = {
3
+ groups?: FilterGroup[] | null;
4
+ };
5
+ export type FilterGroup = {
6
+ groupLogic?: LogicalOperator | null;
7
+ conditionsLogic?: LogicalOperator | null;
8
+ joins?: FilterGroupJoin | null;
9
+ conditions?: FilterGroupCondition[] | null;
10
+ };
11
+ export type FilterGroupJoin = Record<string, JoinOn>;
12
+ export type JoinOn = {
13
+ type?: JoinType | null;
14
+ joins?: FilterGroupJoin | null;
15
+ conditions?: FilterGroupCondition[] | null;
16
+ };
17
+ export declare enum LogicalOperator {
18
+ AND = "AND",
19
+ OR = "OR"
20
+ }
21
+ export declare enum JoinType {
22
+ innerJoin = "innerJoin",
23
+ leftJoin = "leftJoin"
24
+ }
25
+ export type FilterGroupCondition = Record<string, FilterGroupConditionField>;
26
+ export type FilterGroupConditionField = {
27
+ between?: BetweenOperator | null;
28
+ equal?: EqualOperator | null;
29
+ greater?: GreaterOperator | null;
30
+ greaterOrEqual?: GreaterOrEqualOperator | null;
31
+ in?: InOperator | null;
32
+ less?: LessOperator | null;
33
+ lessOrEqual?: LessOrEqualOperator | null;
34
+ like?: LikeOperator | null;
35
+ null?: NullOperator | null;
36
+ have?: HaveOperator | null;
37
+ empty?: EmptyOperator | null;
38
+ [key: string]: Literal | undefined | null;
39
+ };
40
+ export type Scalar = number | string | boolean;
41
+ export type HaveOperator = {
42
+ values: string[];
43
+ not?: boolean | null;
44
+ };
45
+ export type EmptyOperator = {
46
+ not?: boolean | null;
47
+ };
48
+ export type BetweenOperator = {
49
+ from: Scalar;
50
+ to: Scalar;
51
+ not?: boolean | null;
52
+ };
53
+ export type EqualOperator = {
54
+ value: Scalar;
55
+ not?: boolean | null;
56
+ };
57
+ export type GreaterOperator = {
58
+ value: Scalar;
59
+ not?: boolean | null;
60
+ };
61
+ export type GreaterOrEqualOperator = {
62
+ value: Scalar;
63
+ not?: boolean | null;
64
+ };
65
+ export type InOperator = {
66
+ values: Scalar[];
67
+ not?: boolean | null;
68
+ };
69
+ export type LessOperator = {
70
+ value: Scalar;
71
+ not?: boolean | null;
72
+ };
73
+ export type LessOrEqualOperator = {
74
+ value: Scalar;
75
+ not?: boolean | null;
76
+ };
77
+ export type LikeOperator = {
78
+ value: Scalar;
79
+ not?: boolean | null;
80
+ };
81
+ export type NullOperator = {
82
+ not?: boolean | null;
83
+ };
@@ -0,0 +1,17 @@
1
+ import { Facet, NaturalSearchFacets } from '../types/facet';
2
+ import { NaturalSearchSelection } from '../types/values';
3
+ /**
4
+ * Lookup a facet by its `name` and then by its `field`, or return null if not found
5
+ */
6
+ export declare function getFacetFromSelection(facets: NaturalSearchFacets | null, selection: NaturalSearchSelection): Facet | null;
7
+ /**
8
+ * Deep clone a literal via JSON serializing/unserializing
9
+ *
10
+ * It will **not** work with:
11
+ *
12
+ * - functions (will be removed)
13
+ * - `undefined` (will be removed)
14
+ * - cyclic references (will crash)
15
+ * - objects (will be converted to `{}`)
16
+ */
17
+ export declare function deepClone<T>(obj: T extends undefined ? never : T): T;
@@ -0,0 +1,20 @@
1
+ import { BehaviorSubject } from 'rxjs';
2
+ import { FilterGroupConditionField } from '../classes/graphql-doctrine.types';
3
+ export type DropdownComponent = {
4
+ /**
5
+ * Observable of current value as string
6
+ */
7
+ readonly renderedValue: BehaviorSubject<string>;
8
+ /**
9
+ * Get condition, including rich object types
10
+ */
11
+ getCondition(): FilterGroupConditionField;
12
+ /**
13
+ * Returns true if dropdown value is valid
14
+ */
15
+ isValid(): boolean;
16
+ /**
17
+ * Returns true if the dropdown value has change
18
+ */
19
+ isDirty(): boolean;
20
+ };
@@ -0,0 +1,75 @@
1
+ import { Type } from '@angular/core';
2
+ import { DropdownComponent } from './dropdown-component';
3
+ import { NaturalSearchSelection } from './values';
4
+ type BasicFacet = {
5
+ /**
6
+ * The label to be used in the GUI
7
+ */
8
+ display: string;
9
+ /**
10
+ * The field this facet should apply to.
11
+ *
12
+ * In most cases it should be the property name of the model. Something like:
13
+ *
14
+ * - name
15
+ * - description
16
+ * - artist.name
17
+ */
18
+ field: string;
19
+ /**
20
+ * This is required only if there are duplicated `field` in all facets.
21
+ *
22
+ * If `name` exists it will be used as an alternative identifier for facet, instead of `field`, to match
23
+ * a selection with its facet (in `getFacetFromSelection()`). So a selection must be given with the `name`,
24
+ * instead of `field`. And it will also be present in the URL. But it will never appear in the GraphQL selection.
25
+ *
26
+ * https://github.com/Ecodev/natural-search/issues/16
27
+ */
28
+ name?: string;
29
+ /**
30
+ * A function to transform the selection before it is applied onto the filter.
31
+ *
32
+ * This would typically be useful to do unit conversion so the GUI has some user
33
+ * friendly values, but the API works with a "low-level" unit.
34
+ */
35
+ transform?: (s: NaturalSearchSelection) => NaturalSearchSelection;
36
+ };
37
+ /**
38
+ * Facet that is only a flag (set or unset)
39
+ */
40
+ export type FlagFacet<Condition> = {
41
+ /**
42
+ * The value to be returned when the flag is set
43
+ */
44
+ condition: Condition;
45
+ /**
46
+ * If true the value is set when the flag does NOT exist and the
47
+ * value is unset when the flag exists.
48
+ *
49
+ * Defaults to `false`.
50
+ */
51
+ inversed?: boolean;
52
+ } & BasicFacet;
53
+ /**
54
+ * Facet that uses a component in a dropdown
55
+ */
56
+ export type DropdownFacet<C> = {
57
+ component: Type<DropdownComponent>;
58
+ /**
59
+ * Show a button into the dropdown container to validate value. Gives alternative to "click out" and incoming "tab/esc" key.
60
+ */
61
+ showValidateButton?: boolean;
62
+ /**
63
+ * Anything that could be useful for the dropdown component
64
+ */
65
+ configuration?: C;
66
+ } & BasicFacet;
67
+ /**
68
+ * A facet
69
+ */
70
+ export type Facet = DropdownFacet<any> | FlagFacet<any>;
71
+ /**
72
+ * Exhaustive list of facets
73
+ */
74
+ export type NaturalSearchFacets = Facet[];
75
+ export {};
@@ -0,0 +1,32 @@
1
+ import { FilterGroupConditionField } from '../classes/graphql-doctrine.types';
2
+ import { Facet } from './facet';
3
+ /**
4
+ * Type for a search selection
5
+ */
6
+ export type NaturalSearchSelection = {
7
+ field: string;
8
+ /**
9
+ * This is required if the facet also have a `name`.
10
+ *
11
+ * See BasicFacet.name
12
+ */
13
+ name?: string;
14
+ condition: FilterGroupConditionField;
15
+ };
16
+ /**
17
+ * Groups are a list of values, that should be interpreted with AND condition
18
+ */
19
+ export type GroupSelections = NaturalSearchSelection[];
20
+ /**
21
+ * List of groups, that should be interpreted with OR condition
22
+ * Final input / output format
23
+ */
24
+ export type NaturalSearchSelections = GroupSelections[];
25
+ /**
26
+ * Consolidated type for a selection and it's matching facet
27
+ * Used internally for dropdown
28
+ */
29
+ export type DropdownResult = {
30
+ condition: FilterGroupConditionField;
31
+ facet?: Facet;
32
+ };
@@ -0,0 +1,244 @@
1
+ import { Apollo, MutationResult } from 'apollo-angular';
2
+ import { FetchResult, WatchQueryFetchPolicy } from '@apollo/client/core';
3
+ import { AbstractControl, AsyncValidatorFn, UntypedFormGroup, ValidatorFn } from '@angular/forms';
4
+ import { DocumentNode } from 'graphql';
5
+ import { Observable, OperatorFunction } from 'rxjs';
6
+ import { NaturalQueryVariablesManager, QueryVariables } from '../classes/query-variable-manager';
7
+ import { Literal } from '../types/types';
8
+ import { PaginatedData } from '../classes/data-source';
9
+ import { NaturalDebounceService } from './debounce.service';
10
+ export type FormValidators = Record<string, ValidatorFn[]>;
11
+ export type FormAsyncValidators = Record<string, AsyncValidatorFn[]>;
12
+ export type VariablesWithInput = {
13
+ input: Literal;
14
+ };
15
+ export type FormControls = Record<string, AbstractControl>;
16
+ export type WithId<T> = {
17
+ id: string;
18
+ } & T;
19
+ export declare abstract class NaturalAbstractModelService<Tone, Vone extends {
20
+ id: string;
21
+ }, Tall extends PaginatedData<Literal>, Vall extends QueryVariables, Tcreate, Vcreate extends VariablesWithInput, Tupdate, Vupdate extends {
22
+ id: string;
23
+ input: Literal;
24
+ }, Tdelete, Vdelete extends {
25
+ ids: string[];
26
+ }> {
27
+ protected readonly name: string;
28
+ protected readonly oneQuery: DocumentNode | null;
29
+ protected readonly allQuery: DocumentNode | null;
30
+ protected readonly createMutation: DocumentNode | null;
31
+ protected readonly updateMutation: DocumentNode | null;
32
+ protected readonly deleteMutation: DocumentNode | null;
33
+ private readonly createName;
34
+ private readonly updateName;
35
+ private readonly deleteName;
36
+ /**
37
+ * Store the creation mutations that are pending
38
+ */
39
+ private readonly creatingCache;
40
+ protected readonly apollo: Apollo;
41
+ protected readonly naturalDebounceService: NaturalDebounceService;
42
+ private readonly plural;
43
+ /**
44
+ *
45
+ * @param name service and single object query name (eg. userForFront or user).
46
+ * @param oneQuery GraphQL query to fetch a single object from ID (eg. userForCrudQuery).
47
+ * @param allQuery GraphQL query to fetch a filtered list of objects (eg. usersForCrudQuery).
48
+ * @param createMutation GraphQL mutation to create an object.
49
+ * @param updateMutation GraphQL mutation to update an object.
50
+ * @param deleteMutation GraphQL mutation to delete a list of objects.
51
+ * @param plural list query name (eg. usersForFront or users).
52
+ * @param createName create object mutation name (eg. createUser).
53
+ * @param updateName update object mutation name (eg. updateUser).
54
+ * @param deleteName delete object mutation name (eg. deleteUsers).
55
+ */
56
+ constructor(name: string, oneQuery: DocumentNode | null, allQuery: DocumentNode | null, createMutation: DocumentNode | null, updateMutation: DocumentNode | null, deleteMutation: DocumentNode | null, plural?: string | null, createName?: string | null, updateName?: string | null, deleteName?: string | null);
57
+ /**
58
+ * List of individual fields validators
59
+ */
60
+ getFormValidators(model?: Literal): FormValidators;
61
+ /**
62
+ * List of individual async fields validators
63
+ */
64
+ getFormAsyncValidators(model?: Literal): FormAsyncValidators;
65
+ /**
66
+ * List of grouped fields validators (like password + confirm password)
67
+ */
68
+ getFormGroupValidators(model?: Literal): ValidatorFn[];
69
+ /**
70
+ * List of async group fields validators (like unique constraint on multiple columns)
71
+ */
72
+ getFormGroupAsyncValidators(model?: Literal): AsyncValidatorFn[];
73
+ getFormConfig(model: Literal): FormControls;
74
+ /**
75
+ * Create the final FormGroup for the object, including all validators
76
+ *
77
+ * This method should **not** be overridden, but instead `getFormConfig`,
78
+ * `getFormGroupValidators`, `getFormGroupAsyncValidators` might be.
79
+ */
80
+ getFormGroup(model: Literal): UntypedFormGroup;
81
+ /**
82
+ * Get a single object
83
+ *
84
+ * If available it will emit object from cache immediately, then it
85
+ * will **always** fetch from network and then the observable will be completed.
86
+ *
87
+ * You must subscribe to start getting results (and fetch from network).
88
+ */
89
+ getOne(id: string): Observable<Tone>;
90
+ /**
91
+ * Watch a single object
92
+ *
93
+ * If available it will emit object from cache immediately, then it
94
+ * will **always** fetch from network, and then keep watching the cache forever.
95
+ *
96
+ * You must subscribe to start getting results (and fetch from network).
97
+ *
98
+ * You **MUST** unsubscribe.
99
+ */
100
+ watchOne(id: string, fetchPolicy?: WatchQueryFetchPolicy): Observable<Tone>;
101
+ private prepareOneQuery;
102
+ /**
103
+ * Get a collection of objects
104
+ *
105
+ * It will **always** fetch from network and then the observable will be completed.
106
+ * No cache is ever used, so it's slow but correct.
107
+ */
108
+ getAll(queryVariablesManager: NaturalQueryVariablesManager<Vall>): Observable<Tall>;
109
+ /**
110
+ * Get a collection of objects
111
+ *
112
+ * Every time the observable variables change, and they are not undefined,
113
+ * it will return result from cache, then it will **always** fetch from network,
114
+ * and then keep watching the cache forever.
115
+ *
116
+ * You must subscribe to start getting results (and fetch from network).
117
+ *
118
+ * You **MUST** unsubscribe.
119
+ */
120
+ watchAll(queryVariablesManager: NaturalQueryVariablesManager<Vall>, fetchPolicy?: WatchQueryFetchPolicy): Observable<Tall>;
121
+ /**
122
+ * This functions allow to quickly create or update objects.
123
+ *
124
+ * Manages a "creation is pending" status, and update when creation is ready.
125
+ * Uses regular update/updateNow and create methods.
126
+ * Used mainly when editing multiple objects in same controller (like in editable arrays)
127
+ */
128
+ createOrUpdate(object: Vcreate['input'] | WithId<Vupdate['input']>, now?: boolean): Observable<Tcreate | Tupdate>;
129
+ /**
130
+ * Create an object in DB and then refetch the list of objects
131
+ */
132
+ create(object: Vcreate['input']): Observable<Tcreate>;
133
+ /**
134
+ * Update an object, after a short debounce
135
+ */
136
+ update(object: WithId<Vupdate['input']>): Observable<Tupdate>;
137
+ /**
138
+ * Update an object immediately when subscribing
139
+ */
140
+ updateNow(object: WithId<Vupdate['input']>): Observable<Tupdate>;
141
+ /**
142
+ * Delete objects and then refetch the list of objects
143
+ */
144
+ delete(objects: {
145
+ id: string;
146
+ }[]): Observable<Tdelete>;
147
+ /**
148
+ * If the id is provided, resolves an observable model. The observable model will only be emitted after we are sure
149
+ * that Apollo cache is fresh and warm. Then the component can subscribe to the observable model to get the model
150
+ * immediately from Apollo cache and any subsequents future mutations that may happen to Apollo cache.
151
+ *
152
+ * Without id, returns default values, in order to show a creation form.
153
+ */
154
+ resolve(id: string | undefined): Observable<Observable<Tone | Vcreate['input']>>;
155
+ /**
156
+ * Return an object that match the GraphQL input type.
157
+ * It creates an object with manually filled data and add uncompleted data (like required attributes that can be empty strings)
158
+ */
159
+ getInput(object: Literal, forCreation: boolean): Vcreate['input'] | Vupdate['input'];
160
+ /**
161
+ * Return the number of objects matching the query. It may never complete.
162
+ *
163
+ * This is used for the unique validator
164
+ */
165
+ count(queryVariablesManager: NaturalQueryVariablesManager<Vall>): Observable<number>;
166
+ /**
167
+ * Return empty object with some default values from server perspective
168
+ *
169
+ * This is typically useful when showing a form for creation
170
+ */
171
+ getDefaultForServer(): Vcreate['input'];
172
+ /**
173
+ * You probably **should not** use this.
174
+ *
175
+ * If you are trying to *call* this method, instead you probably want to call `getDefaultForServer()` to get default
176
+ * values for a model, or `getFormConfig()` to get a configured form that includes extra form fields.
177
+ *
178
+ * If you are trying to *override* this method, instead you probably want to override `getDefaultForServer()`.
179
+ *
180
+ * The only and **very rare** reason to override this method is if the client needs extra form fields that cannot be
181
+ * accepted by the server (not part of `XXXInput` type) and that are strictly for the client form needs. In that case,
182
+ * then you can return default values for those extra form fields, and the form returned by `getFormConfig()` will
183
+ * include those extra fields.
184
+ */
185
+ protected getFormExtraFieldDefaultValues(): Literal;
186
+ /**
187
+ * This is used to extract only the array of fetched objects out of the entire fetched data
188
+ */
189
+ protected mapAll(): OperatorFunction<FetchResult<unknown>, Tall>;
190
+ /**
191
+ * This is used to extract only the created object out of the entire fetched data
192
+ */
193
+ protected mapCreation(result: MutationResult<unknown>): Tcreate;
194
+ /**
195
+ * This is used to extract only the updated object out of the entire fetched data
196
+ */
197
+ protected mapUpdate(result: MutationResult<unknown>): Tupdate;
198
+ /**
199
+ * This is used to extract only flag when deleting an object
200
+ */
201
+ protected mapDelete(result: MutationResult<unknown>): Tdelete;
202
+ /**
203
+ * Returns additional variables to be used when getting a single object
204
+ *
205
+ * This is typically a site or state ID, and is needed to get appropriate access rights
206
+ */
207
+ protected getPartialVariablesForOne(): Observable<Partial<Vone>>;
208
+ /**
209
+ * Returns additional variables to be used when getting multiple objects
210
+ *
211
+ * This is typically a site or state ID, but it could be something else to further filter the query
212
+ */
213
+ getPartialVariablesForAll(): Observable<Partial<Vall>>;
214
+ /**
215
+ * Returns additional variables to be used when creating an object
216
+ *
217
+ * This is typically a site or state ID
218
+ */
219
+ protected getPartialVariablesForCreation(object: Literal): Partial<Vcreate>;
220
+ /**
221
+ * Returns additional variables to be used when updating an object
222
+ *
223
+ * This is typically a site or state ID
224
+ */
225
+ protected getPartialVariablesForUpdate(object: Literal): Partial<Vupdate>;
226
+ /**
227
+ * Return additional variables to be used when deleting an object
228
+ *
229
+ * This is typically a site or state ID
230
+ */
231
+ protected getPartialVariablesForDelete(objects: Literal[]): Partial<Vdelete>;
232
+ /**
233
+ * Throw exception to prevent executing queries with invalid variables
234
+ */
235
+ protected throwIfObservable(value: unknown): void;
236
+ /**
237
+ * Merge given ID with additional partial variables if there is any
238
+ */
239
+ private getVariablesForOne;
240
+ /**
241
+ * Throw exception to prevent executing null queries
242
+ */
243
+ private throwIfNotQuery;
244
+ }