@lenne.tech/ng-base 12.1.0 → 13.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 (203) hide show
  1. package/{esm2015/lenne.tech-ng-base.js → esm2020/lenne.tech-ng-base.mjs} +0 -0
  2. package/{esm2015/src/lib/base/base.module.js → esm2020/lib/base/base.module.mjs} +39 -8
  3. package/{esm2015/lib/base/classes/basic-user.class.js → esm2020/lib/base/classes/basic-user.class.mjs} +0 -0
  4. package/{esm2015/lib/base/classes/graphql-enum.class.js → esm2020/lib/base/classes/graphql-enum.class.mjs} +0 -0
  5. package/esm2020/lib/base/classes/graphql-meta.class.mjs +171 -0
  6. package/{esm2015/lib/base/classes/graphql-type.class.js → esm2020/lib/base/classes/graphql-type.class.mjs} +0 -0
  7. package/esm2020/lib/base/classes/helper.class.mjs +295 -0
  8. package/{esm2015/lib/base/classes/standard.class.js → esm2020/lib/base/classes/standard.class.mjs} +0 -0
  9. package/esm2020/lib/base/directives/context-menu.directive.mjs +109 -0
  10. package/esm2020/lib/base/directives/lazy-load.directive.mjs +45 -0
  11. package/esm2020/lib/base/directives/match-height.directive.mjs +79 -0
  12. package/esm2020/lib/base/directives/resizable.directive.mjs +90 -0
  13. package/{esm2015/lib/base/enums/comparison-operator.enum.js → esm2020/lib/base/enums/comparison-operator.enum.mjs} +0 -0
  14. package/{esm2015/lib/base/enums/graphql-request-type.enum.js → esm2020/lib/base/enums/graphql-request-type.enum.mjs} +0 -0
  15. package/{esm2015/lib/base/enums/logical-operator.enum.js → esm2020/lib/base/enums/logical-operator.enum.mjs} +0 -0
  16. package/{esm2015/lib/base/enums/sort-order.enum.js → esm2020/lib/base/enums/sort-order.enum.mjs} +0 -0
  17. package/{esm2015/lib/base/factories/apollo-options.factory.js → esm2020/lib/base/factories/apollo-options.factory.mjs} +0 -0
  18. package/esm2020/lib/base/guards/auth.guard.mjs +61 -0
  19. package/esm2020/lib/base/guards/can-deactivate.guard.mjs +16 -0
  20. package/esm2020/lib/base/guards/logout.guard.mjs +32 -0
  21. package/{esm2015/lib/base/index.js → esm2020/lib/base/index.mjs} +0 -0
  22. package/{esm2015/lib/base/interfaces/base-module-config.interface.js → esm2020/lib/base/interfaces/base-module-config.interface.mjs} +0 -0
  23. package/{esm2015/lib/base/interfaces/can-component-deactivate.interface.js → esm2020/lib/base/interfaces/can-component-deactivate.interface.mjs} +0 -0
  24. package/{esm2015/lib/base/interfaces/combined-filter-input.interface.js → esm2020/lib/base/interfaces/combined-filter-input.interface.mjs} +0 -0
  25. package/{esm2015/lib/base/interfaces/field-object.interface.js → esm2020/lib/base/interfaces/field-object.interface.mjs} +0 -0
  26. package/{esm2015/lib/base/interfaces/field.interface.js → esm2020/lib/base/interfaces/field.interface.mjs} +0 -0
  27. package/{esm2015/lib/base/interfaces/filter-input.interface.js → esm2020/lib/base/interfaces/filter-input.interface.mjs} +0 -0
  28. package/{esm2015/lib/base/interfaces/find-args.interface.js → esm2020/lib/base/interfaces/find-args.interface.mjs} +0 -0
  29. package/{esm2015/lib/base/interfaces/graphql-options.interface.js → esm2020/lib/base/interfaces/graphql-options.interface.mjs} +0 -0
  30. package/{esm2015/lib/base/interfaces/graphql-plus-options.interfacen.js → esm2020/lib/base/interfaces/graphql-plus-options.interfacen.mjs} +0 -0
  31. package/{esm2015/lib/base/interfaces/graphql-type-collection.interface.js → esm2020/lib/base/interfaces/graphql-type-collection.interface.mjs} +0 -0
  32. package/{esm2015/lib/base/interfaces/single-filter-input.interface.js → esm2020/lib/base/interfaces/single-filter-input.interface.mjs} +0 -0
  33. package/{esm2015/lib/base/interfaces/sort-input.interface.js → esm2020/lib/base/interfaces/sort-input.interface.mjs} +0 -0
  34. package/esm2020/lib/base/pipes/ellipses.pipe.mjs +22 -0
  35. package/esm2020/lib/base/pipes/safe-html.pipe.mjs +21 -0
  36. package/{esm2015/lib/base/public-api.js → esm2020/lib/base/public-api.mjs} +0 -0
  37. package/{esm2015/lib/base/services/auth.service.js → esm2020/lib/base/services/auth.service.mjs} +14 -17
  38. package/{esm2015/lib/base/services/fullscreen.service.js → esm2020/lib/base/services/fullscreen.service.mjs} +9 -8
  39. package/esm2020/lib/base/services/graphql-meta.service.mjs +123 -0
  40. package/esm2020/lib/base/services/graphql-plus.service.mjs +84 -0
  41. package/esm2020/lib/base/services/graphql.service.mjs +441 -0
  42. package/esm2020/lib/base/services/image.service.mjs +102 -0
  43. package/esm2020/lib/base/services/loader.service.mjs +29 -0
  44. package/esm2020/lib/base/services/scroll.service.mjs +179 -0
  45. package/esm2020/lib/base/services/seo.service.mjs +97 -0
  46. package/esm2020/lib/base/services/storage.service.mjs +132 -0
  47. package/esm2020/lib/base/services/ws.service.mjs +17 -0
  48. package/{esm2015/lib/base/types/storage.type.js → esm2020/lib/base/types/storage.type.mjs} +0 -0
  49. package/{esm2015/lib/base/validators/must-match.validator.js → esm2020/lib/base/validators/must-match.validator.mjs} +0 -0
  50. package/{esm2015/public-api.js → esm2020/public-api.mjs} +0 -0
  51. package/esm2020/src/lib/base/base.module.mjs +97 -0
  52. package/{esm2015/src/lib/base/classes/basic-user.class.js → esm2020/src/lib/base/classes/basic-user.class.mjs} +0 -0
  53. package/{esm2015/src/lib/base/classes/graphql-enum.class.js → esm2020/src/lib/base/classes/graphql-enum.class.mjs} +0 -0
  54. package/esm2020/src/lib/base/classes/graphql-meta.class.mjs +171 -0
  55. package/{esm2015/src/lib/base/classes/graphql-type.class.js → esm2020/src/lib/base/classes/graphql-type.class.mjs} +0 -0
  56. package/esm2020/src/lib/base/classes/helper.class.mjs +295 -0
  57. package/{esm2015/src/lib/base/classes/standard.class.js → esm2020/src/lib/base/classes/standard.class.mjs} +0 -0
  58. package/esm2020/src/lib/base/directives/context-menu.directive.mjs +109 -0
  59. package/esm2020/src/lib/base/directives/lazy-load.directive.mjs +45 -0
  60. package/esm2020/src/lib/base/directives/match-height.directive.mjs +79 -0
  61. package/esm2020/src/lib/base/directives/resizable.directive.mjs +90 -0
  62. package/{esm2015/src/lib/base/enums/comparison-operator.enum.js → esm2020/src/lib/base/enums/comparison-operator.enum.mjs} +0 -0
  63. package/{esm2015/src/lib/base/enums/graphql-request-type.enum.js → esm2020/src/lib/base/enums/graphql-request-type.enum.mjs} +0 -0
  64. package/{esm2015/src/lib/base/enums/logical-operator.enum.js → esm2020/src/lib/base/enums/logical-operator.enum.mjs} +0 -0
  65. package/{esm2015/src/lib/base/enums/sort-order.enum.js → esm2020/src/lib/base/enums/sort-order.enum.mjs} +0 -0
  66. package/{esm2015/src/lib/base/factories/apollo-options.factory.js → esm2020/src/lib/base/factories/apollo-options.factory.mjs} +0 -0
  67. package/esm2020/src/lib/base/guards/auth.guard.mjs +61 -0
  68. package/esm2020/src/lib/base/guards/can-deactivate.guard.mjs +16 -0
  69. package/esm2020/src/lib/base/guards/logout.guard.mjs +32 -0
  70. package/{esm2015/src/lib/base/interfaces/base-module-config.interface.js → esm2020/src/lib/base/interfaces/base-module-config.interface.mjs} +0 -0
  71. package/{esm2015/src/lib/base/interfaces/can-component-deactivate.interface.js → esm2020/src/lib/base/interfaces/can-component-deactivate.interface.mjs} +0 -0
  72. package/{esm2015/src/lib/base/interfaces/combined-filter-input.interface.js → esm2020/src/lib/base/interfaces/combined-filter-input.interface.mjs} +0 -0
  73. package/{esm2015/src/lib/base/interfaces/field-object.interface.js → esm2020/src/lib/base/interfaces/field-object.interface.mjs} +0 -0
  74. package/{esm2015/src/lib/base/interfaces/field.interface.js → esm2020/src/lib/base/interfaces/field.interface.mjs} +0 -0
  75. package/{esm2015/src/lib/base/interfaces/filter-input.interface.js → esm2020/src/lib/base/interfaces/filter-input.interface.mjs} +0 -0
  76. package/{esm2015/src/lib/base/interfaces/find-args.interface.js → esm2020/src/lib/base/interfaces/find-args.interface.mjs} +0 -0
  77. package/{esm2015/src/lib/base/interfaces/graphql-options.interface.js → esm2020/src/lib/base/interfaces/graphql-options.interface.mjs} +0 -0
  78. package/{esm2015/src/lib/base/interfaces/graphql-plus-options.interfacen.js → esm2020/src/lib/base/interfaces/graphql-plus-options.interfacen.mjs} +0 -0
  79. package/{esm2015/src/lib/base/interfaces/graphql-type-collection.interface.js → esm2020/src/lib/base/interfaces/graphql-type-collection.interface.mjs} +0 -0
  80. package/{esm2015/src/lib/base/interfaces/single-filter-input.interface.js → esm2020/src/lib/base/interfaces/single-filter-input.interface.mjs} +0 -0
  81. package/{esm2015/src/lib/base/interfaces/sort-input.interface.js → esm2020/src/lib/base/interfaces/sort-input.interface.mjs} +0 -0
  82. package/{esm2015/src/lib/base/lenne.tech-ng-base-src-lib-base.js → esm2020/src/lib/base/lenne.tech-ng-base-src-lib-base.mjs} +0 -0
  83. package/esm2020/src/lib/base/pipes/ellipses.pipe.mjs +22 -0
  84. package/esm2020/src/lib/base/pipes/safe-html.pipe.mjs +21 -0
  85. package/{esm2015/src/lib/base/public-api.js → esm2020/src/lib/base/public-api.mjs} +0 -0
  86. package/{esm2015/src/lib/base/services/auth.service.js → esm2020/src/lib/base/services/auth.service.mjs} +14 -17
  87. package/{esm2015/src/lib/base/services/fullscreen.service.js → esm2020/src/lib/base/services/fullscreen.service.mjs} +9 -8
  88. package/esm2020/src/lib/base/services/graphql-meta.service.mjs +123 -0
  89. package/esm2020/src/lib/base/services/graphql-plus.service.mjs +84 -0
  90. package/esm2020/src/lib/base/services/graphql.service.mjs +441 -0
  91. package/esm2020/src/lib/base/services/image.service.mjs +102 -0
  92. package/esm2020/src/lib/base/services/loader.service.mjs +29 -0
  93. package/esm2020/src/lib/base/services/scroll.service.mjs +179 -0
  94. package/esm2020/src/lib/base/services/seo.service.mjs +97 -0
  95. package/esm2020/src/lib/base/services/storage.service.mjs +132 -0
  96. package/esm2020/src/lib/base/services/ws.service.mjs +17 -0
  97. package/{esm2015/src/lib/base/types/storage.type.js → esm2020/src/lib/base/types/storage.type.mjs} +0 -0
  98. package/{esm2015/src/lib/base/validators/must-match.validator.js → esm2020/src/lib/base/validators/must-match.validator.mjs} +0 -0
  99. package/fesm2015/{lenne.tech-ng-base-src-lib-base.js → lenne.tech-ng-base-src-lib-base.mjs} +238 -195
  100. package/fesm2015/lenne.tech-ng-base-src-lib-base.mjs.map +1 -0
  101. package/fesm2015/{lenne.tech-ng-base.js → lenne.tech-ng-base.mjs} +238 -195
  102. package/fesm2015/lenne.tech-ng-base.mjs.map +1 -0
  103. package/fesm2020/lenne.tech-ng-base-src-lib-base.mjs +2524 -0
  104. package/fesm2020/lenne.tech-ng-base-src-lib-base.mjs.map +1 -0
  105. package/fesm2020/lenne.tech-ng-base.mjs +2526 -0
  106. package/fesm2020/lenne.tech-ng-base.mjs.map +1 -0
  107. package/lenne.tech-ng-base.d.ts +1 -0
  108. package/lib/base/base.module.d.ts +10 -0
  109. package/lib/base/classes/graphql-meta.class.d.ts +2 -4
  110. package/lib/base/directives/context-menu.directive.d.ts +3 -0
  111. package/lib/base/directives/lazy-load.directive.d.ts +3 -0
  112. package/lib/base/directives/match-height.directive.d.ts +3 -0
  113. package/lib/base/directives/resizable.directive.d.ts +3 -0
  114. package/lib/base/guards/auth.guard.d.ts +3 -0
  115. package/lib/base/guards/can-deactivate.guard.d.ts +3 -0
  116. package/lib/base/guards/logout.guard.d.ts +3 -0
  117. package/lib/base/pipes/ellipses.pipe.d.ts +3 -0
  118. package/lib/base/pipes/safe-html.pipe.d.ts +3 -0
  119. package/lib/base/services/auth.service.d.ts +3 -0
  120. package/lib/base/services/fullscreen.service.d.ts +3 -0
  121. package/lib/base/services/graphql-meta.service.d.ts +3 -0
  122. package/lib/base/services/graphql-plus.service.d.ts +3 -0
  123. package/lib/base/services/graphql.service.d.ts +3 -0
  124. package/lib/base/services/image.service.d.ts +3 -0
  125. package/lib/base/services/loader.service.d.ts +3 -0
  126. package/lib/base/services/scroll.service.d.ts +3 -0
  127. package/lib/base/services/seo.service.d.ts +3 -0
  128. package/lib/base/services/storage.service.d.ts +3 -0
  129. package/lib/base/services/ws.service.d.ts +3 -0
  130. package/package.json +34 -14
  131. package/src/lib/base/base.module.d.ts +10 -0
  132. package/src/lib/base/classes/graphql-meta.class.d.ts +2 -4
  133. package/src/lib/base/directives/context-menu.directive.d.ts +3 -0
  134. package/src/lib/base/directives/lazy-load.directive.d.ts +3 -0
  135. package/src/lib/base/directives/match-height.directive.d.ts +3 -0
  136. package/src/lib/base/directives/resizable.directive.d.ts +3 -0
  137. package/src/lib/base/guards/auth.guard.d.ts +3 -0
  138. package/src/lib/base/guards/can-deactivate.guard.d.ts +3 -0
  139. package/src/lib/base/guards/logout.guard.d.ts +3 -0
  140. package/src/lib/base/lenne.tech-ng-base-src-lib-base.d.ts +1 -0
  141. package/src/lib/base/package.json +5 -6
  142. package/src/lib/base/pipes/ellipses.pipe.d.ts +3 -0
  143. package/src/lib/base/pipes/safe-html.pipe.d.ts +3 -0
  144. package/src/lib/base/services/auth.service.d.ts +3 -0
  145. package/src/lib/base/services/fullscreen.service.d.ts +3 -0
  146. package/src/lib/base/services/graphql-meta.service.d.ts +3 -0
  147. package/src/lib/base/services/graphql-plus.service.d.ts +3 -0
  148. package/src/lib/base/services/graphql.service.d.ts +3 -0
  149. package/src/lib/base/services/image.service.d.ts +3 -0
  150. package/src/lib/base/services/loader.service.d.ts +3 -0
  151. package/src/lib/base/services/scroll.service.d.ts +3 -0
  152. package/src/lib/base/services/seo.service.d.ts +3 -0
  153. package/src/lib/base/services/storage.service.d.ts +3 -0
  154. package/src/lib/base/services/ws.service.d.ts +3 -0
  155. package/bundles/lenne.tech-ng-base-src-lib-base.umd.js +0 -3152
  156. package/bundles/lenne.tech-ng-base-src-lib-base.umd.js.map +0 -1
  157. package/bundles/lenne.tech-ng-base.umd.js +0 -3154
  158. package/bundles/lenne.tech-ng-base.umd.js.map +0 -1
  159. package/esm2015/lib/base/base.module.js +0 -66
  160. package/esm2015/lib/base/classes/graphql-meta.class.js +0 -156
  161. package/esm2015/lib/base/classes/helper.class.js +0 -290
  162. package/esm2015/lib/base/directives/context-menu.directive.js +0 -104
  163. package/esm2015/lib/base/directives/lazy-load.directive.js +0 -43
  164. package/esm2015/lib/base/directives/match-height.directive.js +0 -78
  165. package/esm2015/lib/base/directives/resizable.directive.js +0 -89
  166. package/esm2015/lib/base/guards/auth.guard.js +0 -61
  167. package/esm2015/lib/base/guards/can-deactivate.guard.js +0 -13
  168. package/esm2015/lib/base/guards/logout.guard.js +0 -33
  169. package/esm2015/lib/base/pipes/ellipses.pipe.js +0 -18
  170. package/esm2015/lib/base/pipes/safe-html.pipe.js +0 -20
  171. package/esm2015/lib/base/services/graphql-meta.service.js +0 -116
  172. package/esm2015/lib/base/services/graphql-plus.service.js +0 -90
  173. package/esm2015/lib/base/services/graphql.service.js +0 -423
  174. package/esm2015/lib/base/services/image.service.js +0 -99
  175. package/esm2015/lib/base/services/loader.service.js +0 -27
  176. package/esm2015/lib/base/services/scroll.service.js +0 -172
  177. package/esm2015/lib/base/services/seo.service.js +0 -100
  178. package/esm2015/lib/base/services/storage.service.js +0 -131
  179. package/esm2015/lib/base/services/ws.service.js +0 -16
  180. package/esm2015/src/lib/base/classes/graphql-meta.class.js +0 -156
  181. package/esm2015/src/lib/base/classes/helper.class.js +0 -290
  182. package/esm2015/src/lib/base/directives/context-menu.directive.js +0 -104
  183. package/esm2015/src/lib/base/directives/lazy-load.directive.js +0 -43
  184. package/esm2015/src/lib/base/directives/match-height.directive.js +0 -78
  185. package/esm2015/src/lib/base/directives/resizable.directive.js +0 -89
  186. package/esm2015/src/lib/base/guards/auth.guard.js +0 -61
  187. package/esm2015/src/lib/base/guards/can-deactivate.guard.js +0 -13
  188. package/esm2015/src/lib/base/guards/logout.guard.js +0 -33
  189. package/esm2015/src/lib/base/pipes/ellipses.pipe.js +0 -18
  190. package/esm2015/src/lib/base/pipes/safe-html.pipe.js +0 -20
  191. package/esm2015/src/lib/base/services/graphql-meta.service.js +0 -116
  192. package/esm2015/src/lib/base/services/graphql-plus.service.js +0 -90
  193. package/esm2015/src/lib/base/services/graphql.service.js +0 -423
  194. package/esm2015/src/lib/base/services/image.service.js +0 -99
  195. package/esm2015/src/lib/base/services/loader.service.js +0 -27
  196. package/esm2015/src/lib/base/services/scroll.service.js +0 -172
  197. package/esm2015/src/lib/base/services/seo.service.js +0 -100
  198. package/esm2015/src/lib/base/services/storage.service.js +0 -131
  199. package/esm2015/src/lib/base/services/ws.service.js +0 -16
  200. package/fesm2015/lenne.tech-ng-base-src-lib-base.js.map +0 -1
  201. package/fesm2015/lenne.tech-ng-base.js.map +0 -1
  202. package/lenne.tech-ng-base.metadata.json +0 -1
  203. package/src/lib/base/lenne.tech-ng-base-src-lib-base.metadata.json +0 -1
