@lenne.tech/ng-base 13.6.3 → 13.6.6

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 (165) hide show
  1. package/base-components/components/checkbox/checkbox.component.d.ts +1 -1
  2. package/base-prototype/base-prototype.module.d.ts +6 -5
  3. package/base-prototype/pages/forgot-password/forgot-password.component.d.ts +7 -2
  4. package/base-prototype/pages/login/login.component.d.ts +8 -2
  5. package/base-prototype/pages/register/register.component.d.ts +8 -2
  6. package/esm2020/base-components/components/checkbox/checkbox.component.mjs +3 -3
  7. package/esm2020/base-components/components/input/input.component.mjs +3 -3
  8. package/esm2020/base-prototype/base-prototype.module.mjs +5 -4
  9. package/esm2020/base-prototype/pages/forgot-password/forgot-password.component.mjs +30 -9
  10. package/esm2020/base-prototype/pages/login/login.component.mjs +46 -9
  11. package/esm2020/base-prototype/pages/register/register.component.mjs +45 -11
  12. package/esm2020/public-api.mjs +1 -42
  13. package/esm2020/shared/classes/auth.class.mjs +16 -0
  14. package/esm2020/shared/classes/basic-user.class.mjs +51 -0
  15. package/esm2020/shared/classes/graphql-enum.class.mjs +9 -0
  16. package/esm2020/shared/classes/graphql-meta.class.mjs +171 -0
  17. package/esm2020/shared/classes/graphql-type.class.mjs +13 -0
  18. package/esm2020/shared/classes/helper.class.mjs +304 -0
  19. package/esm2020/shared/classes/standard.class.mjs +40 -0
  20. package/esm2020/{src → shared}/enums/comparison-operator.enum.mjs +1 -1
  21. package/esm2020/shared/enums/graphql-request-type.enum.mjs +10 -0
  22. package/esm2020/shared/enums/logical-operator.enum.mjs +10 -0
  23. package/esm2020/shared/enums/sort-order.enum.mjs +6 -0
  24. package/esm2020/shared/functions/ws-client.function.mjs +39 -0
  25. package/esm2020/shared/interfaces/base-module-config.interface.mjs +3 -0
  26. package/esm2020/shared/interfaces/can-component-deactivate.interface.mjs +2 -0
  27. package/esm2020/shared/interfaces/combined-filter-input.interface.mjs +2 -0
  28. package/esm2020/shared/interfaces/field-object.interface.mjs +2 -0
  29. package/esm2020/shared/interfaces/field.interface.mjs +2 -0
  30. package/esm2020/shared/interfaces/filter-input.interface.mjs +2 -0
  31. package/esm2020/shared/interfaces/find-args.interface.mjs +2 -0
  32. package/esm2020/shared/interfaces/graphql-fields-object.interface.mjs +2 -0
  33. package/esm2020/shared/interfaces/graphql-options.interface.mjs +2 -0
  34. package/esm2020/shared/interfaces/graphql-plus-options.interfacen.mjs +2 -0
  35. package/esm2020/shared/interfaces/graphql-type-collection.interface.mjs +2 -0
  36. package/esm2020/shared/interfaces/single-filter-input.interface.mjs +2 -0
  37. package/esm2020/shared/interfaces/sort-input.interface.mjs +2 -0
  38. package/esm2020/shared/interfaces/time-components.interface.mjs +2 -0
  39. package/esm2020/shared/lenne.tech-ng-base-shared.mjs +5 -0
  40. package/esm2020/shared/public-api.mjs +51 -0
  41. package/esm2020/shared/services/auth.service.mjs +71 -0
  42. package/esm2020/shared/services/forms.service.mjs +25 -0
  43. package/esm2020/shared/services/graphql-meta.service.mjs +123 -0
  44. package/esm2020/shared/services/graphql-plus.service.mjs +84 -0
  45. package/esm2020/shared/services/graphql.service.mjs +441 -0
  46. package/esm2020/shared/services/image.service.mjs +102 -0
  47. package/esm2020/shared/services/loader.service.mjs +29 -0
  48. package/esm2020/shared/services/scroll.service.mjs +179 -0
  49. package/esm2020/shared/services/storage.service.mjs +132 -0
  50. package/esm2020/shared/services/user.service.mjs +82 -0
  51. package/esm2020/shared/services/ws.service.mjs +16 -0
  52. package/esm2020/shared/types/graphql-fields.type.mjs +2 -0
  53. package/esm2020/shared/types/storage.type.mjs +2 -0
  54. package/esm2020/shared/validators/match.validator.mjs +19 -0
  55. package/esm2020/src/base.module.mjs +14 -11
  56. package/esm2020/src/directives/match-height.directive.mjs +2 -2
  57. package/esm2020/src/factories/apollo-options.factory.mjs +14 -12
  58. package/esm2020/src/guards/auth.guard.mjs +3 -3
  59. package/esm2020/src/guards/can-deactivate.guard.mjs +1 -1
  60. package/esm2020/src/guards/logout.guard.mjs +2 -2
  61. package/esm2020/src/services/theme.service.mjs +2 -2
  62. package/fesm2015/lenne.tech-ng-base-base-components.mjs +4 -4
  63. package/fesm2015/lenne.tech-ng-base-base-components.mjs.map +1 -1
  64. package/fesm2015/lenne.tech-ng-base-base-prototype.mjs +113 -22
  65. package/fesm2015/lenne.tech-ng-base-base-prototype.mjs.map +1 -1
  66. package/fesm2015/lenne.tech-ng-base-shared.mjs +1878 -0
  67. package/fesm2015/lenne.tech-ng-base-shared.mjs.map +1 -0
  68. package/fesm2015/lenne.tech-ng-base.mjs +57 -1799
  69. package/fesm2015/lenne.tech-ng-base.mjs.map +1 -1
  70. package/fesm2020/lenne.tech-ng-base-base-components.mjs +4 -4
  71. package/fesm2020/lenne.tech-ng-base-base-components.mjs.map +1 -1
  72. package/fesm2020/lenne.tech-ng-base-base-prototype.mjs +111 -22
  73. package/fesm2020/lenne.tech-ng-base-base-prototype.mjs.map +1 -1
  74. package/fesm2020/lenne.tech-ng-base-shared.mjs +1939 -0
  75. package/fesm2020/lenne.tech-ng-base-shared.mjs.map +1 -0
  76. package/fesm2020/lenne.tech-ng-base.mjs +57 -1854
  77. package/fesm2020/lenne.tech-ng-base.mjs.map +1 -1
  78. package/package.json +10 -1
  79. package/public-api.d.ts +0 -36
  80. package/shared/classes/auth.class.d.ts +9 -0
  81. package/{src → shared}/classes/basic-user.class.d.ts +0 -0
  82. package/{src → shared}/classes/graphql-enum.class.d.ts +0 -0
  83. package/{src → shared}/classes/graphql-meta.class.d.ts +0 -0
  84. package/{src → shared}/classes/graphql-type.class.d.ts +0 -0
  85. package/{src → shared}/classes/helper.class.d.ts +0 -0
  86. package/{src → shared}/classes/standard.class.d.ts +0 -0
  87. package/{src → shared}/enums/comparison-operator.enum.d.ts +0 -0
  88. package/{src → shared}/enums/graphql-request-type.enum.d.ts +0 -0
  89. package/{src → shared}/enums/logical-operator.enum.d.ts +0 -0
  90. package/{src → shared}/enums/sort-order.enum.d.ts +0 -0
  91. package/shared/functions/ws-client.function.d.ts +5 -0
  92. package/{src → shared}/interfaces/base-module-config.interface.d.ts +1 -1
  93. package/{src → shared}/interfaces/can-component-deactivate.interface.d.ts +0 -0
  94. package/{src → shared}/interfaces/combined-filter-input.interface.d.ts +0 -0
  95. package/{src → shared}/interfaces/field-object.interface.d.ts +0 -0
  96. package/{src → shared}/interfaces/field.interface.d.ts +0 -0
  97. package/{src → shared}/interfaces/filter-input.interface.d.ts +0 -0
  98. package/{src → shared}/interfaces/find-args.interface.d.ts +0 -0
  99. package/{src → shared}/interfaces/graphql-fields-object.interface.d.ts +0 -0
  100. package/{src → shared}/interfaces/graphql-options.interface.d.ts +0 -0
  101. package/{src → shared}/interfaces/graphql-plus-options.interfacen.d.ts +0 -0
  102. package/{src → shared}/interfaces/graphql-type-collection.interface.d.ts +0 -0
  103. package/{src → shared}/interfaces/single-filter-input.interface.d.ts +0 -0
  104. package/{src → shared}/interfaces/sort-input.interface.d.ts +0 -0
  105. package/shared/interfaces/time-components.interface.d.ts +6 -0
  106. package/shared/lenne.tech-ng-base-shared.d.ts +5 -0
  107. package/shared/package.json +10 -0
  108. package/shared/public-api.d.ts +43 -0
  109. package/{src → shared}/services/auth.service.d.ts +0 -0
  110. package/{src → shared}/services/forms.service.d.ts +0 -1
  111. package/{src → shared}/services/graphql-meta.service.d.ts +0 -0
  112. package/{src → shared}/services/graphql-plus.service.d.ts +0 -0
  113. package/{src → shared}/services/graphql.service.d.ts +0 -0
  114. package/{src → shared}/services/image.service.d.ts +0 -0
  115. package/{src → shared}/services/loader.service.d.ts +0 -0
  116. package/{src → shared}/services/scroll.service.d.ts +0 -0
  117. package/{src → shared}/services/storage.service.d.ts +0 -0
  118. package/shared/services/user.service.d.ts +42 -0
  119. package/{src → shared}/services/ws.service.d.ts +2 -2
  120. package/{src → shared}/types/graphql-fields.type.d.ts +0 -0
  121. package/{src → shared}/types/storage.type.d.ts +0 -0
  122. package/shared/validators/match.validator.d.ts +4 -0
  123. package/src/base.module.d.ts +4 -2
  124. package/src/directives/match-height.directive.d.ts +1 -1
  125. package/src/factories/apollo-options.factory.d.ts +1 -3
  126. package/src/guards/auth.guard.d.ts +1 -2
  127. package/src/guards/can-deactivate.guard.d.ts +1 -1
  128. package/src/guards/logout.guard.d.ts +1 -1
  129. package/src/services/theme.service.d.ts +1 -1
  130. package/esm2020/src/classes/basic-user.class.mjs +0 -51
  131. package/esm2020/src/classes/graphql-enum.class.mjs +0 -9
  132. package/esm2020/src/classes/graphql-meta.class.mjs +0 -171
  133. package/esm2020/src/classes/graphql-type.class.mjs +0 -13
  134. package/esm2020/src/classes/helper.class.mjs +0 -304
  135. package/esm2020/src/classes/standard.class.mjs +0 -40
  136. package/esm2020/src/enums/graphql-request-type.enum.mjs +0 -10
  137. package/esm2020/src/enums/logical-operator.enum.mjs +0 -10
  138. package/esm2020/src/enums/sort-order.enum.mjs +0 -6
  139. package/esm2020/src/interfaces/base-module-config.interface.mjs +0 -3
  140. package/esm2020/src/interfaces/can-component-deactivate.interface.mjs +0 -2
  141. package/esm2020/src/interfaces/combined-filter-input.interface.mjs +0 -2
  142. package/esm2020/src/interfaces/field-object.interface.mjs +0 -2
  143. package/esm2020/src/interfaces/field.interface.mjs +0 -2
  144. package/esm2020/src/interfaces/filter-input.interface.mjs +0 -2
  145. package/esm2020/src/interfaces/find-args.interface.mjs +0 -2
  146. package/esm2020/src/interfaces/graphql-fields-object.interface.mjs +0 -2
  147. package/esm2020/src/interfaces/graphql-options.interface.mjs +0 -2
  148. package/esm2020/src/interfaces/graphql-plus-options.interfacen.mjs +0 -2
  149. package/esm2020/src/interfaces/graphql-type-collection.interface.mjs +0 -2
  150. package/esm2020/src/interfaces/single-filter-input.interface.mjs +0 -2
  151. package/esm2020/src/interfaces/sort-input.interface.mjs +0 -2
  152. package/esm2020/src/services/auth.service.mjs +0 -71
  153. package/esm2020/src/services/forms.service.mjs +0 -26
  154. package/esm2020/src/services/graphql-meta.service.mjs +0 -123
  155. package/esm2020/src/services/graphql-plus.service.mjs +0 -84
  156. package/esm2020/src/services/graphql.service.mjs +0 -441
  157. package/esm2020/src/services/image.service.mjs +0 -102
  158. package/esm2020/src/services/loader.service.mjs +0 -29
  159. package/esm2020/src/services/scroll.service.mjs +0 -179
  160. package/esm2020/src/services/storage.service.mjs +0 -132
  161. package/esm2020/src/services/ws.service.mjs +0 -17
  162. package/esm2020/src/types/graphql-fields.type.mjs +0 -2
  163. package/esm2020/src/types/storage.type.mjs +0 -2
  164. package/esm2020/src/validators/must-match.validator.mjs +0 -22
  165. package/src/validators/must-match.validator.d.ts +0 -6
