@indice/ng-components 0.2.138-beta → 0.2.139

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 (226) hide show
  1. package/CHANGELOG.md +1 -0
  2. package/README.md +4 -4
  3. package/karma.conf.js +44 -0
  4. package/ng-package.json +10 -0
  5. package/package.json +18 -9
  6. package/scripts/css-bundle.ts +33 -0
  7. package/src/_styles.css +36 -0
  8. package/src/_tests/utilities.service.spec.ts +16 -0
  9. package/src/assets/styles/avatar-initials.css +37 -0
  10. package/src/assets/styles/base.css +46 -0
  11. package/src/assets/styles/cards.css +71 -0
  12. package/src/assets/styles/collapsible-panel.css +25 -0
  13. package/src/assets/styles/components.css +34 -0
  14. package/src/assets/styles/date-picker.component.css +0 -0
  15. package/src/assets/styles/drop-down-menu.css +50 -0
  16. package/src/assets/styles/form-layout.css +49 -0
  17. package/{_styles.css → src/assets/styles/indice-ng-icons-inline.css} +2286 -3504
  18. package/src/assets/styles/list-view-empty-state.css +0 -0
  19. package/src/assets/styles/list-view.css +64 -0
  20. package/{modal.css → src/assets/styles/modal.css} +157 -157
  21. package/src/assets/styles/model-view-layout.css +45 -0
  22. package/src/assets/styles/nav-links.css +35 -0
  23. package/src/assets/styles/notifications-indicator.component.css +43 -0
  24. package/src/assets/styles/pager.css +29 -0
  25. package/src/assets/styles/shell-layout.css +232 -0
  26. package/src/assets/styles/side-pane.css +46 -0
  27. package/src/assets/styles/side-view-layout.css +58 -0
  28. package/src/assets/styles/toast.css +72 -0
  29. package/src/assets/styles/toggle.css +26 -0
  30. package/src/assets/styles/view-layout.css +58 -0
  31. package/src/lib/controls/avatar-initials/avatar-initials.component.html +3 -0
  32. package/src/lib/controls/avatar-initials/avatar-initials.component.ts +47 -0
  33. package/src/lib/controls/collapsible-panel/collapsible-panel.component.html +15 -0
  34. package/src/lib/controls/collapsible-panel/collapsible-panel.component.ts +16 -0
  35. package/src/lib/controls/date-picker/date-picker.component.html +133 -0
  36. package/src/lib/controls/date-picker/date-picker.component.ts +258 -0
  37. package/src/lib/controls/drop-down-menu/drop-down-menu.component.html +61 -0
  38. package/src/lib/controls/drop-down-menu/drop-down-menu.component.ts +59 -0
  39. package/src/lib/controls/kpi-tile/kpi-tile.component.html +18 -0
  40. package/src/lib/controls/kpi-tile/kpi-tile.component.ts +26 -0
  41. package/src/lib/controls/list-view/list-column.component.ts +10 -0
  42. package/src/lib/controls/list-view/list-details-section.component.ts +8 -0
  43. package/src/lib/controls/list-view/list-tile.component.ts +8 -0
  44. package/src/lib/controls/list-view/list-view-empty-state.component.html +20 -0
  45. package/src/lib/controls/list-view/list-view-empty-state.component.ts +19 -0
  46. package/src/lib/controls/list-view/list-view.component.html +151 -0
  47. package/src/lib/controls/list-view/list-view.component.ts +146 -0
  48. package/src/lib/controls/nav-links-list/nav-links-list.component.html +27 -0
  49. package/src/lib/controls/nav-links-list/nav-links-list.component.ts +25 -0
  50. package/src/lib/controls/notifications-indicator/notifications-indicator.component.html +78 -0
  51. package/src/lib/controls/notifications-indicator/notifications-indicator.component.ts +75 -0
  52. package/src/lib/controls/pager/pager.component.html +33 -0
  53. package/src/lib/controls/pager/pager.component.ts +106 -0
  54. package/src/lib/controls/side-pane/side-pane.component.html +10 -0
  55. package/src/lib/controls/side-pane/side-pane.component.ts +59 -0
  56. package/src/lib/controls/skeleton-loader/skeleton-loader.component.html +112 -0
  57. package/src/lib/controls/skeleton-loader/skeleton-loader.component.ts +20 -0
  58. package/src/lib/controls/toaster/toaster-container.component.html +1 -0
  59. package/src/lib/controls/toaster/toaster-container.component.ts +27 -0
  60. package/src/lib/controls/toaster/toaster.component.html +103 -0
  61. package/src/lib/controls/toaster/toaster.component.ts +26 -0
  62. package/src/lib/controls/toggle/toggle.component.html +15 -0
  63. package/src/lib/controls/toggle/toggle.component.ts +58 -0
  64. package/src/lib/directives/click-outside.directive.ts +196 -0
  65. package/src/lib/directives/dynamic-component-host.directive.ts +7 -0
  66. package/src/lib/directives/screen-size.directive.ts +67 -0
  67. package/src/lib/helpers/base-list.component.ts +204 -0
  68. package/src/lib/icons.ts +39 -0
  69. package/src/lib/layouts/shell/shell-footer/shell-footer.component.html +71 -0
  70. package/src/lib/layouts/shell/shell-footer/shell-footer.component.ts +14 -0
  71. package/src/lib/layouts/shell/shell-header/shell-header.component.html +199 -0
  72. package/src/lib/layouts/shell/shell-header/shell-header.component.ts +111 -0
  73. package/src/lib/layouts/shell/shell-layout/shell-layout.component.html +36 -0
  74. package/src/lib/layouts/shell/shell-layout/shell-layout.component.ts +91 -0
  75. package/src/lib/layouts/views/form-layout/form-layout.component.html +67 -0
  76. package/src/lib/layouts/views/form-layout/form-layout.component.ts +66 -0
  77. package/src/lib/layouts/views/model-view-layout/model-view-layout.component.html +43 -0
  78. package/src/lib/layouts/views/model-view-layout/model-view-layout.component.ts +37 -0
  79. package/src/lib/layouts/views/side-view-layout/side-view-layout.component.html +36 -0
  80. package/src/lib/layouts/views/side-view-layout/side-view-layout.component.ts +67 -0
  81. package/src/lib/layouts/views/view-layout/view-layout.component.html +68 -0
  82. package/src/lib/layouts/views/view-layout/view-layout.component.ts +82 -0
  83. package/src/lib/ng-components.module.ts +135 -0
  84. package/src/lib/pages/auth/auth-callback/auth-callback.component.html +1 -0
  85. package/src/lib/pages/auth/auth-callback/auth-callback.component.ts +22 -0
  86. package/src/lib/pages/auth/auth-renew/auth-renew.component.ts +20 -0
  87. package/src/lib/pages/auth/logged-out/logged-out.component.html +1 -0
  88. package/src/lib/pages/auth/logged-out/logged-out.component.ts +22 -0
  89. package/src/lib/pages/http-status/error/error.component.html +13 -0
  90. package/src/lib/pages/http-status/error/error.component.ts +13 -0
  91. package/src/lib/pages/http-status/page-not-found/page-not-found.component.html +14 -0
  92. package/src/lib/pages/http-status/page-not-found/page-not-found.component.ts +14 -0
  93. package/src/lib/pages/http-status/unauthorized/unauthorized.component.html +15 -0
  94. package/src/lib/pages/http-status/unauthorized/unauthorized.component.ts +11 -0
  95. package/src/lib/pipes/address.pipe.ts +17 -0
  96. package/src/lib/pipes/duration-format.pipe.ts +67 -0
  97. package/src/lib/services/component-loader/component-loader-options.class.ts +31 -0
  98. package/src/lib/services/component-loader/component-loader.class.ts +226 -0
  99. package/src/lib/services/component-loader/component-loader.factory.ts +27 -0
  100. package/src/lib/services/component-loader/content-ref.class.ts +10 -0
  101. package/src/lib/services/interceptors/bad-request.interceptor.ts +34 -0
  102. package/src/lib/services/modal-service/modal-backdrop-component.ts +40 -0
  103. package/src/lib/services/modal-service/modal-container-component.ts +125 -0
  104. package/src/lib/services/modal-service/modal-options.class.ts +92 -0
  105. package/src/lib/services/modal-service/modal-service.ts +237 -0
  106. package/src/lib/services/modal-service/modal-styles.class.ts +11 -0
  107. package/src/lib/services/modal-service/modal.class.ts +45 -0
  108. package/src/lib/services/shell-state-service.service.ts +10 -0
  109. package/src/lib/services/toaster.service.ts +23 -0
  110. package/src/lib/services/utilities.service.ts +40 -0
  111. package/src/lib/tokens.ts +6 -0
  112. package/src/lib/types.ts +210 -0
  113. package/{public-api.d.ts → src/public-api.ts} +60 -43
  114. package/src/test.ts +28 -0
  115. package/tsconfig.lib.json +26 -0
  116. package/tsconfig.lib.prod.json +10 -0
  117. package/tsconfig.spec.json +17 -0
  118. package/tslint.json +17 -0
  119. package/webpack.config.js +36 -0
  120. package/bundles/indice-ng-components.umd.js +0 -3784
  121. package/bundles/indice-ng-components.umd.js.map +0 -1
  122. package/esm2015/indice-ng-components.js +0 -5
  123. package/esm2015/lib/controls/avatar-initials/avatar-initials.component.js +0 -51
  124. package/esm2015/lib/controls/collapsible-panel/collapsible-panel.component.js +0 -23
  125. package/esm2015/lib/controls/date-picker/date-picker.component.js +0 -269
  126. package/esm2015/lib/controls/drop-down-menu/drop-down-menu.component.js +0 -72
  127. package/esm2015/lib/controls/kpi-tile/kpi-tile.component.js +0 -39
  128. package/esm2015/lib/controls/list-view/list-column.component.js +0 -25
  129. package/esm2015/lib/controls/list-view/list-details-section.component.js +0 -17
  130. package/esm2015/lib/controls/list-view/list-tile.component.js +0 -17
  131. package/esm2015/lib/controls/list-view/list-view-empty-state.component.js +0 -32
  132. package/esm2015/lib/controls/list-view/list-view.component.js +0 -186
  133. package/esm2015/lib/controls/pager/pager.component.js +0 -133
  134. package/esm2015/lib/controls/side-pane/side-pane.component.js +0 -76
  135. package/esm2015/lib/controls/skeleton-loader/skeleton-loader.component.js +0 -29
  136. package/esm2015/lib/controls/toaster/toaster-container.component.js +0 -31
  137. package/esm2015/lib/controls/toaster/toaster.component.js +0 -34
  138. package/esm2015/lib/controls/toggle/toggle.component.js +0 -68
  139. package/esm2015/lib/directives/click-outside.directive.js +0 -189
  140. package/esm2015/lib/directives/dynamic-component-host.directive.js +0 -17
  141. package/esm2015/lib/helpers/base-list.component.js +0 -182
  142. package/esm2015/lib/icons.js +0 -32
  143. package/esm2015/lib/layouts/shell/shell-footer/shell-footer.component.js +0 -22
  144. package/esm2015/lib/layouts/shell/shell-header/shell-header.component.js +0 -142
  145. package/esm2015/lib/layouts/shell/shell-layout/shell-layout.component.js +0 -101
  146. package/esm2015/lib/layouts/views/form-layout/form-layout.component.js +0 -86
  147. package/esm2015/lib/layouts/views/model-view-layout/model-view-layout.component.js +0 -55
  148. package/esm2015/lib/layouts/views/side-view-layout/side-view-layout.component.js +0 -101
  149. package/esm2015/lib/layouts/views/view-layout/view-layout.component.js +0 -110
  150. package/esm2015/lib/ng-components.module.js +0 -220
  151. package/esm2015/lib/pages/auth/auth-callback/auth-callback.component.js +0 -34
  152. package/esm2015/lib/pages/auth/auth-renew/auth-renew.component.js +0 -31
  153. package/esm2015/lib/pages/auth/logged-out/logged-out.component.js +0 -32
  154. package/esm2015/lib/pages/http-status/error/error.component.js +0 -20
  155. package/esm2015/lib/pages/http-status/page-not-found/page-not-found.component.js +0 -18
  156. package/esm2015/lib/pages/http-status/unauthorized/unauthorized.component.js +0 -17
  157. package/esm2015/lib/pipes/address.pipe.js +0 -21
  158. package/esm2015/lib/pipes/duration-format.pipe.js +0 -64
  159. package/esm2015/lib/pipes/obs-with-status.pipe.js +0 -26
  160. package/esm2015/lib/services/component-loader/component-loader-options.class.js +0 -8
  161. package/esm2015/lib/services/component-loader/component-loader.class.js +0 -192
  162. package/esm2015/lib/services/component-loader/component-loader.factory.js +0 -32
  163. package/esm2015/lib/services/component-loader/content-ref.class.js +0 -13
  164. package/esm2015/lib/services/modal-service/modal-backdrop-component.js +0 -44
  165. package/esm2015/lib/services/modal-service/modal-container-component.js +0 -128
  166. package/esm2015/lib/services/modal-service/modal-options.class.js +0 -35
  167. package/esm2015/lib/services/modal-service/modal-service.js +0 -220
  168. package/esm2015/lib/services/modal-service/modal-styles.class.js +0 -11
  169. package/esm2015/lib/services/modal-service/modal.class.js +0 -27
  170. package/esm2015/lib/services/toaster.service.js +0 -24
  171. package/esm2015/lib/tokens.js +0 -4
  172. package/esm2015/lib/types.js +0 -114
  173. package/esm2015/public-api.js +0 -53
  174. package/fesm2015/indice-ng-components.js +0 -3247
  175. package/fesm2015/indice-ng-components.js.map +0 -1
  176. package/indice-ng-components.d.ts +0 -5
  177. package/lib/controls/avatar-initials/avatar-initials.component.d.ts +0 -14
  178. package/lib/controls/collapsible-panel/collapsible-panel.component.d.ts +0 -10
  179. package/lib/controls/date-picker/date-picker.component.d.ts +0 -48
  180. package/lib/controls/drop-down-menu/drop-down-menu.component.d.ts +0 -25
  181. package/lib/controls/kpi-tile/kpi-tile.component.d.ts +0 -13
  182. package/lib/controls/list-view/list-column.component.d.ts +0 -9
  183. package/lib/controls/list-view/list-details-section.component.d.ts +0 -7
  184. package/lib/controls/list-view/list-tile.component.d.ts +0 -7
  185. package/lib/controls/list-view/list-view-empty-state.component.d.ts +0 -11
  186. package/lib/controls/list-view/list-view.component.d.ts +0 -55
  187. package/lib/controls/pager/pager.component.d.ts +0 -36
  188. package/lib/controls/side-pane/side-pane.component.d.ts +0 -18
  189. package/lib/controls/skeleton-loader/skeleton-loader.component.d.ts +0 -11
  190. package/lib/controls/toaster/toaster-container.component.d.ts +0 -13
  191. package/lib/controls/toaster/toaster.component.d.ts +0 -15
  192. package/lib/controls/toggle/toggle.component.d.ts +0 -19
  193. package/lib/directives/click-outside.directive.d.ts +0 -40
  194. package/lib/directives/dynamic-component-host.directive.d.ts +0 -9
  195. package/lib/helpers/base-list.component.d.ts +0 -42
  196. package/lib/icons.d.ts +0 -30
  197. package/lib/layouts/shell/shell-footer/shell-footer.component.d.ts +0 -8
  198. package/lib/layouts/shell/shell-header/shell-header.component.d.ts +0 -45
  199. package/lib/layouts/shell/shell-layout/shell-layout.component.d.ts +0 -27
  200. package/lib/layouts/views/form-layout/form-layout.component.d.ts +0 -25
  201. package/lib/layouts/views/model-view-layout/model-view-layout.component.d.ts +0 -25
  202. package/lib/layouts/views/side-view-layout/side-view-layout.component.d.ts +0 -28
  203. package/lib/layouts/views/view-layout/view-layout.component.d.ts +0 -31
  204. package/lib/ng-components.module.d.ts +0 -45
  205. package/lib/pages/auth/auth-callback/auth-callback.component.d.ts +0 -13
  206. package/lib/pages/auth/auth-renew/auth-renew.component.d.ts +0 -12
  207. package/lib/pages/auth/logged-out/logged-out.component.d.ts +0 -12
  208. package/lib/pages/http-status/error/error.component.d.ts +0 -8
  209. package/lib/pages/http-status/page-not-found/page-not-found.component.d.ts +0 -8
  210. package/lib/pages/http-status/unauthorized/unauthorized.component.d.ts +0 -8
  211. package/lib/pipes/address.pipe.d.ts +0 -8
  212. package/lib/pipes/duration-format.pipe.d.ts +0 -8
  213. package/lib/pipes/obs-with-status.pipe.d.ts +0 -13
  214. package/lib/services/component-loader/component-loader-options.class.d.ts +0 -30
  215. package/lib/services/component-loader/component-loader.class.d.ts +0 -92
  216. package/lib/services/component-loader/component-loader.factory.d.ts +0 -24
  217. package/lib/services/component-loader/content-ref.class.d.ts +0 -12
  218. package/lib/services/modal-service/modal-backdrop-component.d.ts +0 -20
  219. package/lib/services/modal-service/modal-container-component.d.ts +0 -33
  220. package/lib/services/modal-service/modal-options.class.d.ts +0 -81
  221. package/lib/services/modal-service/modal-service.d.ts +0 -58
  222. package/lib/services/modal-service/modal-styles.class.d.ts +0 -10
  223. package/lib/services/modal-service/modal.class.d.ts +0 -43
  224. package/lib/services/toaster.service.d.ts +0 -11
  225. package/lib/tokens.d.ts +0 -4
  226. package/lib/types.d.ts +0 -135
