@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, effect, contentChild, HostListener, Inject, APP_INITIALIZER, NgModule } from '@angular/core';
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(/&nbsp;/g, ' ')
521
+ .replace(/&hyphen;/g, '-')
522
+ .replace(/&ndash;/g, '-')
523
+ .replace(/&mdash;/g, '-')
524
+ .replace(/&#8211;/g, '-')
525
+ .replace(/&#8212;/g, '-')
526
+ .replace(/&bdquo;/g, '"')
527
+ .replace(/&oacute;/g, 'ó')
528
+ .replace(/&rdquo;/g, '"')
529
+ .replace(/&quot;/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 = [DictionaryService, ConfigsService, ConfigsFacade];
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