@@ -1,239 +1,26 @@
1
- import * as i1$2 from 'apollo-angular';
2
- import { APOLLO_OPTIONS, gql } from 'apollo-angular';
1
+ import { APOLLO_OPTIONS, ApolloModule } from 'apollo-angular';
3
2
  import { HttpLink } from 'apollo-angular/http';
4
3
  import * as i0 from '@angular/core';
5
- import { InjectionToken, Injectable, Inject, Directive, Input, Output, HostBinding, PLATFORM_ID, HostListener, Pipe, NgModule } from '@angular/core';
6
- import { BehaviorSubject, Observable, of, throwError } from 'rxjs';
4
+ import { Directive, Input, Output, HostBinding, PLATFORM_ID, Inject, HostListener, Pipe, NgModule, Injectable } from '@angular/core';
7
5
  import { ApolloLink, split, concat } from '@apollo/client/core';
8
6
  import { InMemoryCache } from '@apollo/client/cache';
9
- import { WebSocketLink } from '@apollo/client/link/ws';
10
7
  import { getMainDefinition } from '@apollo/client/utilities';
8
+ import * as i2 from '@lenne.tech/ng-base/shared';
9
+ import { createRestartableClient, BASE_MODULE_CONFIG, AuthService, WsService } from '@lenne.tech/ng-base/shared';
10
+ import { GraphQLWsLink } from '@apollo/client/link/subscriptions';
11
11
  import { isPlatformBrowser } from '@angular/common';
12
12
  import * as i1 from '@angular/platform-browser';
13
+ import { HttpClientModule } from '@angular/common/http';
14
+ import { Observable, BehaviorSubject } from 'rxjs';
13
15
  import * as i1$1 from '@angular/router';
14
- import { FormControl, FormGroup } from '@angular/forms';
15
- import { buildClientSchema, getIntrospectionQuery } from 'graphql';
16
- import { map } from 'rxjs/operators';
17
-
18
- const BASE_MODULE_CONFIG = new InjectionToken('BASE_MODULE_CONFIG');
19
-
20
- /**
21
- * Storage service for local data storage
22
- */
23
- class StorageService {
24
- /**
25
- * Initializations
26
- */
27
- constructor(moduleConfig) {
28
- this.moduleConfig = moduleConfig;
29
- /**
30
- * Storage
31
- */
32
- this.storage = null;
33
- /**
34
- * Prefix for storage keys
35
- */
36
- this.prefix = '';
37
- // Set storage
38
- const type = moduleConfig.storageType ? moduleConfig.storageType : 'local';
39
- if (window[type + 'Storage']) {
40
- this.storage = window[type + 'Storage'];
41
- }
42
- // Set prefix
43
- this.prefix = '';
44
- if (moduleConfig.prefix) {
45
- this.prefix += moduleConfig.prefix + '_';
46
- }
47
- if (moduleConfig.version) {
48
- this.prefix += moduleConfig.version + '_';
49
- }
50
- }
51
- /**
52
- * Save itemKeys
53
- *
54
- * If you want to save one item, use itemKeys and value parameters like these:
55
- * save('KEY_OF_THE_ITEM', ITEM)
56
- *
57
- * If you want to save multiple items, use itemKeys only (value parameter will be ignored):
58
- * save({'KEY_OF_ITEM_1': ITEM_1, 'KEY_OF_ITEM_2': ITEM_2, ...})
59
- */
60
- save(itemKeys, value) {
61
- // Check local storage
62
- if (!this.storage) {
63
- return false;
64
- }
65
- // Check item keys and value
66
- if (!itemKeys ||
67
- (typeof itemKeys === 'object' && !Object.keys(itemKeys).length) ||
68
- (typeof itemKeys === 'string' && value === undefined)) {
69
- return false;
70
- }
71
- if (typeof itemKeys === 'object') {
72
- for (const [itemKey, itemValue] of Object.entries(itemKeys)) {
73
- this.storage.setItem(this.prefix + itemKey, JSON.stringify(itemValue));
74
- }
75
- return true;
76
- }
77
- this.storage.setItem(this.prefix + itemKeys, JSON.stringify(value));
78
- return true;
79
- }
80
- /**
81
- * Load items via key(s)
82
- */
83
- load(itemKeys) {
84
- // Check local storage
85
- if (!this.storage) {
86
- return;
87
- }
88
- // Check item keys
89
- if (!itemKeys || (Array.isArray(itemKeys) && !itemKeys.length)) {
90
- return null;
91
- }
92
- if (Array.isArray(itemKeys)) {
93
- const back = {};
94
- itemKeys.forEach((itemKey) => {
95
- const loadedItem = this.storage.getItem(this.prefix + itemKey);
96
- if (loadedItem) {
97
- back[itemKey] = JSON.parse(loadedItem);
98
- }
99
- else {
100
- back[itemKey] = null;
101
- }
102
- });
103
- return back;
104
- }
105
- let value = this.storage.getItem(this.prefix + itemKeys);
106
- if (value) {
107
- value = JSON.parse(value);
108
- }
109
- return value;
110
- }
111
- /**
112
- * Remove item from storage
113
- *
114
- * @param itemKeys keys or key to remove
115
- */
116
- remove(itemKeys) {
117
- // Check local storage
118
- if (!this.storage) {
119
- return false;
120
- }
121
- if (Array.isArray(itemKeys)) {
122
- itemKeys.forEach((key) => {
123
- this.storage.removeItem(this.prefix + key);
124
- });
125
- return true;
126
- }
127
- this.storage.removeItem(this.prefix + itemKeys);
128
- return true;
129
- }
130
- /**
131
- * Clear local storage
132
- */
133
- reset() {
134
- this.storage.clear();
135
- }
136
- }
137
- StorageService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.3", ngImport: i0, type: StorageService, deps: [{ token: BASE_MODULE_CONFIG }], target: i0.ɵɵFactoryTarget.Injectable });
138
- StorageService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.3.3", ngImport: i0, type: StorageService, providedIn: 'root' });
139
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.3", ngImport: i0, type: StorageService, decorators: [{
140
- type: Injectable,
141
- args: [{
142
- providedIn: 'root',
143
- }]
144
- }], ctorParameters: function () { return [{ type: undefined, decorators: [{
145
- type: Inject,
146
- args: [BASE_MODULE_CONFIG]
147
- }] }]; } });
148
-
149
- class WsService {
150
- reconnect() {
151
- this.client?.close();
152
- this.client?.connect();
153
- }
154
- }
155
- WsService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.3", ngImport: i0, type: WsService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
156
- WsService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.3.3", ngImport: i0, type: WsService, providedIn: 'root' });
157
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.3", ngImport: i0, type: WsService, decorators: [{
158
- type: Injectable,
159
- args: [{
160
- providedIn: 'root',
161
- }]
162
- }] });
163
-
164
- /**
165
- * Authentication service
166
- */
167
- class AuthService {
168
- /**
169
- * Constructor
170
- */
171
- constructor(moduleConfig, storageService, wsService) {
172
- this.moduleConfig = moduleConfig;
173
- this.storageService = storageService;
174
- this.wsService = wsService;
175
- // Subjects
176
- this._currentUser = new BehaviorSubject(null);
177
- this._token = new BehaviorSubject(null);
178
- this.token = this.storageService.load('token');
179
- this.currentUser = this.storageService.load('currentUser');
180
- }
181
- /**
182
- * Logout
183
- */
184
- logout() {
185
- this.storageService.remove(['token', 'currentUser']);
186
- this.currentUser = null;
187
- this.token = null;
188
- }
189
- // #################################################################
190
- // Current User
191
- // #################################################################
192
- get currentUser() {
193
- return this._currentUser.value;
194
- }
195
- set currentUser(user) {
196
- this._currentUser.next(user);
197
- this.storageService.save('currentUser', user);
198
- }
199
- get currentUserObservable() {
200
- return this._currentUser.asObservable();
201
- }
202
- // #################################################################
203
- // Token
204
- // #################################################################
205
- get token() {
206
- return this._token.value;
207
- }
208
- set token(token) {
209
- this._token.next(token);
210
- this.storageService.save('token', token);
211
- this.wsService.reconnect();
212
- }
213
- get tokenObservable() {
214
- return this._token.asObservable();
215
- }
216
- }
217
- AuthService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.3", ngImport: i0, type: AuthService, deps: [{ token: BASE_MODULE_CONFIG }, { token: StorageService }, { token: WsService }], target: i0.ɵɵFactoryTarget.Injectable });
218
- AuthService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.3.3", ngImport: i0, type: AuthService, providedIn: 'root' });
219
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.3", ngImport: i0, type: AuthService, decorators: [{
220
- type: Injectable,
221
- args: [{
222
- providedIn: 'root',
223
- }]
224
- }], ctorParameters: function () { return [{ type: undefined, decorators: [{
225
- type: Inject,
226
- args: [BASE_MODULE_CONFIG]
227
- }] }, { type: StorageService }, { type: WsService }]; } });
228
16
 
229
17
  /**
230
18
  * Factory for apollo-angular options
231
19
  */
