@net7/boilerplate-common 3.0.1-rc.2

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 (93) hide show
  1. package/README.md +24 -0
  2. package/esm2020/lib/components/index.mjs +2 -0
  3. package/esm2020/lib/components/smart-pagination/smart-pagination.mjs +25 -0
  4. package/esm2020/lib/config-types/common.mjs +2 -0
  5. package/esm2020/lib/config-types/index.mjs +2 -0
  6. package/esm2020/lib/data-sources/breadcrumbs.ds.mjs +7 -0
  7. package/esm2020/lib/data-sources/facets.ds.mjs +9 -0
  8. package/esm2020/lib/data-sources/footer.ds.mjs +10 -0
  9. package/esm2020/lib/data-sources/header.ds.mjs +72 -0
  10. package/esm2020/lib/data-sources/index.mjs +7 -0
  11. package/esm2020/lib/data-sources/smart-pagination.ds.mjs +131 -0
  12. package/esm2020/lib/data-sources/subnav.ds.mjs +25 -0
  13. package/esm2020/lib/event-handlers/breadcrumbs.eh.mjs +20 -0
  14. package/esm2020/lib/event-handlers/footer.eh.mjs +7 -0
  15. package/esm2020/lib/event-handlers/header.eh.mjs +27 -0
  16. package/esm2020/lib/event-handlers/index.mjs +6 -0
  17. package/esm2020/lib/event-handlers/smart-pagination.eh.mjs +19 -0
  18. package/esm2020/lib/event-handlers/subnav.eh.mjs +20 -0
  19. package/esm2020/lib/helpers.mjs +76 -0
  20. package/esm2020/lib/layouts/index.mjs +11 -0
  21. package/esm2020/lib/layouts/main-layout/main-layout.config.mjs +24 -0
  22. package/esm2020/lib/layouts/main-layout/main-layout.ds.mjs +83 -0
  23. package/esm2020/lib/layouts/main-layout/main-layout.eh.mjs +60 -0
  24. package/esm2020/lib/layouts/main-layout/main-layout.mjs +45 -0
  25. package/esm2020/lib/layouts/page404-layout/page404-layout.config.mjs +16 -0
  26. package/esm2020/lib/layouts/page404-layout/page404-layout.ds.mjs +7 -0
  27. package/esm2020/lib/layouts/page404-layout/page404-layout.eh.mjs +36 -0
  28. package/esm2020/lib/layouts/page404-layout/page404-layout.mjs +28 -0
  29. package/esm2020/lib/models/abstract-layout.mjs +27 -0
  30. package/esm2020/lib/models/index.mjs +2 -0
  31. package/esm2020/lib/n7-boilerplate-common.module.mjs +61 -0
  32. package/esm2020/lib/services/communication-providers/apollo.provider.mjs +87 -0
  33. package/esm2020/lib/services/communication-providers/communication-provider.interface.mjs +2 -0
  34. package/esm2020/lib/services/communication-providers/rest.provider.mjs +40 -0
  35. package/esm2020/lib/services/communication.service.mjs +54 -0
  36. package/esm2020/lib/services/configuration.service.mjs +18 -0
  37. package/esm2020/lib/services/index.mjs +10 -0
  38. package/esm2020/lib/services/json-config.service.mjs +55 -0
  39. package/esm2020/lib/services/layouts-configuration.service.mjs +27 -0
  40. package/esm2020/lib/services/local-config.service.mjs +46 -0
  41. package/esm2020/lib/services/main-state.service.mjs +52 -0
  42. package/esm2020/net7-boilerplate-common.mjs +5 -0
  43. package/esm2020/public-api.mjs +14 -0
  44. package/fesm2015/net7-boilerplate-common.mjs +1161 -0
  45. package/fesm2015/net7-boilerplate-common.mjs.map +1 -0
  46. package/fesm2020/net7-boilerplate-common.mjs +1164 -0
  47. package/fesm2020/net7-boilerplate-common.mjs.map +1 -0
  48. package/lib/components/index.d.ts +1 -0
  49. package/lib/components/smart-pagination/smart-pagination.d.ts +9 -0
  50. package/lib/config-types/common.d.ts +22 -0
  51. package/lib/config-types/index.d.ts +1 -0
  52. package/lib/data-sources/breadcrumbs.ds.d.ts +5 -0
  53. package/lib/data-sources/facets.ds.d.ts +7 -0
  54. package/lib/data-sources/footer.ds.d.ts +4 -0
  55. package/lib/data-sources/header.ds.d.ts +9 -0
  56. package/lib/data-sources/index.d.ts +6 -0
  57. package/lib/data-sources/smart-pagination.ds.d.ts +89 -0
  58. package/lib/data-sources/subnav.ds.d.ts +9 -0
  59. package/lib/event-handlers/breadcrumbs.eh.d.ts +4 -0
  60. package/lib/event-handlers/footer.eh.d.ts +4 -0
  61. package/lib/event-handlers/header.eh.d.ts +4 -0
  62. package/lib/event-handlers/index.d.ts +5 -0
  63. package/lib/event-handlers/smart-pagination.eh.d.ts +4 -0
  64. package/lib/event-handlers/subnav.eh.d.ts +4 -0
  65. package/lib/helpers.d.ts +14 -0
  66. package/lib/layouts/index.d.ts +8 -0
  67. package/lib/layouts/main-layout/main-layout.config.d.ts +15 -0
  68. package/lib/layouts/main-layout/main-layout.d.ts +29 -0
  69. package/lib/layouts/main-layout/main-layout.ds.d.ts +21 -0
  70. package/lib/layouts/main-layout/main-layout.eh.d.ts +10 -0
  71. package/lib/layouts/page404-layout/page404-layout.config.d.ts +13 -0
  72. package/lib/layouts/page404-layout/page404-layout.d.ts +14 -0
  73. package/lib/layouts/page404-layout/page404-layout.ds.d.ts +7 -0
  74. package/lib/layouts/page404-layout/page404-layout.eh.d.ts +5 -0
  75. package/lib/models/abstract-layout.d.ts +9 -0
  76. package/lib/models/index.d.ts +1 -0
  77. package/lib/n7-boilerplate-common.module.d.ts +14 -0
  78. package/lib/services/communication-providers/apollo.provider.d.ts +14 -0
  79. package/lib/services/communication-providers/communication-provider.interface.d.ts +3 -0
  80. package/lib/services/communication-providers/rest.provider.d.ts +10 -0
  81. package/lib/services/communication.service.d.ts +17 -0
  82. package/lib/services/configuration.service.d.ts +8 -0
  83. package/lib/services/index.d.ts +8 -0
  84. package/lib/services/json-config.service.d.ts +12 -0
  85. package/lib/services/layouts-configuration.service.d.ts +10 -0
  86. package/lib/services/local-config.service.d.ts +9 -0
  87. package/lib/services/main-state.service.d.ts +17 -0
  88. package/net7-boilerplate-common.d.ts +5 -0
  89. package/package.json +34 -0
  90. package/public-api.d.ts +9 -0
  91. package/src/lib/styles/common/components/_facets-wrapper.scss +38 -0
  92. package/src/lib/styles/common/layouts/_main-layout.scss +48 -0
  93. package/src/lib/styles/common/utilities/_utilities.scss +43 -0