@@ -0,0 +1,226 @@
1
+ import {
2
+ ComponentFactoryResolver,
3
+ ViewContainerRef,
4
+ ComponentFactory,
5
+ Type,
6
+ ElementRef,
7
+ StaticProvider,
8
+ TemplateRef,
9
+ ComponentRef,
10
+ ApplicationRef,
11
+ Injector,
12
+ } from '@angular/core';
13
+ import { Subject } from 'rxjs';
14
+ import { ComponentLoaderOptions } from './component-loader-options.class';
15
+ import { ContentRef } from './content-ref.class';
16
+
17
+ /**
18
+ * Provides ways of loading and handling dynamic content.
19
+ *
20
+ * @remarks
21
+ * Do NOT use this directly, create an instance through {@link ComponentLoaderFactory}
22
+ * You can use this loader in two ways:
23
+ * - Attaches a component to `ViewContainerRef`.
24
+ * - Attaches a component to `ViewContainerRef`. The attached component has a `<ng-content>` tag inside its view. The {@link ComponentLoaderOptions.content} will be drawn inside this tag.
25
+ *
26
+ * @internal
27
+ */
28
+ export class ComponentLoader<T> {
29
+ /**
30
+ * Before content is shown event.
31
+ */
32
+ onBeforeShow = new Subject();
33
+ /**
34
+ * After show content event.
35
+ * @returns The id of newly created component ref.
36
+ */
37
+ onShown = new Subject();
38
+ /**
39
+ * Before content is hidden event.
40
+ * @returns The instance of attached component;
41
+ */
42
+ onBeforeHide = new Subject();
43
+ /**
44
+ * After content is hidden event.
45
+ * @returns The id of destroyed component ref.
46
+ */
47
+ onHidden = new Subject();
48
+
49
+ public instance?: T;
50
+ public componentRef?: ComponentRef<T>;
51
+ private componentFactory?: ComponentFactory<T>;
52
+ private container: string | ElementRef | any;
53
+ private providers: StaticProvider[] = [];
54
+ private contentRef?: ContentRef;
55
+ private containerDefaultSelector = 'body';
56
+ private innerComponent?: ComponentRef<T>;
57
+ constructor(
58
+ private vcr: ViewContainerRef | undefined,
59
+ private cfr: ComponentFactoryResolver,
60
+ private applicationRef: ApplicationRef,
61
+ private injector: Injector
62
+ ) {}
63
+
64
+ /**
65
+ * Attaches component.
66
+ * @param componentType - The type component to attach.
67
+ * @returns Current instance of {@link ComponentLoader}
68
+ */
69
+ public attach(componentType: Type<T>): ComponentLoader<T> {
70
+ this.componentFactory = this.cfr.resolveComponentFactory<T>(componentType);
71
+ return this;
72
+ }
73
+
74
+ /**
75
+ * Body will be used in nothing is provided.
76
+ * @param container - The element in which dynamic content will be drawn inside to. For string case a query to the dom will be executed to find the element.
77
+ * @returns Current instance of {@link ComponentLoader}
78
+ */
79
+ public to(container?: string | ElementRef): ComponentLoader<T> {
80
+ this.container = container || this.container;
81
+ return this;
82
+ }
83
+
84
+ /**
85
+ * Adds provider to the providers array. These providers will be injected to the attached component.
86
+ *
87
+ * @see {@link https://angular.io/guide/glossary#di-token | Injection Token}
88
+ *
89
+ * @param provider - Provider to inject.
90
+ * @returns Current instance of {@link ComponentLoader}
91
+ */
92
+ public provide(provider: StaticProvider): ComponentLoader<T> {
93
+ this.providers.push(provider);
94
+ return this;
95
+ }
96
+
97
+ /**
98
+ * Attaches attached component to dom and any dynamic content if provided.
99
+ * @remarks
100
+ * Also triggers the {@link ComponentLoader.onBeforeShow} and {@link ComponentLoader.onShown} events.
101
+ *
102
+ * @param options - {@link ComponentLoaderOptions}.
103
+ * @returns A reference to the created content.
104
+ */
105
+ public show(options: ComponentLoaderOptions = {}): ComponentRef<T> | undefined {
106
+ if (this.componentRef) {
107
+ throw Error('Component is already shown');
108
+ }
109
+ if (!this.componentFactory) {
110
+ throw Error('You must attach a component');
111
+ }
112
+ this.onBeforeShow.next();
113
+
114
+ if (options.content) {
115
+ this.contentRef = this.getContentRef(options.content, options.context, options.initialState);
116
+ }
117
+ this.createComponentAndAttachToView(options);
118
+ this.appendContentToContainer();
119
+ this.markComponentsForCheck();
120
+
121
+ this.onShown.next(options.id);
122
+
123
+ return this.componentRef;
124
+ }
125
+
126
+ /**
127
+ * Removes attached component from dom.
128
+ * @remarks
129
+ * Also triggers the {@link ComponentLoader.onBeforeHide} and {@link ComponentLoader.onHidden} events.
130
+ *
131
+ * @param id - If provided it is returned through the {@link ComponentLoader.onHidden}.
132
+ * @returns Current instance of {@link ComponentLoader}
133
+ */
134
+ public hide(id?: number | string, result?: any): ComponentLoader<T> {
135
+ if (!this.componentRef) {
136
+ throw Error('No attached component found to hide');
137
+ }
138
+
139
+ this.onBeforeHide.next(this.componentRef.instance);
140
+
141
+ const componentEl = this.componentRef.location.nativeElement;
142
+ componentEl.parentNode.removeChild(componentEl);
143
+ if (this.contentRef?.componentRef) {
144
+ this.contentRef.componentRef.destroy();
145
+ }
146
+ if (this.vcr && this.contentRef?.viewRef) {
147
+ this.vcr.remove(this.vcr.indexOf(this.contentRef.viewRef));
148
+ }
149
+ if (this.contentRef?.viewRef) {
150
+ this.contentRef.viewRef.destroy();
151
+ }
152
+ this.contentRef = void 0;
153
+ this.componentRef = void 0;
154
+
155
+ this.onHidden.next(id ? { id, result } : null);
156
+
157
+ return this;
158
+ }
159
+
160
+ getInnerComponent(): ComponentRef<T> | undefined {
161
+ return this.innerComponent;
162
+ }
163
+
164
+ private markComponentsForCheck() {
165
+ if (this.contentRef?.componentRef) {
166
+ this.innerComponent = this.contentRef.componentRef.instance;
167
+ this.contentRef.componentRef.changeDetectorRef.markForCheck();
168
+ this.contentRef.componentRef.changeDetectorRef.detectChanges();
169
+ }
170
+ this.componentRef!.changeDetectorRef.markForCheck();
171
+ this.componentRef!.changeDetectorRef.detectChanges();
172
+ }
173
+
174
+ private createComponentAndAttachToView(options: ComponentLoaderOptions) {
175
+ const injector = Injector.create({
176
+ providers: this.providers,
177
+ parent: this.injector,
178
+ });
179
+ this.componentRef = this.componentFactory!.create(injector, this.contentRef?.nodes);
180
+ this.applicationRef.attachView(this.componentRef.hostView);
181
+ this.instance = this.componentRef.instance;
182
+ Object.assign(this.componentRef.instance, options);
183
+ }
184
+
185
+ private appendContentToContainer() {
186
+ if (this.container instanceof ElementRef) {
187
+ this.container.nativeElement.appendChild(this.componentRef?.location.nativeElement);
188
+ }
189
+ if (typeof this.container === 'string' && typeof document !== 'undefined') {
190
+ const selectedElement = document.querySelector(this.container) || document.querySelector(this.containerDefaultSelector);
191
+ if (!selectedElement) {
192
+ return;
193
+ }
194
+ selectedElement.appendChild(this.componentRef?.location.nativeElement);
195
+ }
196
+ }
197
+
198
+ private getContentRef(content?: string | TemplateRef<any>, context?: any, initialState?: any): ContentRef {
199
+ //TemplateRef case
200
+ if (content instanceof TemplateRef) {
201
+ if (this.vcr) {
202
+ const viewRef = this.vcr.createEmbeddedView<TemplateRef<T>>(content, context);
203
+ viewRef.markForCheck();
204
+ return new ContentRef([viewRef.rootNodes], viewRef);
205
+ }
206
+ const viewRef = content.createEmbeddedView({});
207
+ this.applicationRef.attachView(viewRef);
208
+ return new ContentRef([viewRef.rootNodes], viewRef);
209
+ }
210
+
211
+ //Component case
212
+ if (typeof content === 'function') {
213
+ const contentCf = this.cfr.resolveComponentFactory(content);
214
+ const injector = Injector.create({
215
+ providers: this.providers,
216
+ parent: this.injector,
217
+ });
218
+ const componentRef = contentCf.create(injector);
219
+ Object.assign(componentRef.instance, initialState);
220
+ this.applicationRef.attachView(componentRef.hostView);
221
+ return new ContentRef([[componentRef.location.nativeElement]], componentRef.hostView, componentRef);
222
+ }
223
+
224
+ throw Error('Unsupported content type');
225
+ }
226
+ }
@@ -0,0 +1,27 @@
1
+ import { ApplicationRef, ComponentFactoryResolver, Injectable, Injector, ViewContainerRef } from '@angular/core';
2
+ import { ComponentLoader } from './component-loader.class';
3
+
4
+ /**
5
+ * Use to create instances of {@link ComponentLoader}.
6
+ *
7
+ * @public
8
+ */
9
+ @Injectable({ providedIn: 'root' })
10
+ export class ComponentLoaderFactory {
11
+ constructor(
12
+ private componentFactoryResolver: ComponentFactoryResolver,
13
+ private injector: Injector,
14
+ private applicationRef: ApplicationRef
15
+ ) {}
16
+
17
+ /**
18
+ * Returns a new instance of {@link ComponentLoader}
19
+ * @param viewContainerRef - The view container the dynamic content will be attached to.
20
+ * @returns A new instance of {@link ComponentLoader}.
21
+ *
22
+ * @public
23
+ */
24
+ createLoader<T>(viewContainerRef?: ViewContainerRef): ComponentLoader<T> {
25
+ return new ComponentLoader<T>(viewContainerRef, this.componentFactoryResolver, this.applicationRef, this.injector);
26
+ }
27
+ }
@@ -0,0 +1,10 @@
1
+ import { ComponentRef, ViewRef } from '@angular/core';
2
+
3
+ /**
4
+ * Holds information about the dynamic content.
5
+ * @remarks
6
+ * `ComponentRef` is undefined in the case content is of `TemplateRef` type.
7
+ */
8
+ export class ContentRef {
9
+ constructor(public nodes: any[], public viewRef?: ViewRef, public componentRef?: ComponentRef<any>) {}
10
+ }
@@ -0,0 +1,34 @@
1
+ import { Inject, Injectable } from '@angular/core';
2
+ import { HttpErrorResponse, HttpEvent, HttpHandler, HttpInterceptor, HttpRequest, HttpResponse } from '@angular/common/http';
3
+
4
+ import { Observable } from 'rxjs';
5
+ import { catchError } from 'rxjs/operators';
6
+ import { ToasterService } from '../toaster.service';
7
+ import { UtilitiesService } from '../utilities.service';
8
+ import { ToastType } from '../../types';
9
+
10
+
11
+ @Injectable()
12
+ export class BadRequestInterceptor implements HttpInterceptor {
13
+ constructor(
14
+ @Inject(ToasterService) private toaster: ToasterService,
15
+ private utilities: UtilitiesService
16
+ ) { }
17
+
18
+ public intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
19
+ return next.handle(request).pipe(
20
+ catchError((error: HttpResponse<any>) => {
21
+ if (error instanceof HttpErrorResponse && error.status === 400) {
22
+ const fileReader = new FileReader();
23
+ fileReader.addEventListener('loadend', () => {
24
+ // tslint:disable-next-line:no-non-null-assertion
25
+ const problemDetails = fileReader.result!;
26
+ this.toaster.show(ToastType.Error, 'Αποτυχία αιτήματος', `${this.utilities.getValidationProblemDetails(JSON.parse(problemDetails.toString()))}`, 6000);
27
+ });
28
+ fileReader.readAsText(error.error);
29
+ }
30
+ throw error;
31
+ })
32
+ );
33
+ }
34
+ }
@@ -0,0 +1,40 @@
1
+ import { Component, ElementRef, OnInit, Renderer2, ViewEncapsulation } from '@angular/core';
2
+ import { ComponentLoader } from '../component-loader/component-loader.class';
3
+ import { animationTime, cssClassNames } from './modal-styles.class';
4
+
5
+ /**
6
+ * Background layer for modals.
7
+ * Override class name to theme it.
8
+ * @see {@link cssClassNames}
9
+ * @internal
10
+ */
11
+ @Component({
12
+ selector: 'lib-modal-backdrop',
13
+ encapsulation: ViewEncapsulation.None,
14
+ template: '',
15
+ host: {
16
+ class: cssClassNames.backdrop,
17
+ },
18
+ })
19
+ export class ModalBackdropComponent implements OnInit {
20
+ private animationsEnabled = false;
21
+ private backdropLoader: ComponentLoader<ModalBackdropComponent> | undefined;
22
+ constructor(private element: ElementRef, private renderer: Renderer2) {}
23
+
24
+ ngOnInit(): void {
25
+ if (this.animationsEnabled) {
26
+ this.renderer.addClass(this.element.nativeElement, cssClassNames.fade);
27
+ this.reflow(this.element.nativeElement);
28
+ }
29
+ this.renderer.addClass(this.element.nativeElement, cssClassNames.show);
30
+ }
31
+
32
+ public hide() {
33
+ this.renderer.removeClass(this.element.nativeElement, cssClassNames.show);
34
+ setTimeout(() => this.backdropLoader?.hide(), this.animationsEnabled ? animationTime.backdrop : 0);
35
+ }
36
+
37
+ reflow(element: any): void {
38
+ ((bs: any): void => bs)(element.offsetHeight);
39
+ }
40
+ }
@@ -0,0 +1,125 @@
1
+ import { Component, ElementRef, HostListener, OnDestroy, OnInit, Renderer2 } from '@angular/core';
2
+ import { animationTime, cssClassNames } from './modal-styles.class';
3
+ import { ModalOptions } from './modal-options.class';
4
+ import { ModalService } from './modal-service';
5
+
6
+ /**
7
+ * Modal container component.
8
+ * @remarks
9
+ * All dynamic content `TemplateRef` or `Component` case will be drawn inside this.
10
+ * You can override css classes to theme it {@link cssClassNames}
11
+ * @internal
12
+ */
13
+ @Component({
14
+ selector: 'lib-modal-container',
15
+ template: `
16
+ <div [class]="'modal-dialog' + (config.class ? ' ' + config.class : '')" role="document" focusTrap>
17
+ <div class="modal-content">
18
+ <ng-content></ng-content>
19
+ </div>
20
+ </div>
21
+ `,
22
+ host: {
23
+ class: 'modal',
24
+ role: 'dialog',
25
+ tabindex: '-1',
26
+ '[attr.aria-modal]': 'true',
27
+ '[attr.aria-labelledby]': 'config.ariaLabelledBy',
28
+ '[attr.aria-describedby]': 'config.ariaDescribedby',
29
+ },
30
+ })
31
+ export class ModalContainerComponent implements OnInit, OnDestroy {
32
+ public level?: number;
33
+ public config: ModalOptions;
34
+ public modalService?: ModalService;
35
+ private isShown = false;
36
+ private animationsEnabled = false;
37
+ private isModalHiding = false;
38
+ private clickStartedInContent = false;
39
+ constructor(options: ModalOptions, protected _element: ElementRef, private renderer: Renderer2) {
40
+ this.config = Object.assign({}, options);
41
+ }
42
+
43
+ ngOnInit(): void {
44
+ if (this.animationsEnabled) {
45
+ this.renderer.addClass(this._element.nativeElement, cssClassNames.fade);
46
+ }
47
+ this.renderer.setStyle(this._element.nativeElement, 'display', 'block');
48
+ setTimeout(
49
+ () => {
50
+ this.isShown = true;
51
+ this.renderer.addClass(this._element.nativeElement, cssClassNames.show);
52
+ },
53
+ this.animationsEnabled ? animationTime.backdrop : 0
54
+ );
55
+ if (this._element.nativeElement) {
56
+ this._element.nativeElement.focus();
57
+ }
58
+ }
59
+
60
+ @HostListener('mousedown', ['$event'])
61
+ onClickStarted(event: MouseEvent): void {
62
+ this.clickStartedInContent = event.target !== this._element.nativeElement;
63
+ }
64
+
65
+ @HostListener('click', ['$event'])
66
+ onClickStop(event: MouseEvent): void {
67
+ const clickedInBackdrop = event.target === this._element.nativeElement && !this.clickStartedInContent;
68
+ if (this.config.ignoreBackdropClick || this.config.backdrop === 'static' || !clickedInBackdrop) {
69
+ this.clickStartedInContent = false;
70
+ return;
71
+ }
72
+ this.hide();
73
+ }
74
+
75
+ @HostListener('window:popstate')
76
+ onPopState(): void {
77
+ this.hide();
78
+ }
79
+
80
+ @HostListener('window:keydown.esc', ['$event'])
81
+ onEsc(event: KeyboardEvent): void {
82
+ if (!this.isShown) {
83
+ return;
84
+ }
85
+ if (event.keyCode === 27 || event.key === 'Escape' || event.key === 'Esc') {
86
+ event.preventDefault();
87
+ }
88
+ if (this.config.keyboard && this.config.id === this.modalService?.getActiveModal().config.id) {
89
+ this.hide();
90
+ }
91
+ }
92
+
93
+ ngOnDestroy(): void {
94
+ if (this.isShown) {
95
+ this._hide();
96
+ }
97
+ }
98
+
99
+ hide(result?: any): void {
100
+ if (this.isModalHiding || !this.isShown) {
101
+ return;
102
+ }
103
+ if (this.config.closeInterceptor) {
104
+ this.config.closeInterceptor().then(
105
+ () => this._hide(),
106
+ () => undefined
107
+ );
108
+ return;
109
+ }
110
+ this._hide(result);
111
+ }
112
+
113
+ private _hide(result?: any): void {
114
+ this.isModalHiding = true;
115
+ this.renderer.removeClass(this._element.nativeElement, cssClassNames.show);
116
+ setTimeout(
117
+ () => {
118
+ this.isShown = false;
119
+ this.modalService?.hide(this.config.id, result);
120
+ this.isModalHiding = false;
121
+ },
122
+ this.animationsEnabled ? animationTime.modal : 0
123
+ );
124
+ }
125
+ }
@@ -0,0 +1,92 @@
1
+ import { Injectable, InjectionToken, StaticProvider } from '@angular/core';
2
+
3
+ /**
4
+ * Modals option can be passed to a specific modal from {@link ModalService.show} or
5
+ * set globbaly using the injection token {@link MODAL_CONFIG_DEFAULT_OVERRIDE}.
6
+ * @remarks
7
+ * Modal specific options are merged with global options.
8
+ * @see {@link modalConfigDefaults} for defaults.
9
+ * @public
10
+ */
11
+ @Injectable()
12
+ export class ModalOptions<T = Record<string, unknown>> {
13
+ /**
14
+ * Id for opened modal. If not set a random one is generated.
15
+ */
16
+ id?: number | string;
17
+ /**
18
+ * If static is set the modal will not close when clicking outside of modal.
19
+ * @remarks
20
+ * Keyboard event (escape key) stills applies. If you must get a result then also set keyboard to false.
21
+ */
22
+ backdrop?: boolean | 'static';
23
+ /**
24
+ * Closes the modal when escape key is pressed.
25
+ */
26
+ keyboard?: boolean;
27
+ /**
28
+ * Shows the modal when initialized.
29
+ */
30
+ show?: boolean;
31
+ /**
32
+ * Ignore the backdrop click. Pretty much the same as backdrop static.
33
+ */
34
+ ignoreBackdropClick?: boolean;
35
+ /**
36
+ * Css class for opened modal.
37
+ */
38
+ class?: string;
39
+ /**
40
+ * Toggle animation.
41
+ */
42
+ animated?: boolean;
43
+ /**
44
+ * Modal initial data.
45
+ * @remarks
46
+ * This data must be known properties of content component.
47
+ */
48
+ initialState?: Partial<T>;
49
+ /**
50
+ * Function to intercept the closure.
51
+ * @remarks
52
+ * You can use to catch the close event and even prevent it from closing.
53
+ */
54
+ closeInterceptor?: CloseInterceptorFn;
55
+ /**
56
+ * Modal static providers.
57
+ * @see {@link https://angular.io/guide/glossary#di-token | Injection Token}
58
+ */
59
+ providers?: StaticProvider[];
60
+ /**
61
+ * aria-labelledby attribute value to set on the modal window.
62
+ */
63
+ ariaLabelledBy?: string;
64
+ /**
65
+ * aria-describedby attribute value to set on the modal window.
66
+ */
67
+ ariaDescribedby?: string;
68
+ }
69
+
70
+ /**
71
+ * Default option values.
72
+ */
73
+ export const modalConfigDefaults: ModalOptions = {
74
+ backdrop: true,
75
+ keyboard: true,
76
+ show: false,
77
+ ignoreBackdropClick: false,
78
+ class: '',
79
+ animated: true,
80
+ initialState: {},
81
+ closeInterceptor: void 0,
82
+ };
83
+
84
+ /**
85
+ * Use this injection token to set global options.
86
+ */
87
+ export const MODAL_CONFIG_DEFAULT_OVERRIDE: InjectionToken<ModalOptions> = new InjectionToken<ModalOptions>('override-default-config');
88
+
89
+ /**
90
+ * Close interceptor promise.
91
+ */
92
+ export type CloseInterceptorFn = () => Promise<void>;