232
20
  function apolloOptionsFactory(baseModuleConfig, httpLink, authService, wsService) {
233
21
  const links = [];
234
- const defaultUrl = 'api.' + window.location.href + '/graphql';
235
22
  const http = httpLink.create({
236
- uri: baseModuleConfig.apiUrl ? baseModuleConfig.apiUrl : 'https://' + defaultUrl,
23
+ uri: baseModuleConfig.apiUrl,
237
24
  });
238
25
  const authMiddleware = new ApolloLink((operation, forward) => {
239
26
  const headers = {};
@@ -246,18 +33,20 @@ function apolloOptionsFactory(baseModuleConfig, httpLink, authService, wsService
246
33
  }
247
34
  return forward(operation);
248
35
  });
36
+ if (baseModuleConfig.logging) {
37
+ console.log(baseModuleConfig);
38
+ }
249
39
  if (baseModuleConfig.wsUrl) {
250
- const wsLink = new WebSocketLink({
251
- uri: baseModuleConfig.wsUrl,
252
- options: {
253
- reconnect: true,
254
- connectionParams: () => ({
40
+ const wsLink = new GraphQLWsLink(createRestartableClient({
41
+ url: baseModuleConfig.wsUrl,
42
+ connectionParams: () => {
43
+ return {
255
44
  Authorization: authService.token ? 'Bearer ' + authService.token : undefined,
256
- }),
45
+ };
257
46
  },
258
- });
47
+ }));
259
48
  // Set client for reconnection on logout/login
260
- wsService.client = wsLink.subscriptionClient;
49
+ wsService.client = wsLink.client;
261
50
  // using the ability to split links, you can send data to each link
262
51
  // depending on what kind of operation is being sent
263
52
  links.push(split(
@@ -433,409 +222,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.3", ngImpor
433
222
  type: Input
434
223
  }] } });
435
224
 
436
- /**
437
- * Helper class
438
- */
439
- class Helper {
440
- /**
441
- * Simple filter function for plain objects
442
- */
443
- static filter(objects, filter) {
444
- return (objects?.filter((element) => {
445
- for (const [key, value] of Object.entries(filter)) {
446
- if (Array.isArray(element[key])) {
447
- for (const item of element[key]) {
448
- if (!element[key].includs(value)) {
449
- return false;
450
- }
451
- }
452
- }
453
- else if (element[key] !== value) {
454
- return false;
455
- }
456
- }
457
- return true;
458
- }) || []);
459
- }
460
- /**
461
- * Convert to a url/uri conform string
462
- * Only:
463
- * - lower case
464
- * - chars, numbers and hyphens
465
- */
466
- static urlString(str, options = {}) {
467
- // Config
468
- const config = {
469
- allowAll: false,
470
- ...options,
471
- };
472
- // To string
473
- str = str + '';
474
- // Trim
475
- str = str.trim();
476
- // Lower case
477
- str = str.toLowerCase();
478
- if (!config.allowAll) {
479
- // Replace spaces
480
- str = str.trim().replace(/\s+/g, '-');
481
- // Replace some special chars
482
- str = str.replace('ä', 'ae');
483
- str = str.replace('ö', 'oe');
484
- str = str.replace('ü', 'ue');
485
- str = str.replace('ß', 'ss');
486
- // Remove other special chars
487
- str = str.replace(/[^a-zA-Z0-9-]/g, '');
488
- }
489
- // Return url conform string
490
- return encodeURI(str);
491
- }
492
- /**
493
- * Simple map function
494
- */
495
- static map(source, target, options = {}) {
496
- // Set config
497
- const config = {
498
- funcAllowed: false,
499
- dateStringToDate: true,
500
- ...options,
501
- };
502
- // Check source
503
- if (!source || typeof source !== 'object' || Array.isArray(source)) {
504
- return target;
505
- }
506
- // Update properties
507
- for (const key of Object.keys(target)) {
508
- if (source[key] !== undefined && (config.funcAllowed || typeof (source[key] !== 'function'))) {
509
- if (typeof source[key] === 'string' && config.dateStringToDate) {
510
- if (Array.isArray(config.dateStringToDate)) {
511
- if (config.dateStringToDate.includes(key)) {
512
- target[key] = Helper.parseDate(source[key]);
513
- }
514
- }
515
- else {
516
- target[key] = Helper.parseDate(source[key]);
517
- }
518
- }
519
- else {
520
- target[key] = source[key];
521
- }
522
- }
523
- }
524
- // Return target
525
- return target;
526
- }
527
- /**
528
- * Create Object or Objects of specified type with specified data
529
- */
530
- static maps(data, targetClass) {
531
- // Check data
532
- if (!data || typeof data !== 'object') {
533
- return undefined;
534
- }
535
- // Check array
536
- if (!Array.isArray(data)) {
537
- data = [data];
538
- }
539
- // Map
540
- return data.map((item) => {
541
- return targetClass.map(item);
542
- });
543
- }
544
- /**
545
- * Get plain parameter
546
- */
547
- static getPlainParameter(parameter) {
548
- if (!parameter) {
549
- return parameter;
550
- }
551
- return parameter?.split('?')?.shift()?.split('#')?.shift();
552
- }
553
- /**
554
- * Get ID of an url parameter
555
- */
556
- static getParameterId(parameter) {
557
- if (!parameter) {
558
- return parameter;
559
- }
560
- return Helper.getPlainParameter(parameter)?.split('-').pop();
561
- }
562
- /**
563
- * Delay
564
- */
565
- static delay(ms) {
566
- const promise = new Promise((resolve) => setTimeout(resolve, ms));
567
- return promise;
568
- }
569
- /**
570
- * Deep freeze
571
- * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze#What_is_shallow_freeze
572
- */
573
- static deepFreeze(object, preparedObjects = []) {
574
- // Prevent infinit regress
575
- if (preparedObjects.includes(object)) {
576
- return object;
577
- }
578
- preparedObjects.push(object);
579
- // Retrieve the property names defined on object
580
- const propNames = Object.getOwnPropertyNames(object);
581
- // Freeze properties before freezing self
582
- for (const name of propNames) {
583
- const value = object[name];
584
- if (value && typeof value === 'object') {
585
- Helper.deepFreeze(value, preparedObjects);
586
- }
587
- }
588
- return Object.freeze(object);
589
- }
590
- /**
591
- * Generates an unique identifier with 24 characters
592
- */
593
- static getUID() {
594
- let dt = new Date().getTime();
595
- const uuid = 'xxxxxxxxxxxxxxxxxxxxxxxx'.replace(/[xy]/g, (c) => {
596
- // eslint-disable-next-line no-bitwise
597
- const r = (dt + Math.random() * 16) % 16 | 0;
598
- dt = Math.floor(dt / 16);
599
- // eslint-disable-next-line no-bitwise
600
- return (c === 'x' ? r : (r & 0x3) | 0x8).toString(16);
601
- });
602
- return uuid;
603
- }
604
- /**
605
- * Parse date string to date object
606
- */
607
- static parseDate(dateString) {
608
- const reISO = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*))(?:Z|(\+|-)([\d|:]*))?$/;
609
- const reMsAjax = /^\/Date\((d|-|.*)\)[\/|\\]$/;
610
- if (typeof dateString === 'string') {
611
- const isoExec = reISO.exec(dateString);
612
- if (isoExec) {
613
- return new Date(dateString);
614
- }
615
- const msAjaxExec = reMsAjax.exec(dateString);
616
- if (msAjaxExec) {
617
- const cleaned = msAjaxExec[1].split(/[-+,.]/);
618
- return new Date(cleaned[0] ? +cleaned[0] : 0 - +cleaned[1]);
619
- }
620
- }
621
- return dateString;
622
- }
623
- /**
624
- * Get browser name and version
625
- */
626
- static getBrowser() {
627
- const userAgent = navigator.userAgent;
628
- let data = userAgent.match(/(opera|chrome|safari|firefox|msie|trident(?=\/))\/?\s*(\d+)/i) || [];
629
- let version;
630
- if (/trident/i.test(data[1])) {
631
- version = /\brv[ :]+(\d+)/g.exec(userAgent) || [];
632
- return { name: 'IE', version: version[1] || '' };
633
- }
634
- if (data[1] === 'Chrome') {
635
- version = userAgent.match(/\bOPR|Edge\/(\d+)/);
636
- if (version != null) {
637
- return { name: 'Opera', version: version[1] };
638
- }
639
- }
640
- data = data[2] ? [data[1], data[2]] : [navigator.appName, navigator.appVersion, '-?'];
641
- version = userAgent.match(/version\/(\d+)/i);
642
- if (version !== null) {
643
- data.splice(1, 1, version[1]);
644
- }
645
- return {
646
- name: data[0],
647
- version: data[1],
648
- };
649
- }
650
- /**
651
- * Whether first parameter is a deep subset of second parameter
652
- * Hint: functions will be ignored
653
- */
654
- static isSubset(a, b) {
655
- // Equal
656
- if (a === b) {
657
- return true;
658
- }
659
- // Different type
660
- if (typeof a !== typeof b) {
661
- return false;
662
- }
663
- // Process array
664
- if (Array.isArray(a)) {
665
- for (const [key, value] of Object.entries(a)) {
666
- if (Helper.isSubset(value, b[key])) {
667
- return false;
668
- }
669
- }
670
- return true;
671
- }
672
- // Process object
673
- if (typeof a === 'object') {
674
- const plain = JSON.parse(JSON.stringify(a));
675
- for (const [key, value] of Object.entries(plain)) {
676
- if (Helper.isSubset(value, b[key])) {
677
- return false;
678
- }
679
- }
680
- return true;
681
- }
682
- // Else
683
- return true;
684
- }
685
- /**
686
- * Whether parameters are equal (have equal properties)
687
- * Hint: functions will be ignored
688
- */
689
- static isEqual(a, b) {
690
- return Helper.isSubset(a, b) && Helper.isSubset(b, a);
691
- }
692
- /**
693
- * First level difference of two objects
694
- * Hint: functions will be ignored and when an array or an object is different the hole array or object will used as property value
695
- *
696
- * @returns Record<string, any> Object with properties from first object
697
- */
698
- static getDiff(a, b, clone = true) {
699
- const result = {};
700
- let firstObject = a;
701
- if (clone) {
702
- firstObject = JSON.parse(JSON.stringify(a));
703
- }
704
- for (const [key, value] of Object.entries(firstObject)) {
705
- if (!Helper.isSubset(value, b[key])) {
706
- result[key] = value;
707
- }
708
- }
709
- return result;
710
- }
711
- /**
712
- * Check if propertie is type of HTMLCollection or NodeList
713
- * See https://stackoverflow.com/a/7238344
714
- *
715
- * @param nodes
716
- */
717
- static isNodeList(nodes) {
718
- try {
719
- const stringRepr = Object.prototype.toString.call(nodes);
720
- return (typeof nodes === 'object' &&
721
- /^\[object (HTMLCollection|NodeList|Object)\]$/.test(stringRepr) &&
722
- typeof nodes.length === 'number' &&
723
- (nodes.length === 0 || (typeof nodes[0] === 'object' && nodes[0].nodeType > 0)));
724
- }
725
- catch (e) {
726
- return false;
727
- }
728
- }
729
- static arrayBufferToBase64(buffer) {
730
- let binary = '';
731
- const bytes = new Uint8Array(buffer);
732
- const len = bytes.byteLength;
733
- for (let i = 0; i < len; i++) {
734
- binary += String.fromCharCode(bytes[i]);
735
- }
736
- return `data:image/*;base64, ${window.btoa(binary)}`;
737
- }
738
- }
739
-
740
- /**
741
- * Image service
742
- */
743
- class ImageService {
744
- /**
745
- * Preaload images (for lazy handling)
746
- *
747
- * @param options
748
- * @protected
749
- */
750
- preLoadImages(options) {
751
- // Init configuration
752
- const config = {
753
- doneFunnction: undefined,
754
- elements: document,
755
- regExp: undefined,
756
- ...options,
757
- };
758
- return new Promise((resolve) => {
759
- // Convert element(s) into array
760
- if (!Array.isArray(config.elements)) {
761
- // NodeList or HTMLCollection
762
- if (Helper.isNodeList(config.elements)) {
763
- config.elements = Array.from(config.elements);
764
- }
765
- // Single element
766
- else {
767
- config.elements = [config.elements];
768
- }
769
- }
770
- // Init loading
771
- const promises = [];
772
- // Get all images
773
- let images = [];
774
- config.elements.forEach((element) => {
775
- images = images.concat(Array.from(element.getElementsByTagName('img')));
776
- });
777
- // Prepare images
778
- for (let image of images) {
779
- const src = image.getAttribute('src');
780
- // Check if changes are necessary and possible
781
- if ((image.complete && image.naturalHeight !== 0) || // already laoded
782
- !src || // Image has no src
783
- config.regExp?.test(src) // Test if src matches regular expression
784
- ) {
785
- continue;
786
- }
787
- // Replace lazy loading image with immediately loading image
788
- if (image.getAttribute('loading') === 'lazy') {
789
- const newImage = document.createElement('img');
790
- Array.from(image.attributes).forEach((attr) => {
791
- if (attr.name !== 'loading' && attr.name !== 'src') {
792
- newImage.setAttribute(attr.name, attr.value);
793
- }
794
- });
795
- image.replaceWith(newImage);
796
- image = newImage;
797
- }
798
- // Wait for laoding
799
- promises.push(this.loadImage(image, src));
800
- }
801
- // Wait until all images loaded
802
- Promise.all(promises)
803
- .catch((e) => console.error('Error during image loading', e))
804
- .finally(async () => {
805
- // Return result
806
- let result;
807
- if (config.doneFunnction) {
808
- result = await config.doneFunction();
809
- }
810
- resolve(result);
811
- });
812
- });
813
- }
814
- /**
815
- * Load image for image element
816
- *
817
- * @param imageElement
818
- * @param src
819
- * @protected
820
- */
821
- async loadImage(imageElement, src) {
822
- src = src || imageElement.src;
823
- return new Promise((resolve, reject) => {
824
- imageElement.onload = () => resolve(imageElement);
825
- imageElement.onerror = reject;
826
- imageElement.src = src;
827
- });
828
- }
829
- }
830
- ImageService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.3", ngImport: i0, type: ImageService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
831
- ImageService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.3.3", ngImport: i0, type: ImageService, providedIn: 'root' });
832
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.3", ngImport: i0, type: ImageService, decorators: [{
833
- type: Injectable,
834
- args: [{
835
- providedIn: 'root',
836
- }]
837
- }] });
838
-
839
225
  /**
840
226
  * Set same height (maximum) to different elements
841
227
  */