@@ -0,0 +1,1161 @@
1
+ import * as i0 from '@angular/core';
2
+ import { Injectable, Inject, Component, Input, NgModule } from '@angular/core';
3
+ import * as i7 from '@angular/common';
4
+ import { CommonModule } from '@angular/common';
5
+ import * as i1 from '@angular/common/http';
6
+ import { HttpClientModule } from '@angular/common/http';
7
+ import * as i6 from '@n7-frontend/components';
8
+ import { DvComponentsLibModule } from '@n7-frontend/components';
9
+ import { ReplaySubject, empty, Subject, of } from 'rxjs';
10
+ import { map, catchError, takeUntil, filter, tap } from 'rxjs/operators';
11
+ import { LayoutBuilder, LayoutDataSource, EventHandler, DataSource, _t } from '@n7-frontend/core';
12
+ import { hideAll } from 'tippy.js';
13
+ import * as i1$1 from '@angular/router';
14
+ import { NavigationStart } from '@angular/router';
15
+ import * as i5 from '@angular/platform-browser';
16
+ import { merge } from 'lodash';
17
+ import slugify from 'slugify';
18
+
19
+ class ConfigurationService {
20
+ constructor() {
21
+ this.defaults = {};
22
+ this.get = (key) => this.defaults[key];
23
+ this.set = (key, value) => { this.defaults[key] = value; };
24
+ }
25
+ }
26
+ ConfigurationService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: ConfigurationService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
27
+ ConfigurationService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: ConfigurationService, providedIn: 'root' });
28
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: ConfigurationService, decorators: [{
29
+ type: Injectable,
30
+ args: [{
31
+ providedIn: 'root',
32
+ }]
33
+ }] });
34
+
35
+ class LayoutsConfigurationService {
36
+ constructor(config) {
37
+ var _a;
38
+ this.config = config;
39
+ this.defaults = {};
40
+ this.get = (key) => this.defaults[key];
41
+ this.set = (key, value) => { this.defaults[key] = value; };
42
+ if ((_a = this.config) === null || _a === void 0 ? void 0 : _a.layouts) {
43
+ Object.keys(this.config.layouts).forEach((key) => {
44
+ this.set(key, this.config.layouts[key]);
45
+ });
46
+ }
47
+ }
48
+ }
49
+ LayoutsConfigurationService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: LayoutsConfigurationService, deps: [{ token: 'config' }], target: i0.ɵɵFactoryTarget.Injectable });
50
+ LayoutsConfigurationService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: LayoutsConfigurationService, providedIn: 'root' });
51
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: LayoutsConfigurationService, decorators: [{
52
+ type: Injectable,
53
+ args: [{
54
+ providedIn: 'root',
55
+ }]
56
+ }], ctorParameters: function () {
57
+ return [{ type: undefined, decorators: [{
58
+ type: Inject,
59
+ args: ['config']
60
+ }] }];
61
+ } });
62
+
63
+ class MainStateService {
64
+ constructor() {
65
+ // custom streams
66
+ this.custom = {};
67
+ // default streams
68
+ this.default = {
69
+ headTitle: new ReplaySubject(),
70
+ pageTitle: new ReplaySubject(),
71
+ subnav: new ReplaySubject(),
72
+ breadcrumbs: new ReplaySubject(),
73
+ filters: new ReplaySubject(),
74
+ header: new ReplaySubject(),
75
+ };
76
+ this.get$ = (key) => this._get('default', key);
77
+ this.getCustom$ = (key) => this._get('custom', key);
78
+ this.update = (key, newValue) => this._update('default', key, newValue);
79
+ this.updateCustom = (key, newValue) => this._update('custom', key, newValue);
80
+ this.has = (key) => !!this.default[key];
81
+ this.hasCustom = (key) => !!this.custom[key];
82
+ }
83
+ addCustom(key, stream$) {
84
+ if (this.custom[key])
85
+ throw Error(`custom stream ${key} exists!`);
86
+ this.custom[key] = stream$;
87
+ }
88
+ _update(type, key, newValue) {
89
+ if (!this[type])
90
+ throw Error(`${type} stream group does not exists!`);
91
+ if (!this[type][key])
92
+ throw Error(`${type} stream ${key} does not exists!`);
93
+ this[type][key].next(newValue);
94
+ }
95
+ _get(type, key) {
96
+ if (!this[type])
97
+ throw Error(`${type} stream group does not exists!`);
98
+ if (!this[type][key])
99
+ throw Error(`${type} stream ${key} does not exists!`);
100
+ return this[type][key];
101
+ }
102
+ }
103
+ MainStateService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: MainStateService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
104
+ MainStateService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: MainStateService, providedIn: 'root' });
105
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: MainStateService, decorators: [{
106
+ type: Injectable,
107
+ args: [{
108
+ providedIn: 'root',
109
+ }]
110
+ }] });
111
+
112
+ const DEFAULT_TREE_DEPTH = 15;
113
+ class ApolloProvider {
114
+ constructor(http, configuration) {
115
+ this.http = http;
116
+ this.configuration = configuration;
117
+ }
118
+ request$(providerConfig, requestId, options) {
119
+ const { params, method, httpOptions } = options;
120
+ const treeDepth = this.configuration.get('treeDepth') || DEFAULT_TREE_DEPTH;
121
+ const config = providerConfig.config ? providerConfig.config(treeDepth) : {};
122
+ let query;
123
+ if (config && config[requestId]) {
124
+ query = config[requestId];
125
+ }
126
+ query = query || {};
127
+ const { queryName } = query;
128
+ let { queryBody } = query;
129
+ // config query control
130
+ if (!queryName || !queryBody) {
131
+ throw Error(`No config found for requestId '${requestId}'`);
132
+ }
133
+ if (params) {
134
+ const paramsStr = this.makeParamsStr(params);
135
+ queryBody = queryBody.replace('__PARAMS__', paramsStr);
136
+ }
137
+ else {
138
+ queryBody = queryBody.replace('(__PARAMS__)', '');
139
+ }
140
+ let source$;
141
+ if (method && method === 'GET') {
142
+ source$ = this.http.get(providerConfig.baseUrl);
143
+ }
144
+ else {
145
+ source$ = this.http.post(providerConfig.baseUrl, { query: queryBody }, httpOptions);
146
+ }
147
+ return source$.pipe(map((response) => response.data[queryName]));
148
+ }
149
+ makeParamsStr(params) {
150
+ const paramsStr = [];
151
+ Object.keys(params).forEach((key) => {
152
+ if (Array.isArray(params[key])) {
153
+ const arrStr = [];
154
+ params[key].forEach((val) => {
155
+ if (typeof val === 'object') {
156
+ const subParamsStr = this.makeParamsStr(val);
157
+ arrStr.push(`{ ${subParamsStr} }`);
158
+ }
159
+ else if (typeof val === 'number' || typeof val === 'boolean' || val === null) {
160
+ arrStr.push(`${val}`);
161
+ }
162
+ else {
163
+ arrStr.push(`"${val}"`);
164
+ }
165
+ });
166
+ paramsStr.push(`${key}: [${arrStr.join(',')}]`);
167
+ }
168
+ else if (typeof params[key] === 'object' && params[key]) {
169
+ const subParamsStr = this.makeParamsStr(params[key]);
170
+ paramsStr.push(`${key}: { ${subParamsStr} }`);
171
+ }
172
+ else if (typeof params[key] === 'string' && key.indexOf('$') === 0) {
173
+ paramsStr.push(`${key.replace('$', '')}: ${params[key]}`);
174
+ }
175
+ else if (typeof params[key] === 'number' || typeof params[key] === 'boolean' || params[key] === null) {
176
+ paramsStr.push(`${key}: ${params[key]}`);
177
+ }
178
+ else {
179
+ paramsStr.push(`${key}: "${params[key]}"`);
180
+ }
181
+ });
182
+ return paramsStr.join(' ');
183
+ }
184
+ }
185
+ ApolloProvider.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: ApolloProvider, deps: [{ token: i1.HttpClient }, { token: ConfigurationService }], target: i0.ɵɵFactoryTarget.Injectable });
186
+ ApolloProvider.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: ApolloProvider, providedIn: 'root' });
187
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: ApolloProvider, decorators: [{
188
+ type: Injectable,
189
+ args: [{
190
+ providedIn: 'root',
191
+ }]
192
+ }], ctorParameters: function () { return [{ type: i1.HttpClient }, { type: ConfigurationService }]; } });
193
+
194
+ class RestProvider {
195
+ constructor(http) {
196
+ this.http = http;
197
+ }
198
+ request$(providerConfig, requestId, options = {}) {
199
+ const { params, httpOptions, urlParams = '', } = options;
200
+ let { method } = options;
201
+ let point;
202
+ // default method
203
+ if (!method) {
204
+ method = providerConfig.defaultMethod || 'GET';
205
+ }
206
+ if (providerConfig.config && providerConfig.config[requestId]) {
207
+ point = providerConfig.config[requestId];
208
+ }
209
+ // config point control
210
+ if (!point) {
211
+ throw Error(`No config found for requestId "${requestId}"`);
212
+ }
213
+ if (method === 'POST' || method === 'PUT') {
214
+ return this.http[method.toLowerCase()](providerConfig.baseUrl + point + urlParams, params, httpOptions);
215
+ }
216
+ if (method === 'GET' || method === 'DELETE') {
217
+ return this.http[method.toLowerCase()](providerConfig.baseUrl + point + urlParams, httpOptions);
218
+ }
219
+ throw Error(`Rest method ${method} not supported`);
220
+ }
221
+ }
222
+ RestProvider.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: RestProvider, deps: [{ token: i1.HttpClient }], target: i0.ɵɵFactoryTarget.Injectable });
223
+ RestProvider.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: RestProvider, providedIn: 'root' });
224
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: RestProvider, decorators: [{
225
+ type: Injectable,
226
+ args: [{
227
+ providedIn: 'root',
228
+ }]
229
+ }], ctorParameters: function () { return [{ type: i1.HttpClient }]; } });
230
+
231
+ class CommunicationService {
232
+ constructor(config, apollo, rest) {
233
+ this.config = config;
234
+ this.apollo = apollo;
235
+ this.rest = rest;
236
+ try {
237
+ this.communicationConfig = this.config.get('communication');
238
+ this.defaultProvider = this.communicationConfig.defaultProvider;
239
+ }
240
+ catch (err) {
241
+ throw Error('No communications.defaultProvider setted in config');
242
+ }
243
+ }
244
+ request$(requestId, options = {}, provider) {
245
+ const activeProvider = provider || this.defaultProvider;
246
+ const activeProviderConfig = this.communicationConfig.providers[activeProvider];
247
+ if (!activeProviderConfig) {
248
+ throw Error(`There is no config for "${activeProvider}" provider`);
249
+ }
250
+ // provider.type control for retrocompatibility
251
+ const activeProviderType = activeProviderConfig.type || activeProvider;
252
+ if (!this[activeProviderType]) {
253
+ throw Error(`There is no "${activeProviderType}" provider type`);
254
+ }
255
+ const { onError } = options;
256
+ return this[activeProviderType].request$(activeProviderConfig, requestId, options)
257
+ .pipe(catchError((error) => this.handleError(error, onError)));
258
+ }
259
+ handleError(error, onError) {
260
+ if (onError) {
261
+ onError(error);
262
+ }
263
+ else {
264
+ console.warn('No error handler for communication request', error);
265
+ }
266
+ return empty();
267
+ }
268
+ }
269
+ CommunicationService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: CommunicationService, deps: [{ token: ConfigurationService }, { token: ApolloProvider }, { token: RestProvider }], target: i0.ɵɵFactoryTarget.Injectable });
270
+ CommunicationService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: CommunicationService, providedIn: 'root' });
271
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: CommunicationService, decorators: [{
272
+ type: Injectable,
273
+ args: [{
274
+ providedIn: 'root',
275
+ }]
276
+ }], ctorParameters: function () { return [{ type: ConfigurationService }, { type: ApolloProvider }, { type: RestProvider }]; } });
277
+
278
+ class AbstractLayout {
279
+ constructor(config) {
280
+ this.config = config;
281
+ this.widgets = this.config.widgets;
282
+ this.lb = new LayoutBuilder(this.config.layoutId);
283
+ }
284
+ onInit() {
285
+ // on ready
286
+ this.lb.ready$.subscribe(() => {
287
+ this.lb.eventHandler.emitInner('init', this.initPayload());
288
+ });
289
+ const LayoutDS = this.config.layoutDS;
290
+ const LayoutEH = this.config.layoutEH;
291
+ this.lb.init({
292
+ widgetsConfig: this.widgets,
293
+ widgetsDataSources: this.config.widgetsDataSources,
294
+ widgetsEventHandlers: this.config.widgetsEventHandlers,
295
+ dataSource: new LayoutDS(),
296
+ eventHandler: new LayoutEH(),
297
+ });
298
+ }
299
+ onDestroy() {
300
+ this.lb.eventHandler.emitInner('destroy');
301
+ }
302
+ }
303
+
304
+ class MainLayoutDS extends LayoutDataSource {
305
+ onInit({ configuration, mainState, router, options, titleService, route, }) {
306
+ this.configuration = configuration;
307
+ this.mainState = mainState;
308
+ this.router = router;
309
+ this.route = route;
310
+ this.titleService = titleService;
311
+ this.options = options;
312
+ // update header
313
+ if (this.configuration.get('header')) {
314
+ this.one('header').update(this.configuration.get('header'));
315
+ }
316
+ if (this.configuration.get('footer')) {
317
+ this.one('footer').update(this.configuration.get('footer'));
318
+ }
319
+ // main state updates
320
+ this.mainState.get$('headTitle').subscribe((val) => {
321
+ this.titleService.setTitle(val);
322
+ });
323
+ this.mainState.get$('pageTitle').subscribe((val) => {
324
+ this.pageTitle = val;
325
+ });
326
+ this.mainState.get$('subnav').subscribe((val) => {
327
+ this.one('subnav').update(val);
328
+ });
329
+ this.mainState.get$('breadcrumbs').subscribe((val) => {
330
+ this.one('breadcrumbs').update(val);
331
+ });
332
+ this.mainState.get$('header').subscribe((val) => {
333
+ this.one('header').update(val);
334
+ });
335
+ // mainState test
336
+ /* this.mainState.addCustom('customNav', new Subject());
337
+ this.mainState.get$('pageTitle').subscribe(val => console.log('pageTitle', val));
338
+ this.mainState.getCustom$('customNav').subscribe(val => console.log('customNav', val));
339
+
340
+ this.mainState.update('pageTitle', 'hola');
341
+ this.mainState.updateCustom('customNav', {'hello': 'mundo!'});
342
+
343
+ setTimeout(() => {
344
+ this.mainState.update('pageTitle', 'chao');
345
+ this.mainState.updateCustom('customNav', {'hello': 'world!'});
346
+ console.log('has', {
347
+ 'pageSubTitle' : this.mainState.has('pageSubTitle'),
348
+ 'customNav' : this.mainState.hasCustom('customNav'),
349
+ 'customNavs' : this.mainState.has('customNavs'),
350
+ });
351
+ }, 5000); */
352
+ }
353
+ // navigate emitter (click) handler
354
+ onNavigate(payload) {
355
+ // router navigation
356
+ if (payload.handler === 'router') {
357
+ const { path, queryParams } = payload;
358
+ // path control
359
+ if (!path)
360
+ throw Error('onNavigate: no path for router navigate');
361
+ if (queryParams) {
362
+ this.router.navigate(path, {
363
+ relativeTo: this.route,
364
+ queryParams,
365
+ queryParamsHandling: 'merge',
366
+ });
367
+ }
368
+ else {
369
+ this.router.navigate(path);
370
+ }
371
+ // on change
372
+ this._onRouterNavigate();
373
+ }
374
+ }
375
+ // links routerLink change handler
376
+ onRouterChanged() {
377
+ hideAll();
378
+ }
379
+ _onRouterNavigate() {
380
+ // hide tippy
381
+ hideAll();
382
+ }
383
+ }
384
+
385
+ class MainLayoutEH extends EventHandler {
386
+ constructor() {
387
+ super(...arguments);
388
+ this.destroyed$ = new Subject();
389
+ }
390
+ listen() {
391
+ this.innerEvents$.subscribe(({ type, payload }) => {
392
+ switch (type) {
393
+ case 'main-layout.init':
394
+ this.dataSource.onInit(payload);
395
+ this.mainState = payload.mainState;
396
+ this.route = payload.route;
397
+ this.router = payload.router;
398
+ this._listenRouterChanges();
399
+ this._listenMainStateChanges();
400
+ break;
401
+ case 'main-layout.destroy':
402
+ this.destroyed$.next();
403
+ break;
404
+ default:
405
+ break;
406
+ }
407
+ });
408
+ // listen to global events
409
+ EventHandler.globalEvents$.pipe(takeUntil(this.destroyed$)).subscribe(({ type, payload }) => {
410
+ switch (type) {
411
+ case 'global.navigate':
412
+ this.dataSource.onNavigate(payload);
413
+ break;
414
+ default:
415
+ break;
416
+ }
417
+ });
418
+ }
419
+ _listenRouterChanges() {
420
+ this.route.queryParams.pipe(filter((params) => {
421
+ if (Object.keys(params).length)
422
+ return true;
423
+ return false;
424
+ })).subscribe((params) => {
425
+ this.emitGlobal('queryparams', params);
426
+ });
427
+ // router changed
428
+ this.router.events.pipe(filter((event) => event instanceof NavigationStart)).subscribe(() => {
429
+ this.emitOuter('routerchange');
430
+ this.dataSource.onRouterChanged();
431
+ });
432
+ }
433
+ _listenMainStateChanges() {
434
+ this.mainState.addCustom('currentNav', new Subject());
435
+ this.mainState.getCustom$('currentNav').subscribe((val) => {
436
+ this.emitOuter('currentnavchange', val);
437
+ });
438
+ }
439
+ }
440
+
441
+ const MOBILE_CLASS = 'is-mobile-nav-displayed';
442
+ const ACTIVE_CLASS = 'is-active';
443
+ class HeaderDS extends DataSource {
444
+ transform(data) {
445
+ if (!data) {
446
+ return null;
447
+ }
448
+ return Object.assign(Object.assign({}, data), { menuToggle: {
449
+ open: {
450
+ payload: 'mobile-open'
451
+ },
452
+ close: {
453
+ payload: 'mobile-close'
454
+ }
455
+ } });
456
+ }
457
+ onCurrentNavChange(payload) {
458
+ this.output.nav.items.forEach((item) => {
459
+ this.updateItemClass(item, payload);
460
+ if (item.subnav) {
461
+ item.subnav.forEach((subNavItem) => {
462
+ this.updateItemClass(subNavItem, payload);
463
+ });
464
+ }
465
+ });
466
+ }
467
+ onRouterChange() {
468
+ if (!this.output) {
469
+ return;
470
+ }
471
+ let { classes } = this.output;
472
+ classes = classes || '';
473
+ classes = classes.split(' ');
474
+ if (classes.includes(MOBILE_CLASS)) {
475
+ classes.splice(classes.indexOf(MOBILE_CLASS), 1);
476
+ this.output.classes = classes.join(' ');
477
+ }
478
+ }
479
+ onClick(payload) {
480
+ // mobile control
481
+ if (['mobile-open', 'mobile-close'].includes(payload)) {
482
+ let { classes } = this.output;
483
+ classes = classes || '';
484
+ classes = classes.split(' ');
485
+ if (classes.includes(MOBILE_CLASS)) {
486
+ classes.splice(classes.indexOf(MOBILE_CLASS), 1);
487
+ }
488
+ else {
489
+ classes.push(MOBILE_CLASS);
490
+ }
491
+ this.output.classes = classes.join(' ');
492
+ }
493
+ }
494
+ updateItemClass(item, payload) {
495
+ let itemClasses = [];
496
+ if (item.classes) {
497
+ itemClasses = itemClasses.concat(item.classes.split(' '));
498
+ }
499
+ if (item._meta.id === payload && !itemClasses.includes(ACTIVE_CLASS)) {
500
+ itemClasses.push(ACTIVE_CLASS);
501
+ }
502
+ else if (itemClasses.includes(ACTIVE_CLASS)) {
503
+ itemClasses.splice(itemClasses.indexOf(ACTIVE_CLASS, 1));
504
+ }
505
+ item.classes = itemClasses.join(' ');
506
+ }
507
+ }
508
+
509
+ class SubnavDS extends DataSource {
510
+ transform(data) {
511
+ return {
512
+ classes: 'main-subnav',
513
+ items: data,
514
+ };
515
+ }
516
+ setActive(id) {
517
+ this.output.items.forEach((item) => {
518
+ if (item._meta.id === id) {
519
+ item.classes = 'is-current';
520
+ item._meta.isActive = true;
521
+ }
522
+ else {
523
+ item.classes = '';
524
+ item._meta.isActive = false;
525
+ }
526
+ });
527
+ }
528
+ getActive() {
529
+ return this.output.items.filter((item) => item._meta.isActive)[0] || null;
530
+ }
531
+ }
532
+
533
+ class BreadcrumbsDS extends DataSource {
534
+ transform(data) {
535
+ return data;
536
+ }
537
+ }
538
+
539
+ class FacetsDS extends DataSource {
540
+ transform({ fields }) {
541
+ const { searchModel } = this.options;
542
+ this.searchModel = searchModel;
543
+ return fields;
544
+ }
545
+ }
546
+
547
+ class FooterDS extends DataSource {
548
+ transform(data) {
549
+ if (!data) {
550
+ return null;
551
+ }
552
+ return data;
553
+ }
554
+ }
555
+
556
+ class SmartPaginationDS extends DataSource {
557
+ constructor() {
558
+ super(...arguments);
559
+ this.paginationBuilder = (tp, cp, pl, m, href, qp) => {
560
+ const result = [];
561
+ /*
562
+ tp - total pages
563
+ cp - current page
564
+ pl - page limit
565
+ m - pagination mode (href or payloads)
566
+ href - href for anchor wrapper
567
+ qp - query params for pagination
568
+ */
569
+ let limit = pl;
570
+ if (tp <= limit) {
571
+ limit = tp - 1;
572
+ }
573
+ if (limit) {
574
+ let lp; // last page
575
+ let fp; // first page
576
+ if (cp > Math.floor(limit / 2)) {
577
+ if (tp === 2) {
578
+ lp = tp;
579
+ fp = 1;
580
+ // when currentPage is after half-point
581
+ // (example: [ 14 ][ 15 ][!16!][ 17 ][ 18 ])
582
+ }
583
+ else if (cp < (tp - Math.floor(limit / 2))) {
584
+ lp = cp / 1 + Math.floor(limit / 2);
585
+ fp = cp / 1 - Math.floor(limit / 2);
586
+ }
587
+ else {
588
+ lp = tp;
589
+ fp = cp - limit + (tp - cp);
590
+ }
591
+ }
592
+ else {
593
+ // when currentPage is before half-point
594
+ // (example: [ 1 ][!2!][ 3 ][ 4 ][ 5 ])
595
+ lp = limit + 1;
596
+ fp = 1;
597
+ }
598
+ for (let i = fp; i <= lp; i += 1) {
599
+ result.push({
600
+ text: String(i),
601
+ classes: cp === i ? 'is-active' : '',
602
+ anchor: cp !== i ? this._getPaginationAnchor(i, m, href, qp) : null,
603
+ });
604
+ }
605
+ }
606
+ else {
607
+ result.push({
608
+ text: '1',
609
+ classes: cp === 1 ? 'is-active' : '',
610
+ anchor: cp !== 1 ? this._getPaginationAnchor(1, m, href, qp) : null,
611
+ });
612
+ for (let i = 1; i < tp; i += 1) {
613
+ result.push({
614
+ text: String(i + 1),
615
+ classes: cp === i + 1 ? 'is-active' : '',
616
+ anchor: cp !== i + 1 ? this._getPaginationAnchor(i + 1, m, href, qp) : null,
617
+ });
618
+ }
619
+ }
620
+ return {
621
+ links: result,
622
+ first: {
623
+ classes: cp === 1 ? 'is-disabled' : '',
624
+ anchor: cp !== 1 ? this._getPaginationAnchor(1, m, href, qp) : null,
625
+ },
626
+ prev: {
627
+ classes: cp === 1 ? 'is-disabled' : '',
628
+ anchor: cp !== 1 ? this._getPaginationAnchor(cp / 1 - 1, m, href, qp) : null,
629
+ },
630
+ next: {
631
+ classes: cp === tp ? 'is-disabled' : '',
632
+ anchor: cp !== tp ? this._getPaginationAnchor(cp / 1 + 1, m, href, qp) : null,
633
+ },
634
+ last: {
635
+ classes: cp === tp ? 'is-disabled' : '',
636
+ anchor: cp !== tp ? this._getPaginationAnchor(tp, m, href, qp) : null,
637
+ },
638
+ };
639
+ };
640
+ }
641
+ transform(data) {
642
+ const { totalPages, currentPage, pageLimit, sizes } = data;
643
+ const { mode, href, queryParams } = this.options;
644
+ // ===== WARNINGS =====
645
+ if (!['href', 'payload'].includes(mode)) {
646
+ console.warn('(smart-pagination) The "mode" option is incorrect. Please specify "href" or "payload" as the mode option.');
647
+ }
648
+ const { links, first, prev, next, last, } = this.paginationBuilder(totalPages, +currentPage, pageLimit, mode, href, queryParams);
649
+ return {
650
+ first,
651
+ prev,
652
+ next,
653
+ last,
654
+ links,
655
+ select: sizes ? {
656
+ label: sizes.label || _t('search#resultsamount'),
657
+ options: sizes.list.map((s) => ({
658
+ text: s,
659
+ selected: s === sizes.active,
660
+ })),
661
+ payload: 'select-size',
662
+ } : null,
663
+ };
664
+ }
665
+ _getPaginationAnchor(page, mode, href, queryParams) {
666
+ switch (mode) {
667
+ case 'payload':
668
+ return {
669
+ payload: { source: 'pagination', page },
670
+ };
671
+ case 'href':
672
+ return {
673
+ href: queryParams ? href : href + page,
674
+ queryParams: queryParams ? Object.assign(Object.assign({}, queryParams), { page }) : null,
675
+ };
676
+ default:
677
+ break;
678
+ }
679
+ return {};
680
+ }
681
+ }
682
+
683
+ var DS = /*#__PURE__*/Object.freeze({
684
+ __proto__: null,
685
+ HeaderDS: HeaderDS,
686
+ SubnavDS: SubnavDS,
687
+ BreadcrumbsDS: BreadcrumbsDS,
688
+ FacetsDS: FacetsDS,
689
+ FooterDS: FooterDS,
690
+ SmartPaginationDS: SmartPaginationDS
691
+ });
692
+
693
+ class HeaderEH extends EventHandler {
694
+ listen() {
695
+ this.innerEvents$.subscribe(({ type, payload }) => {
696
+ switch (type) {
697
+ case 'header.click':
698
+ this.dataSource.onClick(payload);
699
+ break;
700
+ default:
701
+ break;
702
+ }
703
+ });
704
+ this.outerEvents$.subscribe(({ type, payload }) => {
705
+ switch (type) {
706
+ case 'main-layout.currentnavchange':
707
+ this.dataSource.onCurrentNavChange(payload);
708
+ break;
709
+ case 'main-layout.routerchange':
710
+ this.dataSource.onRouterChange();
711
+ break;
712
+ default:
713
+ break;
714
+ }
715
+ });
716
+ }
717
+ }
718
+
719
+ class SubnavEH extends EventHandler {
720
+ listen() {
721
+ this.innerEvents$.subscribe(({ type, payload }) => {
722
+ switch (type) {
723
+ case 'subnav.click':
724
+ // navigate control
725
+ if (payload.source === 'navigate') {
726
+ this.emitGlobal('navigate', payload);
727
+ }
728
+ // global signal
729
+ this.emitGlobal(type, payload);
730
+ break;
731
+ default:
732
+ break;
733
+ }
734
+ });
735
+ }
736
+ }
737
+
738
+ class BreadcrumbsEH extends EventHandler {
739
+ listen() {
740
+ this.innerEvents$.subscribe(({ type, payload }) => {
741
+ switch (type) {
742
+ case 'breadcrumbs.click':
743
+ // navigate control
744
+ if (payload.source === 'navigate') {
745
+ this.emitGlobal('navigate', payload);
746
+ }
747
+ // global signal
748
+ this.emitGlobal(type, payload);
749
+ break;
750
+ default:
751
+ break;
752
+ }
753
+ });
754
+ }
755
+ }
756
+
757
+ class FooterEH extends EventHandler {
758
+ listen() {
759
+ // no events
760
+ }
761
+ }
762
+
763
+ class SmartPaginationEH extends EventHandler {
764
+ listen() {
765
+ this.innerEvents$.subscribe(({ type, payload }) => {
766
+ switch (type) {
767
+ case 'n7-smart-pagination.change':
768
+ this.emitOuter('change', payload);
769
+ break;
770
+ case 'n7-smart-pagination.click':
771
+ this.emitOuter('click', payload);
772
+ break;
773
+ default:
774
+ console.warn('unhandled inner event of type', type);
775
+ break;
776
+ }
777
+ });
778
+ }
779
+ }
780
+
781
+ var EH = /*#__PURE__*/Object.freeze({
782
+ __proto__: null,
783
+ HeaderEH: HeaderEH,
784
+ SubnavEH: SubnavEH,
785
+ BreadcrumbsEH: BreadcrumbsEH,
786
+ FooterEH: FooterEH,
787
+ SmartPaginationEH: SmartPaginationEH
788
+ });
789
+
790
+ const MainLayoutConfig = {
791
+ layoutId: 'main-layout',
792
+ widgets: [{
793
+ id: 'header',
794
+ }, {
795
+ id: 'subnav',
796
+ }, {
797
+ id: 'breadcrumbs',
798
+ }, {
799
+ id: 'footer',
800
+ }],
801
+ layoutDS: MainLayoutDS,
802
+ layoutEH: MainLayoutEH,
803
+ widgetsDataSources: DS,
804
+ widgetsEventHandlers: EH,
805
+ options: {
806
+ // TODO
807
+ },
808
+ };
809
+
810
+ class MainLayoutComponent extends AbstractLayout {
811
+ constructor(router, route, configuration, layoutsConfiguration, mainState, titleService) {
812
+ super(layoutsConfiguration.get('MainLayoutConfig') || MainLayoutConfig);
813
+ this.router = router;
814
+ this.route = route;
815
+ this.configuration = configuration;
816
+ this.layoutsConfiguration = layoutsConfiguration;
817
+ this.mainState = mainState;
818
+ this.titleService = titleService;
819
+ }
820
+ initPayload() {
821
+ return {
822
+ configuration: this.configuration,
823
+ mainState: this.mainState,
824
+ router: this.router,
825
+ route: this.route,
826
+ titleService: this.titleService,
827
+ options: this.config.options || {},
828
+ };
829
+ }
830
+ ngOnInit() {
831
+ this.onInit();
832
+ }
833
+ ngOnDestroy() {
834
+ this.onDestroy();
835
+ }
836
+ }
837
+ MainLayoutComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: MainLayoutComponent, deps: [{ token: i1$1.Router }, { token: i1$1.ActivatedRoute }, { token: ConfigurationService }, { token: LayoutsConfigurationService }, { token: MainStateService }, { token: i5.Title }], target: i0.ɵɵFactoryTarget.Component });
838
+ MainLayoutComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.2.1", type: MainLayoutComponent, selector: "main-layout", usesInheritance: true, ngImport: i0, template: "<div class=\"n7-main-layout\" id=\"main-layout\">\n <div class=\"n7-page-content\">\n <n7-header\n [data]=\"lb.widgets['header'].ds.out$ | async\"\n [emit]=\"lb.widgets['header'].emit\">\n </n7-header>\n <main class=\"n7-content\">\n <div class=\"n7-top-page-bar\">\n <div class=\"n7-top-page-bar__main\"></div>\n </div>\n <div class=\"n7-alert-bar\">\n <!--<n7-alert\n [attr.id]=\"'main-layout-alert'\"\n [data]=\"lb.dataSource.alertData$ | async\"\n [emit]=\"lb.dataSource.closeAlert.bind(lb.dataSource)\"></n7-alert>-->\n </div>\n <ng-content></ng-content>\n </main>\n </div>\n <n7-footer\n [data]=\"lb.widgets['footer'].ds.out$ | async\"\n [emit]=\"lb.widgets['footer'].emit\">\n </n7-footer>\n</div>\n", components: [{ type: i6.HeaderComponent, selector: "n7-header", inputs: ["data", "emit"] }, { type: i6.FooterComponent, selector: "n7-footer", inputs: ["data", "emit"] }], pipes: { "async": i7.AsyncPipe } });
839
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: MainLayoutComponent, decorators: [{
840
+ type: Component,
841
+ args: [{ selector: 'main-layout', template: "<div class=\"n7-main-layout\" id=\"main-layout\">\n <div class=\"n7-page-content\">\n <n7-header\n [data]=\"lb.widgets['header'].ds.out$ | async\"\n [emit]=\"lb.widgets['header'].emit\">\n </n7-header>\n <main class=\"n7-content\">\n <div class=\"n7-top-page-bar\">\n <div class=\"n7-top-page-bar__main\"></div>\n </div>\n <div class=\"n7-alert-bar\">\n <!--<n7-alert\n [attr.id]=\"'main-layout-alert'\"\n [data]=\"lb.dataSource.alertData$ | async\"\n [emit]=\"lb.dataSource.closeAlert.bind(lb.dataSource)\"></n7-alert>-->\n </div>\n <ng-content></ng-content>\n </main>\n </div>\n <n7-footer\n [data]=\"lb.widgets['footer'].ds.out$ | async\"\n [emit]=\"lb.widgets['footer'].emit\">\n </n7-footer>\n</div>\n" }]
842
+ }], ctorParameters: function () { return [{ type: i1$1.Router }, { type: i1$1.ActivatedRoute }, { type: ConfigurationService }, { type: LayoutsConfigurationService }, { type: MainStateService }, { type: i5.Title }]; } });
843
+
844
+ class Page404LayoutDS extends LayoutDataSource {
845
+ onInit({ options }) {
846
+ this.options = options;
847
+ }
848
+ }
849
+
850
+ class Page404LayoutEH extends EventHandler {
851
+ constructor() {
852
+ super(...arguments);
853
+ this.destroyed$ = new Subject();
854
+ }
855
+ listen() {
856
+ this.innerEvents$.subscribe(({ type, payload }) => {
857
+ switch (type) {
858
+ case 'n7-page404-layout.init':
859
+ this.dataSource.onInit(payload);
860
+ break;
861
+ case 'n7-page404-layout.destroy':
862
+ this.destroyed$.next();
863
+ break;
864
+ default:
865
+ break;
866
+ }
867
+ });
868
+ // listen to global events
869
+ /* EventHandler.globalEvents$.pipe(
870
+ takeUntil(this.destroyed$)
871
+ ).subscribe(({type, payload}) => {
872
+ switch(type){
873
+ case 'global.navigate':
874
+ this.dataSource.onNavigate(payload);
875
+ break;
876
+
877
+ default:
878
+ break;
879
+ }
880
+ }); */
881
+ }
882
+ }
883
+
884
+ const Page404LayoutConfig = {
885
+ layoutId: 'n7-page404-layout',
886
+ widgets: [],
887
+ layoutDS: Page404LayoutDS,
888
+ layoutEH: Page404LayoutEH,
889
+ widgetsDataSources: DS,
890
+ widgetsEventHandlers: EH,
891
+ options: {
892
+ // TODO
893
+ },
894
+ };
895
+
896
+ class Page404LayoutComponent extends AbstractLayout {
897
+ constructor(layoutsConfiguration) {
898
+ super(layoutsConfiguration.get('Page404LayoutConfig') || Page404LayoutConfig);
899
+ }
900
+ initPayload() {
901
+ return {
902
+ options: this.config.options || {},
903
+ };
904
+ }
905
+ ngOnInit() {
906
+ this.onInit();
907
+ }
908
+ ngOnDestroy() {
909
+ this.onDestroy();
910
+ }
911
+ }
912
+ Page404LayoutComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: Page404LayoutComponent, deps: [{ token: LayoutsConfigurationService }], target: i0.ɵɵFactoryTarget.Component });
913
+ Page404LayoutComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.2.1", type: Page404LayoutComponent, selector: "n7-page404-layout", usesInheritance: true, ngImport: i0, template: "<div class=\"n7-page404-layout\">\n 404 - Resource not found\n</div>" });
914
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: Page404LayoutComponent, decorators: [{
915
+ type: Component,
916
+ args: [{ selector: 'n7-page404-layout', template: "<div class=\"n7-page404-layout\">\n 404 - Resource not found\n</div>" }]
917
+ }], ctorParameters: function () { return [{ type: LayoutsConfigurationService }]; } });
918
+
919
+ class SmartPaginationComponent {
920
+ constructor() {
921
+ this.handlePaginationEvent.bind(this);
922
+ }
923
+ handlePaginationEvent(type, payload) {
924
+ if (!this.emit)
925
+ return;
926
+ this.emit('change', payload);
927
+ }
928
+ }
929
+ SmartPaginationComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: SmartPaginationComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
930
+ SmartPaginationComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.2.1", type: SmartPaginationComponent, selector: "n7-smart-pagination", inputs: { data: "data", emit: "emit" }, ngImport: i0, template: "<div class=\"n7-smart-pagination\" *ngIf=\"data\">\n <n7-pagination\n [data]=\"data\"\n [emit]=\"emit\">\n </n7-pagination>\n</div>", components: [{ type: i6.PaginationComponent, selector: "n7-pagination", inputs: ["data", "emit"] }], directives: [{ type: i7.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] });
931
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: SmartPaginationComponent, decorators: [{
932
+ type: Component,
933
+ args: [{ selector: 'n7-smart-pagination', template: "<div class=\"n7-smart-pagination\" *ngIf=\"data\">\n <n7-pagination\n [data]=\"data\"\n [emit]=\"emit\">\n </n7-pagination>\n</div>" }]
934
+ }], ctorParameters: function () { return []; }, propDecorators: { data: [{
935
+ type: Input
936
+ }], emit: [{
937
+ type: Input
938
+ }] } });
939
+
940
+ const COMPONENTS = [
941
+ MainLayoutComponent,
942
+ Page404LayoutComponent,
943
+ SmartPaginationComponent,
944
+ ];
945
+ class N7BoilerplateCommonModule {
946
+ static forRoot(config) {
947
+ return {
948
+ ngModule: N7BoilerplateCommonModule,
949
+ providers: [
950
+ MainStateService,
951
+ ConfigurationService,
952
+ LayoutsConfigurationService,
953
+ CommunicationService,
954
+ { provide: 'config', useValue: config },
955
+ ],
956
+ };
957
+ }
958
+ }
959
+ N7BoilerplateCommonModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: N7BoilerplateCommonModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
960
+ N7BoilerplateCommonModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: N7BoilerplateCommonModule, declarations: [MainLayoutComponent,
961
+ Page404LayoutComponent,
962
+ SmartPaginationComponent], imports: [CommonModule,
963
+ HttpClientModule,
964
+ DvComponentsLibModule], exports: [MainLayoutComponent,
965
+ Page404LayoutComponent,
966
+ SmartPaginationComponent] });
967
+ N7BoilerplateCommonModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: N7BoilerplateCommonModule, providers: [], imports: [[
968
+ CommonModule,
969
+ HttpClientModule,
970
+ DvComponentsLibModule,
971
+ ]] });
972
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: N7BoilerplateCommonModule, decorators: [{
973
+ type: NgModule,
974
+ args: [{
975
+ declarations: COMPONENTS,
976
+ imports: [
977
+ CommonModule,
978
+ HttpClientModule,
979
+ DvComponentsLibModule,
980
+ ],
981
+ providers: [],
982
+ exports: COMPONENTS
983
+ }]
984
+ }] });
985
+
986
+ class JsonConfigService {
987
+ constructor(http, config) {
988
+ this.http = http;
989
+ this.config = config;
990
+ }
991
+ load(path) {
992
+ return this.http.get(path).pipe(catchError(() => of({})), tap((response) => this._handleResponse(response))).toPromise();
993
+ }
994
+ _handleResponse(response) {
995
+ // set loaded json config
996
+ if (response) {
997
+ Object.keys(response).forEach((key) => {
998
+ const oldValue = this.config.get(key);
999
+ const newValue = response[key];
1000
+ this.config.set(key, merge(oldValue, newValue));
1001
+ });
1002
+ // config keys colors
1003
+ if (response['config-keys']) {
1004
+ const headTag = document.querySelector('head');
1005
+ const styleElement = document.createElement('style');
1006
+ const styles = [];
1007
+ Object.keys(response['config-keys']).forEach((key) => {
1008
+ const configKey = response['config-keys'][key] || {};
1009
+ const className = configKey['class-name'];
1010
+ if (configKey.color && configKey.color.hex) {
1011
+ // add css class
1012
+ styles.push(`--color-${className}: ${configKey.color.hex};`);
1013
+ }
1014
+ });
1015
+ if (styles.length) {
1016
+ styles.unshift(':root {');
1017
+ styles.push('}');
1018
+ styleElement.appendChild(document.createTextNode(styles.join('\n')));
1019
+ headTag.appendChild(styleElement);
1020
+ }
1021
+ }
1022
+ }
1023
+ }
1024
+ }
1025
+ JsonConfigService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: JsonConfigService, deps: [{ token: i1.HttpClient }, { token: ConfigurationService }], target: i0.ɵɵFactoryTarget.Injectable });
1026
+ JsonConfigService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: JsonConfigService, providedIn: 'root' });
1027
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: JsonConfigService, decorators: [{
1028
+ type: Injectable,
1029
+ args: [{
1030
+ providedIn: 'root',
1031
+ }]
1032
+ }], ctorParameters: function () { return [{ type: i1.HttpClient }, { type: ConfigurationService }]; } });
1033
+
1034
+ class LocalConfigService {
1035
+ constructor(config) {
1036
+ this.config = config;
1037
+ }
1038
+ load(config) {
1039
+ return of(true).pipe(tap(() => {
1040
+ if (config) {
1041
+ Object.keys(config).forEach((key) => this.config.set(key, config[key]));
1042
+ // config keys colors
1043
+ if (config['config-keys']) {
1044
+ const headTag = document.querySelector('head');
1045
+ const styleElement = document.createElement('style');
1046
+ const styles = [];
1047
+ Object.keys(config['config-keys']).forEach((key) => {
1048
+ const configKey = config['config-keys'][key] || {};
1049
+ const className = configKey['class-name'];
1050
+ if (configKey.color && configKey.color.hex) {
1051
+ // add css class
1052
+ styles.push(`--color-${className}: ${configKey.color.hex};`);
1053
+ }
1054
+ });
1055
+ if (styles.length) {
1056
+ styles.unshift(':root {');
1057
+ styles.push('}');
1058
+ styleElement.appendChild(document.createTextNode(styles.join('\n')));
1059
+ headTag.appendChild(styleElement);
1060
+ }
1061
+ }
1062
+ }
1063
+ })).toPromise();
1064
+ }
1065
+ }
1066
+ LocalConfigService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: LocalConfigService, deps: [{ token: ConfigurationService }], target: i0.ɵɵFactoryTarget.Injectable });
1067
+ LocalConfigService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: LocalConfigService, providedIn: 'root' });
1068
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: LocalConfigService, decorators: [{
1069
+ type: Injectable,
1070
+ args: [{
1071
+ providedIn: 'root',
1072
+ }]
1073
+ }], ctorParameters: function () { return [{ type: ConfigurationService }]; } });
1074
+
1075
+ // main layout
1076
+
1077
+ // eslint-disable-next-line import/no-extraneous-dependencies
1078
+ const domParser = new DOMParser();
1079
+ const helpers = {
1080
+ prettifySnakeCase(key, label) {
1081
+ if (typeof label === 'string') {
1082
+ return label;
1083
+ }
1084
+ return (key || '').split('_').map((word, index) => (index === 0 ? this.ucFirst(word) : word)).join(' ');
1085
+ },
1086
+ ucFirst(str) {
1087
+ return str.charAt(0).toUpperCase() + str.slice(1);
1088
+ },
1089
+ slugify(str) {
1090
+ if (!str) {
1091
+ return '';
1092
+ }
1093
+ const parsedDoc = domParser.parseFromString(str, 'text/html');
1094
+ let parsedString = parsedDoc.body.textContent || '';
1095
+ // custom replacements
1096
+ parsedString = parsedString.replace(/\//g, '-');
1097
+ return slugify(parsedString, {
1098
+ remove: /[*+~.()'"!:@,]/g,
1099
+ lower: true
1100
+ });
1101
+ },
1102
+ browserIsIE() {
1103
+ return window.navigator.userAgent.match(/(MSIE|Trident)/);
1104
+ },
1105
+ escapeQuotes(str) {
1106
+ if (typeof str !== 'string') {
1107
+ return '';
1108
+ }
1109
+ return str
1110
+ .replace(/"/g, '\\\\\\"')
1111
+ .replace(/'/g, '\\\\\'');
1112
+ },
1113
+ unescapeQuotes(str) {
1114
+ if (typeof str !== 'string') {
1115
+ return '';
1116
+ }
1117
+ return str
1118
+ .replace(/\\\\\\"/g, '"')
1119
+ .replace(/\\\\'/g, '\'');
1120
+ },
1121
+ escapeDoubleQuotes(str) {
1122
+ if (str.search(/\\?(")([\w\s]+)\\?(")/g) >= 0) {
1123
+ // match piece of string between double quotes
1124
+ return str.replace(/\\?(")([\w\s]+)\\?(")/g, '\\$1$2\\$3'); // thanks @slevithan!
1125
+ }
1126
+ return str.replace(/\\([\s\S])|(")/g, '\\\\\\$1$2'); // thanks @slevithan!
1127
+ },
1128
+ unescapeDoubleQuotes(str) {
1129
+ return (str && str !== '') ? str.replace(/\\*(")/g, '$1') : str; // thanks @slevithan!
1130
+ },
1131
+ striptags(str) {
1132
+ if (typeof str !== 'string') {
1133
+ return '';
1134
+ }
1135
+ return str.replace(/(<([^>]+)>)/gi, '');
1136
+ },
1137
+ isElementInViewport(el) {
1138
+ if (!el) {
1139
+ throw Error('There is no element');
1140
+ }
1141
+ const rect = el.getBoundingClientRect();
1142
+ return rect.bottom > 0
1143
+ && rect.right > 0
1144
+ && rect.left < (window.innerWidth || document.documentElement.clientWidth)
1145
+ && rect.top < (window.innerHeight || document.documentElement.clientHeight);
1146
+ },
1147
+ /** Return true if an object is empty */
1148
+ isEmpty: (obj) => (typeof obj === 'object'
1149
+ && Object.keys(obj).length === 0)
1150
+ };
1151
+
1152
+ /*
1153
+ * Public API Surface of n7-boilerplate-common
1154
+ */
1155
+
1156
+ /**
1157
+ * Generated bundle index. Do not edit.
1158
+ */
1159
+
1160
+ export { AbstractLayout, ApolloProvider, BreadcrumbsDS, BreadcrumbsEH, CommunicationService, ConfigurationService, FacetsDS, FooterDS, FooterEH, HeaderDS, HeaderEH, JsonConfigService, LayoutsConfigurationService, LocalConfigService, MainLayoutComponent, MainLayoutConfig, MainLayoutDS, MainLayoutEH, MainStateService, N7BoilerplateCommonModule, Page404LayoutComponent, Page404LayoutConfig, Page404LayoutDS, Page404LayoutEH, RestProvider, SmartPaginationComponent, SmartPaginationDS, SmartPaginationEH, SubnavDS, SubnavEH, helpers };
1161
+ //# sourceMappingURL=net7-boilerplate-common.mjs.map