@@ -0,0 +1,2526 @@
1
+ import * as i1$2 from 'apollo-angular';
2
+ import { APOLLO_OPTIONS, gql } from 'apollo-angular';
3
+ import { HttpLink } from 'apollo-angular/http';
4
+ 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';
7
+ import { ApolloLink, split, concat } from '@apollo/client/core';
8
+ import { InMemoryCache } from '@apollo/client/cache';
9
+ import { WebSocketLink } from '@apollo/client/link/ws';
10
+ import { getMainDefinition } from '@apollo/client/utilities';
11
+ import { isPlatformBrowser } from '@angular/common';
12
+ import * as i1 from '@angular/platform-browser';
13
+ import * as i1$1 from '@angular/router';
14
+ import { buildClientSchema, getIntrospectionQuery } from 'graphql';
15
+ import { map } from 'rxjs/operators';
16
+
17
+ const BASE_MODULE_CONFIG = new InjectionToken('BASE_MODULE_CONFIG');
18
+
19
+ /**
20
+ * Storage service for local data storage
21
+ */
22
+ class StorageService {
23
+ /**
24
+ * Initializations
25
+ */
26
+ constructor(moduleConfig) {
27
+ this.moduleConfig = moduleConfig;
28
+ /**
29
+ * Storage
30
+ */
31
+ this.storage = null;
32
+ /**
33
+ * Prefix for storage keys
34
+ */
35
+ this.prefix = '';
36
+ // Set storage
37
+ const type = moduleConfig.storageType ? moduleConfig.storageType : 'local';
38
+ if (window[type + 'Storage']) {
39
+ this.storage = window[type + 'Storage'];
40
+ }
41
+ // Set prefix
42
+ this.prefix = '';
43
+ if (moduleConfig.prefix) {
44
+ this.prefix += moduleConfig.prefix + '_';
45
+ }
46
+ if (moduleConfig.version) {
47
+ this.prefix += moduleConfig.version + '_';
48
+ }
49
+ }
50
+ /**
51
+ * Save itemKeys
52
+ *
53
+ * If you want to save one item, use itemKeys and value parameters like these:
54
+ * save('KEY_OF_THE_ITEM', ITEM)
55
+ *
56
+ * If you want to save multiple items, use itemKeys only (value parameter will be ignored):
57
+ * save({'KEY_OF_ITEM_1': ITEM_1, 'KEY_OF_ITEM_2': ITEM_2, ...})
58
+ */
59
+ save(itemKeys, value) {
60
+ // Check local storage
61
+ if (!this.storage) {
62
+ return false;
63
+ }
64
+ // Check item keys and value
65
+ if (!itemKeys ||
66
+ (typeof itemKeys === 'object' && !Object.keys(itemKeys).length) ||
67
+ (typeof itemKeys === 'string' && value === undefined)) {
68
+ return false;
69
+ }
70
+ if (typeof itemKeys === 'object') {
71
+ for (const [itemKey, itemValue] of Object.entries(itemKeys)) {
72
+ this.storage.setItem(this.prefix + itemKey, JSON.stringify(itemValue));
73
+ }
74
+ return true;
75
+ }
76
+ this.storage.setItem(this.prefix + itemKeys, JSON.stringify(value));
77
+ return true;
78
+ }
79
+ /**
80
+ * Load items via key(s)
81
+ */
82
+ load(itemKeys) {
83
+ // Check local storage
84
+ if (!this.storage) {
85
+ return;
86
+ }
87
+ // Check item keys
88
+ if (!itemKeys || (Array.isArray(itemKeys) && !itemKeys.length)) {
89
+ return null;
90
+ }
91
+ if (Array.isArray(itemKeys)) {
92
+ const back = {};
93
+ itemKeys.forEach((itemKey) => {
94
+ const loadedItem = this.storage.getItem(this.prefix + itemKey);
95
+ if (loadedItem) {
96
+ back[itemKey] = JSON.parse(loadedItem);
97
+ }
98
+ else {
99
+ back[itemKey] = null;
100
+ }
101
+ });
102
+ return back;
103
+ }
104
+ let value = this.storage.getItem(this.prefix + itemKeys);
105
+ if (value) {
106
+ value = JSON.parse(value);
107
+ }
108
+ return value;
109
+ }
110
+ /**
111
+ * Remove item from storage
112
+ *
113
+ * @param itemKeys keys or key to remove
114
+ */
115
+ remove(itemKeys) {
116
+ // Check local storage
117
+ if (!this.storage) {
118
+ return false;
119
+ }
120
+ if (Array.isArray(itemKeys)) {
121
+ itemKeys.forEach((key) => {
122
+ this.storage.removeItem(this.prefix + key);
123
+ });
124
+ return true;
125
+ }
126
+ this.storage.removeItem(this.prefix + itemKeys);
127
+ return true;
128
+ }
129
+ /**
130
+ * Clear local storage
131
+ */
132
+ reset() {
133
+ this.storage.clear();
134
+ }
135
+ }
136
+ StorageService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.0", ngImport: i0, type: StorageService, deps: [{ token: BASE_MODULE_CONFIG }], target: i0.ɵɵFactoryTarget.Injectable });
137
+ StorageService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.3.0", ngImport: i0, type: StorageService, providedIn: 'root' });
138
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.0", ngImport: i0, type: StorageService, decorators: [{
139
+ type: Injectable,
140
+ args: [{
141
+ providedIn: 'root',
142
+ }]
143
+ }], ctorParameters: function () { return [{ type: undefined, decorators: [{
144
+ type: Inject,
145
+ args: [BASE_MODULE_CONFIG]
146
+ }] }]; } });
147
+
148
+ class WsService {
149
+ reconnect() {
150
+ this.client?.close();
151
+ this.client?.connect();
152
+ }
153
+ }
154
+ WsService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.0", ngImport: i0, type: WsService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
155
+ WsService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.3.0", ngImport: i0, type: WsService, providedIn: 'root' });
156
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.0", ngImport: i0, type: WsService, decorators: [{
157
+ type: Injectable,
158
+ args: [{
159
+ providedIn: 'root',
160
+ }]
161
+ }] });
162
+
163
+ /**
164
+ * Authentication service
165
+ */
166
+ class AuthService {
167
+ /**
168
+ * Constructor
169
+ */
170
+ constructor(moduleConfig, storageService, wsService) {
171
+ this.moduleConfig = moduleConfig;
172
+ this.storageService = storageService;
173
+ this.wsService = wsService;
174
+ // Subjects
175
+ this._currentUser = new BehaviorSubject(null);
176
+ this._token = new BehaviorSubject(null);
177
+ this.token = this.storageService.load('token');
178
+ this.currentUser = this.storageService.load('currentUser');
179
+ }
180
+ /**
181
+ * Logout
182
+ */
183
+ logout() {
184
+ this.storageService.remove(['token', 'currentUser']);
185
+ this.currentUser = null;
186
+ this.token = null;
187
+ }
188
+ // #################################################################
189
+ // Current User
190
+ // #################################################################
191
+ get currentUser() {
192
+ return this._currentUser.value;
193
+ }
194
+ set currentUser(user) {
195
+ this._currentUser.next(user);
196
+ this.storageService.save('currentUser', user);
197
+ }
198
+ get currentUserObservable() {
199
+ return this._currentUser.asObservable();
200
+ }
201
+ // #################################################################
202
+ // Token
203
+ // #################################################################
204
+ get token() {
205
+ return this._token.value;
206
+ }
207
+ set token(token) {
208
+ this._token.next(token);
209
+ this.storageService.save('token', token);
210
+ this.wsService.reconnect();
211
+ }
212
+ get tokenObservable() {
213
+ return this._token.asObservable();
214
+ }
215
+ }
216
+ AuthService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.0", ngImport: i0, type: AuthService, deps: [{ token: BASE_MODULE_CONFIG }, { token: StorageService }, { token: WsService }], target: i0.ɵɵFactoryTarget.Injectable });
217
+ AuthService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.3.0", ngImport: i0, type: AuthService, providedIn: 'root' });
218
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.0", ngImport: i0, type: AuthService, decorators: [{
219
+ type: Injectable,
220
+ args: [{
221
+ providedIn: 'root',
222
+ }]
223
+ }], ctorParameters: function () { return [{ type: undefined, decorators: [{
224
+ type: Inject,
225
+ args: [BASE_MODULE_CONFIG]
226
+ }] }, { type: StorageService }, { type: WsService }]; } });
227
+
228
+ /**
229
+ * Factory for apollo-angular options
230
+ */
231
+ function apolloOptionsFactory(baseModuleConfig, httpLink, authService, wsService) {
232
+ const links = [];
233
+ const defaultUrl = 'api.' + window.location.href + '/graphql';
234
+ const http = httpLink.create({
235
+ uri: baseModuleConfig.apiUrl ? baseModuleConfig.apiUrl : 'https://' + defaultUrl,
236
+ });
237
+ const authMiddleware = new ApolloLink((operation, forward) => {
238
+ const headers = {};
239
+ if (localStorage) {
240
+ const token = authService.token || null;
241
+ if (token) {
242
+ headers.Authorization = 'Bearer ' + token;
243
+ }
244
+ operation.setContext(() => ({ headers }));
245
+ }
246
+ return forward(operation);
247
+ });
248
+ if (baseModuleConfig.wsUrl) {
249
+ const wsLink = new WebSocketLink({
250
+ uri: baseModuleConfig.wsUrl,
251
+ options: {
252
+ reconnect: true,
253
+ connectionParams: () => ({
254
+ Authorization: authService.token ? 'Bearer ' + authService.token : undefined,
255
+ }),
256
+ },
257
+ });
258
+ // Set client for reconnection on logout/login
259
+ wsService.client = wsLink.subscriptionClient;
260
+ // using the ability to split links, you can send data to each link
261
+ // depending on what kind of operation is being sent
262
+ links.push(split(
263
+ // split based on operation type
264
+ ({ query }) => {
265
+ // @ts-ignore
266
+ const { kind, operation } = getMainDefinition(query);
267
+ return kind === 'OperationDefinition' && operation === 'subscription';
268
+ }, wsLink, concat(authMiddleware, http)));
269
+ }
270
+ else {
271
+ links.push(http);
272
+ links.push(authMiddleware);
273
+ }
274
+ return {
275
+ link: ApolloLink.from(links),
276
+ cache: new InMemoryCache(),
277
+ defaultOptions: {
278
+ query: {
279
+ fetchPolicy: 'network-only',
280
+ },
281
+ },
282
+ };
283
+ }
284
+
285
+ /**
286
+ * Directive vor context menu
287
+ * See https://stackblitz.com/edit/angular-custom-context-menu
288
+ */
289
+ class ContextMenuDirective {
290
+ constructor(el) {
291
+ this.el = el;
292
+ this.xGap = 0;
293
+ this.yGap = 0;
294
+ this.overflowSpace = 10;
295
+ this.selectors = '*';
296
+ this.clickedElement = null;
297
+ this.previousDisplayStatus = null;
298
+ }
299
+ ngOnInit() {
300
+ if (this.ltContextMenu) {
301
+ this.previousDisplayStatus = this.ltContextMenu.style.display;
302
+ }
303
+ // Add a click listener to the window,
304
+ // so that we can close the context menu on left click
305
+ window.addEventListener('click', () => {
306
+ this.showContextMenu(null, false);
307
+ });
308
+ // Close context menu when escape is pressed
309
+ window.addEventListener('keydown', (e) => {
310
+ if (e.code === 'Escape') {
311
+ this.showContextMenu(null, false);
312
+ }
313
+ });
314
+ // Add an event listener to listen to the 'contextmenu' event
315
+ this.el.nativeElement.addEventListener('contextmenu', (e) => {
316
+ // Prevent the default context menu to popup
317
+ if (e.preventDefault) {
318
+ e.preventDefault();
319
+ }
320
+ // Shows our own context menu
321
+ this.showContextMenu(e, true);
322
+ });
323
+ }
324
+ // Shows or hides our custom context menu, which is specified as a input
325
+ showContextMenu(event, show) {
326
+ const cm = this.ltContextMenu;
327
+ if (cm) {
328
+ // Try to open context menu
329
+ if (show && event && event instanceof MouseEvent) {
330
+ // Get valid clicked structureElement
331
+ const clickedElement = event?.target?.closest(this.selectors);
332
+ if (clickedElement) {
333
+ // Set clicked structureElement
334
+ this.clickedElement = clickedElement;
335
+ setTimeout(() => {
336
+ // Set display status
337
+ cm.style.display = 'block';
338
+ // Calculate top position
339
+ let top = event.y + this.yGap;
340
+ if (top + cm.offsetHeight + 10 > document.documentElement.clientHeight) {
341
+ top = document.documentElement.clientHeight - cm.offsetHeight - this.overflowSpace;
342
+ }
343
+ // Calculate left position
344
+ let left = event.x + this.xGap;
345
+ if (left + cm.offsetWidth + 10 > document.documentElement.clientWidth) {
346
+ left = document.documentElement.clientWidth - cm.offsetWidth - this.overflowSpace;
347
+ }
348
+ // Set position
349
+ cm.style.top = top + 'px';
350
+ cm.style.left = left + 'px';
351
+ // Show
352
+ cm.style.opacity = '1.0';
353
+ cm.style['pointer-events'] = 'auto';
354
+ }, 1);
355
+ return;
356
+ }
357
+ }
358
+ // Close context menu
359
+ this.clickedElement = null;
360
+ if (this.previousDisplayStatus) {
361
+ cm.style.display = this.previousDisplayStatus;
362
+ }
363
+ cm.style.opacity = '0.01';
364
+ cm.style['pointer-events'] = 'none';
365
+ }
366
+ }
367
+ }
368
+ ContextMenuDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.0", ngImport: i0, type: ContextMenuDirective, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive });
369
+ ContextMenuDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.3.0", type: ContextMenuDirective, selector: "[ltContextMenu]", inputs: { contextMenuData: "contextMenuData", ltContextMenu: "ltContextMenu", xGap: "xGap", yGap: "yGap", overflowSpace: "overflowSpace", selectors: "selectors" }, outputs: { clickedElement: "clickedElement" }, exportAs: ["contextMenuData"], ngImport: i0 });
370
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.0", ngImport: i0, type: ContextMenuDirective, decorators: [{
371
+ type: Directive,
372
+ args: [{
373
+ selector: '[ltContextMenu]',
374
+ exportAs: 'contextMenuData',
375
+ }]
376
+ }], ctorParameters: function () { return [{ type: i0.ElementRef }]; }, propDecorators: { contextMenuData: [{
377
+ type: Input
378
+ }], ltContextMenu: [{
379
+ type: Input
380
+ }], xGap: [{
381
+ type: Input
382
+ }], yGap: [{
383
+ type: Input
384
+ }], overflowSpace: [{
385
+ type: Input
386
+ }], selectors: [{
387
+ type: Input
388
+ }], clickedElement: [{
389
+ type: Output
390
+ }] } });
391
+
392
+ /**
393
+ * Directive for lazy loading images
394
+ */
395
+ class LazyLoadDirective {
396
+ constructor(el) {
397
+ this.el = el;
398
+ this.srcAttr = null;
399
+ }
400
+ ngAfterViewInit() {
401
+ this.canLazyLoad() ? this.lazyLoadImage() : this.loadImage();
402
+ }
403
+ canLazyLoad() {
404
+ return window && 'IntersectionObserver' in window;
405
+ }
406
+ lazyLoadImage() {
407
+ const obs = new IntersectionObserver((entries) => {
408
+ entries.forEach(({ isIntersecting }) => {
409
+ if (isIntersecting) {
410
+ this.loadImage();
411
+ obs.unobserve(this.el.nativeElement);
412
+ }
413
+ });
414
+ });
415
+ obs.observe(this.el.nativeElement);
416
+ }
417
+ loadImage() {
418
+ this.srcAttr = this.src;
419
+ }
420
+ }
421
+ LazyLoadDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.0", ngImport: i0, type: LazyLoadDirective, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive });
422
+ LazyLoadDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.3.0", type: LazyLoadDirective, selector: "img[ltLazyLoad]", inputs: { src: "src" }, host: { properties: { "attr.src": "this.srcAttr" } }, ngImport: i0 });
423
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.0", ngImport: i0, type: LazyLoadDirective, decorators: [{
424
+ type: Directive,
425
+ args: [{
426
+ selector: 'img[ltLazyLoad]',
427
+ }]
428
+ }], ctorParameters: function () { return [{ type: i0.ElementRef }]; }, propDecorators: { srcAttr: [{
429
+ type: HostBinding,
430
+ args: ['attr.src']
431
+ }], src: [{
432
+ type: Input
433
+ }] } });
434
+
435
+ /**
436
+ * Helper class
437
+ */
438
+ class Helper {
439
+ /**
440
+ * Simple filter function for plain objects
441
+ */
442
+ static filter(objects, filter) {
443
+ return (objects?.filter((element) => {
444
+ for (const [key, value] of Object.entries(filter)) {
445
+ if (Array.isArray(element[key])) {
446
+ for (const item of element[key]) {
447
+ if (!element[key].includs(value)) {
448
+ return false;
449
+ }
450
+ }
451
+ }
452
+ else if (element[key] !== value) {
453
+ return false;
454
+ }
455
+ }
456
+ return true;
457
+ }) || []);
458
+ }
459
+ /**
460
+ * Convert to a url/uri conform string
461
+ * Only:
462
+ * - lower case
463
+ * - chars, numbers and hyphens
464
+ */
465
+ static urlString(str, options = {}) {
466
+ // Config
467
+ const config = {
468
+ allowAll: false,
469
+ ...options,
470
+ };
471
+ // To string
472
+ str = str + '';
473
+ // Trim
474
+ str = str.trim();
475
+ // Lower case
476
+ str = str.toLowerCase();
477
+ if (!config.allowAll) {
478
+ // Replace spaces
479
+ str = str.trim().replace(/\s+/g, '-');
480
+ // Replace some special chars
481
+ str = str.replace('ä', 'ae');
482
+ str = str.replace('ö', 'oe');
483
+ str = str.replace('ü', 'ue');
484
+ str = str.replace('ß', 'ss');
485
+ // Remove other special chars
486
+ str = str.replace(/[^a-zA-Z0-9-]/g, '');
487
+ }
488
+ // Return url conform string
489
+ return encodeURI(str);
490
+ }
491
+ /**
492
+ * Simple map function
493
+ */
494
+ static map(source, target, options = {}) {
495
+ // Set config
496
+ const config = {
497
+ funcAllowed: false,
498
+ dateStringToDate: true,
499
+ ...options,
500
+ };
501
+ // Check source
502
+ if (!source || typeof source !== 'object' || Array.isArray(source)) {
503
+ return target;
504
+ }
505
+ // Update properties
506
+ for (const key of Object.keys(target)) {
507
+ if (source[key] !== undefined && (config.funcAllowed || typeof (source[key] !== 'function'))) {
508
+ if (typeof source[key] === 'string' && config.dateStringToDate) {
509
+ if (Array.isArray(config.dateStringToDate)) {
510
+ if (config.dateStringToDate.includes(key)) {
511
+ target[key] = Helper.parseDate(source[key]);
512
+ }
513
+ }
514
+ else {
515
+ target[key] = Helper.parseDate(source[key]);
516
+ }
517
+ }
518
+ else {
519
+ target[key] = source[key];
520
+ }
521
+ }
522
+ }
523
+ // Return target
524
+ return target;
525
+ }
526
+ /**
527
+ * Create Object or Objects of specified type with specified data
528
+ */
529
+ static maps(data, targetClass) {
530
+ // Check data
531
+ if (!data || typeof data !== 'object') {
532
+ return undefined;
533
+ }
534
+ // Check array
535
+ if (!Array.isArray(data)) {
536
+ data = [data];
537
+ }
538
+ // Map
539
+ return data.map((item) => {
540
+ return targetClass.map(item);
541
+ });
542
+ }
543
+ /**
544
+ * Get plain parameter
545
+ */
546
+ static getPlainParameter(parameter) {
547
+ if (!parameter) {
548
+ return parameter;
549
+ }
550
+ return parameter?.split('?')?.shift()?.split('#')?.shift();
551
+ }
552
+ /**
553
+ * Get ID of an url parameter
554
+ */
555
+ static getParameterId(parameter) {
556
+ if (!parameter) {
557
+ return parameter;
558
+ }
559
+ return Helper.getPlainParameter(parameter)?.split('-').pop();
560
+ }
561
+ /**
562
+ * Delay
563
+ */
564
+ static delay(ms) {
565
+ const promise = new Promise((resolve) => setTimeout(resolve, ms));
566
+ return promise;
567
+ }
568
+ /**
569
+ * Deep freeze
570
+ * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze#What_is_shallow_freeze
571
+ */
572
+ static deepFreeze(object, preparedObjects = []) {
573
+ // Prevent infinit regress
574
+ if (preparedObjects.includes(object)) {
575
+ return object;
576
+ }
577
+ preparedObjects.push(object);
578
+ // Retrieve the property names defined on object
579
+ const propNames = Object.getOwnPropertyNames(object);
580
+ // Freeze properties before freezing self
581
+ for (const name of propNames) {
582
+ const value = object[name];
583
+ if (value && typeof value === 'object') {
584
+ Helper.deepFreeze(value, preparedObjects);
585
+ }
586
+ }
587
+ return Object.freeze(object);
588
+ }
589
+ /**
590
+ * Generates an unique identifier with 24 characters
591
+ */
592
+ static getUID() {
593
+ let dt = new Date().getTime();
594
+ const uuid = 'xxxxxxxxxxxxxxxxxxxxxxxx'.replace(/[xy]/g, (c) => {
595
+ // eslint-disable-next-line no-bitwise
596
+ const r = (dt + Math.random() * 16) % 16 | 0;
597
+ dt = Math.floor(dt / 16);
598
+ // eslint-disable-next-line no-bitwise
599
+ return (c === 'x' ? r : (r & 0x3) | 0x8).toString(16);
600
+ });
601
+ return uuid;
602
+ }
603
+ /**
604
+ * Parse date string to date object
605
+ */
606
+ static parseDate(dateString) {
607
+ const reISO = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*))(?:Z|(\+|-)([\d|:]*))?$/;
608
+ const reMsAjax = /^\/Date\((d|-|.*)\)[\/|\\]$/;
609
+ if (typeof dateString === 'string') {
610
+ const isoExec = reISO.exec(dateString);
611
+ if (isoExec) {
612
+ return new Date(dateString);
613
+ }
614
+ const msAjaxExec = reMsAjax.exec(dateString);
615
+ if (msAjaxExec) {
616
+ const cleaned = msAjaxExec[1].split(/[-+,.]/);
617
+ return new Date(cleaned[0] ? +cleaned[0] : 0 - +cleaned[1]);
618
+ }
619
+ }
620
+ return dateString;
621
+ }
622
+ /**
623
+ * Get browser name and version
624
+ */
625
+ static getBrowser() {
626
+ const userAgent = navigator.userAgent;
627
+ let data = userAgent.match(/(opera|chrome|safari|firefox|msie|trident(?=\/))\/?\s*(\d+)/i) || [];
628
+ let version;
629
+ if (/trident/i.test(data[1])) {
630
+ version = /\brv[ :]+(\d+)/g.exec(userAgent) || [];
631
+ return { name: 'IE', version: version[1] || '' };
632
+ }
633
+ if (data[1] === 'Chrome') {
634
+ version = userAgent.match(/\bOPR|Edge\/(\d+)/);
635
+ if (version != null) {
636
+ return { name: 'Opera', version: version[1] };
637
+ }
638
+ }
639
+ data = data[2] ? [data[1], data[2]] : [navigator.appName, navigator.appVersion, '-?'];
640
+ version = userAgent.match(/version\/(\d+)/i);
641
+ if (version !== null) {
642
+ data.splice(1, 1, version[1]);
643
+ }
644
+ return {
645
+ name: data[0],
646
+ version: data[1],
647
+ };
648
+ }
649
+ /**
650
+ * Whether first parameter is a deep subset of second parameter
651
+ * Hint: functions will be ignored
652
+ */
653
+ static isSubset(a, b) {
654
+ // Equal
655
+ if (a === b) {
656
+ return true;
657
+ }
658
+ // Different type
659
+ if (typeof a !== typeof b) {
660
+ return false;
661
+ }
662
+ // Process array
663
+ if (Array.isArray(a)) {
664
+ for (const [key, value] of Object.entries(a)) {
665
+ if (Helper.isSubset(value, b[key])) {
666
+ return false;
667
+ }
668
+ }
669
+ return true;
670
+ }
671
+ // Process object
672
+ if (typeof a === 'object') {
673
+ const plain = JSON.parse(JSON.stringify(a));
674
+ for (const [key, value] of Object.entries(plain)) {
675
+ if (Helper.isSubset(value, b[key])) {
676
+ return false;
677
+ }
678
+ }
679
+ return true;
680
+ }
681
+ // Else
682
+ return true;
683
+ }
684
+ /**
685
+ * Whether parameters are equal (have equal properties)
686
+ * Hint: functions will be ignored
687
+ */
688
+ static isEqual(a, b) {
689
+ return Helper.isSubset(a, b) && Helper.isSubset(b, a);
690
+ }
691
+ /**
692
+ * First level difference of two objects
693
+ * Hint: functions will be ignored and when an array or an object is different the hole array or object will used as property value
694
+ *
695
+ * @returns Record<string, any> Object with properties from first object
696
+ */
697
+ static getDiff(a, b, clone = true) {
698
+ const result = {};
699
+ let firstObject = a;
700
+ if (clone) {
701
+ firstObject = JSON.parse(JSON.stringify(a));
702
+ }
703
+ for (const [key, value] of Object.entries(firstObject)) {
704
+ if (!Helper.isSubset(value, b[key])) {
705
+ result[key] = value;
706
+ }
707
+ }
708
+ return result;
709
+ }
710
+ /**
711
+ * Check if propertie is type of HTMLCollection or NodeList
712
+ * See https://stackoverflow.com/a/7238344
713
+ *
714
+ * @param nodes
715
+ */
716
+ static isNodeList(nodes) {
717
+ try {
718
+ const stringRepr = Object.prototype.toString.call(nodes);
719
+ return (typeof nodes === 'object' &&
720
+ /^\[object (HTMLCollection|NodeList|Object)\]$/.test(stringRepr) &&
721
+ typeof nodes.length === 'number' &&
722
+ (nodes.length === 0 || (typeof nodes[0] === 'object' && nodes[0].nodeType > 0)));
723
+ }
724
+ catch (e) {
725
+ return false;
726
+ }
727
+ }
728
+ }
729
+
730
+ /**
731
+ * Image service
732
+ */
733
+ class ImageService {
734
+ /**
735
+ * Preaload images (for lazy handling)
736
+ *
737
+ * @param options
738
+ * @protected
739
+ */
740
+ preLoadImages(options) {
741
+ // Init configuration
742
+ const config = {
743
+ doneFunnction: undefined,
744
+ elements: document,
745
+ regExp: undefined,
746
+ ...options,
747
+ };
748
+ return new Promise((resolve) => {
749
+ // Convert element(s) into array
750
+ if (!Array.isArray(config.elements)) {
751
+ // NodeList or HTMLCollection
752
+ if (Helper.isNodeList(config.elements)) {
753
+ config.elements = Array.from(config.elements);
754
+ }
755
+ // Single element
756
+ else {
757
+ config.elements = [config.elements];
758
+ }
759
+ }
760
+ // Init loading
761
+ const promises = [];
762
+ // Get all images
763
+ let images = [];
764
+ config.elements.forEach((element) => {
765
+ images = images.concat(Array.from(element.getElementsByTagName('img')));
766
+ });
767
+ // Prepare images
768
+ for (let image of images) {
769
+ const src = image.getAttribute('src');
770
+ // Check if changes are necessary and possible
771
+ if ((image.complete && image.naturalHeight !== 0) || // already laoded
772
+ !src || // Image has no src
773
+ config.regExp?.test(src) // Test if src matches regular expression
774
+ ) {
775
+ continue;
776
+ }
777
+ // Replace lazy loading image with immediately loading image
778
+ if (image.getAttribute('loading') === 'lazy') {
779
+ const newImage = document.createElement('img');
780
+ Array.from(image.attributes).forEach((attr) => {
781
+ if (attr.name !== 'loading' && attr.name !== 'src') {
782
+ newImage.setAttribute(attr.name, attr.value);
783
+ }
784
+ });
785
+ image.replaceWith(newImage);
786
+ image = newImage;
787
+ }
788
+ // Wait for laoding
789
+ promises.push(this.loadImage(image, src));
790
+ }
791
+ // Wait until all images loaded
792
+ Promise.all(promises)
793
+ .catch((e) => console.error('Error during image loading', e))
794
+ .finally(async () => {
795
+ // Return result
796
+ let result;
797
+ if (config.doneFunnction) {
798
+ result = await config.doneFunction();
799
+ }
800
+ resolve(result);
801
+ });
802
+ });
803
+ }
804
+ /**
805
+ * Load image for image element
806
+ *
807
+ * @param imageElement
808
+ * @param src
809
+ * @protected
810
+ */
811
+ async loadImage(imageElement, src) {
812
+ src = src || imageElement.src;
813
+ return new Promise((resolve, reject) => {
814
+ imageElement.onload = () => resolve(imageElement);
815
+ imageElement.onerror = reject;
816
+ imageElement.src = src;
817
+ });
818
+ }
819
+ }
820
+ ImageService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.0", ngImport: i0, type: ImageService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
821
+ ImageService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.3.0", ngImport: i0, type: ImageService, providedIn: 'root' });
822
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.0", ngImport: i0, type: ImageService, decorators: [{
823
+ type: Injectable,
824
+ args: [{
825
+ providedIn: 'root',
826
+ }]
827
+ }] });
828
+
829
+ /**
830
+ * Set same height (maximum) to different elements
831
+ */
832
+ class MatchHeightDirective {
833
+ constructor(el, imageService, platformId) {
834
+ this.el = el;
835
+ this.imageService = imageService;
836
+ // Replace lazy loading images with immediate loading images
837
+ this.loadImages = true;
838
+ this.isBrowser = isPlatformBrowser(platformId);
839
+ }
840
+ onResize() {
841
+ this.matchHeight(this.el.nativeElement, this.ltMatchHeight);
842
+ }
843
+ ngOnInit() {
844
+ this.matchHeight(this.el.nativeElement, this.ltMatchHeight);
845
+ }
846
+ async matchHeight(parent, target) {
847
+ if (!parent) {
848
+ return;
849
+ }
850
+ let classNames;
851
+ if (!Array.isArray(target)) {
852
+ classNames = [target];
853
+ }
854
+ else {
855
+ classNames = target;
856
+ }
857
+ for (const className of classNames) {
858
+ // find all child structureElements with the selected class name
859
+ const children = parent.getElementsByClassName(className);
860
+ if (!children || children.length < 2) {
861
+ continue;
862
+ }
863
+ // Load images of children
864
+ if (this.loadImages) {
865
+ await this.imageService.preLoadImages({ elements: children });
866
+ }
867
+ // reset all children height
868
+ Array.from(children).forEach((element) => {
869
+ element.style.height = 'initial';
870
+ });
871
+ // get all the child structureElements heights
872
+ const itemHeights = Array.from(children).map((element) => {
873
+ if (element.getBoundingClientRect) {
874
+ return element.getBoundingClientRect().height;
875
+ }
876
+ return 0;
877
+ });
878
+ // find out the tallest one
879
+ const maxHeight = itemHeights.reduce((prev, curr) => (curr > prev ? curr : prev), 0);
880
+ // update the child structureElements height to the tallest one
881
+ Array.from(children).forEach((element) => (element.style.height = `${maxHeight}px`));
882
+ }
883
+ }
884
+ }
885
+ MatchHeightDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.0", ngImport: i0, type: MatchHeightDirective, deps: [{ token: i0.ElementRef }, { token: ImageService }, { token: PLATFORM_ID }], target: i0.ɵɵFactoryTarget.Directive });
886
+ MatchHeightDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.3.0", type: MatchHeightDirective, selector: "[ltMatchHeight]", inputs: { ltMatchHeight: "ltMatchHeight", loadImages: "loadImages" }, host: { listeners: { "window:resize": "onResize()" } }, ngImport: i0 });
887
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.0", ngImport: i0, type: MatchHeightDirective, decorators: [{
888
+ type: Directive,
889
+ args: [{
890
+ selector: '[ltMatchHeight]',
891
+ }]
892
+ }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: ImageService }, { type: undefined, decorators: [{
893
+ type: Inject,
894
+ args: [PLATFORM_ID]
895
+ }] }]; }, propDecorators: { ltMatchHeight: [{
896
+ type: Input
897
+ }], loadImages: [{
898
+ type: Input
899
+ }], onResize: [{
900
+ type: HostListener,
901
+ args: ['window:resize']
902
+ }] } });
903
+
904
+ /**
905
+ * Reszise detection
906
+ * (inpsired by: https://stackblitz.com/edit/angular-resizable)
907
+ */
908
+ class ResizableDirective {
909
+ constructor(el) {
910
+ this.el = el;
911
+ this.resizableGrabWidth = 8;
912
+ this.resizableMinWidth = 10;
913
+ this.dragging = false;
914
+ }
915
+ ngOnInit() {
916
+ this.addListenerToDocument();
917
+ this.addListenerToElement();
918
+ }
919
+ mouseMoveG(evt) {
920
+ if (!this.dragging) {
921
+ return;
922
+ }
923
+ this.newWidth(evt.clientX - this.el.nativeElement.offsetLeft);
924
+ evt.stopPropagation();
925
+ }
926
+ newWidth(wid) {
927
+ const result = Math.max(this.resizableMinWidth, wid);
928
+ this.el.nativeElement.style.width = result + 'px';
929
+ }
930
+ mouseDown(evt) {
931
+ if (this.inDragRegion(evt)) {
932
+ this.dragging = true;
933
+ this.preventGlobalMouseEvents();
934
+ evt.stopPropagation();
935
+ }
936
+ }
937
+ restoreGlobalMouseEvents() {
938
+ document.body.style['pointer-events'] = 'auto';
939
+ }
940
+ mouseUpG(evt) {
941
+ if (!this.dragging) {
942
+ return;
943
+ }
944
+ this.restoreGlobalMouseEvents();
945
+ this.dragging = false;
946
+ evt.stopPropagation();
947
+ }
948
+ mouseMove(evt) {
949
+ if (this.inDragRegion(evt) || this.dragging) {
950
+ this.el.nativeElement.style.cursor = 'col-resize';
951
+ }
952
+ else {
953
+ this.el.nativeElement.style.cursor = 'default';
954
+ }
955
+ }
956
+ preventGlobalMouseEvents() {
957
+ document.body.style['pointer-events'] = 'none';
958
+ }
959
+ inDragRegion(evt) {
960
+ return this.el.nativeElement.clientWidth - evt.clientX + this.el.nativeElement.offsetLeft < this.resizableGrabWidth;
961
+ }
962
+ addListenerToDocument() {
963
+ document.addEventListener('mousemove', (e) => {
964
+ this.mouseMoveG(e);
965
+ }, true);
966
+ document.addEventListener('mouseup', (e) => {
967
+ this.mouseUpG(e);
968
+ }, true);
969
+ }
970
+ addListenerToElement() {
971
+ this.el.nativeElement.addEventListener('mousedown', (e) => {
972
+ this.mouseDown(e);
973
+ }, true);
974
+ this.el.nativeElement.addEventListener('mousemove', (e) => {
975
+ this.mouseMove(e);
976
+ }, true);
977
+ }
978
+ }
979
+ ResizableDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.0", ngImport: i0, type: ResizableDirective, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive });
980
+ ResizableDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.3.0", type: ResizableDirective, selector: "[ltResizable]", inputs: { resizableGrabWidth: "resizableGrabWidth", resizableMinWidth: "resizableMinWidth" }, ngImport: i0 });
981
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.0", ngImport: i0, type: ResizableDirective, decorators: [{
982
+ type: Directive,
983
+ args: [{
984
+ selector: '[ltResizable]',
985
+ }]
986
+ }], ctorParameters: function () { return [{ type: i0.ElementRef }]; }, propDecorators: { resizableGrabWidth: [{
987
+ type: Input
988
+ }], resizableMinWidth: [{
989
+ type: Input
990
+ }] } });
991
+
992
+ /**
993
+ * Truncate string with ellipses
994
+ */
995
+ class EllipsesPipe {
996
+ transform(value, limit) {
997
+ if (!value) {
998
+ return null;
999
+ }
1000
+ return value.length > limit ? value.substring(0, limit) + '...' : value;
1001
+ }
1002
+ }
1003
+ EllipsesPipe.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.0", ngImport: i0, type: EllipsesPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
1004
+ EllipsesPipe.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "12.0.0", version: "13.3.0", ngImport: i0, type: EllipsesPipe, name: "ltEllipses" });
1005
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.0", ngImport: i0, type: EllipsesPipe, decorators: [{
1006
+ type: Pipe,
1007
+ args: [{
1008
+ name: 'ltEllipses',
1009
+ }]
1010
+ }] });
1011
+
1012
+ /**
1013
+ * Declarate html as safe
1014
+ */
1015
+ class SafeHtmlPipe {
1016
+ constructor(sanitized) {
1017
+ this.sanitized = sanitized;
1018
+ }
1019
+ transform(value) {
1020
+ return this.sanitized.bypassSecurityTrustHtml(value);
1021
+ }
1022
+ }
1023
+ SafeHtmlPipe.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.0", ngImport: i0, type: SafeHtmlPipe, deps: [{ token: i1.DomSanitizer }], target: i0.ɵɵFactoryTarget.Pipe });
1024
+ SafeHtmlPipe.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "12.0.0", version: "13.3.0", ngImport: i0, type: SafeHtmlPipe, name: "ltSafeHtml" });
1025
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.0", ngImport: i0, type: SafeHtmlPipe, decorators: [{
1026
+ type: Pipe,
1027
+ args: [{ name: 'ltSafeHtml' }]
1028
+ }], ctorParameters: function () { return [{ type: i1.DomSanitizer }]; } });
1029
+
1030
+ // Imported and exported elements
1031
+ const elements = [
1032
+ // Directives
1033
+ ContextMenuDirective,
1034
+ LazyLoadDirective,
1035
+ MatchHeightDirective,
1036
+ ResizableDirective,
1037
+ // Pipes
1038
+ EllipsesPipe,
1039
+ SafeHtmlPipe,
1040
+ ];
1041
+ /**
1042
+ * Base module
1043
+ */
1044
+ class BaseModule {
1045
+ /**
1046
+ * Set configuration of base module in root module of the app
1047
+ */
1048
+ static forRoot(baseModuleConfig = {}, AppAuthService) {
1049
+ // Default config
1050
+ const config = {
1051
+ apiUrl: 'localhost:3000',
1052
+ authGuardRedirectUrl: '/auth',
1053
+ logging: false,
1054
+ version: null,
1055
+ prefix: null,
1056
+ scrollDetectionOffset: 200,
1057
+ scrollOffset: 100,
1058
+ storageType: 'local',
1059
+ ...baseModuleConfig,
1060
+ };
1061
+ // Prepare providers
1062
+ const providers = [
1063
+ {
1064
+ provide: BASE_MODULE_CONFIG,
1065
+ useValue: baseModuleConfig,
1066
+ },
1067
+ ];
1068
+ // Add apollo features if API URL is set
1069
+ if (baseModuleConfig.apiUrl) {
1070
+ providers.push({
1071
+ provide: APOLLO_OPTIONS,
1072
+ useFactory: apolloOptionsFactory,
1073
+ deps: [BASE_MODULE_CONFIG, HttpLink, AppAuthService ? AppAuthService : AuthService, WsService],
1074
+ });
1075
+ }
1076
+ else if (config.logging) {
1077
+ console.log('apiUrl is missing, ApolloLink is not initialized');
1078
+ }
1079
+ // Return root module
1080
+ return {
1081
+ ngModule: BaseModule,
1082
+ providers,
1083
+ };
1084
+ }
1085
+ }
1086
+ BaseModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.0", ngImport: i0, type: BaseModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
1087
+ BaseModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "13.3.0", ngImport: i0, type: BaseModule, declarations: [
1088
+ // Directives
1089
+ ContextMenuDirective,
1090
+ LazyLoadDirective,
1091
+ MatchHeightDirective,
1092
+ ResizableDirective,
1093
+ // Pipes
1094
+ EllipsesPipe,
1095
+ SafeHtmlPipe], exports: [
1096
+ // Directives
1097
+ ContextMenuDirective,
1098
+ LazyLoadDirective,
1099
+ MatchHeightDirective,
1100
+ ResizableDirective,
1101
+ // Pipes
1102
+ EllipsesPipe,
1103
+ SafeHtmlPipe] });
1104
+ BaseModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "13.3.0", ngImport: i0, type: BaseModule });
1105
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.0", ngImport: i0, type: BaseModule, decorators: [{
1106
+ type: NgModule,
1107
+ args: [{
1108
+ declarations: elements,
1109
+ exports: elements,
1110
+ }]
1111
+ }] });
1112
+
1113
+ /**
1114
+ * Standard class
1115
+ * Other classes should extend the Standard class, if they offer own functions
1116
+ * If the extended class uses object properties with own map functions, it should implement its own map function
1117
+ */
1118
+ class Standard {
1119
+ /**
1120
+ * Static map method
1121
+ */
1122
+ static map(data, item = new this()) {
1123
+ return item.map(data);
1124
+ }
1125
+ /**
1126
+ * Map data into an object
1127
+ */
1128
+ map(data) {
1129
+ return Helper.map(data, this);
1130
+ }
1131
+ /**
1132
+ * Clone object (and map additional data)
1133
+ */
1134
+ clone(mapData) {
1135
+ const current = JSON.parse(JSON.stringify(this));
1136
+ if (mapData) {
1137
+ Object.assign(current, mapData);
1138
+ }
1139
+ return new this.constructor().map(current);
1140
+ }
1141
+ /**
1142
+ * Compare this with another object
1143
+ * Hint: functions will be ignored and when an array or an object is different the hole array or object will used as property value
1144
+ *
1145
+ * @return Record<string, any> with properties of this object which are different
1146
+ */
1147
+ getDiff(compare, clone = true) {
1148
+ return Helper.getDiff(this, compare, clone);
1149
+ }
1150
+ }
1151
+
1152
+ /**
1153
+ * User class
1154
+ */
1155
+ class BasicUser extends Standard {
1156
+ constructor() {
1157
+ super(...arguments);
1158
+ this.id = undefined;
1159
+ this.email = undefined;
1160
+ this.firstName = undefined;
1161
+ this.lastName = undefined;
1162
+ this.roles = [];
1163
+ this.username = undefined;
1164
+ }
1165
+ // ===================================================================================================================
1166
+ // Methods
1167
+ // ===================================================================================================================
1168
+ /**
1169
+ * Mapping
1170
+ */
1171
+ map(data) {
1172
+ Helper.map(data, this);
1173
+ return this;
1174
+ }
1175
+ /**
1176
+ * Checks whether the user has at least one of the required roles
1177
+ */
1178
+ hasRole(roles) {
1179
+ if (typeof roles === 'string') {
1180
+ roles = [roles];
1181
+ }
1182
+ if (!this.roles || this.roles.length < 1) {
1183
+ return false;
1184
+ }
1185
+ return !roles || roles.length < 1 ? true : this.roles.some((role) => roles.includes(role));
1186
+ }
1187
+ /**
1188
+ * Checks whether the user has all required roles
1189
+ */
1190
+ hasAllRoles(roles) {
1191
+ if (typeof roles === 'string') {
1192
+ roles = [roles];
1193
+ }
1194
+ if (!this.roles || this.roles.length < 1) {
1195
+ return false;
1196
+ }
1197
+ return !roles ? true : roles.every((role) => this.roles.includes(role));
1198
+ }
1199
+ }
1200
+
1201
+ /**
1202
+ * GraphQL enum
1203
+ */
1204
+ class GraphQLEnum {
1205
+ constructor(value) {
1206
+ this.value = value;
1207
+ }
1208
+ }
1209
+
1210
+ /**
1211
+ * GraphQL type
1212
+ */
1213
+ class GraphQLType extends Standard {
1214
+ constructor() {
1215
+ super(...arguments);
1216
+ this.type = '';
1217
+ this.isEnum = false;
1218
+ this.validEnums = [];
1219
+ }
1220
+ }
1221
+
1222
+ /**
1223
+ * GraphQL meta
1224
+ */
1225
+ class GraphQLMeta {
1226
+ /**
1227
+ * Integrate schema
1228
+ */
1229
+ constructor(schema) {
1230
+ this.schema = schema;
1231
+ // Frozen caches
1232
+ this.args = {};
1233
+ this.fields = {};
1234
+ if (!schema) {
1235
+ throw Error('Missing schema');
1236
+ }
1237
+ }
1238
+ /**
1239
+ * Get arguments of GraphQL function
1240
+ */
1241
+ getArgs(functionName, options = {}) {
1242
+ const { cache, freeze, type } = {
1243
+ cache: true,
1244
+ freeze: true,
1245
+ type: undefined,
1246
+ ...options,
1247
+ };
1248
+ // Get cache
1249
+ if (cache && freeze) {
1250
+ const args = this.args[functionName + type];
1251
+ if (args) {
1252
+ return args;
1253
+ }
1254
+ }
1255
+ const func = this.getFunction(functionName, { type });
1256
+ const result = {};
1257
+ if (func?.args) {
1258
+ func.args.forEach((item) => {
1259
+ result[item.name] = this.getDeepType(item.type);
1260
+ });
1261
+ }
1262
+ // Set cache
1263
+ if (freeze) {
1264
+ this.args[functionName + type] = Helper.deepFreeze(result);
1265
+ }
1266
+ return result;
1267
+ }
1268
+ /**
1269
+ * Get fields of GraphQL function
1270
+ */
1271
+ getFields(functionName, options = {}) {
1272
+ const { cache, freeze, type } = {
1273
+ cache: true,
1274
+ freeze: true,
1275
+ type: undefined,
1276
+ ...options,
1277
+ };
1278
+ // Get cache
1279
+ if (cache && freeze) {
1280
+ const args = this.fields[functionName + type];
1281
+ if (args) {
1282
+ return args;
1283
+ }
1284
+ }
1285
+ const func = this.getFunction(functionName, options);
1286
+ const result = this.getDeepType(func.type);
1287
+ // Set cache
1288
+ if (freeze) {
1289
+ this.fields[functionName + type] = Helper.deepFreeze(result);
1290
+ }
1291
+ return result;
1292
+ }
1293
+ /**
1294
+ * Get GraphQL function
1295
+ */
1296
+ getFunction(name, options = {}) {
1297
+ // Set config
1298
+ const config = {
1299
+ ...options,
1300
+ };
1301
+ // Init possible functions
1302
+ let functions = {};
1303
+ // If function type is set
1304
+ if (config.type) {
1305
+ const graphQLType = config.type.charAt(0).toUpperCase() + config.type.slice(1);
1306
+ const type = this.schema.getType(graphQLType);
1307
+ if (type) {
1308
+ functions = type.getFields();
1309
+ }
1310
+ }
1311
+ // If function type is not set
1312
+ else {
1313
+ ['Subscription', 'Mutation', 'Query'].forEach((item) => {
1314
+ const type = this.schema.getType(item);
1315
+ if (type) {
1316
+ functions = {
1317
+ ...functions,
1318
+ ...(type.getFields() || {}),
1319
+ };
1320
+ }
1321
+ });
1322
+ }
1323
+ // Get function via name
1324
+ return functions[name];
1325
+ }
1326
+ /**
1327
+ * Get type
1328
+ */
1329
+ getType(name) {
1330
+ return this.schema.getType(name);
1331
+ }
1332
+ /**
1333
+ * Get deep type data
1334
+ */
1335
+ getDeepType(type, prepared = new WeakMap()) {
1336
+ // Check type
1337
+ if (!type) {
1338
+ return type;
1339
+ }
1340
+ // Infinite regress protection
1341
+ const preparedObject = {};
1342
+ // Check prepared
1343
+ if (typeof type === 'object') {
1344
+ const preparedType = prepared.get(type);
1345
+ if (preparedType) {
1346
+ return preparedType;
1347
+ }
1348
+ // Set prepared
1349
+ prepared.set(type, preparedObject);
1350
+ }
1351
+ // Search deeper
1352
+ if (type.ofType) {
1353
+ const ofTypeResult = this.getDeepType(type.ofType, prepared);
1354
+ Object.assign(preparedObject, ofTypeResult);
1355
+ return ofTypeResult;
1356
+ }
1357
+ // Process fields
1358
+ if (type._fields) {
1359
+ const result = {};
1360
+ for (const [key, value] of Object.entries(type._fields)) {
1361
+ result[key] = this.getDeepType(value, prepared);
1362
+ }
1363
+ Object.assign(preparedObject, result);
1364
+ return result;
1365
+ }
1366
+ // Get type name
1367
+ if (type.type) {
1368
+ const typeResult = this.getDeepType(type.type, prepared);
1369
+ Object.assign(preparedObject, typeResult);
1370
+ return typeResult;
1371
+ }
1372
+ // Initialize GraphQLType
1373
+ const graphqlType = GraphQLType.map({
1374
+ type: type.name,
1375
+ });
1376
+ // Set enum values
1377
+ if (!!type._values) {
1378
+ graphqlType.isEnum = true;
1379
+ for (const [key, value] of Object.entries(type._nameLookup)) {
1380
+ if (!value.isDeprecated) {
1381
+ graphqlType.validEnums.push(key);
1382
+ }
1383
+ }
1384
+ }
1385
+ // Finish
1386
+ prepared.set(type, graphqlType);
1387
+ return graphqlType;
1388
+ }
1389
+ }
1390
+
1391
+ /**
1392
+ * Authentication guard
1393
+ */
1394
+ class AuthGuard {
1395
+ /**
1396
+ * Imports
1397
+ */
1398
+ constructor(router, authService, moduleConfig) {
1399
+ this.router = router;
1400
+ this.authService = authService;
1401
+ this.moduleConfig = moduleConfig;
1402
+ }
1403
+ /**
1404
+ * Can activate main route
1405
+ */
1406
+ canActivate(route, state) {
1407
+ return new Observable((subscriber) => {
1408
+ let allowed = false;
1409
+ const opposite = route?.data?.opposite ? route?.data?.opposite : false;
1410
+ const redirectUrl = route?.data?.redirectUrl ? route.data.redirectUrl : this.moduleConfig.authGuardRedirectUrl;
1411
+ if (this.authService.token && !opposite) {
1412
+ if (route.data.allowedRole) {
1413
+ const user = this.authService.currentUser;
1414
+ allowed = user?.roles?.includes(route.data.allowedRole);
1415
+ }
1416
+ else {
1417
+ allowed = true;
1418
+ }
1419
+ }
1420
+ else if (!this.authService.token && opposite) {
1421
+ allowed = true;
1422
+ }
1423
+ if (!allowed) {
1424
+ this.router.navigate([redirectUrl]);
1425
+ }
1426
+ subscriber.next(allowed);
1427
+ subscriber.complete();
1428
+ });
1429
+ }
1430
+ /**
1431
+ * Can activate child route
1432
+ */
1433
+ canActivateChild(route, state) {
1434
+ return this.canActivate(route, state);
1435
+ }
1436
+ }
1437
+ AuthGuard.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.0", ngImport: i0, type: AuthGuard, deps: [{ token: i1$1.Router }, { token: AuthService }, { token: BASE_MODULE_CONFIG }], target: i0.ɵɵFactoryTarget.Injectable });
1438
+ AuthGuard.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.3.0", ngImport: i0, type: AuthGuard });
1439
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.0", ngImport: i0, type: AuthGuard, decorators: [{
1440
+ type: Injectable
1441
+ }], ctorParameters: function () { return [{ type: i1$1.Router }, { type: AuthService }, { type: undefined, decorators: [{
1442
+ type: Inject,
1443
+ args: [BASE_MODULE_CONFIG]
1444
+ }] }]; } });
1445
+
1446
+ /**
1447
+ * Guard to check if a component can be deactivated
1448
+ */
1449
+ class CanDeactivateGuard {
1450
+ canDeactivate(component) {
1451
+ return component.canDeactivate ? component.canDeactivate() : true;
1452
+ }
1453
+ }
1454
+ CanDeactivateGuard.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.0", ngImport: i0, type: CanDeactivateGuard, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
1455
+ CanDeactivateGuard.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.3.0", ngImport: i0, type: CanDeactivateGuard });
1456
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.0", ngImport: i0, type: CanDeactivateGuard, decorators: [{
1457
+ type: Injectable
1458
+ }] });
1459
+
1460
+ /**
1461
+ * Logout guard
1462
+ */
1463
+ class LogoutGuard {
1464
+ constructor(router, authService) {
1465
+ this.router = router;
1466
+ this.authService = authService;
1467
+ }
1468
+ canActivate(route, state) {
1469
+ return new Observable((subscriber) => {
1470
+ if (this.authService.token) {
1471
+ this.authService.logout();
1472
+ }
1473
+ subscriber.next(true);
1474
+ subscriber.complete();
1475
+ });
1476
+ }
1477
+ canActivateChild(route, state) {
1478
+ return this.canActivate(route, state);
1479
+ }
1480
+ }
1481
+ LogoutGuard.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.0", ngImport: i0, type: LogoutGuard, deps: [{ token: i1$1.Router }, { token: AuthService }], target: i0.ɵɵFactoryTarget.Injectable });
1482
+ LogoutGuard.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.3.0", ngImport: i0, type: LogoutGuard });
1483
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.0", ngImport: i0, type: LogoutGuard, decorators: [{
1484
+ type: Injectable
1485
+ }], ctorParameters: function () { return [{ type: i1$1.Router }, { type: AuthService }]; } });
1486
+
1487
+ /**
1488
+ * Comparison operator enum
1489
+ */
1490
+ var ComparisonOperatorEnum;
1491
+ (function (ComparisonOperatorEnum) {
1492
+ ComparisonOperatorEnum["EQ"] = "EQ";
1493
+ ComparisonOperatorEnum["GT"] = "GT";
1494
+ ComparisonOperatorEnum["GTE"] = "GTE";
1495
+ ComparisonOperatorEnum["IN"] = "IN";
1496
+ ComparisonOperatorEnum["LT"] = "LT";
1497
+ ComparisonOperatorEnum["LTE"] = "LTE";
1498
+ ComparisonOperatorEnum["NE"] = "NE";
1499
+ ComparisonOperatorEnum["NIN"] = "NIN";
1500
+ ComparisonOperatorEnum["REGEX"] = "REGEX";
1501
+ })(ComparisonOperatorEnum || (ComparisonOperatorEnum = {}));
1502
+
1503
+ /**
1504
+ * GraphQL request type enum
1505
+ */
1506
+ var GraphQLRequestType;
1507
+ (function (GraphQLRequestType) {
1508
+ GraphQLRequestType["QUERY"] = "query";
1509
+ GraphQLRequestType["MUTATION"] = "mutation";
1510
+ GraphQLRequestType["SUBSCRIPTION"] = "subscription";
1511
+ })(GraphQLRequestType || (GraphQLRequestType = {}));
1512
+
1513
+ /**
1514
+ * Logical operator enum
1515
+ */
1516
+ var LogicalOperatorEnum;
1517
+ (function (LogicalOperatorEnum) {
1518
+ LogicalOperatorEnum["AND"] = "AND";
1519
+ LogicalOperatorEnum["NOR"] = "NOR";
1520
+ LogicalOperatorEnum["OR"] = "OR";
1521
+ })(LogicalOperatorEnum || (LogicalOperatorEnum = {}));
1522
+
1523
+ var SortOrderEnum;
1524
+ (function (SortOrderEnum) {
1525
+ SortOrderEnum["ASC"] = "ASC";
1526
+ SortOrderEnum["DESC"] = "DESC";
1527
+ })(SortOrderEnum || (SortOrderEnum = {}));
1528
+
1529
+ /**
1530
+ * Fullscreen service
1531
+ */
1532
+ class FullscreenService {
1533
+ constructor() {
1534
+ this._isFullscreenActive = new BehaviorSubject(false);
1535
+ this.listenToFullscreenEvent();
1536
+ }
1537
+ get fullscreenState() {
1538
+ return this._isFullscreenActive.value;
1539
+ }
1540
+ get fullscreenStateAsObservable() {
1541
+ return this._isFullscreenActive.asObservable();
1542
+ }
1543
+ toggleFullscreen() {
1544
+ const elem = document.documentElement;
1545
+ if (!this._isFullscreenActive.value) {
1546
+ elem.requestFullscreen();
1547
+ this._isFullscreenActive.next(true);
1548
+ }
1549
+ else {
1550
+ document.exitFullscreen();
1551
+ this._isFullscreenActive.next(false);
1552
+ }
1553
+ }
1554
+ /**
1555
+ * Event Listener for fullscreen toggle
1556
+ */
1557
+ listenToFullscreenEvent() {
1558
+ document.addEventListener('fullscreenchange', () => {
1559
+ if (document.fullscreenElement) {
1560
+ this._isFullscreenActive.next(true);
1561
+ }
1562
+ else {
1563
+ this._isFullscreenActive.next(false);
1564
+ }
1565
+ });
1566
+ }
1567
+ }
1568
+ FullscreenService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.0", ngImport: i0, type: FullscreenService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
1569
+ FullscreenService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.3.0", ngImport: i0, type: FullscreenService, providedIn: 'root' });
1570
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.0", ngImport: i0, type: FullscreenService, decorators: [{
1571
+ type: Injectable,
1572
+ args: [{
1573
+ providedIn: 'root',
1574
+ }]
1575
+ }], ctorParameters: function () { return []; } });
1576
+
1577
+ /**
1578
+ * GraphQL meta service
1579
+ *
1580
+ * For collecting meta information of the GraphQL API
1581
+ */
1582
+ class GraphQLMetaService {
1583
+ /**
1584
+ * Include services
1585
+ */
1586
+ constructor(apollo) {
1587
+ this.apollo = apollo;
1588
+ }
1589
+ /**
1590
+ * Getter of introspectionQuery
1591
+ */
1592
+ get introspectionQuery() {
1593
+ return JSON.parse(JSON.stringify(this._introspectionQuery));
1594
+ }
1595
+ /**
1596
+ * Get schema for API
1597
+ * See https://www.apollographql.com/blog/three-ways-to-represent-your-graphql-schema-a41f4175100d
1598
+ */
1599
+ getSchema(options = {}) {
1600
+ // Get configurations
1601
+ const config = {
1602
+ cache: true,
1603
+ freeze: true,
1604
+ ...options,
1605
+ };
1606
+ // Use caching
1607
+ if (config.cache) {
1608
+ if (config.freeze && this._frozenSchema) {
1609
+ return of(this._frozenSchema);
1610
+ }
1611
+ if (this._introspectionQuery) {
1612
+ return of(buildClientSchema(this.introspectionQuery));
1613
+ }
1614
+ if (config.freeze && this._frozenSchemaObservable) {
1615
+ return this._frozenSchemaObservable;
1616
+ }
1617
+ else if (!config.freeze && this._schemaObservable) {
1618
+ return this._schemaObservable;
1619
+ }
1620
+ }
1621
+ // Request schema from server
1622
+ const observable = this.apollo
1623
+ .query({
1624
+ query: gql(getIntrospectionQuery({ descriptions: false })),
1625
+ })
1626
+ .pipe(map((schema) => {
1627
+ // Cache introspectionQuery
1628
+ this._introspectionQuery = schema.data;
1629
+ // Convert schema to GraphQLSchema
1630
+ this._frozenSchema = Helper.deepFreeze(buildClientSchema(this.introspectionQuery));
1631
+ // Return GraphQLSchema
1632
+ if (config.freeze) {
1633
+ return this._frozenSchema;
1634
+ }
1635
+ return buildClientSchema(schema.data);
1636
+ }));
1637
+ // Set observables
1638
+ if (config.freeze) {
1639
+ this._frozenSchemaObservable = observable;
1640
+ }
1641
+ else {
1642
+ this._schemaObservable = observable;
1643
+ }
1644
+ // Return result
1645
+ return observable;
1646
+ }
1647
+ /**
1648
+ * Get meta for API
1649
+ * See https://www.apollographql.com/blog/three-ways-to-represent-your-graphql-schema-a41f4175100d
1650
+ */
1651
+ getMeta(options = {}) {
1652
+ // Get configurations
1653
+ const config = {
1654
+ cache: true,
1655
+ log: false,
1656
+ ...options,
1657
+ };
1658
+ // Use caching
1659
+ if (config.cache) {
1660
+ if (this._meta) {
1661
+ return of(this._meta);
1662
+ }
1663
+ else if (this._metaObservable) {
1664
+ return this._metaObservable;
1665
+ }
1666
+ }
1667
+ // Request schema from server
1668
+ const observable = this.getSchema(options).pipe(map((schema) => {
1669
+ // Log
1670
+ if (config.log) {
1671
+ console.log({ schema });
1672
+ }
1673
+ this._meta = new GraphQLMeta(schema);
1674
+ return this._meta;
1675
+ }));
1676
+ // Set observables
1677
+ this._metaObservable = observable;
1678
+ // Return result
1679
+ return observable;
1680
+ }
1681
+ }
1682
+ GraphQLMetaService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.0", ngImport: i0, type: GraphQLMetaService, deps: [{ token: i1$2.Apollo }], target: i0.ɵɵFactoryTarget.Injectable });
1683
+ GraphQLMetaService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.3.0", ngImport: i0, type: GraphQLMetaService, providedIn: 'root' });
1684
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.0", ngImport: i0, type: GraphQLMetaService, decorators: [{
1685
+ type: Injectable,
1686
+ args: [{
1687
+ providedIn: 'root',
1688
+ }]
1689
+ }], ctorParameters: function () { return [{ type: i1$2.Apollo }]; } });
1690
+
1691
+ /**
1692
+ * GraphQL service
1693
+ */
1694
+ class GraphQLService {
1695
+ /**
1696
+ * Include services
1697
+ */
1698
+ constructor(apollo, graphQLMetaService) {
1699
+ this.apollo = apollo;
1700
+ this.graphQLMetaService = graphQLMetaService;
1701
+ }
1702
+ /**
1703
+ * GraphQL request
1704
+ */
1705
+ graphQl(graphql, options = {}) {
1706
+ // Check arguments
1707
+ if (!graphql) {
1708
+ throwError('Missing graphql argument');
1709
+ }
1710
+ // Get config
1711
+ const config = {
1712
+ arguments: null,
1713
+ fields: null,
1714
+ log: false,
1715
+ model: null,
1716
+ type: GraphQLRequestType.QUERY,
1717
+ ...options,
1718
+ };
1719
+ // Convert class to Object for arguments
1720
+ if (typeof config.arguments === 'function') {
1721
+ config.arguments = new config.arguments();
1722
+ }
1723
+ // Convert class to Object for fields
1724
+ if (typeof config.fields === 'function') {
1725
+ config.fields = new config.fields();
1726
+ }
1727
+ // Log
1728
+ if (config.log) {
1729
+ console.log({ config });
1730
+ }
1731
+ // Send request
1732
+ return new Observable((subscriber) => {
1733
+ // Get meta
1734
+ this.graphQLMetaService.getMeta({ log: config.log }).subscribe((meta) => {
1735
+ // Prepare fields
1736
+ let fields;
1737
+ let allowedFields;
1738
+ // Log meta
1739
+ if (config.log) {
1740
+ console.log({ meta });
1741
+ }
1742
+ if (config.fields) {
1743
+ allowedFields = meta.getFields(graphql, { type: config.type });
1744
+ // Log meta
1745
+ if (config.log) {
1746
+ console.log({ allowedFields });
1747
+ }
1748
+ const fieldsData = this.prepareFields(config.fields, {
1749
+ allowed: allowedFields,
1750
+ });
1751
+ // Log fields data
1752
+ if (config.log) {
1753
+ fieldsData.usedFields.sort();
1754
+ fieldsData.schemaFields.sort();
1755
+ const filtered = fieldsData.schemaFields.filter((field) => !fieldsData.usedFields.includes(field));
1756
+ const unused = this.graphQLTypeCollectionToStringArray(allowedFields).filter((field) => !fieldsData.usedFields.includes(field));
1757
+ console.log({ fieldsData, filtered, unused });
1758
+ }
1759
+ fields = fieldsData.fieldsString;
1760
+ }
1761
+ if (fields && !fields.startsWith('{')) {
1762
+ fields = '{' + fields + '\n}';
1763
+ }
1764
+ // Log fields
1765
+ if (config.log) {
1766
+ console.log({ fields });
1767
+ }
1768
+ // Get allowed args
1769
+ const allowedArgs = meta.getArgs(graphql, { type: config.type });
1770
+ // Log allowed args
1771
+ if (config.log) {
1772
+ console.log({ allowedArgs });
1773
+ }
1774
+ const argsData = this.prepareArguments(config.arguments, {
1775
+ allowed: allowedArgs,
1776
+ });
1777
+ // Log args data
1778
+ if (config.log) {
1779
+ argsData.usedArgs.sort();
1780
+ argsData.schemaArgs.sort();
1781
+ const filtered = argsData.schemaArgs.filter((field) => !argsData.usedArgs.includes(field));
1782
+ const unused = this.graphQLTypeCollectionToStringArray(allowedArgs)
1783
+ .sort()
1784
+ .filter((field) => !argsData.usedArgs.includes(field));
1785
+ console.log({ argsData, filtered, unused });
1786
+ }
1787
+ const args = argsData?.argsString || '';
1788
+ // Log
1789
+ if (config.log) {
1790
+ console.log({ graphQL: graphql, args, fields, type: config.type });
1791
+ }
1792
+ // Prepare request
1793
+ const documentNode = fields
1794
+ ? gql(config.type + '{\n' + graphql + args + fields + '\n}')
1795
+ : gql(config.type + '{\n' + graphql + args + '\n}');
1796
+ // Log
1797
+ if (config.log) {
1798
+ console.log({ documentNode });
1799
+ }
1800
+ const request = {};
1801
+ request[config.type] = documentNode;
1802
+ // Log
1803
+ if (config.log) {
1804
+ console.log({ request });
1805
+ }
1806
+ let func;
1807
+ if (config.type === GraphQLRequestType.MUTATION) {
1808
+ func = 'mutate';
1809
+ request[config.type] = documentNode;
1810
+ }
1811
+ else if (config.type === GraphQLRequestType.SUBSCRIPTION) {
1812
+ func = 'subscribe';
1813
+ request.query = documentNode;
1814
+ }
1815
+ else {
1816
+ func = config.type;
1817
+ request[config.type] = documentNode;
1818
+ }
1819
+ this.apollo[func](request).subscribe((result) => {
1820
+ const data = result?.data?.[graphql] !== undefined ? result.data[graphql] : result;
1821
+ // Direct data
1822
+ if (!config.model) {
1823
+ subscriber.next(data);
1824
+ }
1825
+ // Map data as array
1826
+ else if (Array.isArray(data)) {
1827
+ subscriber.next(data.map((item) => {
1828
+ return config.model.map(item);
1829
+ }));
1830
+ }
1831
+ // Map data
1832
+ else {
1833
+ subscriber.next(config.model.map(data));
1834
+ }
1835
+ if (config.type !== GraphQLRequestType.SUBSCRIPTION) {
1836
+ // Done
1837
+ subscriber.complete();
1838
+ }
1839
+ }, (error) => {
1840
+ subscriber.error(error);
1841
+ subscriber.complete();
1842
+ });
1843
+ });
1844
+ });
1845
+ }
1846
+ /**
1847
+ * Get fields / args from IGraphQLTypeCollection
1848
+ */
1849
+ graphQLTypeCollectionToStringArray(collection, current = '', result = [], cacheNode = []) {
1850
+ if (collection) {
1851
+ if (collection instanceof GraphQLType) {
1852
+ result.push(current);
1853
+ }
1854
+ else {
1855
+ if (current?.includes('.')) {
1856
+ cacheNode.push(current.split('.')[1]);
1857
+ }
1858
+ else if (current) {
1859
+ cacheNode.push(current);
1860
+ }
1861
+ for (const key of Object.keys(collection)) {
1862
+ if (current === key || cacheNode.includes(key)) {
1863
+ continue;
1864
+ }
1865
+ this.graphQLTypeCollectionToStringArray(collection[key], current ? current + '.' + key : key, result, cacheNode);
1866
+ }
1867
+ }
1868
+ }
1869
+ return result;
1870
+ }
1871
+ /**
1872
+ * Prepare arguments for GraphQL request
1873
+ */
1874
+ prepareArguments(args, options = {}) {
1875
+ // Init config variables
1876
+ const { allowed, level, parent, schemaArgs, usedArgs } = {
1877
+ allowed: null,
1878
+ level: 1,
1879
+ parent: '',
1880
+ schemaArgs: [],
1881
+ usedArgs: [],
1882
+ ...options,
1883
+ };
1884
+ // Check args
1885
+ if (args === undefined || args === null) {
1886
+ return { argsString: '', schemaArgs, usedArgs };
1887
+ }
1888
+ // Init args
1889
+ const result = [];
1890
+ // Process array
1891
+ if (Array.isArray(args)) {
1892
+ const allowedKeys = allowed ? Object.keys(allowed) : null;
1893
+ for (const item of args) {
1894
+ let key = null;
1895
+ if (allowed) {
1896
+ if (allowed.length < 1) {
1897
+ break;
1898
+ }
1899
+ key = allowedKeys?.shift();
1900
+ }
1901
+ // Process value
1902
+ result.push(this.prepareArguments(item, {
1903
+ allowed: key ? allowed[key] : null,
1904
+ level: level + 1,
1905
+ parent: parent + key + '.',
1906
+ schemaArgs,
1907
+ usedArgs,
1908
+ }).argsString);
1909
+ }
1910
+ // Encapsulation of the array result
1911
+ if (result.length) {
1912
+ // Complete result, encapsulated via round brackets
1913
+ if (level === 1) {
1914
+ return { argsString: '(' + result.join(', ') + ')', schemaArgs, usedArgs };
1915
+ }
1916
+ // Deeper result part, encapsulated via square brackets
1917
+ else {
1918
+ return { argsString: '[' + result.join(', ') + ']', schemaArgs, usedArgs };
1919
+ }
1920
+ }
1921
+ }
1922
+ // Process object
1923
+ else if (typeof args === 'object') {
1924
+ // Check object is empty
1925
+ if (args && Object.keys(args).length === 0 && Object.getPrototypeOf(args) === Object.prototype) {
1926
+ return { argsString: '{}', schemaArgs, usedArgs };
1927
+ }
1928
+ // Process all object entries
1929
+ for (const [key, value] of Object.entries(args)) {
1930
+ // Init data for current entry
1931
+ const currentKey = parent + key;
1932
+ schemaArgs.push(currentKey);
1933
+ // If the allowed key handling is enabled and the current key is not included in the list of allowed keys,
1934
+ // the current key will be skipped
1935
+ if (allowed && !allowed[key]) {
1936
+ continue;
1937
+ }
1938
+ // Skip value if not exists
1939
+ if (value === undefined || value === null) {
1940
+ continue;
1941
+ }
1942
+ // Add current key to metadata
1943
+ usedArgs.push(currentKey);
1944
+ // Process GraphQLEnum
1945
+ if (value instanceof GraphQLEnum) {
1946
+ result.push(key + ':' + value.value);
1947
+ continue;
1948
+ }
1949
+ // Process array
1950
+ else if (Array.isArray(value)) {
1951
+ result.push(key +
1952
+ ': [' +
1953
+ value.map((item) => this.prepareArguments(item, {
1954
+ allowed: allowed[key],
1955
+ level: level + 1,
1956
+ parent: currentKey + '.',
1957
+ schemaArgs,
1958
+ usedArgs,
1959
+ }).argsString) +
1960
+ ']');
1961
+ continue;
1962
+ }
1963
+ // Prepare additional result string
1964
+ let additionalResult = key + ': ';
1965
+ // Value is a date object
1966
+ if (typeof value === 'object' && Object.prototype.toString.call(value) === '[object Date]') {
1967
+ additionalResult += `"""${value.toString()}"""`;
1968
+ }
1969
+ // Value is a string
1970
+ else if (typeof value === 'string') {
1971
+ // Enum (doesn't need quotation marks)
1972
+ if (allowed[key].isEnum) {
1973
+ additionalResult += value;
1974
+ }
1975
+ // String
1976
+ else {
1977
+ additionalResult += `"""${value.replace(/"/g, '\\"')}"""`;
1978
+ }
1979
+ }
1980
+ // Value is a simple boolean or a number
1981
+ else if (typeof value === 'boolean' || typeof value === 'number') {
1982
+ additionalResult += value;
1983
+ }
1984
+ // Others
1985
+ else {
1986
+ additionalResult += this.prepareArguments(value, {
1987
+ allowed: allowed[key],
1988
+ level: level + 1,
1989
+ parent: currentKey + '.',
1990
+ schemaArgs,
1991
+ usedArgs,
1992
+ }).argsString;
1993
+ }
1994
+ // Push deeper part into result array
1995
+ result.push(additionalResult);
1996
+ }
1997
+ // Encapsulation of the object result
1998
+ if (result.length) {
1999
+ // Complete result, encapsulated via round brackets
2000
+ if (level === 1) {
2001
+ return { argsString: '(' + result.join(', ') + ')', schemaArgs, usedArgs };
2002
+ }
2003
+ // Deeper result part, encapsulated via curly brackets
2004
+ else {
2005
+ return { argsString: '{' + result.join(', ') + '}', schemaArgs, usedArgs };
2006
+ }
2007
+ }
2008
+ }
2009
+ // Prepare and process other / unknown values as JSON
2010
+ else {
2011
+ return { argsString: JSON.stringify(args), schemaArgs, usedArgs };
2012
+ }
2013
+ }
2014
+ /**
2015
+ * Prepare fields for GraphQL request
2016
+ */
2017
+ prepareFields(fields, options = {}) {
2018
+ // Config
2019
+ const { allowed, parent, schemaFields, spaces, tab, usedFields } = {
2020
+ allowed: null,
2021
+ parent: '',
2022
+ schemaFields: [],
2023
+ spaces: 2,
2024
+ tab: 1,
2025
+ usedFields: [],
2026
+ ...options,
2027
+ };
2028
+ // Init fields string
2029
+ let fieldsString = '';
2030
+ // Check fields
2031
+ if (!fields) {
2032
+ return { fieldsString, schemaFields, usedFields };
2033
+ }
2034
+ // Process string
2035
+ if (typeof fields === 'string') {
2036
+ if (allowed &&
2037
+ ((typeof allowed === 'string' && allowed !== fields) || (typeof allowed === 'object' && !allowed[fields]))) {
2038
+ return { fieldsString, schemaFields, usedFields };
2039
+ }
2040
+ return { fieldsString: '\n' + ' '.repeat(spaces).repeat(tab) + fields, schemaFields, usedFields };
2041
+ }
2042
+ // Process array
2043
+ else if (Array.isArray(fields)) {
2044
+ for (const item of fields) {
2045
+ if (typeof item === 'object') {
2046
+ fieldsString =
2047
+ fieldsString +
2048
+ this.prepareFields(item, {
2049
+ allowed,
2050
+ parent,
2051
+ spaces,
2052
+ schemaFields,
2053
+ tab: tab + 1,
2054
+ usedFields,
2055
+ }).fieldsString;
2056
+ continue;
2057
+ }
2058
+ const currentPath = parent + item;
2059
+ schemaFields.push(currentPath);
2060
+ if (allowed && !allowed?.[item]) {
2061
+ continue;
2062
+ }
2063
+ usedFields.push(currentPath);
2064
+ fieldsString =
2065
+ fieldsString +
2066
+ this.prepareFields(item, {
2067
+ allowed: typeof allowed?.[item] === 'object' && !(allowed?.[item] instanceof GraphQLType) ? allowed?.[item] : item,
2068
+ parent: currentPath + '.',
2069
+ spaces,
2070
+ schemaFields,
2071
+ tab: tab + 1,
2072
+ usedFields,
2073
+ }).fieldsString;
2074
+ }
2075
+ }
2076
+ // Process object
2077
+ else if (typeof fields === 'object') {
2078
+ for (const [key, val] of Object.entries(fields)) {
2079
+ const currentPath = parent + key;
2080
+ schemaFields.push(currentPath);
2081
+ if (allowed && !allowed[key]) {
2082
+ continue;
2083
+ }
2084
+ usedFields.push(currentPath);
2085
+ if (typeof val !== 'object' || !Object.keys(val).length) {
2086
+ fieldsString = fieldsString + '\n' + ' '.repeat(spaces).repeat(tab) + key;
2087
+ }
2088
+ else {
2089
+ fieldsString =
2090
+ fieldsString +
2091
+ '\n' +
2092
+ ' '.repeat(spaces).repeat(tab) +
2093
+ key +
2094
+ ' ' +
2095
+ '{' +
2096
+ this.prepareFields(val, {
2097
+ allowed: typeof allowed?.[key] === 'object' && !(allowed?.[key] instanceof GraphQLType) ? allowed?.[key] : key,
2098
+ parent: currentPath + '.',
2099
+ spaces,
2100
+ schemaFields,
2101
+ tab: tab + 1,
2102
+ usedFields,
2103
+ }).fieldsString +
2104
+ '\n' +
2105
+ ' '.repeat(spaces).repeat(tab) +
2106
+ '}';
2107
+ }
2108
+ }
2109
+ }
2110
+ // Return result
2111
+ return { fieldsString, schemaFields, usedFields };
2112
+ }
2113
+ }
2114
+ GraphQLService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.0", ngImport: i0, type: GraphQLService, deps: [{ token: i1$2.Apollo }, { token: GraphQLMetaService }], target: i0.ɵɵFactoryTarget.Injectable });
2115
+ GraphQLService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.3.0", ngImport: i0, type: GraphQLService, providedIn: 'root' });
2116
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.0", ngImport: i0, type: GraphQLService, decorators: [{
2117
+ type: Injectable,
2118
+ args: [{
2119
+ providedIn: 'root',
2120
+ }]
2121
+ }], ctorParameters: function () { return [{ type: i1$2.Apollo }, { type: GraphQLMetaService }]; } });
2122
+
2123
+ /**
2124
+ * Loader service for loading indication
2125
+ */
2126
+ class LoaderService {
2127
+ constructor() {
2128
+ this.isLoading = new BehaviorSubject(false);
2129
+ }
2130
+ start() {
2131
+ this.isLoading.next(true);
2132
+ }
2133
+ stop() {
2134
+ this.isLoading.next(false);
2135
+ }
2136
+ getAsObservable() {
2137
+ return this.isLoading.asObservable();
2138
+ }
2139
+ }
2140
+ LoaderService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.0", ngImport: i0, type: LoaderService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
2141
+ LoaderService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.3.0", ngImport: i0, type: LoaderService, providedIn: 'root' });
2142
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.0", ngImport: i0, type: LoaderService, decorators: [{
2143
+ type: Injectable,
2144
+ args: [{
2145
+ providedIn: 'root',
2146
+ }]
2147
+ }] });
2148
+
2149
+ /**
2150
+ * GraphQL plus service, for extra error handling and loading indication
2151
+ */
2152
+ class GraphQLPlusService extends GraphQLService {
2153
+ /**
2154
+ * Include services
2155
+ */
2156
+ constructor(apollo, graphqlMetaService, loaderService) {
2157
+ super(apollo, graphqlMetaService);
2158
+ this.apollo = apollo;
2159
+ this.graphqlMetaService = graphqlMetaService;
2160
+ this.loaderService = loaderService;
2161
+ }
2162
+ graphQl(graphql, options = {}) {
2163
+ this.handleLoader('start', options);
2164
+ return new Observable((subscriber) => {
2165
+ super.graphQl(graphql, options).subscribe((response) => {
2166
+ if (response && response.errors) {
2167
+ this.handleError(response.errors, options.excludedErrors);
2168
+ subscriber.error(response);
2169
+ this.handleLoader('stop', options);
2170
+ subscriber.complete();
2171
+ }
2172
+ subscriber.next(response);
2173
+ this.handleLoader('stop', options);
2174
+ if (options.type !== GraphQLRequestType.SUBSCRIPTION) {
2175
+ subscriber.complete();
2176
+ }
2177
+ }, (error) => {
2178
+ if (!options.ignoreErrors) {
2179
+ this.handleError(error, options.excludedErrors);
2180
+ }
2181
+ subscriber.error(error);
2182
+ this.handleLoader('stop', options);
2183
+ subscriber.complete();
2184
+ });
2185
+ });
2186
+ }
2187
+ handleLoader(state, options) {
2188
+ if (options.loading) {
2189
+ if (state === 'start') {
2190
+ this.loaderService.start();
2191
+ }
2192
+ else if (state === 'stop') {
2193
+ this.loaderService.stop();
2194
+ }
2195
+ }
2196
+ }
2197
+ handleError(error, excludedErrors = null) {
2198
+ if (excludedErrors) {
2199
+ if (Array.isArray(excludedErrors)) {
2200
+ excludedErrors.forEach((excludedError) => {
2201
+ if (error.message.includes(excludedError.toLowerCase())) {
2202
+ return;
2203
+ }
2204
+ });
2205
+ }
2206
+ else if (error.message.toLowerCase().includes(excludedErrors?.toLowerCase())) {
2207
+ return;
2208
+ }
2209
+ }
2210
+ this.displayError(error);
2211
+ }
2212
+ displayError(error) {
2213
+ console.error(error);
2214
+ }
2215
+ }
2216
+ GraphQLPlusService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.0", ngImport: i0, type: GraphQLPlusService, deps: [{ token: i1$2.Apollo }, { token: GraphQLMetaService }, { token: LoaderService }], target: i0.ɵɵFactoryTarget.Injectable });
2217
+ GraphQLPlusService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.3.0", ngImport: i0, type: GraphQLPlusService, providedIn: 'root' });
2218
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.0", ngImport: i0, type: GraphQLPlusService, decorators: [{
2219
+ type: Injectable,
2220
+ args: [{
2221
+ providedIn: 'root',
2222
+ }]
2223
+ }], ctorParameters: function () { return [{ type: i1$2.Apollo }, { type: GraphQLMetaService }, { type: LoaderService }]; } });
2224
+
2225
+ /**
2226
+ * Scroll service for autoscroll to specific fragments
2227
+ */
2228
+ class ScrollService {
2229
+ /**
2230
+ * Initializer
2231
+ */
2232
+ constructor(router, moduleConfig, imageService) {
2233
+ this.router = router;
2234
+ this.moduleConfig = moduleConfig;
2235
+ this.imageService = imageService;
2236
+ /**
2237
+ * Is a scroll listener set
2238
+ *
2239
+ * @protected
2240
+ */
2241
+ this.scrollListener = false;
2242
+ /**
2243
+ * Current scroll timer;
2244
+ *
2245
+ * @protected
2246
+ */
2247
+ this.scrollTimer = -1;
2248
+ const config = {
2249
+ scrollDetectionOffset: 200,
2250
+ scrollOffset: 100,
2251
+ scrollSamplingRate: 100,
2252
+ ...moduleConfig,
2253
+ };
2254
+ this.detectionOffset = config.scrollDetectionOffset;
2255
+ this.scrollOffset = config.scrollOffset;
2256
+ this.scrollSamplingRate = config.scrollSamplingRate;
2257
+ }
2258
+ /**
2259
+ * Scroll to structureElement with specific ID
2260
+ */
2261
+ async scrollTo(id, options = {}) {
2262
+ // Prepare config
2263
+ const config = {
2264
+ checkUrl: false,
2265
+ loadImagesBefore: true,
2266
+ resetStyles: false,
2267
+ setOverflow: true,
2268
+ stopPropagation: true,
2269
+ ...options,
2270
+ };
2271
+ // Check current URL
2272
+ if (config.checkUrl && this.router.url !== '/' && !this.router.url.startsWith('/#')) {
2273
+ await this.router.navigate(['/'], { fragment: id });
2274
+ return !config.stopPropagation;
2275
+ }
2276
+ // Check if target element exits
2277
+ const el = document.getElementById(id);
2278
+ if (!el) {
2279
+ console.error('Missing scroll element with ID:', id);
2280
+ return !config.stopPropagation;
2281
+ }
2282
+ // Check if body overflow is visible
2283
+ // This is necessary for scroll handling
2284
+ const body = document.querySelector('body');
2285
+ let undoOverflowChanges = false;
2286
+ const scrollBodyStyles = JSON.parse(JSON.stringify(window.getComputedStyle(body)));
2287
+ if (config.setOverflow && (scrollBodyStyles.overflowX !== 'visible' || scrollBodyStyles.overflowY !== 'visible')) {
2288
+ // Set body overflow to visible
2289
+ console.warn('Style of body element for overflowX and overflowY will be set to "visible" for scrolling!');
2290
+ body.style.overflowX = 'visible';
2291
+ body.style.overflowY = 'visible';
2292
+ undoOverflowChanges = true;
2293
+ }
2294
+ // Load images before scrolling (once)
2295
+ if (config.loadImagesBefore) {
2296
+ await this.imageService.preLoadImages();
2297
+ }
2298
+ // Get get bounding rect of target element
2299
+ const cords = el.getBoundingClientRect();
2300
+ // Scroll to element
2301
+ window.scrollBy({ top: cords.top - this.scrollOffset, behavior: 'smooth' });
2302
+ await this.scrollDone({
2303
+ doneFunction: () => {
2304
+ // Undo changes
2305
+ if (undoOverflowChanges && config.resetStyles) {
2306
+ body.style.overflowX = scrollBodyStyles.overflowX;
2307
+ body.style.overflowY = scrollBodyStyles.overflowY;
2308
+ console.warn('Original style of body element for overflowX and overflowY is set.');
2309
+ }
2310
+ },
2311
+ });
2312
+ // Return stop propagation configuration
2313
+ return !config.stopPropagation;
2314
+ }
2315
+ /**
2316
+ * Get last active structureElement
2317
+ */
2318
+ getLastActiveElement(list) {
2319
+ const currentScrollPosition = window.scrollY;
2320
+ const elementsWithId = document.querySelectorAll('[id]');
2321
+ let lastId = null;
2322
+ let lastPosition = 0 - this.detectionOffset - 1;
2323
+ elementsWithId.forEach((element) => {
2324
+ const cords = element.getBoundingClientRect();
2325
+ const top = cords.top + window.pageYOffset - this.detectionOffset;
2326
+ if ((!list || !list.length || list.includes(element.id)) && // In list
2327
+ top < currentScrollPosition && // In active area
2328
+ lastPosition < top // Higher than the last one
2329
+ ) {
2330
+ lastId = element.id;
2331
+ lastPosition = top;
2332
+ }
2333
+ });
2334
+ return lastId;
2335
+ }
2336
+ /**
2337
+ * Check if ID is active
2338
+ */
2339
+ isActive(id, list, isFirst) {
2340
+ const lastActiveElement = this.getLastActiveElement(list);
2341
+ return id === lastActiveElement || (lastActiveElement === null && isFirst);
2342
+ }
2343
+ /**
2344
+ * Scroll done promise
2345
+ */
2346
+ async scrollDone(options = {}) {
2347
+ // Init configuration
2348
+ const config = {
2349
+ doneFunction: undefined,
2350
+ ...options,
2351
+ };
2352
+ // Wait for scroll done
2353
+ await this.scrollDoneDetection();
2354
+ // Get result
2355
+ if (config.doneFunction) {
2356
+ return config.doneFunction();
2357
+ }
2358
+ }
2359
+ /**
2360
+ * Scroll done detecton
2361
+ *
2362
+ * @protected
2363
+ */
2364
+ scrollDoneDetection() {
2365
+ // Return current scroll promise (Singelton)
2366
+ if (this.scrollPromise) {
2367
+ return this.scrollPromise;
2368
+ }
2369
+ // Create current scroll promise
2370
+ this.scrollPromise = new Promise((resolve) => {
2371
+ this.scrollPromiseResolve = resolve;
2372
+ if (this.scrollTimer !== -1) {
2373
+ window.clearTimeout(this.scrollTimer);
2374
+ }
2375
+ this.scrollTimer = window.setTimeout(() => {
2376
+ window.removeEventListener('scroll', this.scrollDoneDetection.bind(this));
2377
+ this.scrollPromise = undefined;
2378
+ resolve();
2379
+ }, this.scrollSamplingRate);
2380
+ });
2381
+ // Lisitening to scroll event;
2382
+ window.addEventListener('scroll', this.scrollDoneDetection.bind(this));
2383
+ // Return promise
2384
+ return this.scrollPromise;
2385
+ }
2386
+ }
2387
+ ScrollService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.0", ngImport: i0, type: ScrollService, deps: [{ token: i1$1.Router }, { token: BASE_MODULE_CONFIG }, { token: ImageService }], target: i0.ɵɵFactoryTarget.Injectable });
2388
+ ScrollService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.3.0", ngImport: i0, type: ScrollService, providedIn: 'root' });
2389
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.0", ngImport: i0, type: ScrollService, decorators: [{
2390
+ type: Injectable,
2391
+ args: [{
2392
+ providedIn: 'root',
2393
+ }]
2394
+ }], ctorParameters: function () { return [{ type: i1$1.Router }, { type: undefined, decorators: [{
2395
+ type: Inject,
2396
+ args: [BASE_MODULE_CONFIG]
2397
+ }] }, { type: ImageService }]; } });
2398
+
2399
+ /**
2400
+ * SEO service for setting HTML meta data
2401
+ */
2402
+ class SEOService {
2403
+ constructor(titleService, metaTagService) {
2404
+ this.titleService = titleService;
2405
+ this.metaTagService = metaTagService;
2406
+ }
2407
+ initPageForSEO(input) {
2408
+ this.setGeneralData(input);
2409
+ this.setTwitterData(input);
2410
+ this.setTwitterData(input);
2411
+ this.setFacebookData(input);
2412
+ if (input.keywords) {
2413
+ this.setPageKeywords(input.keywords);
2414
+ }
2415
+ }
2416
+ /**
2417
+ * Set general metadata
2418
+ *
2419
+ * @param data
2420
+ * @private
2421
+ */
2422
+ setGeneralData(data) {
2423
+ this.titleService.setTitle(data.title);
2424
+ this.metaTagService.updateTag({ name: 'description', content: data.description });
2425
+ }
2426
+ /**
2427
+ * Set metadata for twitter
2428
+ *
2429
+ * @param data
2430
+ * @private
2431
+ */
2432
+ setTwitterData(data) {
2433
+ this.metaTagService.updateTag({ name: 'twitter:title', content: data.title });
2434
+ this.metaTagService.updateTag({ name: 'twitter:description', content: data.description });
2435
+ this.metaTagService.updateTag({
2436
+ property: 'twitter:url',
2437
+ content: data.url ? data.url : window.location.href,
2438
+ });
2439
+ if (data.image) {
2440
+ this.metaTagService.updateTag({
2441
+ property: 'twitter:image',
2442
+ content: data.image,
2443
+ });
2444
+ this.metaTagService.updateTag({
2445
+ property: 'twitter:card',
2446
+ content: 'summary_large_image',
2447
+ });
2448
+ }
2449
+ }
2450
+ /**
2451
+ * Set metadata for facebook
2452
+ *
2453
+ * @param data
2454
+ * @private
2455
+ */
2456
+ setFacebookData(data) {
2457
+ this.metaTagService.updateTag({ property: 'og:title', content: data.title });
2458
+ this.metaTagService.updateTag({ property: 'og:description', content: data.description });
2459
+ this.metaTagService.updateTag({
2460
+ property: 'og:type',
2461
+ content: 'website',
2462
+ });
2463
+ this.metaTagService.updateTag({
2464
+ property: 'og:url',
2465
+ content: data.url ? data.url : window.location.href,
2466
+ });
2467
+ if (data.image) {
2468
+ this.metaTagService.updateTag({
2469
+ property: 'og:image',
2470
+ content: data.image,
2471
+ });
2472
+ }
2473
+ }
2474
+ /**
2475
+ * Set page keywords
2476
+ *
2477
+ * @param keywords
2478
+ * @private
2479
+ */
2480
+ setPageKeywords(keywords) {
2481
+ this.metaTagService.updateTag({ name: 'keywords', content: keywords });
2482
+ }
2483
+ }
2484
+ SEOService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.0", ngImport: i0, type: SEOService, deps: [{ token: i1.Title }, { token: i1.Meta }], target: i0.ɵɵFactoryTarget.Injectable });
2485
+ SEOService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.3.0", ngImport: i0, type: SEOService, providedIn: 'root' });
2486
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.0", ngImport: i0, type: SEOService, decorators: [{
2487
+ type: Injectable,
2488
+ args: [{
2489
+ providedIn: 'root',
2490
+ }]
2491
+ }], ctorParameters: function () { return [{ type: i1.Title }, { type: i1.Meta }]; } });
2492
+
2493
+ /**
2494
+ * Custom validator to check that two fields match
2495
+ * (inspirated by https://jasonwatmore.com/post/2018/11/07/angular-7-reactive-forms-validation-example)
2496
+ */
2497
+ function MustMatch(controlName, matchingControlName) {
2498
+ return (formGroup) => {
2499
+ const control = formGroup.controls[controlName];
2500
+ const matchingControl = formGroup.controls[matchingControlName];
2501
+ if (matchingControl.errors && !matchingControl.errors.mustMatch) {
2502
+ // return if another validator has already found an error on the matchingControl
2503
+ return;
2504
+ }
2505
+ // set error on matchingControl if validation fails
2506
+ if (control.value !== matchingControl.value) {
2507
+ matchingControl.setErrors({ mustMatch: true });
2508
+ }
2509
+ else {
2510
+ matchingControl.setErrors(null);
2511
+ }
2512
+ };
2513
+ }
2514
+
2515
+ /**
2516
+ * Exports for public API
2517
+ */
2518
+
2519
+ // Export libs
2520
+
2521
+ /**
2522
+ * Generated bundle index. Do not edit.
2523
+ */
2524
+
2525
+ export { AuthGuard, AuthService, BASE_MODULE_CONFIG, BaseModule, BasicUser, CanDeactivateGuard, ComparisonOperatorEnum, ContextMenuDirective, EllipsesPipe, FullscreenService, GraphQLEnum, GraphQLMeta, GraphQLMetaService, GraphQLPlusService, GraphQLRequestType, GraphQLService, GraphQLType, Helper, ImageService, LazyLoadDirective, LoaderService, LogicalOperatorEnum, LogoutGuard, MatchHeightDirective, MustMatch, ResizableDirective, SEOService, SafeHtmlPipe, ScrollService, SortOrderEnum, Standard, StorageService, WsService, apolloOptionsFactory };
2526
+ //# sourceMappingURL=lenne.tech-ng-base.mjs.map