@@ -892,14 +278,14 @@ class MatchHeightDirective {
892
278
  }
893
279
  }
894
280
  }
895
- MatchHeightDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.3", ngImport: i0, type: MatchHeightDirective, deps: [{ token: i0.ElementRef }, { token: ImageService }, { token: PLATFORM_ID }], target: i0.ɵɵFactoryTarget.Directive });
281
+ MatchHeightDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.3", ngImport: i0, type: MatchHeightDirective, deps: [{ token: i0.ElementRef }, { token: i2.ImageService }, { token: PLATFORM_ID }], target: i0.ɵɵFactoryTarget.Directive });
896
282
  MatchHeightDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.3.3", type: MatchHeightDirective, selector: "[ltMatchHeight]", inputs: { ltMatchHeight: "ltMatchHeight", loadImages: "loadImages" }, host: { listeners: { "window:resize": "onResize()" } }, ngImport: i0 });
897
283
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.3", ngImport: i0, type: MatchHeightDirective, decorators: [{
898
284
  type: Directive,
899
285
  args: [{
900
286
  selector: '[ltMatchHeight]',
901
287
  }]
902
- }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: ImageService }, { type: undefined, decorators: [{
288
+ }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i2.ImageService }, { type: undefined, decorators: [{
903
289
  type: Inject,
904
290
  args: [PLATFORM_ID]
905
291
  }] }]; }, propDecorators: { ltMatchHeight: [{
@@ -1122,7 +508,7 @@ class BaseModule {
1122
508
  static forRoot(baseModuleConfig = {}, AppAuthService) {
1123
509
  // Default config
1124
510
  const config = {
1125
- apiUrl: 'localhost:3000',
511
+ apiUrl: '',
1126
512
  authGuardRedirectUrl: '/auth',
1127
513
  logging: false,
1128
514
  version: null,
@@ -1132,11 +518,14 @@ class BaseModule {
1132
518
  storageType: 'local',
1133
519
  ...baseModuleConfig,
1134
520
  };
521
+ if (config.logging) {
522
+ console.log('Config:', config);
523
+ }
1135
524
  // Prepare providers
1136
525
  const providers = [
1137
526
  {
1138
527
  provide: BASE_MODULE_CONFIG,
1139
- useValue: baseModuleConfig,
528
+ useValue: config,
1140
529
  },
1141
530
  ];
1142
531
  // Add apollo features if API URL is set
@@ -1167,7 +556,7 @@ BaseModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "13
1167
556
  // Pipes
1168
557
  EllipsesPipe,
1169
558
  SafeHtmlPipe,
1170
- DateAgoPipe], exports: [
559
+ DateAgoPipe], imports: [ApolloModule, HttpClientModule], exports: [
1171
560
  // Directives
1172
561
  ContextMenuDirective,
1173
562
  LazyLoadDirective,
@@ -1176,320 +565,43 @@ BaseModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "13
1176
565
  // Pipes
1177
566
  EllipsesPipe,
1178
567
  SafeHtmlPipe,
1179
- DateAgoPipe] });
1180
- BaseModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "13.3.3", ngImport: i0, type: BaseModule });
568
+ DateAgoPipe, ApolloModule, HttpClientModule] });
569
+ BaseModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "13.3.3", ngImport: i0, type: BaseModule, imports: [[ApolloModule, HttpClientModule], ApolloModule, HttpClientModule] });
1181
570
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.3", ngImport: i0, type: BaseModule, decorators: [{
1182
571
  type: NgModule,
1183
572
  args: [{
573
+ imports: [ApolloModule, HttpClientModule],
1184
574
  declarations: elements,
1185
- exports: elements,
575
+ exports: [...elements, ApolloModule, HttpClientModule],
1186
576
  }]
1187
577
  }] });
1188
578
 
579
+ function debounce(delay = 300) {
580
+ return function (target, propertyKey, descriptor) {
581
+ let timeout = null;
582
+ const original = descriptor.value;
583
+ descriptor.value = function (...args) {
584
+ clearTimeout(timeout);
585
+ timeout = setTimeout(() => original.apply(this, args), delay);
586
+ };
587
+ return descriptor;
588
+ };
589
+ }
590
+
1189
591
  /**
1190
- * Standard class
1191
- * Other classes should extend the Standard class, if they offer own functions
1192
- * If the extended class uses object properties with own map functions, it should implement its own map function
592
+ * Authentication guard
1193
593
  */
