@smartsoft001-mobilems/angular 2.9.0 → 2.10.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.
|
@@ -1,17 +1,18 @@
|
|
|
1
1
|
import { __decorate, __metadata } from 'tslib';
|
|
2
2
|
import * as i0 from '@angular/core';
|
|
3
|
-
import { Injectable, inject, signal, Component, Directive,
|
|
4
|
-
import { DomSanitizer } from '@angular/platform-browser';
|
|
5
|
-
import { ReduxAction, AppBaseComponent, PageBaseComponent, BaseComponent } from '@smartsoft001/angular';
|
|
3
|
+
import { Injectable, inject, PLATFORM_ID, signal, effect, computed, Component, Directive, contentChild, HostListener, Inject, APP_INITIALIZER, NgModule } from '@angular/core';
|
|
4
|
+
import { Meta, Title, DomSanitizer } from '@angular/platform-browser';
|
|
5
|
+
import { StyleService as StyleService$1, ReduxAction, AppBaseComponent, PageBaseComponent, BaseComponent } from '@smartsoft001/angular';
|
|
6
6
|
import { HttpClient } from '@angular/common/http';
|
|
7
7
|
import * as moment from 'moment';
|
|
8
8
|
import { lastValueFrom, combineLatest, firstValueFrom, of, throwError } from 'rxjs';
|
|
9
|
-
import { map, catchError } from 'rxjs/operators';
|
|
9
|
+
import { map, filter, catchError } from 'rxjs/operators';
|
|
10
|
+
import { isPlatformBrowser, DOCUMENT } from '@angular/common';
|
|
11
|
+
import { Router, ActivatedRoute, NavigationEnd, RouterOutlet, RouterModule } from '@angular/router';
|
|
12
|
+
import { TranslateService } from '@ngx-translate/core';
|
|
10
13
|
import { CrudService, CrudFacade } from '@smartsoft001/crud-shell-angular';
|
|
11
|
-
import { RouterOutlet, RouterModule } from '@angular/router';
|
|
12
14
|
import * as _ from 'lodash';
|
|
13
15
|
import { Debounce } from 'lodash-decorators';
|
|
14
|
-
import { DOCUMENT } from '@angular/common';
|
|
15
16
|
|
|
16
17
|
function setTranslationsAndLang(service) {
|
|
17
18
|
const map = {
|
|
@@ -35,11 +36,57 @@ const TRANSLATE_DATA_PL = {
|
|
|
35
36
|
const environment = {
|
|
36
37
|
production: false,
|
|
37
38
|
apiUrl: '',
|
|
39
|
+
multimediaUrl: '',
|
|
40
|
+
mainLogoPath: '/assets/gfx/logo/main-logo.png',
|
|
38
41
|
};
|
|
39
42
|
|
|
43
|
+
class AuthStorageService {
|
|
44
|
+
constructor() {
|
|
45
|
+
this.STORAGE_KEY = 'user';
|
|
46
|
+
}
|
|
47
|
+
setUser(user) {
|
|
48
|
+
if (typeof localStorage !== 'undefined') {
|
|
49
|
+
localStorage.setItem(this.STORAGE_KEY, JSON.stringify(user));
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
getUser() {
|
|
53
|
+
if (typeof localStorage !== 'undefined') {
|
|
54
|
+
const item = localStorage.getItem(this.STORAGE_KEY);
|
|
55
|
+
if (item) {
|
|
56
|
+
try {
|
|
57
|
+
return JSON.parse(item);
|
|
58
|
+
}
|
|
59
|
+
catch (error) {
|
|
60
|
+
console.error('Failed to parse user from localStorage', error);
|
|
61
|
+
return null;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
return null;
|
|
66
|
+
}
|
|
67
|
+
removeUser() {
|
|
68
|
+
if (typeof localStorage !== 'undefined') {
|
|
69
|
+
localStorage.removeItem(this.STORAGE_KEY);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
hasUser() {
|
|
73
|
+
return this.getUser() !== null;
|
|
74
|
+
}
|
|
75
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.0", ngImport: i0, type: AuthStorageService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
76
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.0", ngImport: i0, type: AuthStorageService, providedIn: 'root' }); }
|
|
77
|
+
}
|
|
78
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.0", ngImport: i0, type: AuthStorageService, decorators: [{
|
|
79
|
+
type: Injectable,
|
|
80
|
+
args: [{
|
|
81
|
+
providedIn: 'root',
|
|
82
|
+
}]
|
|
83
|
+
}] });
|
|
84
|
+
|
|
40
85
|
class SharedConfig {
|
|
41
86
|
constructor() {
|
|
42
87
|
this.apiUrl = '';
|
|
88
|
+
this.multimediaUrl = '';
|
|
89
|
+
this.mainLogoPath = '/assets/gfx/logo/main-logo.png';
|
|
43
90
|
}
|
|
44
91
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.0", ngImport: i0, type: SharedConfig, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
45
92
|
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.0", ngImport: i0, type: SharedConfig }); }
|
|
@@ -87,6 +134,71 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.0", ngImpor
|
|
|
87
134
|
}]
|
|
88
135
|
}] });
|
|
89
136
|
|
|
137
|
+
const DEFAULT_COLORS = {
|
|
138
|
+
black: 'black',
|
|
139
|
+
yellow: 'yellow',
|
|
140
|
+
white: 'white',
|
|
141
|
+
transparentBlack: 'rgba(0, 0, 0, 0.9)',
|
|
142
|
+
wcagColor1: '#F4B735',
|
|
143
|
+
wcagColor2: '#1B1B1B',
|
|
144
|
+
};
|
|
145
|
+
class ContrastService {
|
|
146
|
+
constructor() {
|
|
147
|
+
this.platformId = inject(PLATFORM_ID);
|
|
148
|
+
this.isBrowser = isPlatformBrowser(this.platformId);
|
|
149
|
+
this.isActive = signal(false, ...(ngDevMode ? [{ debugName: "isActive" }] : []));
|
|
150
|
+
// Apply contrast changes to DOM
|
|
151
|
+
effect(() => {
|
|
152
|
+
if (this.isBrowser) {
|
|
153
|
+
this.applyContrast(this.isActive());
|
|
154
|
+
}
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
changeTheme(active) {
|
|
158
|
+
this.isActive.set(active);
|
|
159
|
+
}
|
|
160
|
+
toggle() {
|
|
161
|
+
this.isActive.update((value) => !value);
|
|
162
|
+
}
|
|
163
|
+
applyContrast(active) {
|
|
164
|
+
if (!this.isBrowser)
|
|
165
|
+
return;
|
|
166
|
+
const docElement = document.documentElement;
|
|
167
|
+
if (active) {
|
|
168
|
+
this.setProperties(docElement);
|
|
169
|
+
docElement.classList.add('cv');
|
|
170
|
+
}
|
|
171
|
+
else {
|
|
172
|
+
this.removeProperties(docElement);
|
|
173
|
+
docElement.classList.remove('cv');
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
setProperties(element) {
|
|
177
|
+
element.style.setProperty('--cv-black', DEFAULT_COLORS.black);
|
|
178
|
+
element.style.setProperty('--cv-yellow', DEFAULT_COLORS.yellow);
|
|
179
|
+
element.style.setProperty('--cv-white', DEFAULT_COLORS.white);
|
|
180
|
+
element.style.setProperty('--cv-black-transparent', DEFAULT_COLORS.transparentBlack);
|
|
181
|
+
element.style.setProperty('--cv-wcag-color-1', DEFAULT_COLORS.wcagColor1);
|
|
182
|
+
element.style.setProperty('--cv-wcag-color-2', DEFAULT_COLORS.wcagColor2);
|
|
183
|
+
}
|
|
184
|
+
removeProperties(element) {
|
|
185
|
+
element.style.removeProperty('--cv-black');
|
|
186
|
+
element.style.removeProperty('--cv-yellow');
|
|
187
|
+
element.style.removeProperty('--cv-white');
|
|
188
|
+
element.style.removeProperty('--cv-black-transparent');
|
|
189
|
+
element.style.removeProperty('--cv-wcag-color-1');
|
|
190
|
+
element.style.removeProperty('--cv-wcag-color-2');
|
|
191
|
+
}
|
|
192
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.0", ngImport: i0, type: ContrastService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
193
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.0", ngImport: i0, type: ContrastService, providedIn: 'root' }); }
|
|
194
|
+
}
|
|
195
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.0", ngImport: i0, type: ContrastService, decorators: [{
|
|
196
|
+
type: Injectable,
|
|
197
|
+
args: [{
|
|
198
|
+
providedIn: 'root',
|
|
199
|
+
}]
|
|
200
|
+
}], ctorParameters: () => [] });
|
|
201
|
+
|
|
90
202
|
class DictionaryService {
|
|
91
203
|
constructor() {
|
|
92
204
|
this.httpClient = inject(HttpClient);
|
|
@@ -126,6 +238,561 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.0", ngImpor
|
|
|
126
238
|
}]
|
|
127
239
|
}] });
|
|
128
240
|
|
|
241
|
+
class FileUrlService {
|
|
242
|
+
constructor() {
|
|
243
|
+
this.config = inject(SharedConfig);
|
|
244
|
+
}
|
|
245
|
+
get(fileOrPath, mode = 'cache', noImagePlaceholder = 'assets/no-image.svg') {
|
|
246
|
+
const multimediaUrl = this.config.multimediaUrl;
|
|
247
|
+
if (!multimediaUrl) {
|
|
248
|
+
return noImagePlaceholder;
|
|
249
|
+
}
|
|
250
|
+
let path;
|
|
251
|
+
if (typeof fileOrPath === 'string') {
|
|
252
|
+
path = fileOrPath;
|
|
253
|
+
}
|
|
254
|
+
else {
|
|
255
|
+
if (!fileOrPath || !fileOrPath.filePath) {
|
|
256
|
+
return noImagePlaceholder;
|
|
257
|
+
}
|
|
258
|
+
// Check if it's an upload path (direct URL)
|
|
259
|
+
if (fileOrPath.filePath.indexOf('upload') === -1) {
|
|
260
|
+
return (multimediaUrl + this.getPath(mode) + this.getFileName(fileOrPath));
|
|
261
|
+
}
|
|
262
|
+
path = fileOrPath.filePath;
|
|
263
|
+
}
|
|
264
|
+
// Remove leading slash if present
|
|
265
|
+
if (path[0] === '/') {
|
|
266
|
+
path = path.substring(1);
|
|
267
|
+
}
|
|
268
|
+
return multimediaUrl + path;
|
|
269
|
+
}
|
|
270
|
+
getFileName(file) {
|
|
271
|
+
if (file.filePath &&
|
|
272
|
+
file.extension &&
|
|
273
|
+
file.filePath.indexOf(file.extension) > -1) {
|
|
274
|
+
return file.filePath;
|
|
275
|
+
}
|
|
276
|
+
return file.filePath + '.' + file.extension;
|
|
277
|
+
}
|
|
278
|
+
getPath(mode) {
|
|
279
|
+
switch (mode) {
|
|
280
|
+
case 'big':
|
|
281
|
+
return 'upload/cache/multimedia_big/';
|
|
282
|
+
case 'cache':
|
|
283
|
+
return 'upload/cache/multimedia_detail/';
|
|
284
|
+
case 'noCache':
|
|
285
|
+
return 'upload/multimedia/';
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.0", ngImport: i0, type: FileUrlService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
289
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.0", ngImport: i0, type: FileUrlService, providedIn: 'root' }); }
|
|
290
|
+
}
|
|
291
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.0", ngImport: i0, type: FileUrlService, decorators: [{
|
|
292
|
+
type: Injectable,
|
|
293
|
+
args: [{
|
|
294
|
+
providedIn: 'root',
|
|
295
|
+
}]
|
|
296
|
+
}] });
|
|
297
|
+
|
|
298
|
+
class GlobalService {
|
|
299
|
+
constructor() {
|
|
300
|
+
this.showHeader = signal(true, ...(ngDevMode ? [{ debugName: "showHeader" }] : []));
|
|
301
|
+
this.showFooter = signal(true, ...(ngDevMode ? [{ debugName: "showFooter" }] : []));
|
|
302
|
+
}
|
|
303
|
+
setHeaderVisibility(visible) {
|
|
304
|
+
this.showHeader.set(visible);
|
|
305
|
+
}
|
|
306
|
+
setFooterVisibility(visible) {
|
|
307
|
+
this.showFooter.set(visible);
|
|
308
|
+
}
|
|
309
|
+
hexToRgb(hex) {
|
|
310
|
+
if (!hex)
|
|
311
|
+
return null;
|
|
312
|
+
// Remove # if present
|
|
313
|
+
let cleanHex = hex.replace(/^#/, '');
|
|
314
|
+
// Expand 3-character hex to 6-character (#abc -> #aabbcc)
|
|
315
|
+
if (cleanHex.length === 3) {
|
|
316
|
+
cleanHex = cleanHex
|
|
317
|
+
.split('')
|
|
318
|
+
.map((char) => char + char)
|
|
319
|
+
.join('');
|
|
320
|
+
}
|
|
321
|
+
// Parse 6-character hex
|
|
322
|
+
const result = cleanHex.match(/.{2}/g);
|
|
323
|
+
if (!result || result.length !== 3)
|
|
324
|
+
return null;
|
|
325
|
+
return result.map((x) => parseInt(x, 16));
|
|
326
|
+
}
|
|
327
|
+
rgbToHex(r, g, b) {
|
|
328
|
+
return ('#' +
|
|
329
|
+
[r, g, b]
|
|
330
|
+
.map((x) => {
|
|
331
|
+
const hex = x.toString(16);
|
|
332
|
+
return hex.length === 1 ? '0' + hex : hex;
|
|
333
|
+
})
|
|
334
|
+
.join(''));
|
|
335
|
+
}
|
|
336
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.0", ngImport: i0, type: GlobalService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
337
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.0", ngImport: i0, type: GlobalService, providedIn: 'root' }); }
|
|
338
|
+
}
|
|
339
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.0", ngImport: i0, type: GlobalService, decorators: [{
|
|
340
|
+
type: Injectable,
|
|
341
|
+
args: [{
|
|
342
|
+
providedIn: 'root',
|
|
343
|
+
}]
|
|
344
|
+
}] });
|
|
345
|
+
|
|
346
|
+
const TRANSLATION_CONFIG_KEY = 'TRANSLATION_CONFIG';
|
|
347
|
+
class TranslationService {
|
|
348
|
+
constructor() {
|
|
349
|
+
this.translateService = inject(TranslateService);
|
|
350
|
+
this._config = signal({
|
|
351
|
+
language: this.getInitialLanguage(),
|
|
352
|
+
}, ...(ngDevMode ? [{ debugName: "_config" }] : []));
|
|
353
|
+
this.config = this._config.asReadonly();
|
|
354
|
+
this.config$ = this.translateService.onLangChange.pipe();
|
|
355
|
+
this.currentLanguage = computed(() => this._config().language, ...(ngDevMode ? [{ debugName: "currentLanguage" }] : []));
|
|
356
|
+
}
|
|
357
|
+
getInitialLanguage() {
|
|
358
|
+
if (typeof localStorage !== 'undefined') {
|
|
359
|
+
const stored = localStorage.getItem(TRANSLATION_CONFIG_KEY);
|
|
360
|
+
if (stored) {
|
|
361
|
+
try {
|
|
362
|
+
const parsed = JSON.parse(stored);
|
|
363
|
+
return parsed.language;
|
|
364
|
+
}
|
|
365
|
+
catch (error) {
|
|
366
|
+
console.warn('Failed to parse translation config', error);
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
return this.translateService.getBrowserLang() || 'en';
|
|
371
|
+
}
|
|
372
|
+
get(key, params) {
|
|
373
|
+
return this.translateService.instant(key, params);
|
|
374
|
+
}
|
|
375
|
+
async init(defaultLang = 'en', availableLangs = ['en', 'pl']) {
|
|
376
|
+
this.translateService.setDefaultLang(defaultLang);
|
|
377
|
+
this.translateService.addLangs(availableLangs);
|
|
378
|
+
let lang = this._config().language;
|
|
379
|
+
if (!availableLangs.includes(lang)) {
|
|
380
|
+
lang = defaultLang;
|
|
381
|
+
this._config.set({ language: lang });
|
|
382
|
+
}
|
|
383
|
+
await this.translateService.use(lang).toPromise();
|
|
384
|
+
}
|
|
385
|
+
setLanguage(language) {
|
|
386
|
+
this._config.set({ language });
|
|
387
|
+
this.save();
|
|
388
|
+
this.translateService.use(language);
|
|
389
|
+
}
|
|
390
|
+
save() {
|
|
391
|
+
if (typeof localStorage !== 'undefined') {
|
|
392
|
+
localStorage.setItem(TRANSLATION_CONFIG_KEY, JSON.stringify(this._config()));
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.0", ngImport: i0, type: TranslationService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
396
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.0", ngImport: i0, type: TranslationService, providedIn: 'root' }); }
|
|
397
|
+
}
|
|
398
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.0", ngImport: i0, type: TranslationService, decorators: [{
|
|
399
|
+
type: Injectable,
|
|
400
|
+
args: [{
|
|
401
|
+
providedIn: 'root',
|
|
402
|
+
}]
|
|
403
|
+
}] });
|
|
404
|
+
|
|
405
|
+
class MetaService {
|
|
406
|
+
constructor() {
|
|
407
|
+
this.meta = inject(Meta);
|
|
408
|
+
this.title = inject(Title);
|
|
409
|
+
this.translationService = inject(TranslationService);
|
|
410
|
+
this.router = inject(Router);
|
|
411
|
+
this.activatedRoute = inject(ActivatedRoute);
|
|
412
|
+
this.config = inject(SharedConfig);
|
|
413
|
+
this.resetMetadata();
|
|
414
|
+
}
|
|
415
|
+
keepUpdatingPageTitle(onRouteChange) {
|
|
416
|
+
if (onRouteChange) {
|
|
417
|
+
this.routerSubscription = this.router.events
|
|
418
|
+
.pipe(filter((event) => event instanceof NavigationEnd), map(() => this.getRouteTitle()))
|
|
419
|
+
.subscribe((dynamicTitle) => {
|
|
420
|
+
if (dynamicTitle) {
|
|
421
|
+
this.setTitle(dynamicTitle);
|
|
422
|
+
}
|
|
423
|
+
});
|
|
424
|
+
return this.routerSubscription;
|
|
425
|
+
}
|
|
426
|
+
else {
|
|
427
|
+
const dynamicTitle = this.getRouteTitle();
|
|
428
|
+
if (dynamicTitle) {
|
|
429
|
+
this.setTitle(dynamicTitle);
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
setPageMetadata(title = '', description = '') {
|
|
434
|
+
if (title) {
|
|
435
|
+
this.setTitle(title);
|
|
436
|
+
}
|
|
437
|
+
if (description) {
|
|
438
|
+
this.setDescription(description);
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
setObjectMetadata(objectData) {
|
|
442
|
+
if (objectData.image) {
|
|
443
|
+
this.setImageMetadata(objectData.image, objectData.title, objectData.type);
|
|
444
|
+
}
|
|
445
|
+
if (objectData.title) {
|
|
446
|
+
this.setTitle(objectData.title);
|
|
447
|
+
}
|
|
448
|
+
if (objectData.description) {
|
|
449
|
+
this.setDescription(objectData.description);
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
setImageMetadata(image, imageAlt, type) {
|
|
453
|
+
const multimediaUrl = this.config.multimediaUrl;
|
|
454
|
+
if (!multimediaUrl || !image?.filePath) {
|
|
455
|
+
return;
|
|
456
|
+
}
|
|
457
|
+
try {
|
|
458
|
+
const imageUrl = this.buildImageUrl(multimediaUrl, image, type);
|
|
459
|
+
this.meta.updateTag({ property: 'og:image', content: imageUrl });
|
|
460
|
+
this.meta.updateTag({ property: 'og:image:type', content: 'image/jpeg' });
|
|
461
|
+
this.meta.updateTag({ property: 'og:image:width', content: '600' });
|
|
462
|
+
this.meta.updateTag({ property: 'og:image:height', content: '600' });
|
|
463
|
+
if (imageAlt) {
|
|
464
|
+
this.meta.updateTag({
|
|
465
|
+
property: 'og:image:alt',
|
|
466
|
+
content: this.removeHtmlTags(imageAlt),
|
|
467
|
+
});
|
|
468
|
+
}
|
|
469
|
+
else {
|
|
470
|
+
this.meta.removeTag("property='og:image:alt'");
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
catch (error) {
|
|
474
|
+
console.warn('Failed to set image metadata', error);
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
resetMetadata() {
|
|
478
|
+
const baseTitle = this.translationService.get('base-portal-title') || 'Portal';
|
|
479
|
+
this.meta.updateTag({ property: 'og:type', content: 'website' });
|
|
480
|
+
this.meta.updateTag({ property: 'og:title', content: baseTitle });
|
|
481
|
+
this.meta.updateTag({ property: 'og:description', content: '' });
|
|
482
|
+
this.meta.updateTag({ name: 'description', content: '' });
|
|
483
|
+
this.meta.updateTag({
|
|
484
|
+
property: 'og:image',
|
|
485
|
+
content: 'assets/gfx/no-img/no-img-header.jpg',
|
|
486
|
+
});
|
|
487
|
+
this.meta.updateTag({ property: 'og:image:alt', content: baseTitle });
|
|
488
|
+
this.meta.updateTag({ property: 'og:image:type', content: 'image/jpeg' });
|
|
489
|
+
this.meta.updateTag({ property: 'og:image:width', content: '250' });
|
|
490
|
+
this.meta.updateTag({ property: 'og:image:height', content: '250' });
|
|
491
|
+
}
|
|
492
|
+
updateTag(tag) {
|
|
493
|
+
this.meta.updateTag(tag);
|
|
494
|
+
}
|
|
495
|
+
setTitle(titleText) {
|
|
496
|
+
const plainTitle = this.removeHtmlTags(titleText);
|
|
497
|
+
this.title.setTitle(plainTitle);
|
|
498
|
+
this.meta.updateTag({ property: 'og:title', content: plainTitle });
|
|
499
|
+
}
|
|
500
|
+
setDescription(description) {
|
|
501
|
+
const plainDesc = this.removeHtmlTags(description);
|
|
502
|
+
this.meta.updateTag({ property: 'og:description', content: plainDesc });
|
|
503
|
+
this.meta.updateTag({ name: 'description', content: plainDesc });
|
|
504
|
+
}
|
|
505
|
+
destroy() {
|
|
506
|
+
this.routerSubscription?.unsubscribe();
|
|
507
|
+
}
|
|
508
|
+
buildImageUrl(baseUrl, image, type) {
|
|
509
|
+
const cleanBaseUrl = baseUrl.endsWith('/') ? baseUrl.slice(0, -1) : baseUrl;
|
|
510
|
+
if (type === 'object' && image.filePath) {
|
|
511
|
+
return `${cleanBaseUrl}/${image.filePath}.jpg`;
|
|
512
|
+
}
|
|
513
|
+
return `${cleanBaseUrl}/${image.filePath}`;
|
|
514
|
+
}
|
|
515
|
+
removeHtmlTags(value) {
|
|
516
|
+
if (!value)
|
|
517
|
+
return '';
|
|
518
|
+
return value
|
|
519
|
+
.replace(/<.*?>/g, '')
|
|
520
|
+
.replace(/ /g, ' ')
|
|
521
|
+
.replace(/‐/g, '-')
|
|
522
|
+
.replace(/–/g, '-')
|
|
523
|
+
.replace(/—/g, '-')
|
|
524
|
+
.replace(/–/g, '-')
|
|
525
|
+
.replace(/—/g, '-')
|
|
526
|
+
.replace(/„/g, '"')
|
|
527
|
+
.replace(/ó/g, 'ó')
|
|
528
|
+
.replace(/”/g, '"')
|
|
529
|
+
.replace(/"/g, '"');
|
|
530
|
+
}
|
|
531
|
+
getRouteTitle() {
|
|
532
|
+
let child = this.activatedRoute.firstChild;
|
|
533
|
+
while (child?.firstChild) {
|
|
534
|
+
child = child.firstChild;
|
|
535
|
+
}
|
|
536
|
+
if (!child)
|
|
537
|
+
return '';
|
|
538
|
+
const snapshot = child.snapshot;
|
|
539
|
+
if (snapshot.data['subtitle']) {
|
|
540
|
+
return snapshot.data['subtitle'];
|
|
541
|
+
}
|
|
542
|
+
if (snapshot.data['title']) {
|
|
543
|
+
return snapshot.data['title'];
|
|
544
|
+
}
|
|
545
|
+
return '';
|
|
546
|
+
}
|
|
547
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.0", ngImport: i0, type: MetaService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
548
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.0", ngImport: i0, type: MetaService, providedIn: 'root' }); }
|
|
549
|
+
}
|
|
550
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.0", ngImport: i0, type: MetaService, decorators: [{
|
|
551
|
+
type: Injectable,
|
|
552
|
+
args: [{
|
|
553
|
+
providedIn: 'root',
|
|
554
|
+
}]
|
|
555
|
+
}], ctorParameters: () => [] });
|
|
556
|
+
|
|
557
|
+
class SeoService {
|
|
558
|
+
constructor() {
|
|
559
|
+
this.title = inject(Title);
|
|
560
|
+
this.meta = inject(Meta);
|
|
561
|
+
}
|
|
562
|
+
updateTitle(titleText) {
|
|
563
|
+
const decodedTitle = this.decodeHtml(titleText);
|
|
564
|
+
if (decodedTitle) {
|
|
565
|
+
this.title.setTitle(decodedTitle);
|
|
566
|
+
}
|
|
567
|
+
}
|
|
568
|
+
updateMetaTags(metaTags) {
|
|
569
|
+
metaTags.forEach((tag) => this.meta.updateTag(tag));
|
|
570
|
+
}
|
|
571
|
+
updateDescription(description) {
|
|
572
|
+
const decodedDesc = this.decodeHtml(description);
|
|
573
|
+
if (decodedDesc) {
|
|
574
|
+
this.meta.updateTag({ name: 'description', content: decodedDesc });
|
|
575
|
+
}
|
|
576
|
+
}
|
|
577
|
+
updateOgTags(title, description, image, url) {
|
|
578
|
+
const tags = [];
|
|
579
|
+
if (title) {
|
|
580
|
+
tags.push({
|
|
581
|
+
property: 'og:title',
|
|
582
|
+
content: this.decodeHtml(title) || title,
|
|
583
|
+
});
|
|
584
|
+
}
|
|
585
|
+
if (description) {
|
|
586
|
+
tags.push({
|
|
587
|
+
property: 'og:description',
|
|
588
|
+
content: this.decodeHtml(description) || description,
|
|
589
|
+
});
|
|
590
|
+
}
|
|
591
|
+
if (image) {
|
|
592
|
+
tags.push({ property: 'og:image', content: image });
|
|
593
|
+
}
|
|
594
|
+
if (url) {
|
|
595
|
+
tags.push({ property: 'og:url', content: url });
|
|
596
|
+
}
|
|
597
|
+
this.updateMetaTags(tags);
|
|
598
|
+
}
|
|
599
|
+
decodeHtml(encodedStr) {
|
|
600
|
+
if (!encodedStr)
|
|
601
|
+
return encodedStr;
|
|
602
|
+
try {
|
|
603
|
+
const parser = new DOMParser();
|
|
604
|
+
const doc = parser.parseFromString(encodedStr, 'text/html');
|
|
605
|
+
return doc.documentElement.textContent;
|
|
606
|
+
}
|
|
607
|
+
catch (error) {
|
|
608
|
+
console.warn('Failed to decode HTML', error);
|
|
609
|
+
return encodedStr;
|
|
610
|
+
}
|
|
611
|
+
}
|
|
612
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.0", ngImport: i0, type: SeoService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
613
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.0", ngImport: i0, type: SeoService, providedIn: 'root' }); }
|
|
614
|
+
}
|
|
615
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.0", ngImport: i0, type: SeoService, decorators: [{
|
|
616
|
+
type: Injectable,
|
|
617
|
+
args: [{
|
|
618
|
+
providedIn: 'root',
|
|
619
|
+
}]
|
|
620
|
+
}] });
|
|
621
|
+
|
|
622
|
+
class SettingsService {
|
|
623
|
+
constructor() {
|
|
624
|
+
this.translationService = inject(TranslationService);
|
|
625
|
+
this.config = inject(SharedConfig);
|
|
626
|
+
}
|
|
627
|
+
getMediaUrl() {
|
|
628
|
+
const multimediaUrl = this.config.multimediaUrl;
|
|
629
|
+
if (!multimediaUrl) {
|
|
630
|
+
return '';
|
|
631
|
+
}
|
|
632
|
+
// Remove trailing slash if present
|
|
633
|
+
return multimediaUrl.endsWith('/')
|
|
634
|
+
? multimediaUrl.substring(0, multimediaUrl.length - 1)
|
|
635
|
+
: multimediaUrl;
|
|
636
|
+
}
|
|
637
|
+
getBaseTitle() {
|
|
638
|
+
return this.translationService.get('base-portal-title');
|
|
639
|
+
}
|
|
640
|
+
getCanLink() {
|
|
641
|
+
// Could be extended with preview mode config in the future
|
|
642
|
+
return true;
|
|
643
|
+
}
|
|
644
|
+
getMainLogo() {
|
|
645
|
+
return this.config.mainLogoPath;
|
|
646
|
+
}
|
|
647
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.0", ngImport: i0, type: SettingsService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
648
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.0", ngImport: i0, type: SettingsService, providedIn: 'root' }); }
|
|
649
|
+
}
|
|
650
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.0", ngImport: i0, type: SettingsService, decorators: [{
|
|
651
|
+
type: Injectable,
|
|
652
|
+
args: [{
|
|
653
|
+
providedIn: 'root',
|
|
654
|
+
}]
|
|
655
|
+
}] });
|
|
656
|
+
|
|
657
|
+
class StyleService {
|
|
658
|
+
constructor() {
|
|
659
|
+
this.smartStyleService = inject(StyleService$1);
|
|
660
|
+
this.config = inject(SharedConfig);
|
|
661
|
+
}
|
|
662
|
+
init(elementRef, customVariables) {
|
|
663
|
+
const variables = {
|
|
664
|
+
...this.config.styleVariables,
|
|
665
|
+
...customVariables,
|
|
666
|
+
};
|
|
667
|
+
this.smartStyleService.init(elementRef, variables);
|
|
668
|
+
}
|
|
669
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.0", ngImport: i0, type: StyleService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
670
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.0", ngImport: i0, type: StyleService, providedIn: 'root' }); }
|
|
671
|
+
}
|
|
672
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.0", ngImport: i0, type: StyleService, decorators: [{
|
|
673
|
+
type: Injectable,
|
|
674
|
+
args: [{
|
|
675
|
+
providedIn: 'root',
|
|
676
|
+
}]
|
|
677
|
+
}] });
|
|
678
|
+
|
|
679
|
+
const WCAG_CONFIG_KEY = 'WCAG_CONFIG';
|
|
680
|
+
const DEFAULT_CONFIG = {
|
|
681
|
+
contrast: 'normal',
|
|
682
|
+
text: 'normal',
|
|
683
|
+
letterSpacing: 'small',
|
|
684
|
+
wordSpacing: 'small',
|
|
685
|
+
};
|
|
686
|
+
class WcagService {
|
|
687
|
+
constructor() {
|
|
688
|
+
this.translationService = inject(TranslationService);
|
|
689
|
+
this.platformId = inject(PLATFORM_ID);
|
|
690
|
+
this.isBrowser = isPlatformBrowser(this.platformId);
|
|
691
|
+
this._config = signal(this.loadConfig(), ...(ngDevMode ? [{ debugName: "_config" }] : []));
|
|
692
|
+
this.config = this._config.asReadonly();
|
|
693
|
+
this.wordSpacingValue = computed(() => this.getSpacingValue(this._config().wordSpacing), ...(ngDevMode ? [{ debugName: "wordSpacingValue" }] : []));
|
|
694
|
+
this.letterSpacingValue = computed(() => this.getSpacingValue(this._config().letterSpacing), ...(ngDevMode ? [{ debugName: "letterSpacingValue" }] : []));
|
|
695
|
+
// Apply config changes to DOM
|
|
696
|
+
effect(() => {
|
|
697
|
+
const config = this._config();
|
|
698
|
+
this.applyConfigToDOM(config);
|
|
699
|
+
});
|
|
700
|
+
}
|
|
701
|
+
async init() {
|
|
702
|
+
// Config is already loaded in constructor
|
|
703
|
+
// This method kept for backward compatibility
|
|
704
|
+
}
|
|
705
|
+
setContrast(value) {
|
|
706
|
+
this._config.update((config) => ({ ...config, contrast: value }));
|
|
707
|
+
this.announceChange('setContrast', value);
|
|
708
|
+
this.save();
|
|
709
|
+
}
|
|
710
|
+
setText(value) {
|
|
711
|
+
this._config.update((config) => ({ ...config, text: value }));
|
|
712
|
+
this.announceChange('setText', value);
|
|
713
|
+
this.save();
|
|
714
|
+
}
|
|
715
|
+
setLetterSpacing(value) {
|
|
716
|
+
this._config.update((config) => ({ ...config, letterSpacing: value }));
|
|
717
|
+
this.announceChange('setLetterSpacing', value);
|
|
718
|
+
this.save();
|
|
719
|
+
}
|
|
720
|
+
setWordSpacing(value) {
|
|
721
|
+
this._config.update((config) => ({ ...config, wordSpacing: value }));
|
|
722
|
+
this.announceChange('setWordSpacing', value);
|
|
723
|
+
this.save();
|
|
724
|
+
}
|
|
725
|
+
reset() {
|
|
726
|
+
this._config.set(DEFAULT_CONFIG);
|
|
727
|
+
this.save();
|
|
728
|
+
}
|
|
729
|
+
getSpacingValue(spacing) {
|
|
730
|
+
switch (spacing) {
|
|
731
|
+
case 'normal':
|
|
732
|
+
return 1;
|
|
733
|
+
case 'large':
|
|
734
|
+
return 2;
|
|
735
|
+
default:
|
|
736
|
+
return 0;
|
|
737
|
+
}
|
|
738
|
+
}
|
|
739
|
+
loadConfig() {
|
|
740
|
+
if (this.isBrowser && typeof localStorage !== 'undefined') {
|
|
741
|
+
const stored = localStorage.getItem(WCAG_CONFIG_KEY);
|
|
742
|
+
if (stored) {
|
|
743
|
+
try {
|
|
744
|
+
const parsed = JSON.parse(stored);
|
|
745
|
+
return { ...DEFAULT_CONFIG, ...parsed };
|
|
746
|
+
}
|
|
747
|
+
catch (error) {
|
|
748
|
+
console.warn('Failed to parse WCAG config', error);
|
|
749
|
+
}
|
|
750
|
+
}
|
|
751
|
+
}
|
|
752
|
+
return DEFAULT_CONFIG;
|
|
753
|
+
}
|
|
754
|
+
save() {
|
|
755
|
+
if (this.isBrowser && typeof localStorage !== 'undefined') {
|
|
756
|
+
localStorage.setItem(WCAG_CONFIG_KEY, JSON.stringify(this._config()));
|
|
757
|
+
}
|
|
758
|
+
}
|
|
759
|
+
applyConfigToDOM(config) {
|
|
760
|
+
if (!this.isBrowser)
|
|
761
|
+
return;
|
|
762
|
+
const body = document.getElementsByTagName('body')[0];
|
|
763
|
+
if (!body)
|
|
764
|
+
return;
|
|
765
|
+
body.className = '';
|
|
766
|
+
body.className += ` contrast-${config.contrast}`;
|
|
767
|
+
body.className += ` text-${config.text}`;
|
|
768
|
+
body.className += ` letter-spacing-${config.letterSpacing}`;
|
|
769
|
+
body.className += ` word-spacing-${config.wordSpacing}`;
|
|
770
|
+
}
|
|
771
|
+
announceChange(type, value) {
|
|
772
|
+
if (!this.isBrowser)
|
|
773
|
+
return;
|
|
774
|
+
let announceElement = document.getElementById('wcag-change');
|
|
775
|
+
if (!announceElement) {
|
|
776
|
+
announceElement = document.createElement('span');
|
|
777
|
+
announceElement.id = 'wcag-change';
|
|
778
|
+
announceElement.className = 'sr-only';
|
|
779
|
+
announceElement.setAttribute('aria-atomic', 'true');
|
|
780
|
+
announceElement.setAttribute('aria-live', 'polite');
|
|
781
|
+
document.body.appendChild(announceElement);
|
|
782
|
+
}
|
|
783
|
+
const translationKey = `WCAG.${type}.${value}`;
|
|
784
|
+
announceElement.innerHTML = this.translationService.get(translationKey);
|
|
785
|
+
}
|
|
786
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.0", ngImport: i0, type: WcagService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
787
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.0", ngImport: i0, type: WcagService, providedIn: 'root' }); }
|
|
788
|
+
}
|
|
789
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.0", ngImport: i0, type: WcagService, decorators: [{
|
|
790
|
+
type: Injectable,
|
|
791
|
+
args: [{
|
|
792
|
+
providedIn: 'root',
|
|
793
|
+
}]
|
|
794
|
+
}], ctorParameters: () => [] });
|
|
795
|
+
|
|
129
796
|
class CrudBaseService extends CrudService {
|
|
130
797
|
downloadPdf(name, id) {
|
|
131
798
|
return fetch(this.config.apiUrl + this.getUrlNameForDetails() + '/' + id + '/pdf')
|
|
@@ -210,7 +877,21 @@ class CrudBaseService extends CrudService {
|
|
|
210
877
|
}
|
|
211
878
|
}
|
|
212
879
|
|
|
213
|
-
const SERVICES = [
|
|
880
|
+
const SERVICES = [
|
|
881
|
+
DictionaryService,
|
|
882
|
+
ConfigsService,
|
|
883
|
+
ConfigsFacade,
|
|
884
|
+
AuthStorageService,
|
|
885
|
+
TranslationService,
|
|
886
|
+
GlobalService,
|
|
887
|
+
FileUrlService,
|
|
888
|
+
SettingsService,
|
|
889
|
+
WcagService,
|
|
890
|
+
ContrastService,
|
|
891
|
+
MetaService,
|
|
892
|
+
SeoService,
|
|
893
|
+
StyleService,
|
|
894
|
+
];
|
|
214
895
|
|
|
215
896
|
class ConfigsFacade {
|
|
216
897
|
constructor() {
|
|
@@ -724,5 +1405,5 @@ class ImageBox {
|
|
|
724
1405
|
* Generated bundle index. Do not edit.
|
|
725
1406
|
*/
|
|
726
1407
|
|
|
727
|
-
export { AppComponent, COMPONENTS, ConfigsFacade, ConfigsService, CrudBaseService, DictionaryService, FiltersBaseComponent, FiltersContext, GameType, ImageBox, ListMode, PageComponent, SERVICES, ScrollTopComponent, SharedConfig, SharedModule, TRANSLATE_DATA_PL, environment, setTranslationsAndLang };
|
|
1408
|
+
export { AppComponent, AuthStorageService, COMPONENTS, ConfigsFacade, ConfigsService, ContrastService, CrudBaseService, DictionaryService, FileUrlService, FiltersBaseComponent, FiltersContext, GameType, GlobalService, ImageBox, ListMode, MetaService, PageComponent, SERVICES, ScrollTopComponent, SeoService, SettingsService, SharedConfig, SharedModule, StyleService, TRANSLATE_DATA_PL, TranslationService, WcagService, environment, setTranslationsAndLang };
|
|
728
1409
|
//# sourceMappingURL=smartsoft001-mobilems-angular.mjs.map
|