1194
- class Standard {
1195
- /**
1196
- * Static map method
1197
- */
1198
- static map(data, item = new this()) {
1199
- return item.map(data);
1200
- }
1201
- /**
1202
- * Map data into an object
1203
- */
1204
- map(data) {
1205
- return Helper.map(data, this);
1206
- }
594
+ class AuthGuard {
1207
595
  /**
1208
- * Clone object (and map additional data)
596
+ * Imports
1209
597
  */
1210
- clone(mapData) {
1211
- const current = JSON.parse(JSON.stringify(this));
1212
- if (mapData) {
1213
- Object.assign(current, mapData);
1214
- }
1215
- return new this.constructor().map(current);
598
+ constructor(router, authService, moduleConfig) {
599
+ this.router = router;
600
+ this.authService = authService;
601
+ this.moduleConfig = moduleConfig;
1216
602
  }
1217
603
  /**
1218
- * Compare this with another object
1219
- * Hint: functions will be ignored and when an array or an object is different the hole array or object will used as property value
1220
- *
1221
- * @return Record<string, any> with properties of this object which are different
1222
- */
1223
- getDiff(compare, clone = true) {
1224
- return Helper.getDiff(this, compare, clone);
1225
- }
1226
- }
1227
-
1228
- /**
1229
- * User class
1230
- */
1231
- class BasicUser extends Standard {
1232
- constructor() {
1233
- super(...arguments);
1234
- this.id = undefined;
1235
- this.email = undefined;
1236
- this.firstName = undefined;
1237
- this.lastName = undefined;
1238
- this.roles = [];
1239
- this.username = undefined;
1240
- }
1241
- // ===================================================================================================================
1242
- // Methods
1243
- // ===================================================================================================================
1244
- /**
1245
- * Mapping
1246
- */
1247
- map(data) {
1248
- Helper.map(data, this);
1249
- return this;
1250
- }
1251
- /**
1252
- * Checks whether the user has at least one of the required roles
1253
- */
1254
- hasRole(roles) {
1255
- if (typeof roles === 'string') {
1256
- roles = [roles];
1257
- }
1258
- if (!this.roles || this.roles.length < 1) {
1259
- return false;
1260
- }
1261
- return !roles || roles.length < 1 ? true : this.roles.some((role) => roles.includes(role));
1262
- }
1263
- /**
1264
- * Checks whether the user has all required roles
1265
- */
1266
- hasAllRoles(roles) {
1267
- if (typeof roles === 'string') {
1268
- roles = [roles];
1269
- }
1270
- if (!this.roles || this.roles.length < 1) {
1271
- return false;
1272
- }
1273
- return !roles ? true : roles.every((role) => this.roles.includes(role));
1274
- }
1275
- }
1276
-
1277
- /**
1278
- * GraphQL enum
1279
- */
1280
- class GraphQLEnum {
1281
- constructor(value) {
1282
- this.value = value;
1283
- }
1284
- }
1285
-
1286
- /**
1287
- * GraphQL type
1288
- */
1289
- class GraphQLType extends Standard {
1290
- constructor() {
1291
- super(...arguments);
1292
- this.type = '';
1293
- this.isEnum = false;
1294
- this.validEnums = [];
1295
- }
1296
- }
1297
-
1298
- /**
1299
- * GraphQL meta
1300
- */
1301
- class GraphQLMeta {
1302
- /**
1303
- * Integrate schema
1304
- */
1305
- constructor(schema) {
1306
- this.schema = schema;
1307
- // Frozen caches
1308
- this.args = {};
1309
- this.fields = {};
1310
- if (!schema) {
1311
- throw Error('Missing schema');
1312
- }
1313
- }
1314
- /**
1315
- * Get arguments of GraphQL function
1316
- */
1317
- getArgs(functionName, options = {}) {
1318
- const { cache, freeze, type } = {
1319
- cache: true,
1320
- freeze: true,
1321
- type: undefined,
1322
- ...options,
1323
- };
1324
- // Get cache
1325
- if (cache && freeze) {
1326
- const args = this.args[functionName + type];
1327
- if (args) {
1328
- return args;
1329
- }
1330
- }
1331
- const func = this.getFunction(functionName, { type });
1332
- const result = {};
1333
- if (func?.args) {
1334
- func.args.forEach((item) => {
1335
- result[item.name] = this.getDeepType(item.type);
1336
- });
1337
- }
1338
- // Set cache
1339
- if (freeze) {
1340
- this.args[functionName + type] = Helper.deepFreeze(result);
1341
- }
1342
- return result;
1343
- }
1344
- /**
1345
- * Get fields of GraphQL function
1346
- */
1347
- getFields(functionName, options = {}) {
1348
- const { cache, freeze, type } = {
1349
- cache: true,
1350
- freeze: true,
1351
- type: undefined,
1352
- ...options,
1353
- };
1354
- // Get cache
1355
- if (cache && freeze) {
1356
- const args = this.fields[functionName + type];
1357
- if (args) {
1358
- return args;
1359
- }
1360
- }
1361
- const func = this.getFunction(functionName, options);
1362
- const result = this.getDeepType(func.type);
1363
- // Set cache
1364
- if (freeze) {
1365
- this.fields[functionName + type] = Helper.deepFreeze(result);
1366
- }
1367
- return result;
1368
- }
1369
- /**
1370
- * Get GraphQL function
1371
- */
1372
- getFunction(name, options = {}) {
1373
- // Set config
1374
- const config = {
1375
- ...options,
1376
- };
1377
- // Init possible functions
1378
- let functions = {};
1379
- // If function type is set
1380
- if (config.type) {
1381
- const graphQLType = config.type.charAt(0).toUpperCase() + config.type.slice(1);
1382
- const type = this.schema.getType(graphQLType);
1383
- if (type) {
1384
- functions = type.getFields();
1385
- }
1386
- }
1387
- // If function type is not set
1388
- else {
1389
- ['Subscription', 'Mutation', 'Query'].forEach((item) => {
1390
- const type = this.schema.getType(item);
1391
- if (type) {
1392
- functions = {
1393
- ...functions,
1394
- ...(type.getFields() || {}),
1395
- };
1396
- }
1397
- });
1398
- }
1399
- // Get function via name
1400
- return functions[name];
1401
- }
1402
- /**
1403
- * Get type
1404
- */
1405
- getType(name) {
1406
- return this.schema.getType(name);
1407
- }
1408
- /**
1409
- * Get deep type data
1410
- */
1411
- getDeepType(type, prepared = new WeakMap()) {
1412
- // Check type
1413
- if (!type) {
1414
- return type;
1415
- }
1416
- // Infinite regress protection
1417
- const preparedObject = {};
1418
- // Check prepared
1419
- if (typeof type === 'object') {
1420
- const preparedType = prepared.get(type);
1421
- if (preparedType) {
1422
- return preparedType;
1423
- }
1424
- // Set prepared
1425
- prepared.set(type, preparedObject);
1426
- }
1427
- // Search deeper
1428
- if (type.ofType) {
1429
- const ofTypeResult = this.getDeepType(type.ofType, prepared);
1430
- Object.assign(preparedObject, ofTypeResult);
1431
- return ofTypeResult;
1432
- }
1433
- // Process fields
1434
- if (type._fields) {
1435
- const result = {};
1436
- for (const [key, value] of Object.entries(type._fields)) {
1437
- result[key] = this.getDeepType(value, prepared);
1438
- }
1439
- Object.assign(preparedObject, result);
1440
- return result;
1441
- }
1442
- // Get type name
1443
- if (type.type) {
1444
- const typeResult = this.getDeepType(type.type, prepared);
1445
- Object.assign(preparedObject, typeResult);
1446
- return typeResult;
1447
- }
1448
- // Initialize GraphQLType
1449
- const graphqlType = GraphQLType.map({
1450
- type: type.name,
1451
- });
1452
- // Set enum values
1453
- if (!!type._values) {
1454
- graphqlType.isEnum = true;
1455
- for (const [key, value] of Object.entries(type._nameLookup)) {
1456
- if (!value.isDeprecated) {
1457
- graphqlType.validEnums.push(key);
1458
- }
1459
- }
1460
- }
1461
- // Finish
1462
- prepared.set(type, graphqlType);
1463
- return graphqlType;
1464
- }
1465
- }
1466
-
1467
- function debounce(delay = 300) {
1468
- return function (target, propertyKey, descriptor) {
1469
- let timeout = null;
1470
- const original = descriptor.value;
1471
- descriptor.value = function (...args) {
1472
- clearTimeout(timeout);
1473
- timeout = setTimeout(() => original.apply(this, args), delay);
1474
- };
1475
- return descriptor;
1476
- };
1477
- }
1478
-
1479
- /**
1480
- * Authentication guard
1481
- */
1482
- class AuthGuard {
1483
- /**
1484
- * Imports
1485
- */
1486
- constructor(router, authService, moduleConfig) {
1487
- this.router = router;
1488
- this.authService = authService;
1489
- this.moduleConfig = moduleConfig;
1490
- }
1491
- /**
1492
- * Can activate main route
604
+ * Can activate main route
1493
605
  */
1494
606
  canActivate(route, state) {
1495
607
  return new Observable((subscriber) => {
@@ -1522,11 +634,11 @@ class AuthGuard {
1522
634
  return this.canActivate(route, state);
1523
635
  }
1524
636
  }
1525
- AuthGuard.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.3", ngImport: i0, type: AuthGuard, deps: [{ token: i1$1.Router }, { token: AuthService }, { token: BASE_MODULE_CONFIG }], target: i0.ɵɵFactoryTarget.Injectable });
637
+ AuthGuard.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.3", ngImport: i0, type: AuthGuard, deps: [{ token: i1$1.Router }, { token: i2.AuthService }, { token: BASE_MODULE_CONFIG }], target: i0.ɵɵFactoryTarget.Injectable });
1526
638
  AuthGuard.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.3.3", ngImport: i0, type: AuthGuard });
1527
639
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.3", ngImport: i0, type: AuthGuard, decorators: [{
1528
640
  type: Injectable
1529
- }], ctorParameters: function () { return [{ type: i1$1.Router }, { type: AuthService }, { type: undefined, decorators: [{
641
+ }], ctorParameters: function () { return [{ type: i1$1.Router }, { type: i2.AuthService }, { type: undefined, decorators: [{
1530
642
  type: Inject,
1531
643
  args: [BASE_MODULE_CONFIG]
1532
644
  }] }]; } });
@@ -1566,76 +678,11 @@ class LogoutGuard {
1566
678
  return this.canActivate(route, state);
1567
679
  }
1568
680
  }
1569
- LogoutGuard.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.3", ngImport: i0, type: LogoutGuard, deps: [{ token: i1$1.Router }, { token: AuthService }], target: i0.ɵɵFactoryTarget.Injectable });
681
+ LogoutGuard.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.3", ngImport: i0, type: LogoutGuard, deps: [{ token: i1$1.Router }, { token: i2.AuthService }], target: i0.ɵɵFactoryTarget.Injectable });
1570
682
  LogoutGuard.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.3.3", ngImport: i0, type: LogoutGuard });
1571
683
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.3", ngImport: i0, type: LogoutGuard, decorators: [{
1572
684
  type: Injectable
1573
- }], ctorParameters: function () { return [{ type: i1$1.Router }, { type: AuthService }]; } });
1574
-
1575
- /**
1576
- * Comparison operator enum
1577
- */
1578
- var ComparisonOperatorEnum;
1579
- (function (ComparisonOperatorEnum) {
1580
- ComparisonOperatorEnum["EQ"] = "EQ";
1581
- ComparisonOperatorEnum["GT"] = "GT";
1582
- ComparisonOperatorEnum["GTE"] = "GTE";
1583
- ComparisonOperatorEnum["IN"] = "IN";
1584
- ComparisonOperatorEnum["LT"] = "LT";
1585
- ComparisonOperatorEnum["LTE"] = "LTE";
1586
- ComparisonOperatorEnum["NE"] = "NE";
1587
- ComparisonOperatorEnum["NIN"] = "NIN";
1588
- ComparisonOperatorEnum["REGEX"] = "REGEX";
1589
- })(ComparisonOperatorEnum || (ComparisonOperatorEnum = {}));
1590
-
1591
- /**
1592
- * GraphQL request type enum
1593
- */
1594
- var GraphQLRequestType;
1595
- (function (GraphQLRequestType) {
1596
- GraphQLRequestType["QUERY"] = "query";
1597
- GraphQLRequestType["MUTATION"] = "mutation";
1598
- GraphQLRequestType["SUBSCRIPTION"] = "subscription";
1599
- })(GraphQLRequestType || (GraphQLRequestType = {}));
1600
-
1601
- /**
1602
- * Logical operator enum
1603
- */
1604
- var LogicalOperatorEnum;
1605
- (function (LogicalOperatorEnum) {
1606
- LogicalOperatorEnum["AND"] = "AND";
1607
- LogicalOperatorEnum["NOR"] = "NOR";
1608
- LogicalOperatorEnum["OR"] = "OR";
1609
- })(LogicalOperatorEnum || (LogicalOperatorEnum = {}));
1610
-
1611
- var SortOrderEnum;
1612
- (function (SortOrderEnum) {
1613
- SortOrderEnum["ASC"] = "ASC";
1614
- SortOrderEnum["DESC"] = "DESC";
1615
- })(SortOrderEnum || (SortOrderEnum = {}));
1616
-
1617
- class FormsService {
1618
- constructor() { }
1619
- validateAllFormFields(formGroup) {
1620
- Object.keys(formGroup.controls).forEach((field) => {
1621
- const control = formGroup.get(field);
1622
- if (control instanceof FormControl) {
1623
- control.markAsTouched({ onlySelf: true });
1624
- }
1625
- else if (control instanceof FormGroup) {
1626
- this.validateAllFormFields(control);
1627
- }
1628
- });
1629
- }
1630
- }
1631
- FormsService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.3", ngImport: i0, type: FormsService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
1632
- FormsService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.3.3", ngImport: i0, type: FormsService, providedIn: 'root' });
1633
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.3", ngImport: i0, type: FormsService, decorators: [{
1634
- type: Injectable,
1635
- args: [{
1636
- providedIn: 'root',
1637
- }]
1638
- }], ctorParameters: function () { return []; } });
685
+ }], ctorParameters: function () { return [{ type: i1$1.Router }, { type: i2.AuthService }]; } });
1639
686
 
1640
687
  /**
1641
688
  * Fullscreen service
@@ -1685,828 +732,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.3", ngImpor
1685
732
  }]
1686
733
  }], ctorParameters: function () { return []; } });
1687
734
 
1688
- /**
1689
- * GraphQL meta service
1690
- *
1691
- * For collecting meta information of the GraphQL API
1692
- */
1693
- class GraphQLMetaService {
1694
- /**
1695
- * Include services
1696
- */
1697
- constructor(apollo) {
1698
- this.apollo = apollo;
1699
- }
1700
- /**
1701
- * Getter of introspectionQuery
1702
- */
1703
- get introspectionQuery() {
1704
- return JSON.parse(JSON.stringify(this._introspectionQuery));
1705
- }
1706
- /**
1707
- * Get schema for API
1708
- * See https://www.apollographql.com/blog/three-ways-to-represent-your-graphql-schema-a41f4175100d
1709
- */
1710
- getSchema(options = {}) {
1711
- // Get configurations
1712
- const config = {
1713
- cache: true,
1714
- freeze: true,
1715
- ...options,
1716
- };
1717
- // Use caching
1718
- if (config.cache) {
1719
- if (config.freeze && this._frozenSchema) {
1720
- return of(this._frozenSchema);
1721
- }
1722
- if (this._introspectionQuery) {
1723
- return of(buildClientSchema(this.introspectionQuery));
1724
- }
1725
- if (config.freeze && this._frozenSchemaObservable) {
1726
- return this._frozenSchemaObservable;
1727
- }
1728
- else if (!config.freeze && this._schemaObservable) {
1729
- return this._schemaObservable;
1730
- }
1731
- }
1732
- // Request schema from server
1733
- const observable = this.apollo
1734
- .query({
1735
- query: gql(getIntrospectionQuery({ descriptions: false })),
1736
- })
1737
- .pipe(map((schema) => {
1738
- // Cache introspectionQuery
1739
- this._introspectionQuery = schema.data;
1740
- // Convert schema to GraphQLSchema
1741
- this._frozenSchema = Helper.deepFreeze(buildClientSchema(this.introspectionQuery));
1742
- // Return GraphQLSchema
1743
- if (config.freeze) {
1744
- return this._frozenSchema;
1745
- }
1746
- return buildClientSchema(schema.data);
1747
- }));
1748
- // Set observables
1749
- if (config.freeze) {
1750
- this._frozenSchemaObservable = observable;
1751
- }
1752
- else {
1753
- this._schemaObservable = observable;
1754
- }
1755
- // Return result
1756
- return observable;
1757
- }
1758
- /**
1759
- * Get meta for API
1760
- * See https://www.apollographql.com/blog/three-ways-to-represent-your-graphql-schema-a41f4175100d
1761
- */
1762
- getMeta(options = {}) {
1763
- // Get configurations
1764
- const config = {
1765
- cache: true,
1766
- log: false,
1767
- ...options,
1768
- };
1769
- // Use caching
1770
- if (config.cache) {
1771
- if (this._meta) {
1772
- return of(this._meta);
1773
- }
1774
- else if (this._metaObservable) {
1775
- return this._metaObservable;
1776
- }
1777
- }
1778
- // Request schema from server
1779
- const observable = this.getSchema(options).pipe(map((schema) => {
1780
- // Log
1781
- if (config.log) {
1782
- console.log({ schema });
1783
- }
1784
- this._meta = new GraphQLMeta(schema);
1785
- return this._meta;
1786
- }));
1787
- // Set observables
1788
- this._metaObservable = observable;
1789
- // Return result
1790
- return observable;
1791
- }
1792
- }
1793
- GraphQLMetaService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.3", ngImport: i0, type: GraphQLMetaService, deps: [{ token: i1$2.Apollo }], target: i0.ɵɵFactoryTarget.Injectable });
1794
- GraphQLMetaService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.3.3", ngImport: i0, type: GraphQLMetaService, providedIn: 'root' });
1795
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.3", ngImport: i0, type: GraphQLMetaService, decorators: [{
1796
- type: Injectable,
1797
- args: [{
1798
- providedIn: 'root',
1799
- }]
1800
- }], ctorParameters: function () { return [{ type: i1$2.Apollo }]; } });
1801
-
1802
- /**
1803
- * GraphQL service
1804
- */
1805
- class GraphQLService {
1806
- /**
1807
- * Include services
1808
- */
1809
- constructor(apollo, graphQLMetaService) {
1810
- this.apollo = apollo;
1811
- this.graphQLMetaService = graphQLMetaService;
1812
- }
1813
- /**
1814
- * GraphQL request
1815
- */
1816
- graphQl(graphql, options = {}) {
1817
- // Check arguments
1818
- if (!graphql) {
1819
- throwError('Missing graphql argument');
1820
- }
1821
- // Get config
1822
- const config = {
1823
- arguments: null,
1824
- fields: null,
1825
- log: false,
1826
- model: null,
1827
- type: GraphQLRequestType.QUERY,
1828
- ...options,
1829
- };
1830
- // Convert class to Object for arguments
1831
- if (typeof config.arguments === 'function') {
1832
- config.arguments = new config.arguments();
1833
- }
1834
- // Convert class to Object for fields
1835
- if (typeof config.fields === 'function') {
1836
- config.fields = new config.fields();
1837
- }
1838
- // Log
1839
- if (config.log) {
1840
- console.log({ config });
1841
- }
1842
- // Send request
1843
- return new Observable((subscriber) => {
1844
- // Get meta
1845
- this.graphQLMetaService.getMeta({ log: config.log }).subscribe((meta) => {
1846
- // Prepare fields
1847
- let fields;
1848
- let allowedFields;
1849
- // Log meta
1850
- if (config.log) {
1851
- console.log({ meta });
1852
- }
1853
- if (config.fields) {
1854
- allowedFields = meta.getFields(graphql, { type: config.type });
1855
- // Log meta
1856
- if (config.log) {
1857
- console.log({ allowedFields });
1858
- }
1859
- const fieldsData = this.prepareFields(config.fields, {
1860
- allowed: allowedFields,
1861
- });
1862
- // Log fields data
1863
- if (config.log) {
1864
- fieldsData.usedFields.sort();
1865
- fieldsData.schemaFields.sort();
1866
- const filtered = fieldsData.schemaFields.filter((field) => !fieldsData.usedFields.includes(field));
1867
- const unused = this.graphQLTypeCollectionToStringArray(allowedFields).filter((field) => !fieldsData.usedFields.includes(field));
1868
- console.log({ fieldsData, filtered, unused });
1869
- }
1870
- fields = fieldsData.fieldsString;
1871
- }
1872
- if (fields && !fields.startsWith('{')) {
1873
- fields = '{' + fields + '\n}';
1874
- }
1875
- // Log fields
1876
- if (config.log) {
1877
- console.log({ fields });
1878
- }
1879
- // Get allowed args
1880
- const allowedArgs = meta.getArgs(graphql, { type: config.type });
1881
- // Log allowed args
1882
- if (config.log) {
1883
- console.log({ allowedArgs });
1884
- }
1885
- const argsData = this.prepareArguments(config.arguments, {
1886
- allowed: allowedArgs,
1887
- });
1888
- // Log args data
1889
- if (config.log) {
1890
- argsData.usedArgs.sort();
1891
- argsData.schemaArgs.sort();
1892
- const filtered = argsData.schemaArgs.filter((field) => !argsData.usedArgs.includes(field));
1893
- const unused = this.graphQLTypeCollectionToStringArray(allowedArgs)
1894
- .sort()
1895
- .filter((field) => !argsData.usedArgs.includes(field));
1896
- console.log({ argsData, filtered, unused });
1897
- }
1898
- const args = argsData?.argsString || '';
1899
- // Log
1900
- if (config.log) {
1901
- console.log({ graphQL: graphql, args, fields, type: config.type });
1902
- }
1903
- // Prepare request
1904
- const documentNode = fields
1905
- ? gql(config.type + '{\n' + graphql + args + fields + '\n}')
1906
- : gql(config.type + '{\n' + graphql + args + '\n}');
1907
- // Log
1908
- if (config.log) {
1909
- console.log({ documentNode });
1910
- }
1911
- const request = {};
1912
- request[config.type] = documentNode;
1913
- // Log
1914
- if (config.log) {
1915
- console.log({ request });
1916
- }
1917
- let func;
1918
- if (config.type === GraphQLRequestType.MUTATION) {
1919
- func = 'mutate';
1920
- request[config.type] = documentNode;
1921
- }
1922
- else if (config.type === GraphQLRequestType.SUBSCRIPTION) {
1923
- func = 'subscribe';
1924
- request.query = documentNode;
1925
- }
1926
- else {
1927
- func = config.type;
1928
- request[config.type] = documentNode;
1929
- }
1930
- this.apollo[func](request).subscribe((result) => {
1931
- const data = result?.data?.[graphql] !== undefined ? result.data[graphql] : result;
1932
- // Direct data
1933
- if (!config.model) {
1934
- subscriber.next(data);
1935
- }
1936
- // Map data as array
1937
- else if (Array.isArray(data)) {
1938
- subscriber.next(data.map((item) => {
1939
- return config.model.map(item);
1940
- }));
1941
- }
1942
- // Map data
1943
- else {
1944
- subscriber.next(config.model.map(data));
1945
- }
1946
- if (config.type !== GraphQLRequestType.SUBSCRIPTION) {
1947
- // Done
1948
- subscriber.complete();
1949
- }
1950
- }, (error) => {
1951
- subscriber.error(error);
1952
- subscriber.complete();
1953
- });
1954
- });
1955
- });
1956
- }
1957
- /**
1958
- * Get fields / args from IGraphQLTypeCollection
1959
- */
1960
- graphQLTypeCollectionToStringArray(collection, current = '', result = [], cacheNode = []) {
1961
- if (collection) {
1962
- if (collection instanceof GraphQLType) {
1963
- result.push(current);
1964
- }
1965
- else {
1966
- if (current?.includes('.')) {
1967
- cacheNode.push(current.split('.')[1]);
1968
- }
1969
- else if (current) {
1970
- cacheNode.push(current);
1971
- }
1972
- for (const key of Object.keys(collection)) {
1973
- if (current === key || cacheNode.includes(key)) {
1974
- continue;
1975
- }
1976
- this.graphQLTypeCollectionToStringArray(collection[key], current ? current + '.' + key : key, result, cacheNode);
1977
- }
1978
- }
1979
- }
1980
- return result;
1981
- }
1982
- /**
1983
- * Prepare arguments for GraphQL request
1984
- */
1985
- prepareArguments(args, options = {}) {
1986
- // Init config variables
1987
- const { allowed, level, parent, schemaArgs, usedArgs } = {
1988
- allowed: null,
1989
- level: 1,
1990
- parent: '',
1991
- schemaArgs: [],
1992
- usedArgs: [],
1993
- ...options,
1994
- };
1995
- // Check args
1996
- if (args === undefined || args === null) {
1997
- return { argsString: '', schemaArgs, usedArgs };
1998
- }
1999
- // Init args
2000
- const result = [];
2001
- // Process array
2002
- if (Array.isArray(args)) {
2003
- const allowedKeys = allowed ? Object.keys(allowed) : null;
2004
- for (const item of args) {
2005
- let key = null;
2006
- if (allowed) {
2007
- if (allowed.length < 1) {
2008
- break;
2009
- }
2010
- key = allowedKeys?.shift();
2011
- }
2012
- // Process value
2013
- result.push(this.prepareArguments(item, {
2014
- allowed: key ? allowed[key] : null,
2015
- level: level + 1,
2016
- parent: parent + key + '.',
2017
- schemaArgs,
2018
- usedArgs,
2019
- }).argsString);
2020
- }
2021
- // Encapsulation of the array result
2022
- if (result.length) {
2023
- // Complete result, encapsulated via round brackets
2024
- if (level === 1) {
2025
- return { argsString: '(' + result.join(', ') + ')', schemaArgs, usedArgs };
2026
- }
2027
- // Deeper result part, encapsulated via square brackets
2028
- else {
2029
- return { argsString: '[' + result.join(', ') + ']', schemaArgs, usedArgs };
2030
- }
2031
- }
2032
- }
2033
- // Process object
2034
- else if (typeof args === 'object') {
2035
- // Check object is empty
2036
- if (args && Object.keys(args).length === 0 && Object.getPrototypeOf(args) === Object.prototype) {
2037
- return { argsString: '{}', schemaArgs, usedArgs };
2038
- }
2039
- // Process all object entries
2040
- for (const [key, value] of Object.entries(args)) {
2041
- // Init data for current entry
2042
- const currentKey = parent + key;
2043
- schemaArgs.push(currentKey);
2044
- // If the allowed key handling is enabled and the current key is not included in the list of allowed keys,
2045
- // the current key will be skipped
2046
- if (allowed && !allowed[key]) {
2047
- continue;
2048
- }
2049
- // Skip value if not exists
2050
- if (value === undefined || value === null) {
2051
- continue;
2052
- }
2053
- // Add current key to metadata
2054
- usedArgs.push(currentKey);
2055
- // Process GraphQLEnum
2056
- if (value instanceof GraphQLEnum) {
2057
- result.push(key + ':' + value.value);
2058
- continue;
2059
- }
2060
- // Process array
2061
- else if (Array.isArray(value)) {
2062
- result.push(key +
2063
- ': [' +
2064
- value.map((item) => this.prepareArguments(item, {
2065
- allowed: allowed[key],
2066
- level: level + 1,
2067
- parent: currentKey + '.',
2068
- schemaArgs,
2069
- usedArgs,
2070
- }).argsString) +
2071
- ']');
2072
- continue;
2073
- }
2074
- // Prepare additional result string
2075
- let additionalResult = key + ': ';
2076
- // Value is a date object
2077
- if (typeof value === 'object' && Object.prototype.toString.call(value) === '[object Date]') {
2078
- additionalResult += `"""${value.toString()}"""`;
2079
- }
2080
- // Value is a string
2081
- else if (typeof value === 'string') {
2082
- // Enum (doesn't need quotation marks)
2083
- if (allowed[key].isEnum) {
2084
- additionalResult += value;
2085
- }
2086
- // String
2087
- else {
2088
- additionalResult += `"""${value.replace(/"/g, '\\"')}"""`;
2089
- }
2090
- }
2091
- // Value is a simple boolean or a number
2092
- else if (typeof value === 'boolean' || typeof value === 'number') {
2093
- additionalResult += value;
2094
- }
2095
- // Others
2096
- else {
2097
- additionalResult += this.prepareArguments(value, {
2098
- allowed: allowed[key],
2099
- level: level + 1,
2100
- parent: currentKey + '.',
2101
- schemaArgs,
2102
- usedArgs,
2103
- }).argsString;
2104
- }
2105
- // Push deeper part into result array
2106
- result.push(additionalResult);
2107
- }
2108
- // Encapsulation of the object result
2109
- if (result.length) {
2110
- // Complete result, encapsulated via round brackets
2111
- if (level === 1) {
2112
- return { argsString: '(' + result.join(', ') + ')', schemaArgs, usedArgs };
2113
- }
2114
- // Deeper result part, encapsulated via curly brackets
2115
- else {
2116
- return { argsString: '{' + result.join(', ') + '}', schemaArgs, usedArgs };
2117
- }
2118
- }
2119
- }
2120
- // Prepare and process other / unknown values as JSON
2121
- else {
2122
- return { argsString: JSON.stringify(args), schemaArgs, usedArgs };
2123
- }
2124
- }
2125
- /**
2126
- * Prepare fields for GraphQL request
2127
- */
2128
- prepareFields(fields, options = {}) {
2129
- // Config
2130
- const { allowed, parent, schemaFields, spaces, tab, usedFields } = {
2131
- allowed: null,
2132
- parent: '',
2133
- schemaFields: [],
2134
- spaces: 2,
2135
- tab: 1,
2136
- usedFields: [],
2137
- ...options,
2138
- };
2139
- // Init fields string
2140
- let fieldsString = '';
2141
- // Check fields
2142
- if (!fields) {
2143
- return { fieldsString, schemaFields, usedFields };
2144
- }
2145
- // Process string
2146
- if (typeof fields === 'string') {
2147
- if (allowed &&
2148
- ((typeof allowed === 'string' && allowed !== fields) || (typeof allowed === 'object' && !allowed[fields]))) {
2149
- return { fieldsString, schemaFields, usedFields };
2150
- }
2151
- return { fieldsString: '\n' + ' '.repeat(spaces).repeat(tab) + fields, schemaFields, usedFields };
2152
- }
2153
- // Process array
2154
- else if (Array.isArray(fields)) {
2155
- for (const item of fields) {
2156
- if (typeof item === 'object') {
2157
- fieldsString =
2158
- fieldsString +
2159
- this.prepareFields(item, {
2160
- allowed,
2161
- parent,
2162
- spaces,
2163
- schemaFields,
2164
- tab: tab + 1,
2165
- usedFields,
2166
- }).fieldsString;
2167
- continue;
2168
- }
2169
- const currentPath = parent + item;
2170
- schemaFields.push(currentPath);
2171
- if (allowed && !allowed?.[item]) {
2172
- continue;
2173
- }
2174
- usedFields.push(currentPath);
2175
- fieldsString =
2176
- fieldsString +
2177
- this.prepareFields(item, {
2178
- allowed: typeof allowed?.[item] === 'object' && !(allowed?.[item] instanceof GraphQLType) ? allowed?.[item] : item,
2179
- parent: currentPath + '.',
2180
- spaces,
2181
- schemaFields,
2182
- tab: tab + 1,
2183
- usedFields,
2184
- }).fieldsString;
2185
- }
2186
- }
2187
- // Process object
2188
- else if (typeof fields === 'object') {
2189
- for (const [key, val] of Object.entries(fields)) {
2190
- const currentPath = parent + key;
2191
- schemaFields.push(currentPath);
2192
- if (allowed && !allowed[key]) {
2193
- continue;
2194
- }
2195
- usedFields.push(currentPath);
2196
- if (typeof val !== 'object' || !Object.keys(val).length) {
2197
- fieldsString = fieldsString + '\n' + ' '.repeat(spaces).repeat(tab) + key;
2198
- }
2199
- else {
2200
- fieldsString =
2201
- fieldsString +
2202
- '\n' +
2203
- ' '.repeat(spaces).repeat(tab) +
2204
- key +
2205
- ' ' +
2206
- '{' +
2207
- this.prepareFields(val, {
2208
- allowed: typeof allowed?.[key] === 'object' && !(allowed?.[key] instanceof GraphQLType) ? allowed?.[key] : key,
2209
- parent: currentPath + '.',
2210
- spaces,
2211
- schemaFields,
2212
- tab: tab + 1,
2213
- usedFields,
2214
- }).fieldsString +
2215
- '\n' +
2216
- ' '.repeat(spaces).repeat(tab) +
2217
- '}';
2218
- }
2219
- }
2220
- }
2221
- // Return result
2222
- return { fieldsString, schemaFields, usedFields };
2223
- }
2224
- }
2225
- GraphQLService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.3", ngImport: i0, type: GraphQLService, deps: [{ token: i1$2.Apollo }, { token: GraphQLMetaService }], target: i0.ɵɵFactoryTarget.Injectable });
2226
- GraphQLService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.3.3", ngImport: i0, type: GraphQLService, providedIn: 'root' });
2227
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.3", ngImport: i0, type: GraphQLService, decorators: [{
2228
- type: Injectable,
2229
- args: [{
2230
- providedIn: 'root',
2231
- }]
2232
- }], ctorParameters: function () { return [{ type: i1$2.Apollo }, { type: GraphQLMetaService }]; } });
2233
-
2234
- /**
2235
- * Loader service for loading indication
2236
- */
2237
- class LoaderService {
2238
- constructor() {
2239
- this.isLoading = new BehaviorSubject(false);
2240
- }
2241
- start() {
2242
- this.isLoading.next(true);
2243
- }
2244
- stop() {
2245
- this.isLoading.next(false);
2246
- }
2247
- getAsObservable() {
2248
- return this.isLoading.asObservable();
2249
- }
2250
- }
2251
- LoaderService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.3", ngImport: i0, type: LoaderService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
2252
- LoaderService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.3.3", ngImport: i0, type: LoaderService, providedIn: 'root' });
2253
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.3", ngImport: i0, type: LoaderService, decorators: [{
2254
- type: Injectable,
2255
- args: [{
2256
- providedIn: 'root',
2257
- }]
2258
- }] });
2259
-
2260
- /**
2261
- * GraphQL plus service, for extra error handling and loading indication
2262
- */
2263
- class GraphQLPlusService extends GraphQLService {
2264
- /**
2265
- * Include services
2266
- */
2267
- constructor(apollo, graphqlMetaService, loaderService) {
2268
- super(apollo, graphqlMetaService);
2269
- this.apollo = apollo;
2270
- this.graphqlMetaService = graphqlMetaService;
2271
- this.loaderService = loaderService;
2272
- }
2273
- graphQl(graphql, options = {}) {
2274
- this.handleLoader('start', options);
2275
- return new Observable((subscriber) => {
2276
- super.graphQl(graphql, options).subscribe((response) => {
2277
- if (response && response.errors) {
2278
- this.handleError(response.errors, options.excludedErrors);
2279
- subscriber.error(response);
2280
- this.handleLoader('stop', options);
2281
- subscriber.complete();
2282
- }
2283
- subscriber.next(response);
2284
- this.handleLoader('stop', options);
2285
- if (options.type !== GraphQLRequestType.SUBSCRIPTION) {
2286
- subscriber.complete();
2287
- }
2288
- }, (error) => {
2289
- if (!options.ignoreErrors) {
2290
- this.handleError(error, options.excludedErrors);
2291
- }
2292
- subscriber.error(error);
2293
- this.handleLoader('stop', options);
2294
- subscriber.complete();
2295
- });
2296
- });
2297
- }
2298
- handleLoader(state, options) {
2299
- if (options.loading) {
2300
- if (state === 'start') {
2301
- this.loaderService.start();
2302
- }
2303
- else if (state === 'stop') {
2304
- this.loaderService.stop();
2305
- }
2306
- }
2307
- }
2308
- handleError(error, excludedErrors = null) {
2309
- if (excludedErrors) {
2310
- if (Array.isArray(excludedErrors)) {
2311
- excludedErrors.forEach((excludedError) => {
2312
- if (error.message.includes(excludedError.toLowerCase())) {
2313
- return;
2314
- }
2315
- });
2316
- }
2317
- else if (error.message.toLowerCase().includes(excludedErrors?.toLowerCase())) {
2318
- return;
2319
- }
2320
- }
2321
- this.displayError(error);
2322
- }
2323
- displayError(error) {
2324
- console.error(error);
2325
- }
2326
- }
2327
- GraphQLPlusService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.3", ngImport: i0, type: GraphQLPlusService, deps: [{ token: i1$2.Apollo }, { token: GraphQLMetaService }, { token: LoaderService }], target: i0.ɵɵFactoryTarget.Injectable });
2328
- GraphQLPlusService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.3.3", ngImport: i0, type: GraphQLPlusService, providedIn: 'root' });
2329
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.3", ngImport: i0, type: GraphQLPlusService, decorators: [{
2330
- type: Injectable,
2331
- args: [{
2332
- providedIn: 'root',
2333
- }]
2334
- }], ctorParameters: function () { return [{ type: i1$2.Apollo }, { type: GraphQLMetaService }, { type: LoaderService }]; } });
2335
-
2336
- /**
2337
- * Scroll service for autoscroll to specific fragments
2338
- */
2339
- class ScrollService {
2340
- /**
2341
- * Initializer
2342
- */
2343
- constructor(router, moduleConfig, imageService) {
2344
- this.router = router;
2345
- this.moduleConfig = moduleConfig;
2346
- this.imageService = imageService;
2347
- /**
2348
- * Is a scroll listener set
2349
- *
2350
- * @protected
2351
- */
2352
- this.scrollListener = false;
2353
- /**
2354
- * Current scroll timer;
2355
- *
2356
- * @protected
2357
- */
2358
- this.scrollTimer = -1;
2359
- const config = {
2360
- scrollDetectionOffset: 200,
2361
- scrollOffset: 100,
2362
- scrollSamplingRate: 100,
2363
- ...moduleConfig,
2364
- };
2365
- this.detectionOffset = config.scrollDetectionOffset;
2366
- this.scrollOffset = config.scrollOffset;
2367
- this.scrollSamplingRate = config.scrollSamplingRate;
2368
- }
2369
- /**
2370
- * Scroll to structureElement with specific ID
2371
- */
2372
- async scrollTo(id, options = {}) {
2373
- // Prepare config
2374
- const config = {
2375
- checkUrl: false,
2376
- loadImagesBefore: true,
2377
- resetStyles: false,
2378
- setOverflow: true,
2379
- stopPropagation: true,
2380
- ...options,
2381
- };
2382
- // Check current URL
2383
- if (config.checkUrl && this.router.url !== '/' && !this.router.url.startsWith('/#')) {
2384
- await this.router.navigate(['/'], { fragment: id });
2385
- return !config.stopPropagation;
2386
- }
2387
- // Check if target element exits
2388
- const el = document.getElementById(id);
2389
- if (!el) {
2390
- console.error('Missing scroll element with ID:', id);
2391
- return !config.stopPropagation;
2392
- }
2393
- // Check if body overflow is visible
2394
- // This is necessary for scroll handling
2395
- const body = document.querySelector('body');
2396
- let undoOverflowChanges = false;
2397
- const scrollBodyStyles = JSON.parse(JSON.stringify(window.getComputedStyle(body)));
2398
- if (config.setOverflow && (scrollBodyStyles.overflowX !== 'visible' || scrollBodyStyles.overflowY !== 'visible')) {
2399
- // Set body overflow to visible
2400
- console.warn('Style of body element for overflowX and overflowY will be set to "visible" for scrolling!');
2401
- body.style.overflowX = 'visible';
2402
- body.style.overflowY = 'visible';
2403
- undoOverflowChanges = true;
2404
- }
2405
- // Load images before scrolling (once)
2406
- if (config.loadImagesBefore) {
2407
- await this.imageService.preLoadImages();
2408
- }
2409
- // Get get bounding rect of target element
2410
- const cords = el.getBoundingClientRect();
2411
- // Scroll to element
2412
- window.scrollBy({ top: cords.top - this.scrollOffset, behavior: 'smooth' });
2413
- await this.scrollDone({
2414
- doneFunction: () => {
2415
- // Undo changes
2416
- if (undoOverflowChanges && config.resetStyles) {
2417
- body.style.overflowX = scrollBodyStyles.overflowX;
2418
- body.style.overflowY = scrollBodyStyles.overflowY;
2419
- console.warn('Original style of body element for overflowX and overflowY is set.');
2420
- }
2421
- },
2422
- });
2423
- // Return stop propagation configuration
2424
- return !config.stopPropagation;
2425
- }
2426
- /**
2427
- * Get last active structureElement
2428
- */
2429
- getLastActiveElement(list) {
2430
- const currentScrollPosition = window.scrollY;
2431
- const elementsWithId = document.querySelectorAll('[id]');
2432
- let lastId = null;
2433
- let lastPosition = 0 - this.detectionOffset - 1;
2434
- elementsWithId.forEach((element) => {
2435
- const cords = element.getBoundingClientRect();
2436
- const top = cords.top + window.pageYOffset - this.detectionOffset;
2437
- if ((!list || !list.length || list.includes(element.id)) && // In list
2438
- top < currentScrollPosition && // In active area
2439
- lastPosition < top // Higher than the last one
2440
- ) {
2441
- lastId = element.id;
2442
- lastPosition = top;
2443
- }
2444
- });
2445
- return lastId;
2446
- }
2447
- /**
2448
- * Check if ID is active
2449
- */
2450
- isActive(id, list, isFirst) {
2451
- const lastActiveElement = this.getLastActiveElement(list);
2452
- return id === lastActiveElement || (lastActiveElement === null && isFirst);
2453
- }
2454
- /**
2455
- * Scroll done promise
2456
- */
2457
- async scrollDone(options = {}) {
2458
- // Init configuration
2459
- const config = {
2460
- doneFunction: undefined,
2461
- ...options,
2462
- };
2463
- // Wait for scroll done
2464
- await this.scrollDoneDetection();
2465
- // Get result
2466
- if (config.doneFunction) {
2467
- return config.doneFunction();
2468
- }
2469
- }
2470
- /**
2471
- * Scroll done detecton
2472
- *
2473
- * @protected
2474
- */
2475
- scrollDoneDetection() {
2476
- // Return current scroll promise (Singelton)
2477
- if (this.scrollPromise) {
2478
- return this.scrollPromise;
2479
- }
2480
- // Create current scroll promise
2481
- this.scrollPromise = new Promise((resolve) => {
2482
- this.scrollPromiseResolve = resolve;
2483
- if (this.scrollTimer !== -1) {
2484
- window.clearTimeout(this.scrollTimer);
2485
- }
2486
- this.scrollTimer = window.setTimeout(() => {
2487
- window.removeEventListener('scroll', this.scrollDoneDetection.bind(this));
2488
- this.scrollPromise = undefined;
2489
- resolve();
2490
- }, this.scrollSamplingRate);
2491
- });
2492
- // Lisitening to scroll event;
2493
- window.addEventListener('scroll', this.scrollDoneDetection.bind(this));
2494
- // Return promise
2495
- return this.scrollPromise;
2496
- }
2497
- }
2498
- ScrollService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.3", ngImport: i0, type: ScrollService, deps: [{ token: i1$1.Router }, { token: BASE_MODULE_CONFIG }, { token: ImageService }], target: i0.ɵɵFactoryTarget.Injectable });
2499
- ScrollService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.3.3", ngImport: i0, type: ScrollService, providedIn: 'root' });
2500
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.3", ngImport: i0, type: ScrollService, decorators: [{
2501
- type: Injectable,
2502
- args: [{
2503
- providedIn: 'root',
2504
- }]
2505
- }], ctorParameters: function () { return [{ type: i1$1.Router }, { type: undefined, decorators: [{
2506
- type: Inject,
2507
- args: [BASE_MODULE_CONFIG]
2508
- }] }, { type: ImageService }]; } });
2509
-
2510
735
  /**
2511
736
  * SEO service for setting HTML meta data
2512
737
  */
@@ -2631,36 +856,14 @@ class ThemeService {
2631
856
  }
2632
857
  }
2633
858
  }
2634
- ThemeService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.3", ngImport: i0, type: ThemeService, deps: [{ token: StorageService }], target: i0.ɵɵFactoryTarget.Injectable });
859
+ ThemeService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.3", ngImport: i0, type: ThemeService, deps: [{ token: i2.StorageService }], target: i0.ɵɵFactoryTarget.Injectable });
2635
860
  ThemeService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.3.3", ngImport: i0, type: ThemeService, providedIn: 'root' });
2636
861
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.3", ngImport: i0, type: ThemeService, decorators: [{
2637
862
  type: Injectable,
2638
863
  args: [{
2639
864
  providedIn: 'root',
2640
865
  }]
2641
- }], ctorParameters: function () { return [{ type: StorageService }]; } });
2642
-
2643
- /**
2644
- * Custom validator to check that two fields match
2645
- * (inspirated by https://jasonwatmore.com/post/2018/11/07/angular-7-reactive-forms-validation-example)
2646
- */
2647
- const MustMatch = (control) => {
2648
- return (formGroup) => {
2649
- const baseControl = control.get('password');
2650
- const matchingControl = control.get('passwordConfirm');
2651
- if (matchingControl.errors && !matchingControl.errors.mustMatch) {
2652
- // return if another validator has already found an error on the matchingControl
2653
- return null;
2654
- }
2655
- // set error on matchingControl if validation fails
2656
- if (baseControl.value !== matchingControl.value) {
2657
- return { mustMatch: true };
2658
- }
2659
- else {
2660
- return null;
2661
- }
2662
- };
2663
- };
866
+ }], ctorParameters: function () { return [{ type: i2.StorageService }]; } });
2664
867
 
2665
868
  /**
2666
869
  * Exports for public API
@@ -2670,5 +873,5 @@ const MustMatch = (control) => {
2670
873
  * Generated bundle index. Do not edit.
2671
874
  */
2672
875
 
2673
- export { AuthGuard, AuthService, BASE_MODULE_CONFIG, BaseModule, BasicUser, CanDeactivateGuard, ComparisonOperatorEnum, ContextMenuDirective, DateAgoPipe, EllipsesPipe, FormsService, FullscreenService, GraphQLEnum, GraphQLMeta, GraphQLMetaService, GraphQLPlusService, GraphQLRequestType, GraphQLService, GraphQLType, Helper, ImageService, LazyLoadDirective, LoaderService, LogicalOperatorEnum, LogoutGuard, MatchHeightDirective, MustMatch, ResizableDirective, SEOService, SafeHtmlPipe, ScrollService, SortOrderEnum, Standard, StorageService, ThemeService, WsService, apolloOptionsFactory, debounce };
876
+ export { AuthGuard, BaseModule, CanDeactivateGuard, ContextMenuDirective, DateAgoPipe, EllipsesPipe, FullscreenService, LazyLoadDirective, LogoutGuard, MatchHeightDirective, ResizableDirective, SEOService, SafeHtmlPipe, ThemeService, apolloOptionsFactory, debounce };
2674
877
  //# sourceMappingURL=lenne.tech-ng-base.mjs.map