@zambon-dev/ui 0.0.0-stage → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/CHANGELOG.md +2329 -0
  2. package/README.md +80 -2
  3. package/fesm2022/zambon-dev-ui-framework.mjs +5960 -0
  4. package/fesm2022/zambon-dev-ui-framework.mjs.map +1 -0
  5. package/fesm2022/zambon-dev-ui-library.mjs +5795 -0
  6. package/fesm2022/zambon-dev-ui-library.mjs.map +1 -0
  7. package/fesm2022/zambon-dev-ui-shared.mjs +2517 -0
  8. package/fesm2022/zambon-dev-ui-shared.mjs.map +1 -0
  9. package/fesm2022/zambon-dev-ui-testing.mjs +76 -0
  10. package/fesm2022/zambon-dev-ui-testing.mjs.map +1 -0
  11. package/fesm2022/zambon-dev-ui.mjs +3 -0
  12. package/i18n/framework/en.json +63 -0
  13. package/i18n/framework/pt.json +63 -0
  14. package/i18n/shared/external-content/en.json +12 -0
  15. package/i18n/shared/external-content/pt.json +12 -0
  16. package/i18n/shared/language-selector/en.json +5 -0
  17. package/i18n/shared/language-selector/pt.json +5 -0
  18. package/i18n/shared/login/en.json +14 -0
  19. package/i18n/shared/login/pt.json +14 -0
  20. package/i18n/shared/operations-history/en.json +5 -0
  21. package/i18n/shared/operations-history/pt.json +5 -0
  22. package/i18n/shared/services-history/en.json +14 -0
  23. package/i18n/shared/services-history/pt.json +14 -0
  24. package/i18n/shared/top-bar/en.json +7 -0
  25. package/i18n/shared/top-bar/pt.json +7 -0
  26. package/package.json +106 -4
  27. package/styles/common.scss +10 -0
  28. package/styles/components/button.scss +101 -0
  29. package/styles/components/card.scss +13 -0
  30. package/styles/components/dropdown-static.scss +35 -0
  31. package/styles/components/input-group.scss +44 -0
  32. package/styles/components/input.scss +99 -0
  33. package/styles/components/label.scss +3 -0
  34. package/styles/components/row.scss +48 -0
  35. package/styles/mixins/background.scss +31 -0
  36. package/styles/theme.css +75 -0
  37. package/styles/variables.scss +60 -0
  38. package/types/zambon-dev-ui-framework.d.ts +1496 -0
  39. package/types/zambon-dev-ui-library.d.ts +1675 -0
  40. package/types/zambon-dev-ui-shared.d.ts +675 -0
  41. package/types/zambon-dev-ui-testing.d.ts +51 -0
  42. package/types/zambon-dev-ui.d.ts +3 -0
@@ -0,0 +1,2517 @@
1
+ import * as i0 from "@angular/core";
2
+ import { ChangeDetectionStrategy, Component, DOCUMENT, HostListener, Injectable, InjectionToken, Input, NgModule, Pipe, ViewChild, computed, inject, input, model, output, signal, viewChild } from "@angular/core";
3
+ import * as i1$1 from "@angular/router";
4
+ import { ActivatedRoute, Router, RouterModule } from "@angular/router";
5
+ import { APP_CONFIG, AuthService, ButtonComponent, ButtonFiltersComponent, ButtonRefreshComponent, ChildList, DefaultTabViewComponent, FRAMEWORK_VIEW_TYPE, FrameworkViewType, ModalBase, Tab, TabService, TabViewBase, TabsComponent } from "@zambon-dev/ui/framework";
6
+ import { CatalogSelectComponent, DataGridComponent, DataGridDataset, DataProviderService, FormGroupComponent, FormInputGroupComponent, ModalComponent, RibbonGroupComponent, SidebarComponent, SidebarMenuOpenMode, SidebarService, toSidebarMenuOpenMode } from "@zambon-dev/ui/library";
7
+ import { TranslateLoader, TranslatePipe, TranslateService, provideTranslateService } from "@ngx-translate/core";
8
+ import { BehaviorSubject, Subject, catchError, finalize, interval, map, mergeMap, of, shareReplay, switchMap, take, takeUntil, tap } from "rxjs";
9
+ import { HttpBackend, HttpClient } from "@angular/common/http";
10
+ import { JwtHelperService, JwtInterceptor } from "@auth0/angular-jwt";
11
+ import { HubConnectionBuilder, HubConnectionState } from "@microsoft/signalr";
12
+ import { AsyncPipe, DatePipe, JsonPipe } from "@angular/common";
13
+ import { toSignal } from "@angular/core/rxjs-interop";
14
+ import * as i1 from "@angular/forms";
15
+ import { FormBuilder, FormsModule, ReactiveFormsModule, Validators } from "@angular/forms";
16
+ import { DomSanitizer } from "@angular/platform-browser";
17
+ import { MultiTranslateHttpLoader } from "ngx-translate-multi-http-loader";
18
+ var LoginLayoutComponent = class LoginLayoutComponent {
19
+ static ɵfac = i0.ɵɵngDeclareFactory({
20
+ minVersion: "12.0.0",
21
+ version: "22.2.0",
22
+ ngImport: i0,
23
+ type: LoginLayoutComponent,
24
+ deps: [],
25
+ target: i0.ɵɵFactoryTarget.Component
26
+ });
27
+ static ɵcmp = i0.ɵɵngDeclareComponent({
28
+ minVersion: "14.0.0",
29
+ version: "22.2.0",
30
+ type: LoginLayoutComponent,
31
+ isStandalone: true,
32
+ selector: "shared-login-layout",
33
+ ngImport: i0,
34
+ template: "<div class=\"background\"></div>\n\n<div class=\"container\">\n <router-outlet></router-outlet>\n</div>\n",
35
+ styles: ["@layer properties;:host{display:block;height:100vh}.background{position:fixed;z-index:-50;height:100vh;width:100%;overflow:hidden}.background,.background:before{background-image:url(/background.jpg);background-size:cover;background-attachment:fixed}.background:before,.background:after{position:absolute;inset:0;--tw-content: \"\";content:var(--tw-content)}.background:before{--tw-blur: blur(var(--blur-sm, 8px));filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}.background:after{background-color:color-mix(in srgb,#fff 30%,transparent)}@supports (color: color-mix(in lab,red,red)){.background:after{background-color:color-mix(in oklab,var(--color-white, #fff) 30%,transparent)}}.background *{z-index:10}.container{position:absolute;top:50%;left:50%;--tw-translate-x: -50% ;--tw-translate-y: -50% ;translate:var(--tw-translate-x) var(--tw-translate-y)}@property --tw-content{syntax: \"*\"; inherits: false; initial-value: \"\";}@property --tw-blur{syntax: \"*\"; inherits: false;}@property --tw-brightness{syntax: \"*\"; inherits: false;}@property --tw-contrast{syntax: \"*\"; inherits: false;}@property --tw-grayscale{syntax: \"*\"; inherits: false;}@property --tw-hue-rotate{syntax: \"*\"; inherits: false;}@property --tw-invert{syntax: \"*\"; inherits: false;}@property --tw-opacity{syntax: \"*\"; inherits: false;}@property --tw-saturate{syntax: \"*\"; inherits: false;}@property --tw-sepia{syntax: \"*\"; inherits: false;}@property --tw-drop-shadow{syntax: \"*\"; inherits: false;}@property --tw-drop-shadow-color{syntax: \"*\"; inherits: false;}@property --tw-drop-shadow-alpha{syntax: \"<percentage>\"; inherits: false; initial-value: 100%;}@property --tw-drop-shadow-size{syntax: \"*\"; inherits: false;}@property --tw-translate-x{syntax: \"*\"; inherits: false; initial-value: 0;}@property --tw-translate-y{syntax: \"*\"; inherits: false; initial-value: 0;}@property --tw-translate-z{syntax: \"*\"; inherits: false; initial-value: 0;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-content: \"\";--tw-blur: initial;--tw-brightness: initial;--tw-contrast: initial;--tw-grayscale: initial;--tw-hue-rotate: initial;--tw-invert: initial;--tw-opacity: initial;--tw-saturate: initial;--tw-sepia: initial;--tw-drop-shadow: initial;--tw-drop-shadow-color: initial;--tw-drop-shadow-alpha: 100%;--tw-drop-shadow-size: initial;--tw-translate-x: 0;--tw-translate-y: 0;--tw-translate-z: 0}}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"],
36
+ dependencies: [{
37
+ kind: "ngmodule",
38
+ type: RouterModule
39
+ }, {
40
+ kind: "directive",
41
+ type: i1$1.RouterOutlet,
42
+ selector: "router-outlet",
43
+ inputs: ["name", "routerOutletData"],
44
+ outputs: [
45
+ "activate",
46
+ "deactivate",
47
+ "attach",
48
+ "detach"
49
+ ],
50
+ exportAs: ["outlet"]
51
+ }],
52
+ changeDetection: i0.ChangeDetectionStrategy.OnPush
53
+ });
54
+ };
55
+ i0.ɵɵngDeclareClassMetadata({
56
+ minVersion: "12.0.0",
57
+ version: "22.2.0",
58
+ ngImport: i0,
59
+ type: LoginLayoutComponent,
60
+ decorators: [{
61
+ type: Component,
62
+ args: [{
63
+ selector: "shared-login-layout",
64
+ imports: [RouterModule],
65
+ changeDetection: ChangeDetectionStrategy.OnPush,
66
+ template: "<div class=\"background\"></div>\n\n<div class=\"container\">\n <router-outlet></router-outlet>\n</div>\n",
67
+ styles: ["@layer properties;:host{display:block;height:100vh}.background{position:fixed;z-index:-50;height:100vh;width:100%;overflow:hidden}.background,.background:before{background-image:url(/background.jpg);background-size:cover;background-attachment:fixed}.background:before,.background:after{position:absolute;inset:0;--tw-content: \"\";content:var(--tw-content)}.background:before{--tw-blur: blur(var(--blur-sm, 8px));filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}.background:after{background-color:color-mix(in srgb,#fff 30%,transparent)}@supports (color: color-mix(in lab,red,red)){.background:after{background-color:color-mix(in oklab,var(--color-white, #fff) 30%,transparent)}}.background *{z-index:10}.container{position:absolute;top:50%;left:50%;--tw-translate-x: -50% ;--tw-translate-y: -50% ;translate:var(--tw-translate-x) var(--tw-translate-y)}@property --tw-content{syntax: \"*\"; inherits: false; initial-value: \"\";}@property --tw-blur{syntax: \"*\"; inherits: false;}@property --tw-brightness{syntax: \"*\"; inherits: false;}@property --tw-contrast{syntax: \"*\"; inherits: false;}@property --tw-grayscale{syntax: \"*\"; inherits: false;}@property --tw-hue-rotate{syntax: \"*\"; inherits: false;}@property --tw-invert{syntax: \"*\"; inherits: false;}@property --tw-opacity{syntax: \"*\"; inherits: false;}@property --tw-saturate{syntax: \"*\"; inherits: false;}@property --tw-sepia{syntax: \"*\"; inherits: false;}@property --tw-drop-shadow{syntax: \"*\"; inherits: false;}@property --tw-drop-shadow-color{syntax: \"*\"; inherits: false;}@property --tw-drop-shadow-alpha{syntax: \"<percentage>\"; inherits: false; initial-value: 100%;}@property --tw-drop-shadow-size{syntax: \"*\"; inherits: false;}@property --tw-translate-x{syntax: \"*\"; inherits: false; initial-value: 0;}@property --tw-translate-y{syntax: \"*\"; inherits: false; initial-value: 0;}@property --tw-translate-z{syntax: \"*\"; inherits: false; initial-value: 0;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-content: \"\";--tw-blur: initial;--tw-brightness: initial;--tw-contrast: initial;--tw-grayscale: initial;--tw-hue-rotate: initial;--tw-invert: initial;--tw-opacity: initial;--tw-saturate: initial;--tw-sepia: initial;--tw-drop-shadow: initial;--tw-drop-shadow-color: initial;--tw-drop-shadow-alpha: 100%;--tw-drop-shadow-size: initial;--tw-translate-x: 0;--tw-translate-y: 0;--tw-translate-z: 0}}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"]
68
+ }]
69
+ }]
70
+ });
71
+ const EXTERNAL_CONTENT_ROUTE_PATH = "external-content";
72
+ var ExternalContentConfigs = class {
73
+ allowedOrigins = [];
74
+ slowFrameHintDelay = 5e3;
75
+ constructor(options = {}) {
76
+ Object.assign(this, options);
77
+ }
78
+ };
79
+ const EXTERNAL_CONTENT_CONFIGS = new InjectionToken("Embedded external content configuration", {
80
+ providedIn: "root",
81
+ factory: () => new ExternalContentConfigs()
82
+ });
83
+ var AuthenticationService = class AuthenticationService extends AuthService {
84
+ adminAction = "AdministrativeMaster";
85
+ config = inject(APP_CONFIG);
86
+ BASE_URL = `${this.config.BASE_URL}/Authentication`;
87
+ http = inject(HttpClient);
88
+ constructor() {
89
+ super(inject(JwtHelperService), inject(TabService));
90
+ }
91
+ authenticate(model) {
92
+ return this.http.post(`${this.BASE_URL}/SignIn`, model).pipe(map((res) => {
93
+ this.setStorage("username", res.username, model.rememberMe);
94
+ this.setStorage("token", res.token, model.rememberMe);
95
+ this.setStorage("refreshToken", res.refreshToken, model.rememberMe);
96
+ this.setStorage("userInfo", window.btoa(JSON.stringify(res)), model.rememberMe);
97
+ }), catchError((error) => interval(1e3).pipe(mergeMap(() => {
98
+ switch (error.status) {
99
+ case 401: throw "InvalidUsernamePassword";
100
+ default: throw "InternalServerError";
101
+ }
102
+ }))));
103
+ }
104
+ getActions() {
105
+ return this.http.post(`${this.BASE_URL}/GetActions`, {});
106
+ }
107
+ getUserInfo() {
108
+ const userInfo = this.userInfo;
109
+ if (userInfo) return JSON.parse(window.atob(userInfo));
110
+ return null;
111
+ }
112
+ tryRefreshToken() {
113
+ return this.http.post(`${this.BASE_URL}/RefreshToken`, {
114
+ username: this.username ?? "",
115
+ refreshToken: this.refreshToken ?? ""
116
+ }).pipe(tap((res) => {
117
+ this.setStorage("token", res.token);
118
+ this.setStorage("refreshToken", res.refreshToken);
119
+ this.setStorage("userInfo", window.btoa(JSON.stringify(res)));
120
+ }), map((res) => res.token ?? ""));
121
+ }
122
+ static ɵfac = i0.ɵɵngDeclareFactory({
123
+ minVersion: "12.0.0",
124
+ version: "22.2.0",
125
+ ngImport: i0,
126
+ type: AuthenticationService,
127
+ deps: [],
128
+ target: i0.ɵɵFactoryTarget.Injectable
129
+ });
130
+ static ɵprov = i0.ɵɵngDeclareInjectable({
131
+ minVersion: "12.0.0",
132
+ version: "22.2.0",
133
+ ngImport: i0,
134
+ type: AuthenticationService,
135
+ providedIn: "root"
136
+ });
137
+ };
138
+ i0.ɵɵngDeclareClassMetadata({
139
+ minVersion: "12.0.0",
140
+ version: "22.2.0",
141
+ ngImport: i0,
142
+ type: AuthenticationService,
143
+ decorators: [{
144
+ type: Injectable,
145
+ args: [{ providedIn: "root" }]
146
+ }],
147
+ ctorParameters: () => []
148
+ });
149
+ var ExternalContentService = class ExternalContentService {
150
+ maxEntries = 20;
151
+ storageKey = "zambon.externalContent";
152
+ registry = /* @__PURE__ */ new Map();
153
+ sidebarService = inject(SidebarService);
154
+ find(menuID) {
155
+ const known = this.registry.get(menuID) ?? this.readFromStorage(menuID);
156
+ if (known) return of(known);
157
+ return this.sidebarService.getMenuFromUrl(`/${EXTERNAL_CONTENT_ROUTE_PATH}/${menuID}`).pipe(take(1), map((menu) => !!menu && !!menu.url ? this.toEntry(menu) : void 0), catchError(() => of(void 0)));
158
+ }
159
+ register(menu) {
160
+ const entry = this.toEntry(menu);
161
+ this.registry.set(entry.id, entry);
162
+ this.writeToStorage(entry);
163
+ }
164
+ readAllFromStorage() {
165
+ try {
166
+ const raw = window.sessionStorage.getItem(this.storageKey);
167
+ if (!raw) return [];
168
+ const parsed = JSON.parse(raw);
169
+ return Array.isArray(parsed) ? parsed : [];
170
+ } catch {
171
+ return [];
172
+ }
173
+ }
174
+ readFromStorage(menuID) {
175
+ const entry = this.readAllFromStorage().find((candidate) => candidate?.id === menuID);
176
+ if (!!entry && !!entry.url) {
177
+ this.registry.set(entry.id, entry);
178
+ return entry;
179
+ }
180
+ }
181
+ toEntry(menu) {
182
+ return {
183
+ id: menu.id,
184
+ label: menu.label,
185
+ url: menu.url ?? ""
186
+ };
187
+ }
188
+ writeToStorage(entry) {
189
+ try {
190
+ const entries = [entry, ...this.readAllFromStorage().filter((candidate) => candidate?.id !== entry.id)].slice(0, this.maxEntries);
191
+ window.sessionStorage.setItem(this.storageKey, JSON.stringify(entries));
192
+ } catch {}
193
+ }
194
+ static ɵfac = i0.ɵɵngDeclareFactory({
195
+ minVersion: "12.0.0",
196
+ version: "22.2.0",
197
+ ngImport: i0,
198
+ type: ExternalContentService,
199
+ deps: [],
200
+ target: i0.ɵɵFactoryTarget.Injectable
201
+ });
202
+ static ɵprov = i0.ɵɵngDeclareInjectable({
203
+ minVersion: "12.0.0",
204
+ version: "22.2.0",
205
+ ngImport: i0,
206
+ type: ExternalContentService,
207
+ providedIn: "root"
208
+ });
209
+ };
210
+ i0.ɵɵngDeclareClassMetadata({
211
+ minVersion: "12.0.0",
212
+ version: "22.2.0",
213
+ ngImport: i0,
214
+ type: ExternalContentService,
215
+ decorators: [{
216
+ type: Injectable,
217
+ args: [{ providedIn: "root" }]
218
+ }]
219
+ });
220
+ var ExternalUrlResolverService = class ExternalUrlResolverService {
221
+ authenticationService = inject(AuthenticationService);
222
+ translate = inject(TranslateService);
223
+ unknownPlaceholderPattern = /\{[A-Za-z][A-Za-z0-9_]*\}/g;
224
+ isAllowed(url) {
225
+ let parsed;
226
+ try {
227
+ parsed = new URL(url);
228
+ } catch {
229
+ return false;
230
+ }
231
+ return parsed.protocol === "http:" || parsed.protocol === "https:";
232
+ }
233
+ resolve(url) {
234
+ if (!url || url.indexOf("{") === -1) return url;
235
+ const values = this.getPlaceholderValues();
236
+ let resolved = url;
237
+ values.forEach((value, token) => {
238
+ if (resolved.indexOf(token) === -1) return;
239
+ if (value.length === 0) console.warn(`External URL placeholder ${token} has no value for the current user; substituting an empty string.`, url);
240
+ resolved = resolved.split(token).join(encodeURIComponent(value));
241
+ });
242
+ this.warnAboutUnknownPlaceholders(url, resolved);
243
+ return resolved;
244
+ }
245
+ getPlaceholderValues() {
246
+ const user = this.authenticationService.getUserInfo();
247
+ return /* @__PURE__ */ new Map([
248
+ ["{email}", user?.email ?? ""],
249
+ ["{language}", this.translate.currentLang || this.translate.defaultLang || ""],
250
+ ["{userId}", user?.userID?.toString() ?? ""],
251
+ ["{userName}", user?.username ?? ""]
252
+ ]);
253
+ }
254
+ warnAboutUnknownPlaceholders(url, resolved) {
255
+ const unknown = resolved.match(this.unknownPlaceholderPattern) ?? [];
256
+ if (unknown.length > 0) console.warn(`External URL contains unrecognized placeholders and was left as configured: ${unknown.join(", ")}`, url);
257
+ }
258
+ static ɵfac = i0.ɵɵngDeclareFactory({
259
+ minVersion: "12.0.0",
260
+ version: "22.2.0",
261
+ ngImport: i0,
262
+ type: ExternalUrlResolverService,
263
+ deps: [],
264
+ target: i0.ɵɵFactoryTarget.Injectable
265
+ });
266
+ static ɵprov = i0.ɵɵngDeclareInjectable({
267
+ minVersion: "12.0.0",
268
+ version: "22.2.0",
269
+ ngImport: i0,
270
+ type: ExternalUrlResolverService,
271
+ providedIn: "root"
272
+ });
273
+ };
274
+ i0.ɵɵngDeclareClassMetadata({
275
+ minVersion: "12.0.0",
276
+ version: "22.2.0",
277
+ ngImport: i0,
278
+ type: ExternalUrlResolverService,
279
+ decorators: [{
280
+ type: Injectable,
281
+ args: [{ providedIn: "root" }]
282
+ }]
283
+ });
284
+ var NotificationsService = class NotificationsService {
285
+ authService = inject(AuthService);
286
+ config = inject(APP_CONFIG);
287
+ connection;
288
+ notifications$ = new BehaviorSubject([]);
289
+ get isEnabled() {
290
+ return this.config.notificationsEnabled && this.config.notificationsUrl.length > 0;
291
+ }
292
+ getNotifications() {
293
+ return this.notifications$.asObservable();
294
+ }
295
+ getUnreadCount() {
296
+ return this.notifications$.pipe(map((notifications) => notifications.filter((n) => !n.isRead).length));
297
+ }
298
+ markAllAsRead() {
299
+ this.notifications$.next(this.notifications$.value.map((n) => ({
300
+ ...n,
301
+ isRead: true
302
+ })));
303
+ if (this.connection?.state === HubConnectionState.Connected) this.connection.invoke("MarkAllAsRead").catch((error) => {
304
+ console.error("Failed to mark notifications as read on the hub.", error);
305
+ });
306
+ }
307
+ markAsRead(notification) {
308
+ this.notifications$.next(this.notifications$.value.map((n) => n === notification ? {
309
+ ...n,
310
+ isRead: true
311
+ } : n));
312
+ }
313
+ start() {
314
+ if (!this.isEnabled || !!this.connection) return;
315
+ this.connection = new HubConnectionBuilder().withUrl(this.config.notificationsUrl, { accessTokenFactory: () => this.authService.token ?? "" }).withAutomaticReconnect().build();
316
+ this.connection.on("ReceiveNotifications", (notifications) => {
317
+ this.notifications$.next(notifications ?? []);
318
+ });
319
+ this.connection.start().catch((error) => {
320
+ console.error("Failed to connect to the notifications hub.", error);
321
+ });
322
+ }
323
+ async stop() {
324
+ if (this.connection) {
325
+ await this.connection.stop();
326
+ this.connection = void 0;
327
+ }
328
+ }
329
+ static ɵfac = i0.ɵɵngDeclareFactory({
330
+ minVersion: "12.0.0",
331
+ version: "22.2.0",
332
+ ngImport: i0,
333
+ type: NotificationsService,
334
+ deps: [],
335
+ target: i0.ɵɵFactoryTarget.Injectable
336
+ });
337
+ static ɵprov = i0.ɵɵngDeclareInjectable({
338
+ minVersion: "12.0.0",
339
+ version: "22.2.0",
340
+ ngImport: i0,
341
+ type: NotificationsService,
342
+ providedIn: "root"
343
+ });
344
+ };
345
+ i0.ɵɵngDeclareClassMetadata({
346
+ minVersion: "12.0.0",
347
+ version: "22.2.0",
348
+ ngImport: i0,
349
+ type: NotificationsService,
350
+ decorators: [{
351
+ type: Injectable,
352
+ args: [{ providedIn: "root" }]
353
+ }]
354
+ });
355
+ var OperationsHistoryService = class OperationsHistoryService {
356
+ config = inject(APP_CONFIG);
357
+ http = inject(HttpClient);
358
+ list(controllerName, entityID, serviceHistoryID, parameters) {
359
+ return this.http.post(`${this.config.BASE_URL}/${controllerName}/${entityID}/Audit/${serviceHistoryID}`, parameters);
360
+ }
361
+ static ɵfac = i0.ɵɵngDeclareFactory({
362
+ minVersion: "12.0.0",
363
+ version: "22.2.0",
364
+ ngImport: i0,
365
+ type: OperationsHistoryService,
366
+ deps: [],
367
+ target: i0.ɵɵFactoryTarget.Injectable
368
+ });
369
+ static ɵprov = i0.ɵɵngDeclareInjectable({
370
+ minVersion: "12.0.0",
371
+ version: "22.2.0",
372
+ ngImport: i0,
373
+ type: OperationsHistoryService,
374
+ providedIn: "root"
375
+ });
376
+ };
377
+ i0.ɵɵngDeclareClassMetadata({
378
+ minVersion: "12.0.0",
379
+ version: "22.2.0",
380
+ ngImport: i0,
381
+ type: OperationsHistoryService,
382
+ decorators: [{
383
+ type: Injectable,
384
+ args: [{ providedIn: "root" }]
385
+ }]
386
+ });
387
+ var ServicesHistoryService = class ServicesHistoryService {
388
+ config = inject(APP_CONFIG);
389
+ http = inject(HttpClient);
390
+ list(controllerName, entityID, parameters) {
391
+ return this.http.post(`${this.config.BASE_URL}/${controllerName}/${entityID}/Audit`, parameters);
392
+ }
393
+ static ɵfac = i0.ɵɵngDeclareFactory({
394
+ minVersion: "12.0.0",
395
+ version: "22.2.0",
396
+ ngImport: i0,
397
+ type: ServicesHistoryService,
398
+ deps: [],
399
+ target: i0.ɵɵFactoryTarget.Injectable
400
+ });
401
+ static ɵprov = i0.ɵɵngDeclareInjectable({
402
+ minVersion: "12.0.0",
403
+ version: "22.2.0",
404
+ ngImport: i0,
405
+ type: ServicesHistoryService,
406
+ providedIn: "root"
407
+ });
408
+ };
409
+ i0.ɵɵngDeclareClassMetadata({
410
+ minVersion: "12.0.0",
411
+ version: "22.2.0",
412
+ ngImport: i0,
413
+ type: ServicesHistoryService,
414
+ decorators: [{
415
+ type: Injectable,
416
+ args: [{ providedIn: "root" }]
417
+ }]
418
+ });
419
+ var BrandComponent = class BrandComponent {
420
+ config = inject(APP_CONFIG);
421
+ get appName() {
422
+ return this.config.appName;
423
+ }
424
+ get companyName() {
425
+ return this.config.companyName;
426
+ }
427
+ get logoUrl() {
428
+ return this.config.logoUrl;
429
+ }
430
+ static ɵfac = i0.ɵɵngDeclareFactory({
431
+ minVersion: "12.0.0",
432
+ version: "22.2.0",
433
+ ngImport: i0,
434
+ type: BrandComponent,
435
+ deps: [],
436
+ target: i0.ɵɵFactoryTarget.Component
437
+ });
438
+ static ɵcmp = i0.ɵɵngDeclareComponent({
439
+ minVersion: "17.0.0",
440
+ version: "22.2.0",
441
+ type: BrandComponent,
442
+ isStandalone: true,
443
+ selector: "shared-brand",
444
+ ngImport: i0,
445
+ template: "<div class=\"brand\">\n @if (logoUrl) {\n <img class=\"brand-logo\" [src]=\"logoUrl\" [alt]=\"appName\" />\n }\n\n <div class=\"brand-text\">\n <span class=\"brand-app\">{{ appName }}</span>\n @if (companyName) {\n <span class=\"brand-company\">{{ companyName }}</span>\n }\n </div>\n</div>\n",
446
+ styles: ["@layer properties;.brand{display:flex;min-width:0px;align-items:center;gap:calc(var(--spacing, .25rem) * 2)}.brand .brand-app{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:var(--text-sm, .875rem);line-height:var(--tw-leading, var(--text-sm--line-height, calc(1.25 / .875)));--tw-font-weight: var(--font-weight-semibold, 600);font-weight:var(--font-weight-semibold, 600)}.brand .brand-company{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:var(--text-xs, .75rem);line-height:var(--tw-leading, var(--text-xs--line-height, calc(1 / .75)));color:var(--color-stone-500, oklch(55.3% .013 58.071))}.brand .brand-logo{height:calc(var(--spacing, .25rem) * 8);width:calc(var(--spacing, .25rem) * 8);flex-shrink:0;object-fit:contain}.brand .brand-text{display:flex;min-width:0px;flex-direction:column;--tw-leading: var(--leading-tight, 1.25);line-height:var(--leading-tight, 1.25)}@media(max-width:767px){.brand .brand-text{display:none}}@property --tw-font-weight{syntax: \"*\"; inherits: false;}@property --tw-leading{syntax: \"*\"; inherits: false;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-font-weight: initial;--tw-leading: initial}}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"],
447
+ changeDetection: i0.ChangeDetectionStrategy.OnPush
448
+ });
449
+ };
450
+ i0.ɵɵngDeclareClassMetadata({
451
+ minVersion: "12.0.0",
452
+ version: "22.2.0",
453
+ ngImport: i0,
454
+ type: BrandComponent,
455
+ decorators: [{
456
+ type: Component,
457
+ args: [{
458
+ selector: "shared-brand",
459
+ changeDetection: ChangeDetectionStrategy.OnPush,
460
+ template: "<div class=\"brand\">\n @if (logoUrl) {\n <img class=\"brand-logo\" [src]=\"logoUrl\" [alt]=\"appName\" />\n }\n\n <div class=\"brand-text\">\n <span class=\"brand-app\">{{ appName }}</span>\n @if (companyName) {\n <span class=\"brand-company\">{{ companyName }}</span>\n }\n </div>\n</div>\n",
461
+ styles: ["@layer properties;.brand{display:flex;min-width:0px;align-items:center;gap:calc(var(--spacing, .25rem) * 2)}.brand .brand-app{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:var(--text-sm, .875rem);line-height:var(--tw-leading, var(--text-sm--line-height, calc(1.25 / .875)));--tw-font-weight: var(--font-weight-semibold, 600);font-weight:var(--font-weight-semibold, 600)}.brand .brand-company{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:var(--text-xs, .75rem);line-height:var(--tw-leading, var(--text-xs--line-height, calc(1 / .75)));color:var(--color-stone-500, oklch(55.3% .013 58.071))}.brand .brand-logo{height:calc(var(--spacing, .25rem) * 8);width:calc(var(--spacing, .25rem) * 8);flex-shrink:0;object-fit:contain}.brand .brand-text{display:flex;min-width:0px;flex-direction:column;--tw-leading: var(--leading-tight, 1.25);line-height:var(--leading-tight, 1.25)}@media(max-width:767px){.brand .brand-text{display:none}}@property --tw-font-weight{syntax: \"*\"; inherits: false;}@property --tw-leading{syntax: \"*\"; inherits: false;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-font-weight: initial;--tw-leading: initial}}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"]
462
+ }]
463
+ }]
464
+ });
465
+ var EnvironmentBadgeComponent = class EnvironmentBadgeComponent {
466
+ config = inject(APP_CONFIG);
467
+ get badgeClass() {
468
+ return {
469
+ DEV: "env-dev",
470
+ QA: "env-qa",
471
+ STG: "env-stg"
472
+ }[this.environment] ?? "env-neutral";
473
+ }
474
+ get environment() {
475
+ return (this.config.environment ?? "").trim().toUpperCase();
476
+ }
477
+ get isVisible() {
478
+ return this.environment.length > 0 && this.environment !== "PROD";
479
+ }
480
+ static ɵfac = i0.ɵɵngDeclareFactory({
481
+ minVersion: "12.0.0",
482
+ version: "22.2.0",
483
+ ngImport: i0,
484
+ type: EnvironmentBadgeComponent,
485
+ deps: [],
486
+ target: i0.ɵɵFactoryTarget.Component
487
+ });
488
+ static ɵcmp = i0.ɵɵngDeclareComponent({
489
+ minVersion: "17.0.0",
490
+ version: "22.2.0",
491
+ type: EnvironmentBadgeComponent,
492
+ isStandalone: true,
493
+ selector: "shared-environment-badge",
494
+ ngImport: i0,
495
+ template: "@if (isVisible) {\n <span class=\"env-badge {{ badgeClass }}\">\n <span class=\"env-dot\"></span>\n <span class=\"env-label\">{{ environment }}</span>\n </span>\n}\n",
496
+ styles: ["@layer properties;.env-badge{display:inline-flex;align-items:center;gap:calc(var(--spacing, .25rem) * 1.5);border-radius:calc(infinity * 1px);padding-inline:calc(var(--spacing, .25rem) * 2.5);padding-block:.325rem;font-size:var(--text-sm, .875rem);line-height:var(--tw-leading, var(--text-sm--line-height, calc(1.25 / .875)));--tw-font-weight: var(--font-weight-semibold, 600);font-weight:var(--font-weight-semibold, 600);--tw-tracking: var(--tracking-wide, .025em);letter-spacing:var(--tracking-wide, .025em);text-transform:uppercase;--tw-ring-shadow: var(--tw-ring-inset,) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color, currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-inset: inset}.env-badge .env-dot{height:calc(var(--spacing, .25rem) * 1.5);width:calc(var(--spacing, .25rem) * 1.5);flex-shrink:0;border-radius:calc(infinity * 1px)}.env-badge.env-dev{background-color:var(--color-blue-50, oklch(97% .014 254.604));color:var(--color-blue-700, oklch(48.8% .243 264.376));--tw-ring-color: color-mix(in srgb, oklch(54.6% .245 262.881) 20%, transparent)}@supports (color: color-mix(in lab,red,red)){.env-badge.env-dev{--tw-ring-color: color-mix(in oklab, var(--color-blue-600, oklch(54.6% .245 262.881)) 20%, transparent)}}.env-badge.env-dev .env-dot{background-color:var(--color-blue-500, oklch(62.3% .214 259.815))}.env-badge.env-neutral{background-color:var(--color-stone-100, oklch(97% .001 106.424));color:var(--color-stone-600, oklch(44.4% .011 73.639));--tw-ring-color: color-mix(in srgb, oklch(55.3% .013 58.071) 20%, transparent)}@supports (color: color-mix(in lab,red,red)){.env-badge.env-neutral{--tw-ring-color: color-mix(in oklab, var(--color-stone-500, oklch(55.3% .013 58.071)) 20%, transparent)}}.env-badge.env-neutral .env-dot{background-color:var(--color-stone-500, oklch(55.3% .013 58.071))}.env-badge.env-qa{background-color:var(--color-amber-50, oklch(98.7% .022 95.277));color:var(--color-amber-700, oklch(55.5% .163 48.998));--tw-ring-color: color-mix(in srgb, oklch(66.6% .179 58.318) 20%, transparent)}@supports (color: color-mix(in lab,red,red)){.env-badge.env-qa{--tw-ring-color: color-mix(in oklab, var(--color-amber-600, oklch(66.6% .179 58.318)) 20%, transparent)}}.env-badge.env-qa .env-dot{background-color:var(--color-amber-500, oklch(76.9% .188 70.08))}.env-badge.env-stg{background-color:var(--color-violet-50, oklch(96.9% .016 293.756));color:var(--color-violet-700, oklch(49.1% .27 292.581));--tw-ring-color: color-mix(in srgb, oklch(54.1% .281 293.009) 20%, transparent)}@supports (color: color-mix(in lab,red,red)){.env-badge.env-stg{--tw-ring-color: color-mix(in oklab, var(--color-violet-600, oklch(54.1% .281 293.009)) 20%, transparent)}}.env-badge.env-stg .env-dot{background-color:var(--color-violet-500, oklch(60.6% .25 292.717))}@property --tw-font-weight{syntax: \"*\"; inherits: false;}@property --tw-tracking{syntax: \"*\"; inherits: false;}@property --tw-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-shadow-color{syntax: \"*\"; inherits: false;}@property --tw-shadow-alpha{syntax: \"<percentage>\"; inherits: false; initial-value: 100%;}@property --tw-inset-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-inset-shadow-color{syntax: \"*\"; inherits: false;}@property --tw-inset-shadow-alpha{syntax: \"<percentage>\"; inherits: false; initial-value: 100%;}@property --tw-ring-color{syntax: \"*\"; inherits: false;}@property --tw-ring-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-inset-ring-color{syntax: \"*\"; inherits: false;}@property --tw-inset-ring-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-ring-inset{syntax: \"*\"; inherits: false;}@property --tw-ring-offset-width{syntax: \"<length>\"; inherits: false; initial-value: 0px;}@property --tw-ring-offset-color{syntax: \"*\"; inherits: false; initial-value: #fff;}@property --tw-ring-offset-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-font-weight: initial;--tw-tracking: initial;--tw-shadow: 0 0 #0000;--tw-shadow-color: initial;--tw-shadow-alpha: 100%;--tw-inset-shadow: 0 0 #0000;--tw-inset-shadow-color: initial;--tw-inset-shadow-alpha: 100%;--tw-ring-color: initial;--tw-ring-shadow: 0 0 #0000;--tw-inset-ring-color: initial;--tw-inset-ring-shadow: 0 0 #0000;--tw-ring-inset: initial;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-offset-shadow: 0 0 #0000}}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"],
497
+ changeDetection: i0.ChangeDetectionStrategy.OnPush
498
+ });
499
+ };
500
+ i0.ɵɵngDeclareClassMetadata({
501
+ minVersion: "12.0.0",
502
+ version: "22.2.0",
503
+ ngImport: i0,
504
+ type: EnvironmentBadgeComponent,
505
+ decorators: [{
506
+ type: Component,
507
+ args: [{
508
+ selector: "shared-environment-badge",
509
+ changeDetection: ChangeDetectionStrategy.OnPush,
510
+ template: "@if (isVisible) {\n <span class=\"env-badge {{ badgeClass }}\">\n <span class=\"env-dot\"></span>\n <span class=\"env-label\">{{ environment }}</span>\n </span>\n}\n",
511
+ styles: ["@layer properties;.env-badge{display:inline-flex;align-items:center;gap:calc(var(--spacing, .25rem) * 1.5);border-radius:calc(infinity * 1px);padding-inline:calc(var(--spacing, .25rem) * 2.5);padding-block:.325rem;font-size:var(--text-sm, .875rem);line-height:var(--tw-leading, var(--text-sm--line-height, calc(1.25 / .875)));--tw-font-weight: var(--font-weight-semibold, 600);font-weight:var(--font-weight-semibold, 600);--tw-tracking: var(--tracking-wide, .025em);letter-spacing:var(--tracking-wide, .025em);text-transform:uppercase;--tw-ring-shadow: var(--tw-ring-inset,) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color, currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-inset: inset}.env-badge .env-dot{height:calc(var(--spacing, .25rem) * 1.5);width:calc(var(--spacing, .25rem) * 1.5);flex-shrink:0;border-radius:calc(infinity * 1px)}.env-badge.env-dev{background-color:var(--color-blue-50, oklch(97% .014 254.604));color:var(--color-blue-700, oklch(48.8% .243 264.376));--tw-ring-color: color-mix(in srgb, oklch(54.6% .245 262.881) 20%, transparent)}@supports (color: color-mix(in lab,red,red)){.env-badge.env-dev{--tw-ring-color: color-mix(in oklab, var(--color-blue-600, oklch(54.6% .245 262.881)) 20%, transparent)}}.env-badge.env-dev .env-dot{background-color:var(--color-blue-500, oklch(62.3% .214 259.815))}.env-badge.env-neutral{background-color:var(--color-stone-100, oklch(97% .001 106.424));color:var(--color-stone-600, oklch(44.4% .011 73.639));--tw-ring-color: color-mix(in srgb, oklch(55.3% .013 58.071) 20%, transparent)}@supports (color: color-mix(in lab,red,red)){.env-badge.env-neutral{--tw-ring-color: color-mix(in oklab, var(--color-stone-500, oklch(55.3% .013 58.071)) 20%, transparent)}}.env-badge.env-neutral .env-dot{background-color:var(--color-stone-500, oklch(55.3% .013 58.071))}.env-badge.env-qa{background-color:var(--color-amber-50, oklch(98.7% .022 95.277));color:var(--color-amber-700, oklch(55.5% .163 48.998));--tw-ring-color: color-mix(in srgb, oklch(66.6% .179 58.318) 20%, transparent)}@supports (color: color-mix(in lab,red,red)){.env-badge.env-qa{--tw-ring-color: color-mix(in oklab, var(--color-amber-600, oklch(66.6% .179 58.318)) 20%, transparent)}}.env-badge.env-qa .env-dot{background-color:var(--color-amber-500, oklch(76.9% .188 70.08))}.env-badge.env-stg{background-color:var(--color-violet-50, oklch(96.9% .016 293.756));color:var(--color-violet-700, oklch(49.1% .27 292.581));--tw-ring-color: color-mix(in srgb, oklch(54.1% .281 293.009) 20%, transparent)}@supports (color: color-mix(in lab,red,red)){.env-badge.env-stg{--tw-ring-color: color-mix(in oklab, var(--color-violet-600, oklch(54.1% .281 293.009)) 20%, transparent)}}.env-badge.env-stg .env-dot{background-color:var(--color-violet-500, oklch(60.6% .25 292.717))}@property --tw-font-weight{syntax: \"*\"; inherits: false;}@property --tw-tracking{syntax: \"*\"; inherits: false;}@property --tw-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-shadow-color{syntax: \"*\"; inherits: false;}@property --tw-shadow-alpha{syntax: \"<percentage>\"; inherits: false; initial-value: 100%;}@property --tw-inset-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-inset-shadow-color{syntax: \"*\"; inherits: false;}@property --tw-inset-shadow-alpha{syntax: \"<percentage>\"; inherits: false; initial-value: 100%;}@property --tw-ring-color{syntax: \"*\"; inherits: false;}@property --tw-ring-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-inset-ring-color{syntax: \"*\"; inherits: false;}@property --tw-inset-ring-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-ring-inset{syntax: \"*\"; inherits: false;}@property --tw-ring-offset-width{syntax: \"<length>\"; inherits: false; initial-value: 0px;}@property --tw-ring-offset-color{syntax: \"*\"; inherits: false; initial-value: #fff;}@property --tw-ring-offset-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-font-weight: initial;--tw-tracking: initial;--tw-shadow: 0 0 #0000;--tw-shadow-color: initial;--tw-shadow-alpha: 100%;--tw-inset-shadow: 0 0 #0000;--tw-inset-shadow-color: initial;--tw-inset-shadow-alpha: 100%;--tw-ring-color: initial;--tw-ring-shadow: 0 0 #0000;--tw-inset-ring-color: initial;--tw-inset-ring-shadow: 0 0 #0000;--tw-ring-inset: initial;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-offset-shadow: 0 0 #0000}}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"]
512
+ }]
513
+ }]
514
+ });
515
+ var NotificationsComponent = class NotificationsComponent {
516
+ dropdown = viewChild("dropdown", ...ngDevMode ? [{ debugName: "dropdown" }] : /* istanbul ignore next */ []);
517
+ notificationsService = inject(NotificationsService);
518
+ router = inject(Router);
519
+ notifications$ = this.notificationsService.getNotifications();
520
+ showDropdown = signal(false, ...ngDevMode ? [{ debugName: "showDropdown" }] : /* istanbul ignore next */ []);
521
+ unreadCount$ = this.notificationsService.getUnreadCount();
522
+ get isEnabled() {
523
+ return this.notificationsService.isEnabled;
524
+ }
525
+ ngOnInit() {
526
+ this.notificationsService.start();
527
+ }
528
+ onDropdownClick() {
529
+ this.showDropdown.update((isShown) => !isShown);
530
+ }
531
+ onMarkAllAsRead() {
532
+ this.notificationsService.markAllAsRead();
533
+ }
534
+ onNotificationClick(notification) {
535
+ this.notificationsService.markAsRead(notification);
536
+ this.showDropdown.set(false);
537
+ const url = notification.callToActionUrl;
538
+ if (!url) return;
539
+ if (/^https?:\/\//i.test(url)) window.open(url, "_blank", "noopener");
540
+ else this.router.navigateByUrl(url);
541
+ }
542
+ documentClick(event) {
543
+ if (this.showDropdown()) {
544
+ let target = event.target;
545
+ while (target !== null && target.tagName?.toUpperCase() !== "BODY") {
546
+ if (target === this.dropdown()?.nativeElement) return;
547
+ target = target.parentElement;
548
+ }
549
+ this.showDropdown.set(false);
550
+ }
551
+ }
552
+ static ɵfac = i0.ɵɵngDeclareFactory({
553
+ minVersion: "12.0.0",
554
+ version: "22.2.0",
555
+ ngImport: i0,
556
+ type: NotificationsComponent,
557
+ deps: [],
558
+ target: i0.ɵɵFactoryTarget.Component
559
+ });
560
+ static ɵcmp = i0.ɵɵngDeclareComponent({
561
+ minVersion: "17.0.0",
562
+ version: "22.2.0",
563
+ type: NotificationsComponent,
564
+ isStandalone: true,
565
+ selector: "shared-notifications",
566
+ host: { listeners: { "window:click": "documentClick($event)" } },
567
+ viewQueries: [{
568
+ propertyName: "dropdown",
569
+ first: true,
570
+ predicate: ["dropdown"],
571
+ descendants: true,
572
+ isSignal: true
573
+ }],
574
+ ngImport: i0,
575
+ template: "@if (isEnabled) {\n <div #dropdown class=\"notifications\">\n <button\n class=\"btn gray-300 notifications-toggle\"\n type=\"button\"\n (click)=\"onDropdownClick()\"\n [attr.aria-label]=\"'TopBar-Notifications-Title' | translate\"\n >\n <i class=\"fa-solid fa-bell\"></i>\n @if (unreadCount$ | async; as count) {\n <span class=\"notifications-badge\">{{ count }}</span>\n }\n </button>\n\n @if (showDropdown()) {\n <div class=\"notifications-panel\">\n @let items = (notifications$ | async) ?? [];\n\n <div class=\"notifications-header\">\n <span>{{ 'TopBar-Notifications-Title' | translate }}</span>\n @if (items.length > 0) {\n <button type=\"button\" class=\"notifications-mark-all\" (click)=\"onMarkAllAsRead()\">\n {{ 'TopBar-Notifications-MarkAllRead' | translate }}\n </button>\n }\n </div>\n\n @if (items.length > 0) {\n <ul class=\"notifications-list\">\n @for (item of items; track $index) {\n <li class=\"notifications-item\" [class.unread]=\"!item.isRead\">\n <button\n type=\"button\"\n class=\"notifications-item-btn\"\n [class.has-cta]=\"!!item.callToActionUrl\"\n (click)=\"onNotificationClick(item)\"\n >\n <span class=\"notifications-item-icon\"><i class=\"{{ item.icon }}\"></i></span>\n <span class=\"notifications-item-body\">\n <span class=\"notifications-item-title\">{{ item.title }}</span>\n <span class=\"notifications-item-description\">{{ item.description }}</span>\n </span>\n @if (item.callToActionUrl) {\n <i class=\"notifications-item-cta fa-solid fa-chevron-right\"></i>\n }\n </button>\n </li>\n }\n </ul>\n } @else {\n <div class=\"notifications-empty\">{{ 'TopBar-Notifications-Empty' | translate }}</div>\n }\n </div>\n }\n </div>\n}\n",
576
+ styles: ["@layer properties;.notifications{position:relative}.notifications .notifications-badge{position:absolute;top:calc(var(--spacing, .25rem) * -1);right:calc(var(--spacing, .25rem) * -1);height:calc(var(--spacing, .25rem) * 4);min-width:calc(var(--spacing, .25rem) * 4);border-radius:calc(infinity * 1px);padding-inline:var(--spacing, .25rem);display:flex;align-items:center;justify-content:center;font-size:10px;--tw-leading: 1;line-height:1;--tw-font-weight: var(--font-weight-bold, 700);font-weight:var(--font-weight-bold, 700);background-color:var(--color-red-600, oklch(57.7% .245 27.325));color:var(--color-white, #fff)}.notifications .notifications-empty{padding-inline:calc(var(--spacing, .25rem) * 3);padding-block:calc(var(--spacing, .25rem) * 6);text-align:center;font-size:var(--text-sm, .875rem);line-height:var(--tw-leading, var(--text-sm--line-height, calc(1.25 / .875)));color:var(--color-stone-500, oklch(55.3% .013 58.071))}.notifications .notifications-header{display:flex;align-items:center;justify-content:space-between;border-bottom-style:var(--tw-border-style);border-bottom-width:1px;border-color:var(--color-stone-200, oklch(92.3% .003 48.717));padding-inline:calc(var(--spacing, .25rem) * 3);padding-block:calc(var(--spacing, .25rem) * 2);font-size:var(--text-sm, .875rem);line-height:var(--tw-leading, var(--text-sm--line-height, calc(1.25 / .875)));--tw-font-weight: var(--font-weight-semibold, 600);font-weight:var(--font-weight-semibold, 600)}.notifications .notifications-list{max-height:calc(var(--spacing, .25rem) * 80);overflow-y:auto}.notifications .notifications-list .notifications-item{border-bottom-style:var(--tw-border-style);border-bottom-width:1px;border-color:var(--color-stone-100, oklch(97% .001 106.424))}.notifications .notifications-list .notifications-item:last-child{border-bottom-style:var(--tw-border-style);border-bottom-width:0px}.notifications .notifications-list .notifications-item.unread{background-color:color-mix(in srgb,#e6f4ff 60%,transparent)}@supports (color: color-mix(in lab,red,red)){.notifications .notifications-list .notifications-item.unread{background-color:color-mix(in oklab,var(--color-primary-50, #e6f4ff) 60%,transparent)}}.notifications .notifications-list .notifications-item .notifications-item-body{display:flex;min-width:0px;flex:1;flex-direction:column}.notifications .notifications-list .notifications-item .notifications-item-btn{display:flex;width:100%;cursor:pointer;align-items:flex-start;gap:calc(var(--spacing, .25rem) * 2.5);padding-inline:calc(var(--spacing, .25rem) * 3);padding-block:calc(var(--spacing, .25rem) * 2);text-align:left}@media(hover:hover){.notifications .notifications-list .notifications-item .notifications-item-btn:hover{background-color:var(--color-stone-50, oklch(98.5% .001 106.423))}}.notifications .notifications-list .notifications-item .notifications-item-cta{margin-top:var(--spacing, .25rem);flex-shrink:0;font-size:var(--text-xs, .75rem);line-height:var(--tw-leading, var(--text-xs--line-height, calc(1 / .75)));color:var(--color-stone-400, oklch(70.9% .01 56.259))}.notifications .notifications-list .notifications-item .notifications-item-description{font-size:var(--text-xs, .75rem);line-height:var(--tw-leading, var(--text-xs--line-height, calc(1 / .75)));color:var(--color-stone-500, oklch(55.3% .013 58.071))}.notifications .notifications-list .notifications-item .notifications-item-icon{margin-top:calc(var(--spacing, .25rem) * .5);display:flex;height:calc(var(--spacing, .25rem) * 6);width:calc(var(--spacing, .25rem) * 6);flex-shrink:0;align-items:center;justify-content:center;border-radius:calc(infinity * 1px);background-color:var(--color-stone-100, oklch(97% .001 106.424));font-size:var(--text-xs, .75rem);line-height:var(--tw-leading, var(--text-xs--line-height, calc(1 / .75)));color:var(--color-stone-600, oklch(44.4% .011 73.639))}.notifications .notifications-list .notifications-item .notifications-item-title{font-size:var(--text-sm, .875rem);line-height:var(--tw-leading, var(--text-sm--line-height, calc(1.25 / .875)));--tw-font-weight: var(--font-weight-medium, 500);font-weight:var(--font-weight-medium, 500);color:var(--color-stone-800, oklch(26.8% .007 34.298))}.notifications .notifications-mark-all{font-size:var(--text-xs, .75rem);line-height:var(--tw-leading, var(--text-xs--line-height, calc(1 / .75)));--tw-font-weight: var(--font-weight-medium, 500);font-weight:var(--font-weight-medium, 500);color:var(--color-primary-400, #006bb6)}@media(hover:hover){.notifications .notifications-mark-all:hover{color:var(--color-primary-500, #005794)}}.notifications .notifications-panel{position:absolute;top:100%;right:0;z-index:50;margin-top:var(--spacing, .25rem);width:calc(var(--spacing, .25rem) * 80);max-width:90vw;border-radius:var(--radius-md, .375rem);border-style:var(--tw-border-style);border-width:1px;border-color:var(--color-stone-200, oklch(92.3% .003 48.717));background-color:var(--color-white, #fff);--tw-shadow: 0 0 4px 0 var(--tw-shadow-color, rgba(0,0,0,.2)), 0 3px 20px 0 var(--tw-shadow-color, rgba(0,0,0,.19));box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.notifications .notifications-toggle{position:relative}.notifications .notifications-toggle i{margin-right:0}@property --tw-leading{syntax: \"*\"; inherits: false;}@property --tw-font-weight{syntax: \"*\"; inherits: false;}@property --tw-border-style{syntax: \"*\"; inherits: false; initial-value: solid;}@property --tw-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-shadow-color{syntax: \"*\"; inherits: false;}@property --tw-shadow-alpha{syntax: \"<percentage>\"; inherits: false; initial-value: 100%;}@property --tw-inset-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-inset-shadow-color{syntax: \"*\"; inherits: false;}@property --tw-inset-shadow-alpha{syntax: \"<percentage>\"; inherits: false; initial-value: 100%;}@property --tw-ring-color{syntax: \"*\"; inherits: false;}@property --tw-ring-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-inset-ring-color{syntax: \"*\"; inherits: false;}@property --tw-inset-ring-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-ring-inset{syntax: \"*\"; inherits: false;}@property --tw-ring-offset-width{syntax: \"<length>\"; inherits: false; initial-value: 0px;}@property --tw-ring-offset-color{syntax: \"*\"; inherits: false; initial-value: #fff;}@property --tw-ring-offset-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-leading: initial;--tw-font-weight: initial;--tw-border-style: solid;--tw-shadow: 0 0 #0000;--tw-shadow-color: initial;--tw-shadow-alpha: 100%;--tw-inset-shadow: 0 0 #0000;--tw-inset-shadow-color: initial;--tw-inset-shadow-alpha: 100%;--tw-ring-color: initial;--tw-ring-shadow: 0 0 #0000;--tw-inset-ring-color: initial;--tw-inset-ring-shadow: 0 0 #0000;--tw-ring-inset: initial;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-offset-shadow: 0 0 #0000}}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"],
577
+ dependencies: [{
578
+ kind: "pipe",
579
+ type: AsyncPipe,
580
+ name: "async"
581
+ }, {
582
+ kind: "pipe",
583
+ type: TranslatePipe,
584
+ name: "translate"
585
+ }]
586
+ });
587
+ };
588
+ i0.ɵɵngDeclareClassMetadata({
589
+ minVersion: "12.0.0",
590
+ version: "22.2.0",
591
+ ngImport: i0,
592
+ type: NotificationsComponent,
593
+ decorators: [{
594
+ type: Component,
595
+ args: [{
596
+ selector: "shared-notifications",
597
+ imports: [AsyncPipe, TranslatePipe],
598
+ template: "@if (isEnabled) {\n <div #dropdown class=\"notifications\">\n <button\n class=\"btn gray-300 notifications-toggle\"\n type=\"button\"\n (click)=\"onDropdownClick()\"\n [attr.aria-label]=\"'TopBar-Notifications-Title' | translate\"\n >\n <i class=\"fa-solid fa-bell\"></i>\n @if (unreadCount$ | async; as count) {\n <span class=\"notifications-badge\">{{ count }}</span>\n }\n </button>\n\n @if (showDropdown()) {\n <div class=\"notifications-panel\">\n @let items = (notifications$ | async) ?? [];\n\n <div class=\"notifications-header\">\n <span>{{ 'TopBar-Notifications-Title' | translate }}</span>\n @if (items.length > 0) {\n <button type=\"button\" class=\"notifications-mark-all\" (click)=\"onMarkAllAsRead()\">\n {{ 'TopBar-Notifications-MarkAllRead' | translate }}\n </button>\n }\n </div>\n\n @if (items.length > 0) {\n <ul class=\"notifications-list\">\n @for (item of items; track $index) {\n <li class=\"notifications-item\" [class.unread]=\"!item.isRead\">\n <button\n type=\"button\"\n class=\"notifications-item-btn\"\n [class.has-cta]=\"!!item.callToActionUrl\"\n (click)=\"onNotificationClick(item)\"\n >\n <span class=\"notifications-item-icon\"><i class=\"{{ item.icon }}\"></i></span>\n <span class=\"notifications-item-body\">\n <span class=\"notifications-item-title\">{{ item.title }}</span>\n <span class=\"notifications-item-description\">{{ item.description }}</span>\n </span>\n @if (item.callToActionUrl) {\n <i class=\"notifications-item-cta fa-solid fa-chevron-right\"></i>\n }\n </button>\n </li>\n }\n </ul>\n } @else {\n <div class=\"notifications-empty\">{{ 'TopBar-Notifications-Empty' | translate }}</div>\n }\n </div>\n }\n </div>\n}\n",
599
+ styles: ["@layer properties;.notifications{position:relative}.notifications .notifications-badge{position:absolute;top:calc(var(--spacing, .25rem) * -1);right:calc(var(--spacing, .25rem) * -1);height:calc(var(--spacing, .25rem) * 4);min-width:calc(var(--spacing, .25rem) * 4);border-radius:calc(infinity * 1px);padding-inline:var(--spacing, .25rem);display:flex;align-items:center;justify-content:center;font-size:10px;--tw-leading: 1;line-height:1;--tw-font-weight: var(--font-weight-bold, 700);font-weight:var(--font-weight-bold, 700);background-color:var(--color-red-600, oklch(57.7% .245 27.325));color:var(--color-white, #fff)}.notifications .notifications-empty{padding-inline:calc(var(--spacing, .25rem) * 3);padding-block:calc(var(--spacing, .25rem) * 6);text-align:center;font-size:var(--text-sm, .875rem);line-height:var(--tw-leading, var(--text-sm--line-height, calc(1.25 / .875)));color:var(--color-stone-500, oklch(55.3% .013 58.071))}.notifications .notifications-header{display:flex;align-items:center;justify-content:space-between;border-bottom-style:var(--tw-border-style);border-bottom-width:1px;border-color:var(--color-stone-200, oklch(92.3% .003 48.717));padding-inline:calc(var(--spacing, .25rem) * 3);padding-block:calc(var(--spacing, .25rem) * 2);font-size:var(--text-sm, .875rem);line-height:var(--tw-leading, var(--text-sm--line-height, calc(1.25 / .875)));--tw-font-weight: var(--font-weight-semibold, 600);font-weight:var(--font-weight-semibold, 600)}.notifications .notifications-list{max-height:calc(var(--spacing, .25rem) * 80);overflow-y:auto}.notifications .notifications-list .notifications-item{border-bottom-style:var(--tw-border-style);border-bottom-width:1px;border-color:var(--color-stone-100, oklch(97% .001 106.424))}.notifications .notifications-list .notifications-item:last-child{border-bottom-style:var(--tw-border-style);border-bottom-width:0px}.notifications .notifications-list .notifications-item.unread{background-color:color-mix(in srgb,#e6f4ff 60%,transparent)}@supports (color: color-mix(in lab,red,red)){.notifications .notifications-list .notifications-item.unread{background-color:color-mix(in oklab,var(--color-primary-50, #e6f4ff) 60%,transparent)}}.notifications .notifications-list .notifications-item .notifications-item-body{display:flex;min-width:0px;flex:1;flex-direction:column}.notifications .notifications-list .notifications-item .notifications-item-btn{display:flex;width:100%;cursor:pointer;align-items:flex-start;gap:calc(var(--spacing, .25rem) * 2.5);padding-inline:calc(var(--spacing, .25rem) * 3);padding-block:calc(var(--spacing, .25rem) * 2);text-align:left}@media(hover:hover){.notifications .notifications-list .notifications-item .notifications-item-btn:hover{background-color:var(--color-stone-50, oklch(98.5% .001 106.423))}}.notifications .notifications-list .notifications-item .notifications-item-cta{margin-top:var(--spacing, .25rem);flex-shrink:0;font-size:var(--text-xs, .75rem);line-height:var(--tw-leading, var(--text-xs--line-height, calc(1 / .75)));color:var(--color-stone-400, oklch(70.9% .01 56.259))}.notifications .notifications-list .notifications-item .notifications-item-description{font-size:var(--text-xs, .75rem);line-height:var(--tw-leading, var(--text-xs--line-height, calc(1 / .75)));color:var(--color-stone-500, oklch(55.3% .013 58.071))}.notifications .notifications-list .notifications-item .notifications-item-icon{margin-top:calc(var(--spacing, .25rem) * .5);display:flex;height:calc(var(--spacing, .25rem) * 6);width:calc(var(--spacing, .25rem) * 6);flex-shrink:0;align-items:center;justify-content:center;border-radius:calc(infinity * 1px);background-color:var(--color-stone-100, oklch(97% .001 106.424));font-size:var(--text-xs, .75rem);line-height:var(--tw-leading, var(--text-xs--line-height, calc(1 / .75)));color:var(--color-stone-600, oklch(44.4% .011 73.639))}.notifications .notifications-list .notifications-item .notifications-item-title{font-size:var(--text-sm, .875rem);line-height:var(--tw-leading, var(--text-sm--line-height, calc(1.25 / .875)));--tw-font-weight: var(--font-weight-medium, 500);font-weight:var(--font-weight-medium, 500);color:var(--color-stone-800, oklch(26.8% .007 34.298))}.notifications .notifications-mark-all{font-size:var(--text-xs, .75rem);line-height:var(--tw-leading, var(--text-xs--line-height, calc(1 / .75)));--tw-font-weight: var(--font-weight-medium, 500);font-weight:var(--font-weight-medium, 500);color:var(--color-primary-400, #006bb6)}@media(hover:hover){.notifications .notifications-mark-all:hover{color:var(--color-primary-500, #005794)}}.notifications .notifications-panel{position:absolute;top:100%;right:0;z-index:50;margin-top:var(--spacing, .25rem);width:calc(var(--spacing, .25rem) * 80);max-width:90vw;border-radius:var(--radius-md, .375rem);border-style:var(--tw-border-style);border-width:1px;border-color:var(--color-stone-200, oklch(92.3% .003 48.717));background-color:var(--color-white, #fff);--tw-shadow: 0 0 4px 0 var(--tw-shadow-color, rgba(0,0,0,.2)), 0 3px 20px 0 var(--tw-shadow-color, rgba(0,0,0,.19));box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.notifications .notifications-toggle{position:relative}.notifications .notifications-toggle i{margin-right:0}@property --tw-leading{syntax: \"*\"; inherits: false;}@property --tw-font-weight{syntax: \"*\"; inherits: false;}@property --tw-border-style{syntax: \"*\"; inherits: false; initial-value: solid;}@property --tw-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-shadow-color{syntax: \"*\"; inherits: false;}@property --tw-shadow-alpha{syntax: \"<percentage>\"; inherits: false; initial-value: 100%;}@property --tw-inset-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-inset-shadow-color{syntax: \"*\"; inherits: false;}@property --tw-inset-shadow-alpha{syntax: \"<percentage>\"; inherits: false; initial-value: 100%;}@property --tw-ring-color{syntax: \"*\"; inherits: false;}@property --tw-ring-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-inset-ring-color{syntax: \"*\"; inherits: false;}@property --tw-inset-ring-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-ring-inset{syntax: \"*\"; inherits: false;}@property --tw-ring-offset-width{syntax: \"<length>\"; inherits: false; initial-value: 0px;}@property --tw-ring-offset-color{syntax: \"*\"; inherits: false; initial-value: #fff;}@property --tw-ring-offset-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-leading: initial;--tw-font-weight: initial;--tw-border-style: solid;--tw-shadow: 0 0 #0000;--tw-shadow-color: initial;--tw-shadow-alpha: 100%;--tw-inset-shadow: 0 0 #0000;--tw-inset-shadow-color: initial;--tw-inset-shadow-alpha: 100%;--tw-ring-color: initial;--tw-ring-shadow: 0 0 #0000;--tw-inset-ring-color: initial;--tw-inset-ring-shadow: 0 0 #0000;--tw-ring-inset: initial;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-offset-shadow: 0 0 #0000}}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"]
600
+ }]
601
+ }],
602
+ propDecorators: {
603
+ dropdown: [{
604
+ type: i0.ViewChild,
605
+ args: ["dropdown", { isSignal: true }]
606
+ }],
607
+ documentClick: [{
608
+ type: HostListener,
609
+ args: ["window:click", ["$event"]]
610
+ }]
611
+ }
612
+ });
613
+ var LanguageSelectorComponent = class LanguageSelectorComponent {
614
+ dropdown = viewChild("dropdown", ...ngDevMode ? [{ debugName: "dropdown" }] : /* istanbul ignore next */ []);
615
+ showFlag = input(false, ...ngDevMode ? [{ debugName: "showFlag" }] : /* istanbul ignore next */ []);
616
+ title = input("LanguageSelector-Title", ...ngDevMode ? [{ debugName: "title" }] : /* istanbul ignore next */ []);
617
+ translate = inject(TranslateService);
618
+ languages = this.translate.getLangs();
619
+ showDropdown = signal(false, ...ngDevMode ? [{ debugName: "showDropdown" }] : /* istanbul ignore next */ []);
620
+ currentLang = toSignal(this.translate.onLangChange.pipe(map((event) => event.lang)), { initialValue: this.translate.currentLang });
621
+ get selectedLanguage() {
622
+ return this.currentLang();
623
+ }
624
+ onDropdownClick() {
625
+ this.showDropdown.update((isShown) => !isShown);
626
+ }
627
+ onSelectLanguage(language) {
628
+ localStorage.setItem("language", language);
629
+ this.translate.use(language);
630
+ this.showDropdown.set(false);
631
+ }
632
+ documentClick(event) {
633
+ if (this.showDropdown()) {
634
+ let target = event.target;
635
+ while (target !== null && target.tagName?.toUpperCase() !== "BODY") {
636
+ if (target === this.dropdown()?.nativeElement) return;
637
+ target = target.parentElement;
638
+ }
639
+ this.showDropdown.set(false);
640
+ }
641
+ }
642
+ static ɵfac = i0.ɵɵngDeclareFactory({
643
+ minVersion: "12.0.0",
644
+ version: "22.2.0",
645
+ ngImport: i0,
646
+ type: LanguageSelectorComponent,
647
+ deps: [],
648
+ target: i0.ɵɵFactoryTarget.Component
649
+ });
650
+ static ɵcmp = i0.ɵɵngDeclareComponent({
651
+ minVersion: "17.0.0",
652
+ version: "22.2.0",
653
+ type: LanguageSelectorComponent,
654
+ isStandalone: true,
655
+ selector: "shared-language-selector",
656
+ inputs: {
657
+ showFlag: {
658
+ classPropertyName: "showFlag",
659
+ publicName: "showFlag",
660
+ isSignal: true,
661
+ isRequired: false,
662
+ transformFunction: null
663
+ },
664
+ title: {
665
+ classPropertyName: "title",
666
+ publicName: "title",
667
+ isSignal: true,
668
+ isRequired: false,
669
+ transformFunction: null
670
+ }
671
+ },
672
+ host: { listeners: { "window:click": "documentClick($event)" } },
673
+ viewQueries: [{
674
+ propertyName: "dropdown",
675
+ first: true,
676
+ predicate: ["dropdown"],
677
+ descendants: true,
678
+ isSignal: true
679
+ }],
680
+ ngImport: i0,
681
+ template: "<div #dropdown class=\"dropdown right\" [class.show]=\"showDropdown()\">\n <button\n class=\"btn\"\n type=\"button\"\n (click)=\"onDropdownClick()\"\n [class.gray-300]=\"showFlag()\"\n [class.lang-flag-toggle]=\"showFlag()\"\n [attr.aria-label]=\"showFlag() ? (title() | translate) : null\"\n >\n @if (showFlag()) {\n <span class=\"flag flag-{{ selectedLanguage }}\"></span>\n } @else {\n {{ title() | translate }}\n }\n </button>\n\n <ul>\n @for (lang of languages; track lang) {\n <li>\n <button\n type=\"button\"\n class=\"dropdown-item\"\n [class.selected]=\"lang === selectedLanguage\"\n (click)=\"onSelectLanguage(lang)\"\n >\n <span class=\"flag flag-{{ lang }}\"></span>\n <span class=\"dropdown-label\">{{ 'Language-' + lang | translate }}</span>\n </button>\n </li>\n }\n </ul>\n</div>\n",
682
+ styles: ["@layer properties;.dropdown .btn{width:100%;--tw-font-weight: var(--font-weight-medium, 500);font-weight:var(--font-weight-medium, 500)}.dropdown .flag{display:inline-block;height:calc(var(--spacing, .25rem) * 4);width:calc(var(--spacing, .25rem) * 6);flex-shrink:0;border-radius:var(--radius-xs, .125rem);background-size:cover;background-position:center;--tw-ring-shadow: var(--tw-ring-inset,) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color, currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color: color-mix(in srgb, #000 10%, transparent)}@supports (color: color-mix(in lab,red,red)){.dropdown .flag{--tw-ring-color: color-mix(in oklab, var(--color-black, #000) 10%, transparent)}}.dropdown .flag.flag-en{background-image:url('data:image/svg+xml,%3Csvg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 76 40\"%3E%3Crect width=\"76\" height=\"40\" fill=\"%23b22234\"/%3E%3Cg fill=\"%23fff\"%3E%3Crect y=\"3\" width=\"76\" height=\"3\"/%3E%3Crect y=\"9\" width=\"76\" height=\"3\"/%3E%3Crect y=\"15\" width=\"76\" height=\"3\"/%3E%3Crect y=\"22\" width=\"76\" height=\"3\"/%3E%3Crect y=\"28\" width=\"76\" height=\"3\"/%3E%3Crect y=\"34\" width=\"76\" height=\"3\"/%3E%3C/g%3E%3Crect width=\"30\" height=\"22\" fill=\"%233c3b6e\"/%3E%3C/svg%3E')}.dropdown .flag.flag-pt{background-image:url('data:image/svg+xml,%3Csvg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 70 49\"%3E%3Crect width=\"70\" height=\"49\" fill=\"%23009c3b\"/%3E%3Cpath d=\"M35 6L64 24.5L35 43L6 24.5Z\" fill=\"%23ffdf00\"/%3E%3Ccircle cx=\"35\" cy=\"24.5\" r=\"9.8\" fill=\"%23002776\"/%3E%3C/svg%3E')}.dropdown .lang-flag-toggle{display:flex;height:calc(var(--spacing, .25rem) * 9);width:auto;align-items:center;justify-content:center;border-style:var(--tw-border-style);border-width:0px;padding-inline:calc(var(--spacing, .25rem) * 2.5)}.dropdown .lang-flag-toggle:after{border-top-color:currentColor;margin-left:.325rem}.dropdown ul{z-index:50;margin-top:var(--spacing, .25rem);min-width:11rem;padding:var(--spacing, .25rem);border-radius:var(--radius-md, .375rem);border-style:var(--tw-border-style);border-width:1px;border-color:var(--color-stone-200, oklch(92.3% .003 48.717));background-color:var(--color-white, #fff);--tw-backdrop-blur: ;-webkit-backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);--tw-shadow: 0 0 4px 0 var(--tw-shadow-color, rgba(0,0,0,.2)), 0 3px 20px 0 var(--tw-shadow-color, rgba(0,0,0,.19));box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.dropdown ul .dropdown-item{display:flex;width:100%;cursor:pointer;align-items:center;gap:calc(var(--spacing, .25rem) * 2);border-radius:var(--radius-sm, .25rem);padding-inline:calc(var(--spacing, .25rem) * 3);padding-block:calc(var(--spacing, .25rem) * 2);-webkit-user-select:none;user-select:none;text-align:left;font-size:var(--text-sm, .875rem);line-height:var(--tw-leading, var(--text-sm--line-height, calc(1.25 / .875)));color:var(--color-stone-700, oklch(37.4% .01 67.558))}@media(hover:hover){.dropdown ul .dropdown-item:hover{background-color:var(--color-stone-100, oklch(97% .001 106.424))}}@media(hover:hover){.dropdown ul .dropdown-item:hover{color:var(--color-stone-700, oklch(37.4% .01 67.558))}}.dropdown ul .dropdown-item:focus{background-color:var(--color-stone-100, oklch(97% .001 106.424))}.dropdown ul .dropdown-item:focus{--tw-outline-style: none;outline-style:none}@media(forced-colors:active){.dropdown ul .dropdown-item:focus{outline:2px solid transparent;outline-offset:2px}}.dropdown ul .dropdown-item:active{background-color:var(--color-stone-200, oklch(92.3% .003 48.717))}.dropdown ul .dropdown-item:active{color:var(--color-stone-700, oklch(37.4% .01 67.558))}.dropdown ul .dropdown-item.selected{background-color:var(--color-primary-50, #e6f4ff);--tw-font-weight: var(--font-weight-semibold, 600);font-weight:var(--font-weight-semibold, 600);color:var(--color-primary-700, #002f50)}.dropdown ul .dropdown-item.selected:hover{background-color:var(--color-primary-100, #9acaed)}@property --tw-font-weight{syntax: \"*\"; inherits: false;}@property --tw-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-shadow-color{syntax: \"*\"; inherits: false;}@property --tw-shadow-alpha{syntax: \"<percentage>\"; inherits: false; initial-value: 100%;}@property --tw-inset-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-inset-shadow-color{syntax: \"*\"; inherits: false;}@property --tw-inset-shadow-alpha{syntax: \"<percentage>\"; inherits: false; initial-value: 100%;}@property --tw-ring-color{syntax: \"*\"; inherits: false;}@property --tw-ring-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-inset-ring-color{syntax: \"*\"; inherits: false;}@property --tw-inset-ring-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-ring-inset{syntax: \"*\"; inherits: false;}@property --tw-ring-offset-width{syntax: \"<length>\"; inherits: false; initial-value: 0px;}@property --tw-ring-offset-color{syntax: \"*\"; inherits: false; initial-value: #fff;}@property --tw-ring-offset-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-border-style{syntax: \"*\"; inherits: false; initial-value: solid;}@property --tw-backdrop-blur{syntax: \"*\"; inherits: false;}@property --tw-backdrop-brightness{syntax: \"*\"; inherits: false;}@property --tw-backdrop-contrast{syntax: \"*\"; inherits: false;}@property --tw-backdrop-grayscale{syntax: \"*\"; inherits: false;}@property --tw-backdrop-hue-rotate{syntax: \"*\"; inherits: false;}@property --tw-backdrop-invert{syntax: \"*\"; inherits: false;}@property --tw-backdrop-opacity{syntax: \"*\"; inherits: false;}@property --tw-backdrop-saturate{syntax: \"*\"; inherits: false;}@property --tw-backdrop-sepia{syntax: \"*\"; inherits: false;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-font-weight: initial;--tw-shadow: 0 0 #0000;--tw-shadow-color: initial;--tw-shadow-alpha: 100%;--tw-inset-shadow: 0 0 #0000;--tw-inset-shadow-color: initial;--tw-inset-shadow-alpha: 100%;--tw-ring-color: initial;--tw-ring-shadow: 0 0 #0000;--tw-inset-ring-color: initial;--tw-inset-ring-shadow: 0 0 #0000;--tw-ring-inset: initial;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-offset-shadow: 0 0 #0000;--tw-border-style: solid;--tw-backdrop-blur: initial;--tw-backdrop-brightness: initial;--tw-backdrop-contrast: initial;--tw-backdrop-grayscale: initial;--tw-backdrop-hue-rotate: initial;--tw-backdrop-invert: initial;--tw-backdrop-opacity: initial;--tw-backdrop-saturate: initial;--tw-backdrop-sepia: initial}}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"],
683
+ dependencies: [{
684
+ kind: "pipe",
685
+ type: TranslatePipe,
686
+ name: "translate"
687
+ }]
688
+ });
689
+ };
690
+ i0.ɵɵngDeclareClassMetadata({
691
+ minVersion: "12.0.0",
692
+ version: "22.2.0",
693
+ ngImport: i0,
694
+ type: LanguageSelectorComponent,
695
+ decorators: [{
696
+ type: Component,
697
+ args: [{
698
+ selector: "shared-language-selector",
699
+ imports: [TranslatePipe],
700
+ template: "<div #dropdown class=\"dropdown right\" [class.show]=\"showDropdown()\">\n <button\n class=\"btn\"\n type=\"button\"\n (click)=\"onDropdownClick()\"\n [class.gray-300]=\"showFlag()\"\n [class.lang-flag-toggle]=\"showFlag()\"\n [attr.aria-label]=\"showFlag() ? (title() | translate) : null\"\n >\n @if (showFlag()) {\n <span class=\"flag flag-{{ selectedLanguage }}\"></span>\n } @else {\n {{ title() | translate }}\n }\n </button>\n\n <ul>\n @for (lang of languages; track lang) {\n <li>\n <button\n type=\"button\"\n class=\"dropdown-item\"\n [class.selected]=\"lang === selectedLanguage\"\n (click)=\"onSelectLanguage(lang)\"\n >\n <span class=\"flag flag-{{ lang }}\"></span>\n <span class=\"dropdown-label\">{{ 'Language-' + lang | translate }}</span>\n </button>\n </li>\n }\n </ul>\n</div>\n",
701
+ styles: ["@layer properties;.dropdown .btn{width:100%;--tw-font-weight: var(--font-weight-medium, 500);font-weight:var(--font-weight-medium, 500)}.dropdown .flag{display:inline-block;height:calc(var(--spacing, .25rem) * 4);width:calc(var(--spacing, .25rem) * 6);flex-shrink:0;border-radius:var(--radius-xs, .125rem);background-size:cover;background-position:center;--tw-ring-shadow: var(--tw-ring-inset,) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color, currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color: color-mix(in srgb, #000 10%, transparent)}@supports (color: color-mix(in lab,red,red)){.dropdown .flag{--tw-ring-color: color-mix(in oklab, var(--color-black, #000) 10%, transparent)}}.dropdown .flag.flag-en{background-image:url('data:image/svg+xml,%3Csvg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 76 40\"%3E%3Crect width=\"76\" height=\"40\" fill=\"%23b22234\"/%3E%3Cg fill=\"%23fff\"%3E%3Crect y=\"3\" width=\"76\" height=\"3\"/%3E%3Crect y=\"9\" width=\"76\" height=\"3\"/%3E%3Crect y=\"15\" width=\"76\" height=\"3\"/%3E%3Crect y=\"22\" width=\"76\" height=\"3\"/%3E%3Crect y=\"28\" width=\"76\" height=\"3\"/%3E%3Crect y=\"34\" width=\"76\" height=\"3\"/%3E%3C/g%3E%3Crect width=\"30\" height=\"22\" fill=\"%233c3b6e\"/%3E%3C/svg%3E')}.dropdown .flag.flag-pt{background-image:url('data:image/svg+xml,%3Csvg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 70 49\"%3E%3Crect width=\"70\" height=\"49\" fill=\"%23009c3b\"/%3E%3Cpath d=\"M35 6L64 24.5L35 43L6 24.5Z\" fill=\"%23ffdf00\"/%3E%3Ccircle cx=\"35\" cy=\"24.5\" r=\"9.8\" fill=\"%23002776\"/%3E%3C/svg%3E')}.dropdown .lang-flag-toggle{display:flex;height:calc(var(--spacing, .25rem) * 9);width:auto;align-items:center;justify-content:center;border-style:var(--tw-border-style);border-width:0px;padding-inline:calc(var(--spacing, .25rem) * 2.5)}.dropdown .lang-flag-toggle:after{border-top-color:currentColor;margin-left:.325rem}.dropdown ul{z-index:50;margin-top:var(--spacing, .25rem);min-width:11rem;padding:var(--spacing, .25rem);border-radius:var(--radius-md, .375rem);border-style:var(--tw-border-style);border-width:1px;border-color:var(--color-stone-200, oklch(92.3% .003 48.717));background-color:var(--color-white, #fff);--tw-backdrop-blur: ;-webkit-backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);--tw-shadow: 0 0 4px 0 var(--tw-shadow-color, rgba(0,0,0,.2)), 0 3px 20px 0 var(--tw-shadow-color, rgba(0,0,0,.19));box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.dropdown ul .dropdown-item{display:flex;width:100%;cursor:pointer;align-items:center;gap:calc(var(--spacing, .25rem) * 2);border-radius:var(--radius-sm, .25rem);padding-inline:calc(var(--spacing, .25rem) * 3);padding-block:calc(var(--spacing, .25rem) * 2);-webkit-user-select:none;user-select:none;text-align:left;font-size:var(--text-sm, .875rem);line-height:var(--tw-leading, var(--text-sm--line-height, calc(1.25 / .875)));color:var(--color-stone-700, oklch(37.4% .01 67.558))}@media(hover:hover){.dropdown ul .dropdown-item:hover{background-color:var(--color-stone-100, oklch(97% .001 106.424))}}@media(hover:hover){.dropdown ul .dropdown-item:hover{color:var(--color-stone-700, oklch(37.4% .01 67.558))}}.dropdown ul .dropdown-item:focus{background-color:var(--color-stone-100, oklch(97% .001 106.424))}.dropdown ul .dropdown-item:focus{--tw-outline-style: none;outline-style:none}@media(forced-colors:active){.dropdown ul .dropdown-item:focus{outline:2px solid transparent;outline-offset:2px}}.dropdown ul .dropdown-item:active{background-color:var(--color-stone-200, oklch(92.3% .003 48.717))}.dropdown ul .dropdown-item:active{color:var(--color-stone-700, oklch(37.4% .01 67.558))}.dropdown ul .dropdown-item.selected{background-color:var(--color-primary-50, #e6f4ff);--tw-font-weight: var(--font-weight-semibold, 600);font-weight:var(--font-weight-semibold, 600);color:var(--color-primary-700, #002f50)}.dropdown ul .dropdown-item.selected:hover{background-color:var(--color-primary-100, #9acaed)}@property --tw-font-weight{syntax: \"*\"; inherits: false;}@property --tw-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-shadow-color{syntax: \"*\"; inherits: false;}@property --tw-shadow-alpha{syntax: \"<percentage>\"; inherits: false; initial-value: 100%;}@property --tw-inset-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-inset-shadow-color{syntax: \"*\"; inherits: false;}@property --tw-inset-shadow-alpha{syntax: \"<percentage>\"; inherits: false; initial-value: 100%;}@property --tw-ring-color{syntax: \"*\"; inherits: false;}@property --tw-ring-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-inset-ring-color{syntax: \"*\"; inherits: false;}@property --tw-inset-ring-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-ring-inset{syntax: \"*\"; inherits: false;}@property --tw-ring-offset-width{syntax: \"<length>\"; inherits: false; initial-value: 0px;}@property --tw-ring-offset-color{syntax: \"*\"; inherits: false; initial-value: #fff;}@property --tw-ring-offset-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-border-style{syntax: \"*\"; inherits: false; initial-value: solid;}@property --tw-backdrop-blur{syntax: \"*\"; inherits: false;}@property --tw-backdrop-brightness{syntax: \"*\"; inherits: false;}@property --tw-backdrop-contrast{syntax: \"*\"; inherits: false;}@property --tw-backdrop-grayscale{syntax: \"*\"; inherits: false;}@property --tw-backdrop-hue-rotate{syntax: \"*\"; inherits: false;}@property --tw-backdrop-invert{syntax: \"*\"; inherits: false;}@property --tw-backdrop-opacity{syntax: \"*\"; inherits: false;}@property --tw-backdrop-saturate{syntax: \"*\"; inherits: false;}@property --tw-backdrop-sepia{syntax: \"*\"; inherits: false;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-font-weight: initial;--tw-shadow: 0 0 #0000;--tw-shadow-color: initial;--tw-shadow-alpha: 100%;--tw-inset-shadow: 0 0 #0000;--tw-inset-shadow-color: initial;--tw-inset-shadow-alpha: 100%;--tw-ring-color: initial;--tw-ring-shadow: 0 0 #0000;--tw-inset-ring-color: initial;--tw-inset-ring-shadow: 0 0 #0000;--tw-ring-inset: initial;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-offset-shadow: 0 0 #0000;--tw-border-style: solid;--tw-backdrop-blur: initial;--tw-backdrop-brightness: initial;--tw-backdrop-contrast: initial;--tw-backdrop-grayscale: initial;--tw-backdrop-hue-rotate: initial;--tw-backdrop-invert: initial;--tw-backdrop-opacity: initial;--tw-backdrop-saturate: initial;--tw-backdrop-sepia: initial}}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"]
702
+ }]
703
+ }],
704
+ propDecorators: {
705
+ dropdown: [{
706
+ type: i0.ViewChild,
707
+ args: ["dropdown", { isSignal: true }]
708
+ }],
709
+ showFlag: [{
710
+ type: i0.Input,
711
+ args: [{
712
+ isSignal: true,
713
+ alias: "showFlag",
714
+ required: false
715
+ }]
716
+ }],
717
+ title: [{
718
+ type: i0.Input,
719
+ args: [{
720
+ isSignal: true,
721
+ alias: "title",
722
+ required: false
723
+ }]
724
+ }],
725
+ documentClick: [{
726
+ type: HostListener,
727
+ args: ["window:click", ["$event"]]
728
+ }]
729
+ }
730
+ });
731
+ var UserProfileComponent = class UserProfileComponent {
732
+ authenticationService = inject(AuthenticationService);
733
+ user = signal(null, ...ngDevMode ? [{ debugName: "user" }] : /* istanbul ignore next */ []);
734
+ get initials() {
735
+ const parts = this.name.trim().split(/\s+/).filter((p) => p.length > 0);
736
+ if (parts.length === 0) return "";
737
+ return (parts[0].charAt(0) + (parts.length > 1 ? parts[parts.length - 1].charAt(0) : "")).toUpperCase();
738
+ }
739
+ get name() {
740
+ return this.user()?.name ?? "";
741
+ }
742
+ get pictureUrl() {
743
+ return this.user()?.pictureUrl;
744
+ }
745
+ get position() {
746
+ return this.user()?.position ?? "";
747
+ }
748
+ ngOnInit() {
749
+ this.user.set(this.authenticationService.getUserInfo());
750
+ }
751
+ static ɵfac = i0.ɵɵngDeclareFactory({
752
+ minVersion: "12.0.0",
753
+ version: "22.2.0",
754
+ ngImport: i0,
755
+ type: UserProfileComponent,
756
+ deps: [],
757
+ target: i0.ɵɵFactoryTarget.Component
758
+ });
759
+ static ɵcmp = i0.ɵɵngDeclareComponent({
760
+ minVersion: "17.0.0",
761
+ version: "22.2.0",
762
+ type: UserProfileComponent,
763
+ isStandalone: true,
764
+ selector: "shared-user-profile",
765
+ ngImport: i0,
766
+ template: "<div class=\"user-profile\">\n <div class=\"user-text\">\n <span class=\"user-name\">{{ name }}</span>\n @if (position) {\n <span class=\"user-position\">{{ position }}</span>\n }\n </div>\n\n <div class=\"user-avatar\">\n @if (pictureUrl) {\n <img class=\"user-avatar-img\" [src]=\"pictureUrl\" [alt]=\"name\" />\n } @else {\n <span class=\"user-avatar-initials\">{{ initials }}</span>\n }\n </div>\n</div>\n",
767
+ styles: ["@layer properties;@media(max-width:767px){:host{display:none}}.user-profile{display:flex;height:calc(var(--spacing, .25rem) * 9);min-width:0px;align-items:center;gap:calc(var(--spacing, .25rem) * 2);border-radius:var(--radius-sm, .25rem);padding-inline:calc(var(--spacing, .25rem) * 2);-webkit-user-select:none;user-select:none;background-color:color-mix(in srgb,#000 5%,transparent);transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease, var(--default-transition-timing-function, cubic-bezier(.4, 0, .2, 1)));transition-duration:var(--tw-duration, var(--default-transition-duration, .15s))}@supports (color: color-mix(in lab,red,red)){.user-profile{background-color:color-mix(in oklab,var(--color-black, #000) 5%,transparent)}}@media(hover:hover){.user-profile:hover{background-color:color-mix(in srgb,#000 10%,transparent)}@supports (color: color-mix(in lab,red,red)){.user-profile:hover{background-color:color-mix(in oklab,var(--color-black, #000) 10%,transparent)}}}.user-profile .user-avatar{display:flex;height:calc(var(--spacing, .25rem) * 7);width:calc(var(--spacing, .25rem) * 7);flex-shrink:0;align-items:center;justify-content:center;overflow:hidden;border-radius:calc(infinity * 1px);background-color:var(--color-primary-500, #005794);color:var(--color-white, #fff)}.user-profile .user-avatar-img{height:100%;width:100%;object-fit:cover}.user-profile .user-avatar-initials{font-size:var(--text-xs, .75rem);line-height:var(--tw-leading, var(--text-xs--line-height, calc(1 / .75)));--tw-font-weight: var(--font-weight-semibold, 600);font-weight:var(--font-weight-semibold, 600);text-transform:uppercase}.user-profile .user-name{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:var(--text-sm, .875rem);line-height:var(--tw-leading, var(--text-sm--line-height, calc(1.25 / .875)));--tw-leading: calc(var(--spacing, .25rem) * 4);line-height:calc(var(--spacing, .25rem) * 4);--tw-font-weight: var(--font-weight-medium, 500);font-weight:var(--font-weight-medium, 500);color:var(--color-stone-800, oklch(26.8% .007 34.298))}.user-profile .user-position{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:var(--text-xs, .75rem);line-height:var(--tw-leading, var(--text-xs--line-height, calc(1 / .75)));--tw-leading: calc(var(--spacing, .25rem) * 4);line-height:calc(var(--spacing, .25rem) * 4);color:var(--color-stone-500, oklch(55.3% .013 58.071))}.user-profile .user-text{display:flex;min-width:0px;flex-direction:column;text-align:right}@property --tw-font-weight{syntax: \"*\"; inherits: false;}@property --tw-leading{syntax: \"*\"; inherits: false;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-font-weight: initial;--tw-leading: initial}}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"]
768
+ });
769
+ };
770
+ i0.ɵɵngDeclareClassMetadata({
771
+ minVersion: "12.0.0",
772
+ version: "22.2.0",
773
+ ngImport: i0,
774
+ type: UserProfileComponent,
775
+ decorators: [{
776
+ type: Component,
777
+ args: [{
778
+ selector: "shared-user-profile",
779
+ template: "<div class=\"user-profile\">\n <div class=\"user-text\">\n <span class=\"user-name\">{{ name }}</span>\n @if (position) {\n <span class=\"user-position\">{{ position }}</span>\n }\n </div>\n\n <div class=\"user-avatar\">\n @if (pictureUrl) {\n <img class=\"user-avatar-img\" [src]=\"pictureUrl\" [alt]=\"name\" />\n } @else {\n <span class=\"user-avatar-initials\">{{ initials }}</span>\n }\n </div>\n</div>\n",
780
+ styles: ["@layer properties;@media(max-width:767px){:host{display:none}}.user-profile{display:flex;height:calc(var(--spacing, .25rem) * 9);min-width:0px;align-items:center;gap:calc(var(--spacing, .25rem) * 2);border-radius:var(--radius-sm, .25rem);padding-inline:calc(var(--spacing, .25rem) * 2);-webkit-user-select:none;user-select:none;background-color:color-mix(in srgb,#000 5%,transparent);transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease, var(--default-transition-timing-function, cubic-bezier(.4, 0, .2, 1)));transition-duration:var(--tw-duration, var(--default-transition-duration, .15s))}@supports (color: color-mix(in lab,red,red)){.user-profile{background-color:color-mix(in oklab,var(--color-black, #000) 5%,transparent)}}@media(hover:hover){.user-profile:hover{background-color:color-mix(in srgb,#000 10%,transparent)}@supports (color: color-mix(in lab,red,red)){.user-profile:hover{background-color:color-mix(in oklab,var(--color-black, #000) 10%,transparent)}}}.user-profile .user-avatar{display:flex;height:calc(var(--spacing, .25rem) * 7);width:calc(var(--spacing, .25rem) * 7);flex-shrink:0;align-items:center;justify-content:center;overflow:hidden;border-radius:calc(infinity * 1px);background-color:var(--color-primary-500, #005794);color:var(--color-white, #fff)}.user-profile .user-avatar-img{height:100%;width:100%;object-fit:cover}.user-profile .user-avatar-initials{font-size:var(--text-xs, .75rem);line-height:var(--tw-leading, var(--text-xs--line-height, calc(1 / .75)));--tw-font-weight: var(--font-weight-semibold, 600);font-weight:var(--font-weight-semibold, 600);text-transform:uppercase}.user-profile .user-name{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:var(--text-sm, .875rem);line-height:var(--tw-leading, var(--text-sm--line-height, calc(1.25 / .875)));--tw-leading: calc(var(--spacing, .25rem) * 4);line-height:calc(var(--spacing, .25rem) * 4);--tw-font-weight: var(--font-weight-medium, 500);font-weight:var(--font-weight-medium, 500);color:var(--color-stone-800, oklch(26.8% .007 34.298))}.user-profile .user-position{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:var(--text-xs, .75rem);line-height:var(--tw-leading, var(--text-xs--line-height, calc(1 / .75)));--tw-leading: calc(var(--spacing, .25rem) * 4);line-height:calc(var(--spacing, .25rem) * 4);color:var(--color-stone-500, oklch(55.3% .013 58.071))}.user-profile .user-text{display:flex;min-width:0px;flex-direction:column;text-align:right}@property --tw-font-weight{syntax: \"*\"; inherits: false;}@property --tw-leading{syntax: \"*\"; inherits: false;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-font-weight: initial;--tw-leading: initial}}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"]
781
+ }]
782
+ }]
783
+ });
784
+ var TopBarComponent = class TopBarComponent {
785
+ logout = output();
786
+ onLogoutClick() {
787
+ this.logout.emit();
788
+ }
789
+ static ɵfac = i0.ɵɵngDeclareFactory({
790
+ minVersion: "12.0.0",
791
+ version: "22.2.0",
792
+ ngImport: i0,
793
+ type: TopBarComponent,
794
+ deps: [],
795
+ target: i0.ɵɵFactoryTarget.Component
796
+ });
797
+ static ɵcmp = i0.ɵɵngDeclareComponent({
798
+ minVersion: "14.0.0",
799
+ version: "22.2.0",
800
+ type: TopBarComponent,
801
+ isStandalone: true,
802
+ selector: "shared-top-bar",
803
+ outputs: { logout: "logout" },
804
+ ngImport: i0,
805
+ template: "<div class=\"top-bar\">\n <div class=\"top-bar-section top-bar-start\">\n <shared-brand></shared-brand>\n <shared-environment-badge></shared-environment-badge>\n </div>\n\n <div class=\"top-bar-section top-bar-end\">\n <shared-notifications></shared-notifications>\n <shared-language-selector [showFlag]=\"true\"></shared-language-selector>\n\n <!-- Theme switch slot (deferred — see 2026-07-23-top-bar-update-design.md) -->\n\n <shared-user-profile></shared-user-profile>\n\n <button\n class=\"btn gray-300 top-bar-logout\"\n type=\"button\"\n (click)=\"onLogoutClick()\"\n [attr.aria-label]=\"'Main-Logout' | translate\"\n >\n <i class=\"fa-solid fa-arrow-right-from-bracket\"></i>\n </button>\n </div>\n</div>\n",
806
+ styles: [".top-bar{display:flex;width:100%;align-items:center;justify-content:space-between;gap:calc(var(--spacing, .25rem) * 3)}.top-bar .top-bar-end{flex-shrink:0}.top-bar .top-bar-section{display:flex;min-width:0px;align-items:center;gap:calc(var(--spacing, .25rem) * 3)}.top-bar .top-bar-start{min-width:0px}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"],
807
+ dependencies: [
808
+ {
809
+ kind: "component",
810
+ type: BrandComponent,
811
+ selector: "shared-brand"
812
+ },
813
+ {
814
+ kind: "component",
815
+ type: EnvironmentBadgeComponent,
816
+ selector: "shared-environment-badge"
817
+ },
818
+ {
819
+ kind: "component",
820
+ type: LanguageSelectorComponent,
821
+ selector: "shared-language-selector",
822
+ inputs: ["showFlag", "title"]
823
+ },
824
+ {
825
+ kind: "component",
826
+ type: NotificationsComponent,
827
+ selector: "shared-notifications"
828
+ },
829
+ {
830
+ kind: "component",
831
+ type: UserProfileComponent,
832
+ selector: "shared-user-profile"
833
+ },
834
+ {
835
+ kind: "pipe",
836
+ type: TranslatePipe,
837
+ name: "translate"
838
+ }
839
+ ]
840
+ });
841
+ };
842
+ i0.ɵɵngDeclareClassMetadata({
843
+ minVersion: "12.0.0",
844
+ version: "22.2.0",
845
+ ngImport: i0,
846
+ type: TopBarComponent,
847
+ decorators: [{
848
+ type: Component,
849
+ args: [{
850
+ selector: "shared-top-bar",
851
+ imports: [
852
+ BrandComponent,
853
+ EnvironmentBadgeComponent,
854
+ LanguageSelectorComponent,
855
+ NotificationsComponent,
856
+ TranslatePipe,
857
+ UserProfileComponent
858
+ ],
859
+ template: "<div class=\"top-bar\">\n <div class=\"top-bar-section top-bar-start\">\n <shared-brand></shared-brand>\n <shared-environment-badge></shared-environment-badge>\n </div>\n\n <div class=\"top-bar-section top-bar-end\">\n <shared-notifications></shared-notifications>\n <shared-language-selector [showFlag]=\"true\"></shared-language-selector>\n\n <!-- Theme switch slot (deferred — see 2026-07-23-top-bar-update-design.md) -->\n\n <shared-user-profile></shared-user-profile>\n\n <button\n class=\"btn gray-300 top-bar-logout\"\n type=\"button\"\n (click)=\"onLogoutClick()\"\n [attr.aria-label]=\"'Main-Logout' | translate\"\n >\n <i class=\"fa-solid fa-arrow-right-from-bracket\"></i>\n </button>\n </div>\n</div>\n",
860
+ styles: [".top-bar{display:flex;width:100%;align-items:center;justify-content:space-between;gap:calc(var(--spacing, .25rem) * 3)}.top-bar .top-bar-end{flex-shrink:0}.top-bar .top-bar-section{display:flex;min-width:0px;align-items:center;gap:calc(var(--spacing, .25rem) * 3)}.top-bar .top-bar-start{min-width:0px}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"]
861
+ }]
862
+ }],
863
+ propDecorators: { logout: [{
864
+ type: i0.Output,
865
+ args: ["logout"]
866
+ }] }
867
+ });
868
+ var MainLayoutComponent = class MainLayoutComponent {
869
+ logoutModal = viewChild("logoutModal", ...ngDevMode ? [{ debugName: "logoutModal" }] : /* istanbul ignore next */ []);
870
+ authenticationService = inject(AuthenticationService);
871
+ destroy$ = new Subject();
872
+ externalContentService = inject(ExternalContentService);
873
+ externalUrlResolverService = inject(ExternalUrlResolverService);
874
+ router = inject(Router);
875
+ sidebarService = inject(SidebarService);
876
+ tabService = inject(TabService);
877
+ appVersion = inject(APP_CONFIG).version;
878
+ ngOnDestroy() {
879
+ this.destroy$.next(true);
880
+ this.destroy$.complete();
881
+ }
882
+ ngOnInit() {
883
+ const url = this.router.url;
884
+ if (url !== "/" && !this.tabService.isUrlOpen(url)) this.sidebarService.getMenuFromUrl(url).pipe(take(1)).subscribe({
885
+ next: (item) => {
886
+ if (item) this.tabService.updateTabTitle(url, item.label);
887
+ },
888
+ error: () => void 0
889
+ });
890
+ this.sidebarService.menuExternalUrlSelected.pipe(takeUntil(this.destroy$)).subscribe((item) => this.openExternalMenu(item));
891
+ this.sidebarService.menuUrlSelected.pipe(takeUntil(this.destroy$)).subscribe((item) => {
892
+ const tab = new Tab({
893
+ title: item.label,
894
+ url: item.url
895
+ });
896
+ this.tabService.openTab(tab);
897
+ });
898
+ }
899
+ onLogoutClick() {
900
+ this.logoutModal()?.toggleModal();
901
+ }
902
+ onLogoutConfirm() {
903
+ this.authenticationService.signOut();
904
+ this.router.navigate(["/login"]);
905
+ }
906
+ openExternalMenu(item) {
907
+ const rawUrl = item.url ?? "";
908
+ if (rawUrl.length === 0) return;
909
+ if (toSidebarMenuOpenMode(item.openMode) === SidebarMenuOpenMode.ExternalEmbedded) {
910
+ this.externalContentService.register(item);
911
+ const tab = new Tab({
912
+ title: item.label,
913
+ url: `/${EXTERNAL_CONTENT_ROUTE_PATH}/${item.id}`
914
+ });
915
+ this.tabService.openTab(tab);
916
+ return;
917
+ }
918
+ const url = this.externalUrlResolverService.resolve(rawUrl);
919
+ if (!this.externalUrlResolverService.isAllowed(url)) {
920
+ console.error(`Sidebar menu "${item.label}" points to an unsupported external address and was not opened.`, url);
921
+ return;
922
+ }
923
+ window.open(url, "_blank", "noopener,noreferrer");
924
+ }
925
+ static ɵfac = i0.ɵɵngDeclareFactory({
926
+ minVersion: "12.0.0",
927
+ version: "22.2.0",
928
+ ngImport: i0,
929
+ type: MainLayoutComponent,
930
+ deps: [],
931
+ target: i0.ɵɵFactoryTarget.Component
932
+ });
933
+ static ɵcmp = i0.ɵɵngDeclareComponent({
934
+ minVersion: "17.0.0",
935
+ version: "22.2.0",
936
+ type: MainLayoutComponent,
937
+ isStandalone: true,
938
+ selector: "shared-main-layout",
939
+ viewQueries: [{
940
+ propertyName: "logoutModal",
941
+ first: true,
942
+ predicate: ["logoutModal"],
943
+ descendants: true,
944
+ isSignal: true
945
+ }],
946
+ ngImport: i0,
947
+ template: "<div class=\"main-container\">\n <div class=\"sidebar-region\">\n <lib-sidebar>\n @if (appVersion) {\n <span>v{{ appVersion }}</span>\n }\n </lib-sidebar>\n </div>\n\n <shared-top-bar class=\"toolbar\" (logout)=\"onLogoutClick()\"></shared-top-bar>\n\n <div class=\"content\">\n <framework-tabs>\n <router-outlet></router-outlet>\n </framework-tabs>\n </div>\n</div>\n\n<lib-modal #logoutModal position=\"top\" size=\"xl\" [closeButtonText]=\"'Main-Logout-Modal-Message-Cancel' | translate\">\n <div body>\n <h5>{{ 'Main-Logout-Modal-Message' | translate }}</h5>\n </div>\n <div footer>\n <button type=\"button\" class=\"btn red-600\" (click)=\"onLogoutConfirm()\">\n {{ 'Main-Logout-Modal-Message-Confirm' | translate }}\n </button>\n </div>\n</lib-modal>\n",
948
+ styles: ["@charset \"UTF-8\";@layer properties;.main-container{display:grid;height:100vh;max-height:100vh;width:100vw;max-width:100%;background:var(--app-backdrop);grid-template-columns:auto minmax(0,1fr);grid-template-rows:auto minmax(0,1fr);grid-template-areas:\"toolbar toolbar\" \"sidebar content\"}.main-container .sidebar-region{padding:calc(var(--spacing, .25rem) * 3);grid-area:sidebar}.main-container .toolbar{display:flex;justify-content:space-between;border-bottom-style:var(--tw-border-style);border-bottom-width:1px;border-color:var(--color-stone-300, oklch(86.9% .005 56.366));background-color:color-mix(in srgb,#fff 90%,transparent);padding:calc(var(--spacing, .25rem) * 2);--tw-shadow: 0 0 4px 0 var(--tw-shadow-color, rgba(0,0,0,.2)), 0 3px 20px 0 var(--tw-shadow-color, rgba(0,0,0,.19));box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);grid-area:toolbar}@supports (color: color-mix(in lab,red,red)){.main-container .toolbar{background-color:color-mix(in oklab,var(--color-white, #fff) 90%,transparent)}}.main-container .content{padding-inline:calc(var(--spacing, .25rem) * 3);padding-top:calc(var(--spacing, .25rem) * 3);padding-bottom:calc(var(--spacing, .25rem) * 2);grid-area:content}.main-container framework-tabs{height:100%}lib-modal h5{margin-bottom:calc(var(--spacing, .25rem) * 2);font-size:var(--text-lg, 1.125rem);line-height:var(--tw-leading, var(--text-lg--line-height, calc(1.75 / 1.125)));--tw-leading: calc(var(--spacing, .25rem) * 5);line-height:calc(var(--spacing, .25rem) * 5);--tw-font-weight: var(--font-weight-medium, 500);font-weight:var(--font-weight-medium, 500)}@property --tw-border-style{syntax: \"*\"; inherits: false; initial-value: solid;}@property --tw-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-shadow-color{syntax: \"*\"; inherits: false;}@property --tw-shadow-alpha{syntax: \"<percentage>\"; inherits: false; initial-value: 100%;}@property --tw-inset-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-inset-shadow-color{syntax: \"*\"; inherits: false;}@property --tw-inset-shadow-alpha{syntax: \"<percentage>\"; inherits: false; initial-value: 100%;}@property --tw-ring-color{syntax: \"*\"; inherits: false;}@property --tw-ring-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-inset-ring-color{syntax: \"*\"; inherits: false;}@property --tw-inset-ring-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-ring-inset{syntax: \"*\"; inherits: false;}@property --tw-ring-offset-width{syntax: \"<length>\"; inherits: false; initial-value: 0px;}@property --tw-ring-offset-color{syntax: \"*\"; inherits: false; initial-value: #fff;}@property --tw-ring-offset-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-leading{syntax: \"*\"; inherits: false;}@property --tw-font-weight{syntax: \"*\"; inherits: false;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-border-style: solid;--tw-shadow: 0 0 #0000;--tw-shadow-color: initial;--tw-shadow-alpha: 100%;--tw-inset-shadow: 0 0 #0000;--tw-inset-shadow-color: initial;--tw-inset-shadow-alpha: 100%;--tw-ring-color: initial;--tw-ring-shadow: 0 0 #0000;--tw-inset-ring-color: initial;--tw-inset-ring-shadow: 0 0 #0000;--tw-ring-inset: initial;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-offset-shadow: 0 0 #0000;--tw-leading: initial;--tw-font-weight: initial}}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"],
949
+ dependencies: [
950
+ {
951
+ kind: "component",
952
+ type: ModalComponent,
953
+ selector: "lib-modal",
954
+ inputs: [
955
+ "closeButtonText",
956
+ "dialog",
957
+ "modalProcessing",
958
+ "position",
959
+ "size",
960
+ "title"
961
+ ],
962
+ outputs: [
963
+ "closeButtonTextChange",
964
+ "modalProcessingChange",
965
+ "closed"
966
+ ]
967
+ },
968
+ {
969
+ kind: "ngmodule",
970
+ type: RouterModule
971
+ },
972
+ {
973
+ kind: "directive",
974
+ type: i1$1.RouterOutlet,
975
+ selector: "router-outlet",
976
+ inputs: ["name", "routerOutletData"],
977
+ outputs: [
978
+ "activate",
979
+ "deactivate",
980
+ "attach",
981
+ "detach"
982
+ ],
983
+ exportAs: ["outlet"]
984
+ },
985
+ {
986
+ kind: "component",
987
+ type: SidebarComponent,
988
+ selector: "lib-sidebar"
989
+ },
990
+ {
991
+ kind: "component",
992
+ type: TabsComponent,
993
+ selector: "framework-tabs"
994
+ },
995
+ {
996
+ kind: "component",
997
+ type: TopBarComponent,
998
+ selector: "shared-top-bar",
999
+ outputs: ["logout"]
1000
+ },
1001
+ {
1002
+ kind: "pipe",
1003
+ type: TranslatePipe,
1004
+ name: "translate"
1005
+ }
1006
+ ]
1007
+ });
1008
+ };
1009
+ i0.ɵɵngDeclareClassMetadata({
1010
+ minVersion: "12.0.0",
1011
+ version: "22.2.0",
1012
+ ngImport: i0,
1013
+ type: MainLayoutComponent,
1014
+ decorators: [{
1015
+ type: Component,
1016
+ args: [{
1017
+ selector: "shared-main-layout",
1018
+ imports: [
1019
+ ModalComponent,
1020
+ RouterModule,
1021
+ SidebarComponent,
1022
+ TabsComponent,
1023
+ TopBarComponent,
1024
+ TranslatePipe
1025
+ ],
1026
+ template: "<div class=\"main-container\">\n <div class=\"sidebar-region\">\n <lib-sidebar>\n @if (appVersion) {\n <span>v{{ appVersion }}</span>\n }\n </lib-sidebar>\n </div>\n\n <shared-top-bar class=\"toolbar\" (logout)=\"onLogoutClick()\"></shared-top-bar>\n\n <div class=\"content\">\n <framework-tabs>\n <router-outlet></router-outlet>\n </framework-tabs>\n </div>\n</div>\n\n<lib-modal #logoutModal position=\"top\" size=\"xl\" [closeButtonText]=\"'Main-Logout-Modal-Message-Cancel' | translate\">\n <div body>\n <h5>{{ 'Main-Logout-Modal-Message' | translate }}</h5>\n </div>\n <div footer>\n <button type=\"button\" class=\"btn red-600\" (click)=\"onLogoutConfirm()\">\n {{ 'Main-Logout-Modal-Message-Confirm' | translate }}\n </button>\n </div>\n</lib-modal>\n",
1027
+ styles: ["@charset \"UTF-8\";@layer properties;.main-container{display:grid;height:100vh;max-height:100vh;width:100vw;max-width:100%;background:var(--app-backdrop);grid-template-columns:auto minmax(0,1fr);grid-template-rows:auto minmax(0,1fr);grid-template-areas:\"toolbar toolbar\" \"sidebar content\"}.main-container .sidebar-region{padding:calc(var(--spacing, .25rem) * 3);grid-area:sidebar}.main-container .toolbar{display:flex;justify-content:space-between;border-bottom-style:var(--tw-border-style);border-bottom-width:1px;border-color:var(--color-stone-300, oklch(86.9% .005 56.366));background-color:color-mix(in srgb,#fff 90%,transparent);padding:calc(var(--spacing, .25rem) * 2);--tw-shadow: 0 0 4px 0 var(--tw-shadow-color, rgba(0,0,0,.2)), 0 3px 20px 0 var(--tw-shadow-color, rgba(0,0,0,.19));box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);grid-area:toolbar}@supports (color: color-mix(in lab,red,red)){.main-container .toolbar{background-color:color-mix(in oklab,var(--color-white, #fff) 90%,transparent)}}.main-container .content{padding-inline:calc(var(--spacing, .25rem) * 3);padding-top:calc(var(--spacing, .25rem) * 3);padding-bottom:calc(var(--spacing, .25rem) * 2);grid-area:content}.main-container framework-tabs{height:100%}lib-modal h5{margin-bottom:calc(var(--spacing, .25rem) * 2);font-size:var(--text-lg, 1.125rem);line-height:var(--tw-leading, var(--text-lg--line-height, calc(1.75 / 1.125)));--tw-leading: calc(var(--spacing, .25rem) * 5);line-height:calc(var(--spacing, .25rem) * 5);--tw-font-weight: var(--font-weight-medium, 500);font-weight:var(--font-weight-medium, 500)}@property --tw-border-style{syntax: \"*\"; inherits: false; initial-value: solid;}@property --tw-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-shadow-color{syntax: \"*\"; inherits: false;}@property --tw-shadow-alpha{syntax: \"<percentage>\"; inherits: false; initial-value: 100%;}@property --tw-inset-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-inset-shadow-color{syntax: \"*\"; inherits: false;}@property --tw-inset-shadow-alpha{syntax: \"<percentage>\"; inherits: false; initial-value: 100%;}@property --tw-ring-color{syntax: \"*\"; inherits: false;}@property --tw-ring-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-inset-ring-color{syntax: \"*\"; inherits: false;}@property --tw-inset-ring-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-ring-inset{syntax: \"*\"; inherits: false;}@property --tw-ring-offset-width{syntax: \"<length>\"; inherits: false; initial-value: 0px;}@property --tw-ring-offset-color{syntax: \"*\"; inherits: false; initial-value: #fff;}@property --tw-ring-offset-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-leading{syntax: \"*\"; inherits: false;}@property --tw-font-weight{syntax: \"*\"; inherits: false;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-border-style: solid;--tw-shadow: 0 0 #0000;--tw-shadow-color: initial;--tw-shadow-alpha: 100%;--tw-inset-shadow: 0 0 #0000;--tw-inset-shadow-color: initial;--tw-inset-shadow-alpha: 100%;--tw-ring-color: initial;--tw-ring-shadow: 0 0 #0000;--tw-inset-ring-color: initial;--tw-inset-ring-shadow: 0 0 #0000;--tw-ring-inset: initial;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-offset-shadow: 0 0 #0000;--tw-leading: initial;--tw-font-weight: initial}}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"]
1028
+ }]
1029
+ }],
1030
+ propDecorators: { logoutModal: [{
1031
+ type: i0.ViewChild,
1032
+ args: ["logoutModal", { isSignal: true }]
1033
+ }] }
1034
+ });
1035
+ var LoginComponent = class LoginComponent {
1036
+ username = viewChild("username", ...ngDevMode ? [{ debugName: "username" }] : /* istanbul ignore next */ []);
1037
+ form;
1038
+ formState = signal({
1039
+ error: null,
1040
+ loading: false,
1041
+ success: false
1042
+ }, ...ngDevMode ? [{ debugName: "formState" }] : /* istanbul ignore next */ []);
1043
+ authenticationService = inject(AuthenticationService);
1044
+ formBuilder = inject(FormBuilder);
1045
+ router = inject(Router);
1046
+ ngOnInit() {
1047
+ this.form = this.formBuilder.group({
1048
+ password: ["", Validators.required],
1049
+ rememberMe: [false, { nonNullable: true }],
1050
+ username: ["", Validators.required]
1051
+ });
1052
+ }
1053
+ onSubmit() {
1054
+ this.form.markAllAsTouched();
1055
+ if (this.form.valid) {
1056
+ this.form.disable();
1057
+ this.formState.update((state) => ({
1058
+ ...state,
1059
+ error: null,
1060
+ loading: true
1061
+ }));
1062
+ this.authenticationService.authenticate({
1063
+ username: this.form.get("username")?.value.toString() ?? "",
1064
+ password: this.form.get("password")?.value.toString() ?? "",
1065
+ rememberMe: this.form.get("rememberMe")?.value ?? false
1066
+ }).pipe(tap(() => this.formState.update((state) => ({
1067
+ ...state,
1068
+ success: true
1069
+ }))), finalize(() => this.formState.update((state) => ({
1070
+ ...state,
1071
+ loading: false
1072
+ })))).subscribe({
1073
+ next: () => {
1074
+ const params = new URLSearchParams(window.location.search);
1075
+ this.router.navigate([params.get("returnUrl") ?? "/"]);
1076
+ },
1077
+ error: (e) => {
1078
+ this.form.enable();
1079
+ this.form.controls["password"].setValue("");
1080
+ this.form.controls["password"].markAsUntouched();
1081
+ this.username()?.nativeElement.focus();
1082
+ const error = e === "InvalidUsernamePassword" ? "invalid" : "internalServerError";
1083
+ this.formState.update((state) => ({
1084
+ ...state,
1085
+ error
1086
+ }));
1087
+ }
1088
+ });
1089
+ }
1090
+ }
1091
+ static ɵfac = i0.ɵɵngDeclareFactory({
1092
+ minVersion: "12.0.0",
1093
+ version: "22.2.0",
1094
+ ngImport: i0,
1095
+ type: LoginComponent,
1096
+ deps: [],
1097
+ target: i0.ɵɵFactoryTarget.Component
1098
+ });
1099
+ static ɵcmp = i0.ɵɵngDeclareComponent({
1100
+ minVersion: "17.0.0",
1101
+ version: "22.2.0",
1102
+ type: LoginComponent,
1103
+ isStandalone: true,
1104
+ selector: "shared-login",
1105
+ viewQueries: [{
1106
+ propertyName: "username",
1107
+ first: true,
1108
+ predicate: ["username"],
1109
+ descendants: true,
1110
+ isSignal: true
1111
+ }],
1112
+ ngImport: i0,
1113
+ template: "<div class=\"content\">\n <div class=\"login\">\n <div class=\"logo-container\">\n <div class=\"logo\">\n <img src=\"/logo-login.png\" alt=\"Logo\" />\n </div>\n </div>\n\n <h3 class=\"title\">{{ 'Login-Title' | translate }}</h3>\n\n <form [formGroup]=\"form\" (ngSubmit)=\"onSubmit()\">\n <div class=\"validations\" [class.hidden]=\"!formState().error\">\n @if (formState().error === 'invalid') {\n <div>\n {{ 'Login-Errors-Invalid' | translate }}\n </div>\n }\n @if (formState().error === 'internalServerError') {\n <div>\n {{ 'Login-Errors-InternalServerError' | translate }}\n </div>\n }\n </div>\n\n <div class=\"input-group inline\">\n <input\n type=\"text\"\n #username\n id=\"username\"\n formControlName=\"username\"\n class=\"form-input peer\"\n [placeholder]=\"'Login-Username' | translate\"\n />\n\n <div class=\"input-group-text\">\n <label for=\"username\">\n <i class=\"fas fa-user fa-fw\"></i>\n </label>\n </div>\n\n <div class=\"validations\">\n @if (form.get('username')?.hasError('required')) {\n <span>{{ 'Login-Username-Required' | translate }}</span>\n }\n </div>\n </div>\n\n <div class=\"input-group inline\">\n <input\n type=\"password\"\n id=\"password\"\n formControlName=\"password\"\n class=\"form-input\"\n [placeholder]=\"'Login-Password' | translate\"\n />\n\n <div class=\"input-group-text\">\n <label for=\"password\">\n <i class=\"fas fa-key fa-fw\"></i>\n </label>\n </div>\n\n <div class=\"validations\">\n @if (form.get('password')?.hasError('required')) {\n <span>{{ 'Login-Password-Required' | translate }}</span>\n }\n </div>\n </div>\n\n <div class=\"options\">\n <div>\n <input class=\"form-input\" id=\"rememberMe\" formControlName=\"rememberMe\" type=\"checkbox\" />\n <label for=\"rememberMe\">{{ 'Login-RememberMe' | translate }}</label>\n </div>\n\n <shared-language-selector></shared-language-selector>\n </div>\n\n <div class=\"buttons\">\n <button\n type=\"submit\"\n class=\"btn\"\n [class.loading]=\"formState().loading && !formState().success && !formState().error\"\n [class.error]=\"formState().error\"\n [class.success]=\"formState().success\"\n >\n @if (!formState().loading) {\n <i class=\"fas fa-sign-in-alt fa-fw\"></i>\n }\n {{ 'Login-SignIn' | translate }}\n </button>\n </div>\n </form>\n </div>\n\n <div class=\"footer\">\n <span [innerHTML]=\"'Login-Copyright' | translate\"></span>\n <span class=\"design\">{{ 'Login-DesignBy' | translate }}</span>\n </div>\n</div>\n",
1114
+ styles: ["@layer properties;:host{display:block}.content{margin-inline:auto;width:calc(10 / 12 * 100%);border-radius:var(--radius-lg, .5rem);--tw-shadow: 0 4px 8px 0 var(--tw-shadow-color, rgba(0,0,0,.2)), 0 6px 20px 0 var(--tw-shadow-color, rgba(0,0,0,.19));box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}@media(width>=48rem){.content{width:calc(8 / 12 * 100%)}}@media(width>=80rem){.content{width:calc(5 / 12 * 100%)}}:where(.content>:not(:last-child)){--tw-divide-y-reverse: 0;border-bottom-style:var(--tw-border-style);border-top-style:var(--tw-border-style);border-top-width:calc(1px * var(--tw-divide-y-reverse));border-bottom-width:calc(1px * calc(1 - var(--tw-divide-y-reverse)))}:where(.content>:not(:last-child)){border-color:var(--color-zinc-400, oklch(70.5% .015 286.067))}.content .login{position:relative;z-index:10;margin-top:calc(var(--spacing, .25rem) * 20);border-top-left-radius:var(--radius-lg, .5rem);border-top-right-radius:var(--radius-lg, .5rem);background-color:color-mix(in srgb,#fff 60%,transparent);padding-inline:calc(var(--spacing, .25rem) * 6);padding-top:calc(var(--spacing, .25rem) * 20);padding-bottom:calc(var(--spacing, .25rem) * 6);--tw-backdrop-blur: blur(var(--blur-md, 12px));-webkit-backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,)}@supports (color: color-mix(in lab,red,red)){.content .login{background-color:color-mix(in oklab,var(--color-white, #fff) 60%,transparent)}}.content .login .logo-container{margin-top:calc(var(--spacing, .25rem) * -40);margin-right:auto;margin-bottom:calc(var(--spacing, .25rem) * 4);margin-left:auto;width:fit-content;border-radius:var(--radius-3xl, 1.5rem);padding:calc(var(--spacing, .25rem) * 2);background-color:var(--color-white, #fff);--tw-shadow: 0 4px 8px 0 var(--tw-shadow-color, rgba(0,0,0,.2)), 0 6px 20px 0 var(--tw-shadow-color, rgba(0,0,0,.19));box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.content .login .logo-container .logo{width:fit-content;border-radius:var(--radius-3xl, 1.5rem);padding:calc(var(--spacing, .25rem) * 2);border-style:var(--tw-border-style);border-width:2px;border-color:var(--color-amber-300, oklch(87.9% .169 91.605))}.content .login .logo-container .logo img{height:calc(var(--spacing, .25rem) * 40);min-width:fit-content}.content .login .title{padding-bottom:calc(var(--spacing, .25rem) * 5);text-align:center;font-size:var(--text-3xl, 1.875rem);line-height:var(--tw-leading, var(--text-3xl--line-height, 1.2 ));--tw-font-weight: var(--font-weight-bold, 700);font-weight:var(--font-weight-bold, 700)}.content .login form>.validations{text-align:center;--tw-font-weight: var(--font-weight-bold, 700);font-weight:var(--font-weight-bold, 700);color:var(--color-red-500, oklch(63.7% .237 25.331))}.content .login form>.validations:after{margin-inline:auto;margin-bottom:calc(var(--spacing, .25rem) * 2);display:block;border-bottom-style:var(--tw-border-style);border-bottom-width:1px;border-color:var(--color-red-500, oklch(63.7% .237 25.331));--tw-content: \"\";content:var(--tw-content);animation:separator 1s ease-in-out forwards}.content .login form .options{margin-bottom:calc(var(--spacing, .25rem) * 3);display:flex;flex-direction:row;flex-wrap:wrap-reverse;justify-content:space-between}.content .login form .options shared-language-selector{margin-bottom:calc(var(--spacing, .25rem) * 3);width:100%}@media(width>=40rem){.content .login form .options shared-language-selector{margin-bottom:0}}@media(width>=40rem){.content .login form .options shared-language-selector{width:auto}}.content .login form .buttons{display:flex;justify-content:center;gap:calc(var(--spacing, .25rem) * 4)}.content .footer{border-bottom-right-radius:var(--radius-lg, .5rem);border-bottom-left-radius:var(--radius-lg, .5rem);padding-inline:calc(var(--spacing, .25rem) * 2);padding-block:calc(var(--spacing, .25rem) * .5);background-color:color-mix(in srgb,oklch(92.9% .013 255.508) 60%,transparent);--tw-backdrop-blur: blur(var(--blur-md, 12px));-webkit-backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);font-size:var(--text-sm, .875rem);line-height:var(--tw-leading, var(--text-sm--line-height, calc(1.25 / .875)));--tw-font-weight: var(--font-weight-semibold, 600);font-weight:var(--font-weight-semibold, 600);--tw-tracking: var(--tracking-tight, -.025em);letter-spacing:var(--tracking-tight, -.025em);display:flex;flex-wrap:wrap;justify-content:space-between}@supports (color: color-mix(in lab,red,red)){.content .footer{background-color:color-mix(in oklab,var(--color-slate-200, oklch(92.9% .013 255.508)) 60%,transparent)}}@keyframes separator{0%{width:0}to{width:100%}}@property --tw-divide-y-reverse{syntax: \"*\"; inherits: false; initial-value: 0;}@property --tw-border-style{syntax: \"*\"; inherits: false; initial-value: solid;}@property --tw-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-shadow-color{syntax: \"*\"; inherits: false;}@property --tw-shadow-alpha{syntax: \"<percentage>\"; inherits: false; initial-value: 100%;}@property --tw-inset-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-inset-shadow-color{syntax: \"*\"; inherits: false;}@property --tw-inset-shadow-alpha{syntax: \"<percentage>\"; inherits: false; initial-value: 100%;}@property --tw-ring-color{syntax: \"*\"; inherits: false;}@property --tw-ring-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-inset-ring-color{syntax: \"*\"; inherits: false;}@property --tw-inset-ring-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-ring-inset{syntax: \"*\"; inherits: false;}@property --tw-ring-offset-width{syntax: \"<length>\"; inherits: false; initial-value: 0px;}@property --tw-ring-offset-color{syntax: \"*\"; inherits: false; initial-value: #fff;}@property --tw-ring-offset-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-backdrop-blur{syntax: \"*\"; inherits: false;}@property --tw-backdrop-brightness{syntax: \"*\"; inherits: false;}@property --tw-backdrop-contrast{syntax: \"*\"; inherits: false;}@property --tw-backdrop-grayscale{syntax: \"*\"; inherits: false;}@property --tw-backdrop-hue-rotate{syntax: \"*\"; inherits: false;}@property --tw-backdrop-invert{syntax: \"*\"; inherits: false;}@property --tw-backdrop-opacity{syntax: \"*\"; inherits: false;}@property --tw-backdrop-saturate{syntax: \"*\"; inherits: false;}@property --tw-backdrop-sepia{syntax: \"*\"; inherits: false;}@property --tw-font-weight{syntax: \"*\"; inherits: false;}@property --tw-content{syntax: \"*\"; inherits: false; initial-value: \"\";}@property --tw-tracking{syntax: \"*\"; inherits: false;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-divide-y-reverse: 0;--tw-border-style: solid;--tw-shadow: 0 0 #0000;--tw-shadow-color: initial;--tw-shadow-alpha: 100%;--tw-inset-shadow: 0 0 #0000;--tw-inset-shadow-color: initial;--tw-inset-shadow-alpha: 100%;--tw-ring-color: initial;--tw-ring-shadow: 0 0 #0000;--tw-inset-ring-color: initial;--tw-inset-ring-shadow: 0 0 #0000;--tw-ring-inset: initial;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-offset-shadow: 0 0 #0000;--tw-backdrop-blur: initial;--tw-backdrop-brightness: initial;--tw-backdrop-contrast: initial;--tw-backdrop-grayscale: initial;--tw-backdrop-hue-rotate: initial;--tw-backdrop-invert: initial;--tw-backdrop-opacity: initial;--tw-backdrop-saturate: initial;--tw-backdrop-sepia: initial;--tw-font-weight: initial;--tw-content: \"\";--tw-tracking: initial}}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"],
1115
+ dependencies: [
1116
+ {
1117
+ kind: "component",
1118
+ type: LanguageSelectorComponent,
1119
+ selector: "shared-language-selector",
1120
+ inputs: ["showFlag", "title"]
1121
+ },
1122
+ {
1123
+ kind: "ngmodule",
1124
+ type: ReactiveFormsModule
1125
+ },
1126
+ {
1127
+ kind: "directive",
1128
+ type: i1.ɵNgNoValidate,
1129
+ selector: "form:not([ngNoForm]):not([ngNativeValidate])"
1130
+ },
1131
+ {
1132
+ kind: "directive",
1133
+ type: i1.DefaultValueAccessor,
1134
+ selector: "input:not([type=checkbox]):not([ngNoCva])[formControlName],textarea:not([ngNoCva])[formControlName],input:not([type=checkbox]):not([ngNoCva])[formControl],textarea:not([ngNoCva])[formControl],input:not([type=checkbox]):not([ngNoCva])[ngModel],textarea:not([ngNoCva])[ngModel],[ngDefaultControl]"
1135
+ },
1136
+ {
1137
+ kind: "directive",
1138
+ type: i1.CheckboxControlValueAccessor,
1139
+ selector: "input[type=checkbox]:not([ngNoCva])[formControlName],input[type=checkbox]:not([ngNoCva])[formControl],input[type=checkbox]:not([ngNoCva])[ngModel]"
1140
+ },
1141
+ {
1142
+ kind: "directive",
1143
+ type: i1.NgControlStatus,
1144
+ selector: "[formControlName],[ngModel],[formControl]"
1145
+ },
1146
+ {
1147
+ kind: "directive",
1148
+ type: i1.NgControlStatusGroup,
1149
+ selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]"
1150
+ },
1151
+ {
1152
+ kind: "directive",
1153
+ type: i1.FormGroupDirective,
1154
+ selector: "[formGroup]",
1155
+ inputs: ["formGroup"],
1156
+ outputs: ["ngSubmit"],
1157
+ exportAs: ["ngForm"]
1158
+ },
1159
+ {
1160
+ kind: "directive",
1161
+ type: i1.FormControlName,
1162
+ selector: "[formControlName]",
1163
+ inputs: [
1164
+ "formControlName",
1165
+ "disabled",
1166
+ "ngModel"
1167
+ ],
1168
+ outputs: ["ngModelChange"]
1169
+ },
1170
+ {
1171
+ kind: "ngmodule",
1172
+ type: RouterModule
1173
+ },
1174
+ {
1175
+ kind: "pipe",
1176
+ type: TranslatePipe,
1177
+ name: "translate"
1178
+ }
1179
+ ]
1180
+ });
1181
+ };
1182
+ i0.ɵɵngDeclareClassMetadata({
1183
+ minVersion: "12.0.0",
1184
+ version: "22.2.0",
1185
+ ngImport: i0,
1186
+ type: LoginComponent,
1187
+ decorators: [{
1188
+ type: Component,
1189
+ args: [{
1190
+ selector: "shared-login",
1191
+ imports: [
1192
+ LanguageSelectorComponent,
1193
+ ReactiveFormsModule,
1194
+ RouterModule,
1195
+ TranslatePipe
1196
+ ],
1197
+ template: "<div class=\"content\">\n <div class=\"login\">\n <div class=\"logo-container\">\n <div class=\"logo\">\n <img src=\"/logo-login.png\" alt=\"Logo\" />\n </div>\n </div>\n\n <h3 class=\"title\">{{ 'Login-Title' | translate }}</h3>\n\n <form [formGroup]=\"form\" (ngSubmit)=\"onSubmit()\">\n <div class=\"validations\" [class.hidden]=\"!formState().error\">\n @if (formState().error === 'invalid') {\n <div>\n {{ 'Login-Errors-Invalid' | translate }}\n </div>\n }\n @if (formState().error === 'internalServerError') {\n <div>\n {{ 'Login-Errors-InternalServerError' | translate }}\n </div>\n }\n </div>\n\n <div class=\"input-group inline\">\n <input\n type=\"text\"\n #username\n id=\"username\"\n formControlName=\"username\"\n class=\"form-input peer\"\n [placeholder]=\"'Login-Username' | translate\"\n />\n\n <div class=\"input-group-text\">\n <label for=\"username\">\n <i class=\"fas fa-user fa-fw\"></i>\n </label>\n </div>\n\n <div class=\"validations\">\n @if (form.get('username')?.hasError('required')) {\n <span>{{ 'Login-Username-Required' | translate }}</span>\n }\n </div>\n </div>\n\n <div class=\"input-group inline\">\n <input\n type=\"password\"\n id=\"password\"\n formControlName=\"password\"\n class=\"form-input\"\n [placeholder]=\"'Login-Password' | translate\"\n />\n\n <div class=\"input-group-text\">\n <label for=\"password\">\n <i class=\"fas fa-key fa-fw\"></i>\n </label>\n </div>\n\n <div class=\"validations\">\n @if (form.get('password')?.hasError('required')) {\n <span>{{ 'Login-Password-Required' | translate }}</span>\n }\n </div>\n </div>\n\n <div class=\"options\">\n <div>\n <input class=\"form-input\" id=\"rememberMe\" formControlName=\"rememberMe\" type=\"checkbox\" />\n <label for=\"rememberMe\">{{ 'Login-RememberMe' | translate }}</label>\n </div>\n\n <shared-language-selector></shared-language-selector>\n </div>\n\n <div class=\"buttons\">\n <button\n type=\"submit\"\n class=\"btn\"\n [class.loading]=\"formState().loading && !formState().success && !formState().error\"\n [class.error]=\"formState().error\"\n [class.success]=\"formState().success\"\n >\n @if (!formState().loading) {\n <i class=\"fas fa-sign-in-alt fa-fw\"></i>\n }\n {{ 'Login-SignIn' | translate }}\n </button>\n </div>\n </form>\n </div>\n\n <div class=\"footer\">\n <span [innerHTML]=\"'Login-Copyright' | translate\"></span>\n <span class=\"design\">{{ 'Login-DesignBy' | translate }}</span>\n </div>\n</div>\n",
1198
+ styles: ["@layer properties;:host{display:block}.content{margin-inline:auto;width:calc(10 / 12 * 100%);border-radius:var(--radius-lg, .5rem);--tw-shadow: 0 4px 8px 0 var(--tw-shadow-color, rgba(0,0,0,.2)), 0 6px 20px 0 var(--tw-shadow-color, rgba(0,0,0,.19));box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}@media(width>=48rem){.content{width:calc(8 / 12 * 100%)}}@media(width>=80rem){.content{width:calc(5 / 12 * 100%)}}:where(.content>:not(:last-child)){--tw-divide-y-reverse: 0;border-bottom-style:var(--tw-border-style);border-top-style:var(--tw-border-style);border-top-width:calc(1px * var(--tw-divide-y-reverse));border-bottom-width:calc(1px * calc(1 - var(--tw-divide-y-reverse)))}:where(.content>:not(:last-child)){border-color:var(--color-zinc-400, oklch(70.5% .015 286.067))}.content .login{position:relative;z-index:10;margin-top:calc(var(--spacing, .25rem) * 20);border-top-left-radius:var(--radius-lg, .5rem);border-top-right-radius:var(--radius-lg, .5rem);background-color:color-mix(in srgb,#fff 60%,transparent);padding-inline:calc(var(--spacing, .25rem) * 6);padding-top:calc(var(--spacing, .25rem) * 20);padding-bottom:calc(var(--spacing, .25rem) * 6);--tw-backdrop-blur: blur(var(--blur-md, 12px));-webkit-backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,)}@supports (color: color-mix(in lab,red,red)){.content .login{background-color:color-mix(in oklab,var(--color-white, #fff) 60%,transparent)}}.content .login .logo-container{margin-top:calc(var(--spacing, .25rem) * -40);margin-right:auto;margin-bottom:calc(var(--spacing, .25rem) * 4);margin-left:auto;width:fit-content;border-radius:var(--radius-3xl, 1.5rem);padding:calc(var(--spacing, .25rem) * 2);background-color:var(--color-white, #fff);--tw-shadow: 0 4px 8px 0 var(--tw-shadow-color, rgba(0,0,0,.2)), 0 6px 20px 0 var(--tw-shadow-color, rgba(0,0,0,.19));box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.content .login .logo-container .logo{width:fit-content;border-radius:var(--radius-3xl, 1.5rem);padding:calc(var(--spacing, .25rem) * 2);border-style:var(--tw-border-style);border-width:2px;border-color:var(--color-amber-300, oklch(87.9% .169 91.605))}.content .login .logo-container .logo img{height:calc(var(--spacing, .25rem) * 40);min-width:fit-content}.content .login .title{padding-bottom:calc(var(--spacing, .25rem) * 5);text-align:center;font-size:var(--text-3xl, 1.875rem);line-height:var(--tw-leading, var(--text-3xl--line-height, 1.2 ));--tw-font-weight: var(--font-weight-bold, 700);font-weight:var(--font-weight-bold, 700)}.content .login form>.validations{text-align:center;--tw-font-weight: var(--font-weight-bold, 700);font-weight:var(--font-weight-bold, 700);color:var(--color-red-500, oklch(63.7% .237 25.331))}.content .login form>.validations:after{margin-inline:auto;margin-bottom:calc(var(--spacing, .25rem) * 2);display:block;border-bottom-style:var(--tw-border-style);border-bottom-width:1px;border-color:var(--color-red-500, oklch(63.7% .237 25.331));--tw-content: \"\";content:var(--tw-content);animation:separator 1s ease-in-out forwards}.content .login form .options{margin-bottom:calc(var(--spacing, .25rem) * 3);display:flex;flex-direction:row;flex-wrap:wrap-reverse;justify-content:space-between}.content .login form .options shared-language-selector{margin-bottom:calc(var(--spacing, .25rem) * 3);width:100%}@media(width>=40rem){.content .login form .options shared-language-selector{margin-bottom:0}}@media(width>=40rem){.content .login form .options shared-language-selector{width:auto}}.content .login form .buttons{display:flex;justify-content:center;gap:calc(var(--spacing, .25rem) * 4)}.content .footer{border-bottom-right-radius:var(--radius-lg, .5rem);border-bottom-left-radius:var(--radius-lg, .5rem);padding-inline:calc(var(--spacing, .25rem) * 2);padding-block:calc(var(--spacing, .25rem) * .5);background-color:color-mix(in srgb,oklch(92.9% .013 255.508) 60%,transparent);--tw-backdrop-blur: blur(var(--blur-md, 12px));-webkit-backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);font-size:var(--text-sm, .875rem);line-height:var(--tw-leading, var(--text-sm--line-height, calc(1.25 / .875)));--tw-font-weight: var(--font-weight-semibold, 600);font-weight:var(--font-weight-semibold, 600);--tw-tracking: var(--tracking-tight, -.025em);letter-spacing:var(--tracking-tight, -.025em);display:flex;flex-wrap:wrap;justify-content:space-between}@supports (color: color-mix(in lab,red,red)){.content .footer{background-color:color-mix(in oklab,var(--color-slate-200, oklch(92.9% .013 255.508)) 60%,transparent)}}@keyframes separator{0%{width:0}to{width:100%}}@property --tw-divide-y-reverse{syntax: \"*\"; inherits: false; initial-value: 0;}@property --tw-border-style{syntax: \"*\"; inherits: false; initial-value: solid;}@property --tw-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-shadow-color{syntax: \"*\"; inherits: false;}@property --tw-shadow-alpha{syntax: \"<percentage>\"; inherits: false; initial-value: 100%;}@property --tw-inset-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-inset-shadow-color{syntax: \"*\"; inherits: false;}@property --tw-inset-shadow-alpha{syntax: \"<percentage>\"; inherits: false; initial-value: 100%;}@property --tw-ring-color{syntax: \"*\"; inherits: false;}@property --tw-ring-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-inset-ring-color{syntax: \"*\"; inherits: false;}@property --tw-inset-ring-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-ring-inset{syntax: \"*\"; inherits: false;}@property --tw-ring-offset-width{syntax: \"<length>\"; inherits: false; initial-value: 0px;}@property --tw-ring-offset-color{syntax: \"*\"; inherits: false; initial-value: #fff;}@property --tw-ring-offset-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-backdrop-blur{syntax: \"*\"; inherits: false;}@property --tw-backdrop-brightness{syntax: \"*\"; inherits: false;}@property --tw-backdrop-contrast{syntax: \"*\"; inherits: false;}@property --tw-backdrop-grayscale{syntax: \"*\"; inherits: false;}@property --tw-backdrop-hue-rotate{syntax: \"*\"; inherits: false;}@property --tw-backdrop-invert{syntax: \"*\"; inherits: false;}@property --tw-backdrop-opacity{syntax: \"*\"; inherits: false;}@property --tw-backdrop-saturate{syntax: \"*\"; inherits: false;}@property --tw-backdrop-sepia{syntax: \"*\"; inherits: false;}@property --tw-font-weight{syntax: \"*\"; inherits: false;}@property --tw-content{syntax: \"*\"; inherits: false; initial-value: \"\";}@property --tw-tracking{syntax: \"*\"; inherits: false;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-divide-y-reverse: 0;--tw-border-style: solid;--tw-shadow: 0 0 #0000;--tw-shadow-color: initial;--tw-shadow-alpha: 100%;--tw-inset-shadow: 0 0 #0000;--tw-inset-shadow-color: initial;--tw-inset-shadow-alpha: 100%;--tw-ring-color: initial;--tw-ring-shadow: 0 0 #0000;--tw-inset-ring-color: initial;--tw-inset-ring-shadow: 0 0 #0000;--tw-ring-inset: initial;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-offset-shadow: 0 0 #0000;--tw-backdrop-blur: initial;--tw-backdrop-brightness: initial;--tw-backdrop-contrast: initial;--tw-backdrop-grayscale: initial;--tw-backdrop-hue-rotate: initial;--tw-backdrop-invert: initial;--tw-backdrop-opacity: initial;--tw-backdrop-saturate: initial;--tw-backdrop-sepia: initial;--tw-font-weight: initial;--tw-content: \"\";--tw-tracking: initial}}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"]
1199
+ }]
1200
+ }],
1201
+ propDecorators: { username: [{
1202
+ type: i0.ViewChild,
1203
+ args: ["username", { isSignal: true }]
1204
+ }] }
1205
+ });
1206
+ const routes = [{
1207
+ path: "",
1208
+ component: LoginLayoutComponent,
1209
+ children: [{
1210
+ path: "",
1211
+ redirectTo: "login",
1212
+ pathMatch: "full"
1213
+ }, {
1214
+ path: "login",
1215
+ component: LoginComponent
1216
+ }]
1217
+ }];
1218
+ var SharedAuthModule = class SharedAuthModule {
1219
+ static ɵfac = i0.ɵɵngDeclareFactory({
1220
+ minVersion: "12.0.0",
1221
+ version: "22.2.0",
1222
+ ngImport: i0,
1223
+ type: SharedAuthModule,
1224
+ deps: [],
1225
+ target: i0.ɵɵFactoryTarget.NgModule
1226
+ });
1227
+ static ɵmod = i0.ɵɵngDeclareNgModule({
1228
+ minVersion: "14.0.0",
1229
+ version: "22.2.0",
1230
+ ngImport: i0,
1231
+ type: SharedAuthModule,
1232
+ imports: [i1$1.RouterModule]
1233
+ });
1234
+ static ɵinj = i0.ɵɵngDeclareInjector({
1235
+ minVersion: "12.0.0",
1236
+ version: "22.2.0",
1237
+ ngImport: i0,
1238
+ type: SharedAuthModule,
1239
+ imports: [RouterModule.forChild(routes)]
1240
+ });
1241
+ };
1242
+ i0.ɵɵngDeclareClassMetadata({
1243
+ minVersion: "12.0.0",
1244
+ version: "22.2.0",
1245
+ ngImport: i0,
1246
+ type: SharedAuthModule,
1247
+ decorators: [{
1248
+ type: NgModule,
1249
+ args: [{ imports: [RouterModule.forChild(routes)] }]
1250
+ }]
1251
+ });
1252
+ var AuthGuard = class AuthGuard {
1253
+ authenticationService = inject(AuthenticationService);
1254
+ router = inject(Router);
1255
+ canActivate(_, state) {
1256
+ if (!this.authenticationService.isAuthenticated) {
1257
+ this.router.navigate(["/login"], { queryParams: { returnUrl: state.url } });
1258
+ return false;
1259
+ }
1260
+ return true;
1261
+ }
1262
+ static ɵfac = i0.ɵɵngDeclareFactory({
1263
+ minVersion: "12.0.0",
1264
+ version: "22.2.0",
1265
+ ngImport: i0,
1266
+ type: AuthGuard,
1267
+ deps: [],
1268
+ target: i0.ɵɵFactoryTarget.Injectable
1269
+ });
1270
+ static ɵprov = i0.ɵɵngDeclareInjectable({
1271
+ minVersion: "12.0.0",
1272
+ version: "22.2.0",
1273
+ ngImport: i0,
1274
+ type: AuthGuard,
1275
+ providedIn: "root"
1276
+ });
1277
+ };
1278
+ i0.ɵɵngDeclareClassMetadata({
1279
+ minVersion: "12.0.0",
1280
+ version: "22.2.0",
1281
+ ngImport: i0,
1282
+ type: AuthGuard,
1283
+ decorators: [{
1284
+ type: Injectable,
1285
+ args: [{ providedIn: "root" }]
1286
+ }]
1287
+ });
1288
+ var AuthInterceptor = class AuthInterceptor {
1289
+ authenticationService = inject(AuthenticationService);
1290
+ config = inject(APP_CONFIG);
1291
+ jwtInterceptor = inject(JwtInterceptor);
1292
+ refreshToken$;
1293
+ router = inject(Router);
1294
+ intercept(request, next) {
1295
+ if (request.url.indexOf(this.config.BASE_URL) >= 0 && !this.jwtInterceptor.isDisallowedRoute(request) && this.authenticationService.isTokenExpired) {
1296
+ if (!this.refreshToken$) this.refreshToken$ = this.authenticationService.tryRefreshToken().pipe(shareReplay(), tap(() => {
1297
+ this.refreshToken$ = void 0;
1298
+ }));
1299
+ return this.refreshToken$.pipe(switchMap((token) => {
1300
+ return next.handle(request.clone({ setHeaders: { authorization: `Bearer ${token}` } }));
1301
+ }), catchError((err) => {
1302
+ if (err.status === 401) {
1303
+ this.authenticationService.signOut();
1304
+ this.router.navigate(["/login"]);
1305
+ }
1306
+ throw err;
1307
+ }));
1308
+ }
1309
+ return next.handle(request);
1310
+ }
1311
+ static ɵfac = i0.ɵɵngDeclareFactory({
1312
+ minVersion: "12.0.0",
1313
+ version: "22.2.0",
1314
+ ngImport: i0,
1315
+ type: AuthInterceptor,
1316
+ deps: [],
1317
+ target: i0.ɵɵFactoryTarget.Injectable
1318
+ });
1319
+ static ɵprov = i0.ɵɵngDeclareInjectable({
1320
+ minVersion: "12.0.0",
1321
+ version: "22.2.0",
1322
+ ngImport: i0,
1323
+ type: AuthInterceptor
1324
+ });
1325
+ };
1326
+ i0.ɵɵngDeclareClassMetadata({
1327
+ minVersion: "12.0.0",
1328
+ version: "22.2.0",
1329
+ ngImport: i0,
1330
+ type: AuthInterceptor,
1331
+ decorators: [{ type: Injectable }]
1332
+ });
1333
+ var FiltersBase = class FiltersBase {
1334
+ buttonFilters;
1335
+ destroy$ = new Subject();
1336
+ filterForm;
1337
+ formBuilder = inject(FormBuilder);
1338
+ ngOnDestroy() {
1339
+ this.destroy$.next(true);
1340
+ this.destroy$.complete();
1341
+ }
1342
+ ngOnInit() {
1343
+ this.filterForm = this.formSetup();
1344
+ }
1345
+ setFilters(filters) {
1346
+ this.filterForm.patchValue(filters);
1347
+ setTimeout(() => {
1348
+ if (this.buttonFilters) this.buttonFilters.setFilters(filters);
1349
+ });
1350
+ }
1351
+ static ɵfac = i0.ɵɵngDeclareFactory({
1352
+ minVersion: "12.0.0",
1353
+ version: "22.2.0",
1354
+ ngImport: i0,
1355
+ type: FiltersBase,
1356
+ deps: [],
1357
+ target: i0.ɵɵFactoryTarget.Component
1358
+ });
1359
+ static ɵcmp = i0.ɵɵngDeclareComponent({
1360
+ minVersion: "14.0.0",
1361
+ version: "22.2.0",
1362
+ type: FiltersBase,
1363
+ isStandalone: true,
1364
+ selector: "ng-component",
1365
+ viewQueries: [{
1366
+ propertyName: "buttonFilters",
1367
+ first: true,
1368
+ predicate: ButtonFiltersComponent,
1369
+ descendants: true
1370
+ }],
1371
+ ngImport: i0,
1372
+ template: "",
1373
+ isInline: true
1374
+ });
1375
+ };
1376
+ i0.ɵɵngDeclareClassMetadata({
1377
+ minVersion: "12.0.0",
1378
+ version: "22.2.0",
1379
+ ngImport: i0,
1380
+ type: FiltersBase,
1381
+ decorators: [{
1382
+ type: Component,
1383
+ args: [{ template: "" }]
1384
+ }],
1385
+ propDecorators: { buttonFilters: [{
1386
+ type: ViewChild,
1387
+ args: [ButtonFiltersComponent]
1388
+ }] }
1389
+ });
1390
+ var OperationsHistoryDataset = class OperationsHistoryDataset extends DataGridDataset {
1391
+ columns = [{
1392
+ field: "",
1393
+ headerName: ""
1394
+ }];
1395
+ controllerName;
1396
+ operationsHistoryService = inject(OperationsHistoryService);
1397
+ _serviceID;
1398
+ set serviceId(value) {
1399
+ if (this._serviceID !== value) {
1400
+ this._serviceID = value;
1401
+ this.refresh();
1402
+ }
1403
+ }
1404
+ constructor() {
1405
+ super();
1406
+ this.configs.hideColumnHeaders = true;
1407
+ this.configs.showMessageOnEmpty = false;
1408
+ }
1409
+ getData(params) {
1410
+ this.configs.showMessageOnEmpty = !!this._serviceID;
1411
+ return !!this.parentEntityId && !!this.controllerName && !!this._serviceID ? this.operationsHistoryService.list(this.controllerName, this.parentEntityId, this._serviceID, params) : of([]);
1412
+ }
1413
+ static ɵfac = i0.ɵɵngDeclareFactory({
1414
+ minVersion: "12.0.0",
1415
+ version: "22.2.0",
1416
+ ngImport: i0,
1417
+ type: OperationsHistoryDataset,
1418
+ deps: [],
1419
+ target: i0.ɵɵFactoryTarget.Injectable
1420
+ });
1421
+ static ɵprov = i0.ɵɵngDeclareInjectable({
1422
+ minVersion: "12.0.0",
1423
+ version: "22.2.0",
1424
+ ngImport: i0,
1425
+ type: OperationsHistoryDataset
1426
+ });
1427
+ };
1428
+ i0.ɵɵngDeclareClassMetadata({
1429
+ minVersion: "12.0.0",
1430
+ version: "22.2.0",
1431
+ ngImport: i0,
1432
+ type: OperationsHistoryDataset,
1433
+ decorators: [{ type: Injectable }],
1434
+ ctorParameters: () => []
1435
+ });
1436
+ var ServicesHistoryDataset = class ServicesHistoryDataset extends DataGridDataset {
1437
+ columns = [{
1438
+ field: "",
1439
+ headerName: ""
1440
+ }];
1441
+ controllerName;
1442
+ servicesHistoryService = inject(ServicesHistoryService);
1443
+ constructor() {
1444
+ super();
1445
+ this.configs.hideColumnHeaders = true;
1446
+ this.configs.rowHeight = 52;
1447
+ }
1448
+ getData(params) {
1449
+ return !!this.parentEntityId && !!this.controllerName ? this.servicesHistoryService.list(this.controllerName, this.parentEntityId, this.withUtcPeriod(params)) : of([]);
1450
+ }
1451
+ withUtcPeriod(params) {
1452
+ const filters = params.filters;
1453
+ if (!filters?.["changedOnFrom"] && !filters?.["changedOnTo"]) return params;
1454
+ const converted = { ...filters };
1455
+ if (filters["changedOnFrom"]) converted["changedOnFrom"] = ServicesHistoryDataset.toUtcInstant(filters["changedOnFrom"], "start");
1456
+ if (filters["changedOnTo"]) converted["changedOnTo"] = ServicesHistoryDataset.toUtcInstant(filters["changedOnTo"], "end");
1457
+ return {
1458
+ ...params,
1459
+ filters: converted
1460
+ };
1461
+ }
1462
+ static toUtcInstant(value, edge) {
1463
+ const [year, month, day] = value.split("-").map(Number);
1464
+ if ([
1465
+ year,
1466
+ month,
1467
+ day
1468
+ ].some((part) => Number.isNaN(part))) return value;
1469
+ return (edge === "start" ? new Date(year, month - 1, day, 0, 0, 0, 0) : new Date(year, month - 1, day, 23, 59, 59, 999)).toISOString().replace(/Z$/, "");
1470
+ }
1471
+ static ɵfac = i0.ɵɵngDeclareFactory({
1472
+ minVersion: "12.0.0",
1473
+ version: "22.2.0",
1474
+ ngImport: i0,
1475
+ type: ServicesHistoryDataset,
1476
+ deps: [],
1477
+ target: i0.ɵɵFactoryTarget.Injectable
1478
+ });
1479
+ static ɵprov = i0.ɵɵngDeclareInjectable({
1480
+ minVersion: "12.0.0",
1481
+ version: "22.2.0",
1482
+ ngImport: i0,
1483
+ type: ServicesHistoryDataset
1484
+ });
1485
+ };
1486
+ i0.ɵɵngDeclareClassMetadata({
1487
+ minVersion: "12.0.0",
1488
+ version: "22.2.0",
1489
+ ngImport: i0,
1490
+ type: ServicesHistoryDataset,
1491
+ decorators: [{ type: Injectable }],
1492
+ ctorParameters: () => []
1493
+ });
1494
+ var ExternalContentComponent = class ExternalContentComponent extends TabViewBase {
1495
+ frameUrl = signal(void 0, ...ngDevMode ? [{ debugName: "frameUrl" }] : /* istanbul ignore next */ []);
1496
+ isBlocked = signal(false, ...ngDevMode ? [{ debugName: "isBlocked" }] : /* istanbul ignore next */ []);
1497
+ isFrameLoading = signal(false, ...ngDevMode ? [{ debugName: "isFrameLoading" }] : /* istanbul ignore next */ []);
1498
+ isInsecure = signal(false, ...ngDevMode ? [{ debugName: "isInsecure" }] : /* istanbul ignore next */ []);
1499
+ isSlow = signal(false, ...ngDevMode ? [{ debugName: "isSlow" }] : /* istanbul ignore next */ []);
1500
+ isUnavailable = signal(false, ...ngDevMode ? [{ debugName: "isUnavailable" }] : /* istanbul ignore next */ []);
1501
+ label = signal("", ...ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []);
1502
+ resolvedUrl = signal("", ...ngDevMode ? [{ debugName: "resolvedUrl" }] : /* istanbul ignore next */ []);
1503
+ activatedRoute = inject(ActivatedRoute);
1504
+ configs = inject(EXTERNAL_CONTENT_CONFIGS);
1505
+ document = inject(DOCUMENT);
1506
+ externalContentService = inject(ExternalContentService);
1507
+ externalUrlResolverService = inject(ExternalUrlResolverService);
1508
+ sanitizer = inject(DomSanitizer);
1509
+ slowHintTimeout;
1510
+ tabService = inject(TabService);
1511
+ constructor() {
1512
+ super();
1513
+ }
1514
+ ngOnDestroy() {
1515
+ this.clearSlowHint();
1516
+ super.ngOnDestroy();
1517
+ }
1518
+ ngOnInit() {
1519
+ const menuID = Number(this.activatedRoute.snapshot.paramMap.get("menuID"));
1520
+ if (!menuID) {
1521
+ this.isUnavailable.set(true);
1522
+ this.loading = false;
1523
+ return;
1524
+ }
1525
+ this.externalContentService.find(menuID).pipe(take(1), takeUntil(this.destroy$)).subscribe((entry) => this.show(entry));
1526
+ }
1527
+ onFrameLoad() {
1528
+ this.clearSlowHint();
1529
+ this.isFrameLoading.set(false);
1530
+ this.isSlow.set(false);
1531
+ }
1532
+ onOpenInNewTab() {
1533
+ window.open(this.resolvedUrl(), "_blank", "noopener,noreferrer");
1534
+ }
1535
+ onReload() {
1536
+ const url = this.frameUrl();
1537
+ if (!url || this.isFrameLoading()) return;
1538
+ this.frameUrl.set(void 0);
1539
+ this.isFrameLoading.set(true);
1540
+ setTimeout(() => this.displayFrame(url));
1541
+ }
1542
+ clearSlowHint() {
1543
+ if (this.slowHintTimeout !== void 0) {
1544
+ clearTimeout(this.slowHintTimeout);
1545
+ this.slowHintTimeout = void 0;
1546
+ }
1547
+ }
1548
+ isMixedContent(url) {
1549
+ return this.document.location.protocol === "https:" && new URL(url).protocol === "http:";
1550
+ }
1551
+ isOriginAllowed(url) {
1552
+ if (this.configs.allowedOrigins.length === 0) return true;
1553
+ try {
1554
+ return this.configs.allowedOrigins.indexOf(new URL(url).origin) !== -1;
1555
+ } catch {
1556
+ return false;
1557
+ }
1558
+ }
1559
+ show(entry) {
1560
+ this.loading = false;
1561
+ if (!entry || !entry.url) {
1562
+ this.isUnavailable.set(true);
1563
+ return;
1564
+ }
1565
+ this.label.set(entry.label);
1566
+ this.tabService.updateActiveTabRootTitle(entry.label);
1567
+ const url = this.externalUrlResolverService.resolve(entry.url);
1568
+ if (!this.externalUrlResolverService.isAllowed(url) || !this.isOriginAllowed(url)) {
1569
+ console.error(`Embedded menu item "${entry.label}" points to an address that is not allowed and was not displayed.`, url);
1570
+ this.isBlocked.set(true);
1571
+ return;
1572
+ }
1573
+ this.resolvedUrl.set(url);
1574
+ if (this.isMixedContent(url)) {
1575
+ this.isInsecure.set(true);
1576
+ return;
1577
+ }
1578
+ this.displayFrame(this.sanitizer.bypassSecurityTrustResourceUrl(url));
1579
+ }
1580
+ displayFrame(url) {
1581
+ this.isFrameLoading.set(true);
1582
+ this.frameUrl.set(url);
1583
+ this.startSlowHint();
1584
+ }
1585
+ startSlowHint() {
1586
+ this.clearSlowHint();
1587
+ this.slowHintTimeout = setTimeout(() => {
1588
+ this.isFrameLoading.set(false);
1589
+ this.isSlow.set(true);
1590
+ }, this.configs.slowFrameHintDelay);
1591
+ }
1592
+ static ɵfac = i0.ɵɵngDeclareFactory({
1593
+ minVersion: "12.0.0",
1594
+ version: "22.2.0",
1595
+ ngImport: i0,
1596
+ type: ExternalContentComponent,
1597
+ deps: [],
1598
+ target: i0.ɵɵFactoryTarget.Component
1599
+ });
1600
+ static ɵcmp = i0.ɵɵngDeclareComponent({
1601
+ minVersion: "17.0.0",
1602
+ version: "22.2.0",
1603
+ type: ExternalContentComponent,
1604
+ isStandalone: true,
1605
+ selector: "shared-external-content",
1606
+ usesInheritance: true,
1607
+ ngImport: i0,
1608
+ template: "<!-- Published to DefaultTabViewComponent through TabViewService, so the actions sit in the\n application's ribbon like every other screen's. -->\n<ng-template #ribbon>\n <lib-ribbon-group [label]=\"'RibbonGroup-Page' | translate\">\n <!-- Same icon and label as framework-button-refresh, so reloading a report reads as the\n same action as refreshing a grid. `loading` is what spins it while the frame loads. -->\n <framework-button\n icon=\"fa-sync-alt\"\n label=\"Button-Refresh\"\n [disabled]=\"!resolvedUrl() || isInsecure()\"\n [loading]=\"isFrameLoading()\"\n (action)=\"onReload()\"\n >\n </framework-button>\n\n <framework-button\n icon=\"fa-arrow-up-right-from-square\"\n label=\"ExternalContent-OpenInNewTab\"\n [disabled]=\"!resolvedUrl()\"\n (action)=\"onOpenInNewTab()\"\n >\n </framework-button>\n </lib-ribbon-group>\n</ng-template>\n\n@if (isUnavailable()) {\n <div class=\"external-content-message\">\n <i class=\"fa-solid fa-link-slash\"></i>\n <span class=\"external-content-message-title\">{{ 'ExternalContent-Unavailable-Title' | translate }}</span>\n <span>{{ 'ExternalContent-Unavailable-Message' | translate }}</span>\n </div>\n} @else if (isInsecure()) {\n <div class=\"external-content-message\">\n <i class=\"fa-solid fa-shield-halved\"></i>\n <span class=\"external-content-message-title\">{{ 'ExternalContent-Insecure-Title' | translate }}</span>\n <span>{{ 'ExternalContent-Insecure-Message' | translate }}</span>\n </div>\n} @else if (isBlocked()) {\n <div class=\"external-content-message\">\n <i class=\"fa-solid fa-triangle-exclamation\"></i>\n <span class=\"external-content-message-title\">{{ 'ExternalContent-Blocked-Title' | translate }}</span>\n <span>{{ 'ExternalContent-Blocked-Message' | translate }}</span>\n </div>\n} @else {\n @if (isSlow()) {\n <div class=\"external-content-hint\">{{ 'ExternalContent-SlowHint' | translate }}</div>\n }\n @if (frameUrl() || isFrameLoading()) {\n <!--\n The container stays mounted across a reload, which briefly clears frameUrl, so the panel\n does not flicker out and back. What goes away is the frame itself, on purpose.\n\n sandbox and referrerpolicy are STATIC attributes on purpose. Angular rejects `sandbox`\n as a binding on an <iframe> outright (NG0910) — it may only be a static attribute — and\n the whole element then fails to render.\n\n The token list is fixed for every destination, and deliberately not configurable per\n menu item:\n - allow-same-origin keeps the frame in the destination's own origin so its cookies and\n storage work; without it an SSO'd report will not render. It grants no access to ours,\n provided the destination is cross-origin -- never point an embedded item at this\n application's own origin, use an internal route for that.\n - allow-top-navigation is absent on purpose: a framed site must not be able to navigate\n the whole application away.\n - allow-popups-to-escape-sandbox keeps print and download popups usable.\n -->\n <div class=\"external-content-frame-container\">\n @if (isFrameLoading()) {\n <div class=\"external-content-loading\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\">\n <circle class=\"opacity-25\" cx=\"12\" cy=\"12\" r=\"10\" stroke=\"currentColor\" stroke-width=\"4\"></circle>\n <path\n class=\"opacity-75\"\n fill=\"currentColor\"\n d=\"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z\"\n ></path>\n </svg>\n\n <span>{{ 'Loading' | translate }}</span>\n </div>\n }\n @if (frameUrl()) {\n <iframe\n class=\"external-content-frame\"\n sandbox=\"allow-scripts allow-same-origin allow-forms allow-popups allow-popups-to-escape-sandbox allow-downloads\"\n referrerpolicy=\"strict-origin-when-cross-origin\"\n [src]=\"frameUrl()\"\n [attr.title]=\"label() | translate\"\n (load)=\"onFrameLoad()\"\n >\n </iframe>\n }\n </div>\n }\n}\n",
1609
+ styles: ["@layer properties;:host{display:flex;flex-grow:1;flex-direction:column;gap:calc(var(--spacing, .25rem) * 2);overflow:hidden;min-height:0}.external-content-hint{flex:none;border-radius:var(--radius-lg, .5rem);border-style:var(--tw-border-style);border-width:1px;padding-inline:calc(var(--spacing, .25rem) * 3);padding-block:calc(var(--spacing, .25rem) * 2);font-size:var(--text-sm, .875rem);line-height:var(--tw-leading, var(--text-sm--line-height, calc(1.25 / .875)));border-color:var(--color-amber-300, oklch(87.9% .169 91.605));background-color:var(--color-amber-100, oklch(96.2% .059 95.617));color:var(--color-amber-900, oklch(41.4% .112 45.904))}.external-content-frame-container{border-radius:var(--radius-lg, .5rem);border-style:var(--tw-border-style);border-width:1px;border-color:color-mix(in srgb,oklch(87.2% .01 258.338) 90%,transparent);background-color:var(--color-white, #fff);position:relative;display:flex;flex-grow:1;overflow:hidden;min-height:0}@supports (color: color-mix(in lab,red,red)){.external-content-frame-container{border-color:color-mix(in oklab,var(--color-gray-300, oklch(87.2% .01 258.338)) 90%,transparent)}}.external-content-loading{position:absolute;inset:0;z-index:10;display:flex;align-items:center;justify-content:center;gap:calc(var(--spacing, .25rem) * 2);background-color:var(--color-white, #fff);color:var(--color-gray-500, oklch(55.1% .027 264.364))}.external-content-loading svg{height:calc(var(--spacing, .25rem) * 6);min-height:calc(var(--spacing, .25rem) * 6);width:calc(var(--spacing, .25rem) * 6);min-width:calc(var(--spacing, .25rem) * 6);animation:var(--animate-spin, spin 1s linear infinite)}.external-content-frame{width:100%;flex-grow:1;border-style:var(--tw-border-style);border-width:0px;min-height:0}.external-content-message{border-radius:var(--radius-lg, .5rem);border-style:var(--tw-border-style);border-width:1px;border-color:color-mix(in srgb,oklch(87.2% .01 258.338) 90%,transparent);background-color:var(--color-white, #fff);display:flex;flex-grow:1;flex-direction:column;align-items:center;justify-content:center;gap:calc(var(--spacing, .25rem) * 2);padding:calc(var(--spacing, .25rem) * 6);text-align:center}@supports (color: color-mix(in lab,red,red)){.external-content-message{border-color:color-mix(in oklab,var(--color-gray-300, oklch(87.2% .01 258.338)) 90%,transparent)}}.external-content-message i{font-size:var(--text-4xl, 2.25rem);line-height:var(--tw-leading, var(--text-4xl--line-height, calc(2.5 / 2.25)));opacity:40%}.external-content-message .external-content-message-title{font-size:var(--text-lg, 1.125rem);line-height:var(--tw-leading, var(--text-lg--line-height, calc(1.75 / 1.125)));--tw-font-weight: var(--font-weight-semibold, 600);font-weight:var(--font-weight-semibold, 600)}@property --tw-border-style{syntax: \"*\"; inherits: false; initial-value: solid;}@property --tw-font-weight{syntax: \"*\"; inherits: false;}@keyframes spin{to{transform:rotate(360deg)}}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-border-style: solid;--tw-font-weight: initial}}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"],
1610
+ dependencies: [
1611
+ {
1612
+ kind: "component",
1613
+ type: ButtonComponent,
1614
+ selector: "framework-button",
1615
+ inputs: [
1616
+ "color",
1617
+ "icon",
1618
+ "label"
1619
+ ],
1620
+ outputs: ["action"]
1621
+ },
1622
+ {
1623
+ kind: "component",
1624
+ type: RibbonGroupComponent,
1625
+ selector: "lib-ribbon-group",
1626
+ inputs: ["label"]
1627
+ },
1628
+ {
1629
+ kind: "pipe",
1630
+ type: TranslatePipe,
1631
+ name: "translate"
1632
+ }
1633
+ ]
1634
+ });
1635
+ };
1636
+ i0.ɵɵngDeclareClassMetadata({
1637
+ minVersion: "12.0.0",
1638
+ version: "22.2.0",
1639
+ ngImport: i0,
1640
+ type: ExternalContentComponent,
1641
+ decorators: [{
1642
+ type: Component,
1643
+ args: [{
1644
+ selector: "shared-external-content",
1645
+ imports: [
1646
+ ButtonComponent,
1647
+ RibbonGroupComponent,
1648
+ TranslatePipe
1649
+ ],
1650
+ template: "<!-- Published to DefaultTabViewComponent through TabViewService, so the actions sit in the\n application's ribbon like every other screen's. -->\n<ng-template #ribbon>\n <lib-ribbon-group [label]=\"'RibbonGroup-Page' | translate\">\n <!-- Same icon and label as framework-button-refresh, so reloading a report reads as the\n same action as refreshing a grid. `loading` is what spins it while the frame loads. -->\n <framework-button\n icon=\"fa-sync-alt\"\n label=\"Button-Refresh\"\n [disabled]=\"!resolvedUrl() || isInsecure()\"\n [loading]=\"isFrameLoading()\"\n (action)=\"onReload()\"\n >\n </framework-button>\n\n <framework-button\n icon=\"fa-arrow-up-right-from-square\"\n label=\"ExternalContent-OpenInNewTab\"\n [disabled]=\"!resolvedUrl()\"\n (action)=\"onOpenInNewTab()\"\n >\n </framework-button>\n </lib-ribbon-group>\n</ng-template>\n\n@if (isUnavailable()) {\n <div class=\"external-content-message\">\n <i class=\"fa-solid fa-link-slash\"></i>\n <span class=\"external-content-message-title\">{{ 'ExternalContent-Unavailable-Title' | translate }}</span>\n <span>{{ 'ExternalContent-Unavailable-Message' | translate }}</span>\n </div>\n} @else if (isInsecure()) {\n <div class=\"external-content-message\">\n <i class=\"fa-solid fa-shield-halved\"></i>\n <span class=\"external-content-message-title\">{{ 'ExternalContent-Insecure-Title' | translate }}</span>\n <span>{{ 'ExternalContent-Insecure-Message' | translate }}</span>\n </div>\n} @else if (isBlocked()) {\n <div class=\"external-content-message\">\n <i class=\"fa-solid fa-triangle-exclamation\"></i>\n <span class=\"external-content-message-title\">{{ 'ExternalContent-Blocked-Title' | translate }}</span>\n <span>{{ 'ExternalContent-Blocked-Message' | translate }}</span>\n </div>\n} @else {\n @if (isSlow()) {\n <div class=\"external-content-hint\">{{ 'ExternalContent-SlowHint' | translate }}</div>\n }\n @if (frameUrl() || isFrameLoading()) {\n <!--\n The container stays mounted across a reload, which briefly clears frameUrl, so the panel\n does not flicker out and back. What goes away is the frame itself, on purpose.\n\n sandbox and referrerpolicy are STATIC attributes on purpose. Angular rejects `sandbox`\n as a binding on an <iframe> outright (NG0910) — it may only be a static attribute — and\n the whole element then fails to render.\n\n The token list is fixed for every destination, and deliberately not configurable per\n menu item:\n - allow-same-origin keeps the frame in the destination's own origin so its cookies and\n storage work; without it an SSO'd report will not render. It grants no access to ours,\n provided the destination is cross-origin -- never point an embedded item at this\n application's own origin, use an internal route for that.\n - allow-top-navigation is absent on purpose: a framed site must not be able to navigate\n the whole application away.\n - allow-popups-to-escape-sandbox keeps print and download popups usable.\n -->\n <div class=\"external-content-frame-container\">\n @if (isFrameLoading()) {\n <div class=\"external-content-loading\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\">\n <circle class=\"opacity-25\" cx=\"12\" cy=\"12\" r=\"10\" stroke=\"currentColor\" stroke-width=\"4\"></circle>\n <path\n class=\"opacity-75\"\n fill=\"currentColor\"\n d=\"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z\"\n ></path>\n </svg>\n\n <span>{{ 'Loading' | translate }}</span>\n </div>\n }\n @if (frameUrl()) {\n <iframe\n class=\"external-content-frame\"\n sandbox=\"allow-scripts allow-same-origin allow-forms allow-popups allow-popups-to-escape-sandbox allow-downloads\"\n referrerpolicy=\"strict-origin-when-cross-origin\"\n [src]=\"frameUrl()\"\n [attr.title]=\"label() | translate\"\n (load)=\"onFrameLoad()\"\n >\n </iframe>\n }\n </div>\n }\n}\n",
1651
+ styles: ["@layer properties;:host{display:flex;flex-grow:1;flex-direction:column;gap:calc(var(--spacing, .25rem) * 2);overflow:hidden;min-height:0}.external-content-hint{flex:none;border-radius:var(--radius-lg, .5rem);border-style:var(--tw-border-style);border-width:1px;padding-inline:calc(var(--spacing, .25rem) * 3);padding-block:calc(var(--spacing, .25rem) * 2);font-size:var(--text-sm, .875rem);line-height:var(--tw-leading, var(--text-sm--line-height, calc(1.25 / .875)));border-color:var(--color-amber-300, oklch(87.9% .169 91.605));background-color:var(--color-amber-100, oklch(96.2% .059 95.617));color:var(--color-amber-900, oklch(41.4% .112 45.904))}.external-content-frame-container{border-radius:var(--radius-lg, .5rem);border-style:var(--tw-border-style);border-width:1px;border-color:color-mix(in srgb,oklch(87.2% .01 258.338) 90%,transparent);background-color:var(--color-white, #fff);position:relative;display:flex;flex-grow:1;overflow:hidden;min-height:0}@supports (color: color-mix(in lab,red,red)){.external-content-frame-container{border-color:color-mix(in oklab,var(--color-gray-300, oklch(87.2% .01 258.338)) 90%,transparent)}}.external-content-loading{position:absolute;inset:0;z-index:10;display:flex;align-items:center;justify-content:center;gap:calc(var(--spacing, .25rem) * 2);background-color:var(--color-white, #fff);color:var(--color-gray-500, oklch(55.1% .027 264.364))}.external-content-loading svg{height:calc(var(--spacing, .25rem) * 6);min-height:calc(var(--spacing, .25rem) * 6);width:calc(var(--spacing, .25rem) * 6);min-width:calc(var(--spacing, .25rem) * 6);animation:var(--animate-spin, spin 1s linear infinite)}.external-content-frame{width:100%;flex-grow:1;border-style:var(--tw-border-style);border-width:0px;min-height:0}.external-content-message{border-radius:var(--radius-lg, .5rem);border-style:var(--tw-border-style);border-width:1px;border-color:color-mix(in srgb,oklch(87.2% .01 258.338) 90%,transparent);background-color:var(--color-white, #fff);display:flex;flex-grow:1;flex-direction:column;align-items:center;justify-content:center;gap:calc(var(--spacing, .25rem) * 2);padding:calc(var(--spacing, .25rem) * 6);text-align:center}@supports (color: color-mix(in lab,red,red)){.external-content-message{border-color:color-mix(in oklab,var(--color-gray-300, oklch(87.2% .01 258.338)) 90%,transparent)}}.external-content-message i{font-size:var(--text-4xl, 2.25rem);line-height:var(--tw-leading, var(--text-4xl--line-height, calc(2.5 / 2.25)));opacity:40%}.external-content-message .external-content-message-title{font-size:var(--text-lg, 1.125rem);line-height:var(--tw-leading, var(--text-lg--line-height, calc(1.75 / 1.125)));--tw-font-weight: var(--font-weight-semibold, 600);font-weight:var(--font-weight-semibold, 600)}@property --tw-border-style{syntax: \"*\"; inherits: false; initial-value: solid;}@property --tw-font-weight{syntax: \"*\"; inherits: false;}@keyframes spin{to{transform:rotate(360deg)}}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-border-style: solid;--tw-font-weight: initial}}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"]
1652
+ }]
1653
+ }],
1654
+ ctorParameters: () => []
1655
+ });
1656
+ const externalContentRoutes = [{
1657
+ path: EXTERNAL_CONTENT_ROUTE_PATH,
1658
+ children: [{
1659
+ path: ":menuID",
1660
+ component: DefaultTabViewComponent,
1661
+ data: { [FRAMEWORK_VIEW_TYPE]: FrameworkViewType.List },
1662
+ children: [{
1663
+ path: "",
1664
+ component: ExternalContentComponent
1665
+ }]
1666
+ }]
1667
+ }];
1668
+ var OperationsHistoryModalComponent = class OperationsHistoryModalComponent extends ModalBase {
1669
+ modal = viewChild(ModalComponent, ...ngDevMode ? [{ debugName: "modal" }] : /* istanbul ignore next */ []);
1670
+ newValues = input(...ngDevMode ? [void 0, { debugName: "newValues" }] : /* istanbul ignore next */ []);
1671
+ oldValues = input(...ngDevMode ? [void 0, { debugName: "oldValues" }] : /* istanbul ignore next */ []);
1672
+ isModalShown = computed(() => this.modal()?.isOpen() ?? false, ...ngDevMode ? [{ debugName: "isModalShown" }] : /* istanbul ignore next */ []);
1673
+ toggle() {
1674
+ this.modal()?.toggleModal();
1675
+ }
1676
+ static ɵfac = i0.ɵɵngDeclareFactory({
1677
+ minVersion: "12.0.0",
1678
+ version: "22.2.0",
1679
+ ngImport: i0,
1680
+ type: OperationsHistoryModalComponent,
1681
+ deps: null,
1682
+ target: i0.ɵɵFactoryTarget.Component
1683
+ });
1684
+ static ɵcmp = i0.ɵɵngDeclareComponent({
1685
+ minVersion: "17.2.0",
1686
+ version: "22.2.0",
1687
+ type: OperationsHistoryModalComponent,
1688
+ isStandalone: true,
1689
+ selector: "shared-operations-history-modal",
1690
+ inputs: {
1691
+ newValues: {
1692
+ classPropertyName: "newValues",
1693
+ publicName: "newValues",
1694
+ isSignal: true,
1695
+ isRequired: false,
1696
+ transformFunction: null
1697
+ },
1698
+ oldValues: {
1699
+ classPropertyName: "oldValues",
1700
+ publicName: "oldValues",
1701
+ isSignal: true,
1702
+ isRequired: false,
1703
+ transformFunction: null
1704
+ }
1705
+ },
1706
+ viewQueries: [{
1707
+ propertyName: "modal",
1708
+ first: true,
1709
+ predicate: ModalComponent,
1710
+ descendants: true,
1711
+ isSignal: true
1712
+ }],
1713
+ usesInheritance: true,
1714
+ ngImport: i0,
1715
+ template: "<lib-modal size=\"6xl\" [title]=\"'OperationsHistory-Modal-Title' | translate\">\n <div body>\n <pre>{{ oldValues() | json }}</pre>\n <pre>{{ newValues() | json }}</pre>\n </div>\n</lib-modal>\n",
1716
+ styles: ["div[body]{display:flex;flex-direction:row}div[body] pre{width:50%;flex-grow:1;overflow-x:auto;font-size:var(--text-sm, .875rem);line-height:var(--tw-leading, var(--text-sm--line-height, calc(1.25 / .875)))}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"],
1717
+ dependencies: [
1718
+ {
1719
+ kind: "component",
1720
+ type: ModalComponent,
1721
+ selector: "lib-modal",
1722
+ inputs: [
1723
+ "closeButtonText",
1724
+ "dialog",
1725
+ "modalProcessing",
1726
+ "position",
1727
+ "size",
1728
+ "title"
1729
+ ],
1730
+ outputs: [
1731
+ "closeButtonTextChange",
1732
+ "modalProcessingChange",
1733
+ "closed"
1734
+ ]
1735
+ },
1736
+ {
1737
+ kind: "pipe",
1738
+ type: JsonPipe,
1739
+ name: "json"
1740
+ },
1741
+ {
1742
+ kind: "pipe",
1743
+ type: TranslatePipe,
1744
+ name: "translate"
1745
+ }
1746
+ ]
1747
+ });
1748
+ };
1749
+ i0.ɵɵngDeclareClassMetadata({
1750
+ minVersion: "12.0.0",
1751
+ version: "22.2.0",
1752
+ ngImport: i0,
1753
+ type: OperationsHistoryModalComponent,
1754
+ decorators: [{
1755
+ type: Component,
1756
+ args: [{
1757
+ selector: "shared-operations-history-modal",
1758
+ imports: [
1759
+ JsonPipe,
1760
+ ModalComponent,
1761
+ TranslatePipe
1762
+ ],
1763
+ template: "<lib-modal size=\"6xl\" [title]=\"'OperationsHistory-Modal-Title' | translate\">\n <div body>\n <pre>{{ oldValues() | json }}</pre>\n <pre>{{ newValues() | json }}</pre>\n </div>\n</lib-modal>\n",
1764
+ styles: ["div[body]{display:flex;flex-direction:row}div[body] pre{width:50%;flex-grow:1;overflow-x:auto;font-size:var(--text-sm, .875rem);line-height:var(--tw-leading, var(--text-sm--line-height, calc(1.25 / .875)))}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"]
1765
+ }]
1766
+ }],
1767
+ propDecorators: {
1768
+ modal: [{
1769
+ type: i0.ViewChild,
1770
+ args: [i0.forwardRef(() => ModalComponent), { isSignal: true }]
1771
+ }],
1772
+ newValues: [{
1773
+ type: i0.Input,
1774
+ args: [{
1775
+ isSignal: true,
1776
+ alias: "newValues",
1777
+ required: false
1778
+ }]
1779
+ }],
1780
+ oldValues: [{
1781
+ type: i0.Input,
1782
+ args: [{
1783
+ isSignal: true,
1784
+ alias: "oldValues",
1785
+ required: false
1786
+ }]
1787
+ }]
1788
+ }
1789
+ });
1790
+ var OperationsHistoryChildListComponent = class OperationsHistoryChildListComponent extends ChildList {
1791
+ modal = viewChild(OperationsHistoryModalComponent, ...ngDevMode ? [{ debugName: "modal" }] : /* istanbul ignore next */ []);
1792
+ operationTemplate = viewChild("operationTemplate", ...ngDevMode ? [{ debugName: "operationTemplate" }] : /* istanbul ignore next */ []);
1793
+ set controllerName(value) {
1794
+ this.dataGridDataset.controllerName = value;
1795
+ }
1796
+ set filters(value) {
1797
+ this.dataGridDataset.setFilters(value);
1798
+ }
1799
+ set serviceID(value) {
1800
+ this.dataGridDataset.serviceId = value;
1801
+ }
1802
+ selectedNewValues = signal(null, ...ngDevMode ? [{ debugName: "selectedNewValues" }] : /* istanbul ignore next */ []);
1803
+ selectedOldValues = signal(null, ...ngDevMode ? [{ debugName: "selectedOldValues" }] : /* istanbul ignore next */ []);
1804
+ ngAfterViewInit() {
1805
+ this.dataGridDataset.columns[0].template = this.operationTemplate();
1806
+ }
1807
+ openModal() {
1808
+ const modal = this.modal();
1809
+ if (modal && !modal.isModalShown()) modal.toggle();
1810
+ }
1811
+ selectedRowChanged() {
1812
+ super.selectedRowChanged();
1813
+ if (this.dataGridDataset.hasSelectedRows) {
1814
+ const key = this.dataGridDataset.selectedRowKeys[0];
1815
+ const data = this.dataGridDataset.getRowData(key);
1816
+ this.selectedOldValues.set(JSON.parse(data.oldValues?.trim() ?? ""));
1817
+ this.selectedNewValues.set(JSON.parse(data.newValues?.trim() ?? ""));
1818
+ }
1819
+ }
1820
+ static ɵfac = i0.ɵɵngDeclareFactory({
1821
+ minVersion: "12.0.0",
1822
+ version: "22.2.0",
1823
+ ngImport: i0,
1824
+ type: OperationsHistoryChildListComponent,
1825
+ deps: null,
1826
+ target: i0.ɵɵFactoryTarget.Component
1827
+ });
1828
+ static ɵcmp = i0.ɵɵngDeclareComponent({
1829
+ minVersion: "17.2.0",
1830
+ version: "22.2.0",
1831
+ type: OperationsHistoryChildListComponent,
1832
+ isStandalone: true,
1833
+ selector: "shared-operations-history-child-list",
1834
+ inputs: {
1835
+ controllerName: "controllerName",
1836
+ filters: "filters",
1837
+ serviceID: "serviceID"
1838
+ },
1839
+ providers: [{
1840
+ provide: DataGridDataset,
1841
+ useClass: OperationsHistoryDataset
1842
+ }],
1843
+ viewQueries: [{
1844
+ propertyName: "modal",
1845
+ first: true,
1846
+ predicate: OperationsHistoryModalComponent,
1847
+ descendants: true,
1848
+ isSignal: true
1849
+ }, {
1850
+ propertyName: "operationTemplate",
1851
+ first: true,
1852
+ predicate: ["operationTemplate"],
1853
+ descendants: true,
1854
+ isSignal: true
1855
+ }],
1856
+ usesInheritance: true,
1857
+ ngImport: i0,
1858
+ template: "<lib-data-grid [lazyLoadRows]=\"true\"> </lib-data-grid>\n\n<ng-template #operationTemplate let-rowData=\"rowData\">\n <div\n class=\"operation-content\"\n role=\"button\"\n tabindex=\"0\"\n (click)=\"openModal()\"\n (keydown.enter)=\"openModal()\"\n (keydown.space)=\"openModal(); $event.preventDefault()\"\n >\n <span\n class=\"operation\"\n [class.added]=\"rowData.operationType === 'Added'\"\n [class.deleted]=\"rowData.operationType === 'Deleted'\"\n [class.modified]=\"rowData.operationType === 'Modified'\"\n [class.unchanged]=\"rowData.operationType === 'Unchanged'\"\n >\n {{ rowData.operationType }}\n </span>\n {{ rowData.entityName }}\n </div>\n</ng-template>\n\n<shared-operations-history-modal [newValues]=\"selectedNewValues()\" [oldValues]=\"selectedOldValues()\">\n</shared-operations-history-modal>\n",
1859
+ styles: ["@layer properties;:host{width:100%;max-width:100%;min-width:100%}lib-data-grid{height:100%}lib-data-grid ::ng-deep .body lib-data-grid-row{padding:0!important}.operation-content{padding-inline:calc(var(--spacing, .25rem) * 3);padding-block:calc(var(--spacing, .25rem) * 2)}.operation-content .operation{font-size:var(--text-sm, .875rem);line-height:var(--tw-leading, var(--text-sm--line-height, calc(1.25 / .875)));--tw-font-weight: var(--font-weight-semibold, 600);font-weight:var(--font-weight-semibold, 600)}.operation-content .operation.added{color:var(--color-green-700, oklch(52.7% .154 150.069))}.operation-content .operation.deleted{color:var(--color-red-700, oklch(50.5% .213 27.518))}.operation-content .operation.modified{color:var(--color-blue-700, oklch(48.8% .243 264.376))}.operation-content .operation.unchanged{color:var(--color-gray-700, oklch(37.3% .034 259.733))}@property --tw-font-weight{syntax: \"*\"; inherits: false;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-font-weight: initial}}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"],
1860
+ dependencies: [{
1861
+ kind: "component",
1862
+ type: DataGridComponent,
1863
+ selector: "lib-data-grid",
1864
+ inputs: [
1865
+ "disabled",
1866
+ "lazyLoadRows",
1867
+ "showButtons"
1868
+ ]
1869
+ }, {
1870
+ kind: "component",
1871
+ type: OperationsHistoryModalComponent,
1872
+ selector: "shared-operations-history-modal",
1873
+ inputs: ["newValues", "oldValues"]
1874
+ }]
1875
+ });
1876
+ };
1877
+ i0.ɵɵngDeclareClassMetadata({
1878
+ minVersion: "12.0.0",
1879
+ version: "22.2.0",
1880
+ ngImport: i0,
1881
+ type: OperationsHistoryChildListComponent,
1882
+ decorators: [{
1883
+ type: Component,
1884
+ args: [{
1885
+ selector: "shared-operations-history-child-list",
1886
+ imports: [DataGridComponent, OperationsHistoryModalComponent],
1887
+ providers: [{
1888
+ provide: DataGridDataset,
1889
+ useClass: OperationsHistoryDataset
1890
+ }],
1891
+ template: "<lib-data-grid [lazyLoadRows]=\"true\"> </lib-data-grid>\n\n<ng-template #operationTemplate let-rowData=\"rowData\">\n <div\n class=\"operation-content\"\n role=\"button\"\n tabindex=\"0\"\n (click)=\"openModal()\"\n (keydown.enter)=\"openModal()\"\n (keydown.space)=\"openModal(); $event.preventDefault()\"\n >\n <span\n class=\"operation\"\n [class.added]=\"rowData.operationType === 'Added'\"\n [class.deleted]=\"rowData.operationType === 'Deleted'\"\n [class.modified]=\"rowData.operationType === 'Modified'\"\n [class.unchanged]=\"rowData.operationType === 'Unchanged'\"\n >\n {{ rowData.operationType }}\n </span>\n {{ rowData.entityName }}\n </div>\n</ng-template>\n\n<shared-operations-history-modal [newValues]=\"selectedNewValues()\" [oldValues]=\"selectedOldValues()\">\n</shared-operations-history-modal>\n",
1892
+ styles: ["@layer properties;:host{width:100%;max-width:100%;min-width:100%}lib-data-grid{height:100%}lib-data-grid ::ng-deep .body lib-data-grid-row{padding:0!important}.operation-content{padding-inline:calc(var(--spacing, .25rem) * 3);padding-block:calc(var(--spacing, .25rem) * 2)}.operation-content .operation{font-size:var(--text-sm, .875rem);line-height:var(--tw-leading, var(--text-sm--line-height, calc(1.25 / .875)));--tw-font-weight: var(--font-weight-semibold, 600);font-weight:var(--font-weight-semibold, 600)}.operation-content .operation.added{color:var(--color-green-700, oklch(52.7% .154 150.069))}.operation-content .operation.deleted{color:var(--color-red-700, oklch(50.5% .213 27.518))}.operation-content .operation.modified{color:var(--color-blue-700, oklch(48.8% .243 264.376))}.operation-content .operation.unchanged{color:var(--color-gray-700, oklch(37.3% .034 259.733))}@property --tw-font-weight{syntax: \"*\"; inherits: false;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-font-weight: initial}}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"]
1893
+ }]
1894
+ }],
1895
+ propDecorators: {
1896
+ modal: [{
1897
+ type: i0.ViewChild,
1898
+ args: [i0.forwardRef(() => OperationsHistoryModalComponent), { isSignal: true }]
1899
+ }],
1900
+ operationTemplate: [{
1901
+ type: i0.ViewChild,
1902
+ args: ["operationTemplate", { isSignal: true }]
1903
+ }],
1904
+ controllerName: [{ type: Input }],
1905
+ filters: [{ type: Input }],
1906
+ serviceID: [{ type: Input }]
1907
+ }
1908
+ });
1909
+ var BypassHtmlSanitizerPipe = class BypassHtmlSanitizerPipe {
1910
+ sanitizer = inject(DomSanitizer);
1911
+ transform(html) {
1912
+ return this.sanitizer.bypassSecurityTrustHtml(html);
1913
+ }
1914
+ static ɵfac = i0.ɵɵngDeclareFactory({
1915
+ minVersion: "12.0.0",
1916
+ version: "22.2.0",
1917
+ ngImport: i0,
1918
+ type: BypassHtmlSanitizerPipe,
1919
+ deps: [],
1920
+ target: i0.ɵɵFactoryTarget.Pipe
1921
+ });
1922
+ static ɵpipe = i0.ɵɵngDeclarePipe({
1923
+ minVersion: "14.0.0",
1924
+ version: "22.2.0",
1925
+ ngImport: i0,
1926
+ type: BypassHtmlSanitizerPipe,
1927
+ isStandalone: true,
1928
+ name: "bypassHtmlSanitizer"
1929
+ });
1930
+ };
1931
+ i0.ɵɵngDeclareClassMetadata({
1932
+ minVersion: "12.0.0",
1933
+ version: "22.2.0",
1934
+ ngImport: i0,
1935
+ type: BypassHtmlSanitizerPipe,
1936
+ decorators: [{
1937
+ type: Pipe,
1938
+ args: [{ name: "bypassHtmlSanitizer" }]
1939
+ }]
1940
+ });
1941
+ var EnumLabelPipe = class EnumLabelPipe {
1942
+ transform(value, enumType) {
1943
+ if (value === void 0 || enumType === void 0) return "";
1944
+ const keys = Object.keys(enumType).filter((key) => !isNaN(Number(enumType[key])));
1945
+ const index = keys.map((key) => enumType[key]).indexOf(value);
1946
+ if (index >= 0) return keys[index];
1947
+ return "";
1948
+ }
1949
+ static ɵfac = i0.ɵɵngDeclareFactory({
1950
+ minVersion: "12.0.0",
1951
+ version: "22.2.0",
1952
+ ngImport: i0,
1953
+ type: EnumLabelPipe,
1954
+ deps: [],
1955
+ target: i0.ɵɵFactoryTarget.Pipe
1956
+ });
1957
+ static ɵpipe = i0.ɵɵngDeclarePipe({
1958
+ minVersion: "14.0.0",
1959
+ version: "22.2.0",
1960
+ ngImport: i0,
1961
+ type: EnumLabelPipe,
1962
+ isStandalone: true,
1963
+ name: "enumLabel"
1964
+ });
1965
+ };
1966
+ i0.ɵɵngDeclareClassMetadata({
1967
+ minVersion: "12.0.0",
1968
+ version: "22.2.0",
1969
+ ngImport: i0,
1970
+ type: EnumLabelPipe,
1971
+ decorators: [{
1972
+ type: Pipe,
1973
+ args: [{ name: "enumLabel" }]
1974
+ }]
1975
+ });
1976
+ var UtcDatePipe = class UtcDatePipe {
1977
+ static timeZoneMarker = /(?:Z|[+-]\d{2}:?\d{2})$/i;
1978
+ transform(value) {
1979
+ if (!value) return null;
1980
+ const newDate = new Date(value);
1981
+ if (Number.isNaN(newDate.getTime())) return null;
1982
+ if (typeof value === "string" && UtcDatePipe.timeZoneMarker.test(value.trim())) return newDate;
1983
+ return /* @__PURE__ */ new Date(newDate.getTime() - newDate.getTimezoneOffset() * 6e4);
1984
+ }
1985
+ static ɵfac = i0.ɵɵngDeclareFactory({
1986
+ minVersion: "12.0.0",
1987
+ version: "22.2.0",
1988
+ ngImport: i0,
1989
+ type: UtcDatePipe,
1990
+ deps: [],
1991
+ target: i0.ɵɵFactoryTarget.Pipe
1992
+ });
1993
+ static ɵpipe = i0.ɵɵngDeclarePipe({
1994
+ minVersion: "14.0.0",
1995
+ version: "22.2.0",
1996
+ ngImport: i0,
1997
+ type: UtcDatePipe,
1998
+ isStandalone: true,
1999
+ name: "utcDate"
2000
+ });
2001
+ };
2002
+ i0.ɵɵngDeclareClassMetadata({
2003
+ minVersion: "12.0.0",
2004
+ version: "22.2.0",
2005
+ ngImport: i0,
2006
+ type: UtcDatePipe,
2007
+ decorators: [{
2008
+ type: Pipe,
2009
+ args: [{ name: "utcDate" }]
2010
+ }]
2011
+ });
2012
+ var ServicesHistoryChildListComponent = class ServicesHistoryChildListComponent extends ChildList {
2013
+ serviceTemplate = viewChild("serviceTemplate", ...ngDevMode ? [{ debugName: "serviceTemplate" }] : /* istanbul ignore next */ []);
2014
+ set controllerName(value) {
2015
+ this.dataGridDataset.controllerName = value;
2016
+ }
2017
+ filtersChanged = output();
2018
+ selectedServiceID = signal(void 0, ...ngDevMode ? [{ debugName: "selectedServiceID" }] : /* istanbul ignore next */ []);
2019
+ ngAfterViewInit() {
2020
+ this.dataGridDataset.columns[0].template = this.serviceTemplate();
2021
+ }
2022
+ ngOnInit() {
2023
+ super.ngOnInit();
2024
+ this.dataGridDataset.filtersChanged.pipe(takeUntil(this.destroy$)).subscribe((filters) => this.filtersChanged.emit(filters));
2025
+ this.dataGridDataset.loadStarted.pipe(takeUntil(this.destroy$)).subscribe(() => {
2026
+ this.selectedServiceID.set(void 0);
2027
+ });
2028
+ }
2029
+ selectedRowChanged() {
2030
+ super.selectedRowChanged();
2031
+ if (this.dataGridDataset.hasSelectedRows) {
2032
+ const selectedKey = this.dataGridDataset.selectedRowKeys[0];
2033
+ this.selectedServiceID.set(this.dataGridDataset.getRowID(selectedKey));
2034
+ }
2035
+ }
2036
+ static ɵfac = i0.ɵɵngDeclareFactory({
2037
+ minVersion: "12.0.0",
2038
+ version: "22.2.0",
2039
+ ngImport: i0,
2040
+ type: ServicesHistoryChildListComponent,
2041
+ deps: null,
2042
+ target: i0.ɵɵFactoryTarget.Component
2043
+ });
2044
+ static ɵcmp = i0.ɵɵngDeclareComponent({
2045
+ minVersion: "17.2.0",
2046
+ version: "22.2.0",
2047
+ type: ServicesHistoryChildListComponent,
2048
+ isStandalone: true,
2049
+ selector: "shared-services-history-child-list",
2050
+ inputs: { controllerName: "controllerName" },
2051
+ outputs: { filtersChanged: "filtersChanged" },
2052
+ viewQueries: [{
2053
+ propertyName: "serviceTemplate",
2054
+ first: true,
2055
+ predicate: ["serviceTemplate"],
2056
+ descendants: true,
2057
+ isSignal: true
2058
+ }],
2059
+ usesInheritance: true,
2060
+ ngImport: i0,
2061
+ template: "<lib-data-grid [lazyLoadRows]=\"true\"> </lib-data-grid>\n\n<ng-template #serviceTemplate let-rowData=\"rowData\">\n <div class=\"service-content\">\n <div class=\"icon\">\n <i class=\"fa-solid fa-circle fa-lg\"></i>\n </div>\n <div class=\"information\">\n <div class=\"service-name\">\n {{ rowData.name }}\n </div>\n <div class=\"details\">\n <span class=\"datetime\"\n ><i class=\"fa-solid fa-clock\"></i>\n {{ rowData.changedOn | utcDate | date: ('Format-DateTime' | translate) }}</span\n >\n <span class=\"user\"><i class=\"fa-solid fa-user\"></i> {{ rowData.changedByName }}</span>\n </div>\n </div>\n </div>\n</ng-template>\n",
2062
+ styles: ["@layer properties;:host{width:100%;max-width:100%;min-width:100%}lib-data-grid{height:100%}lib-data-grid ::ng-deep .body lib-data-grid-row{padding:0!important}.service-content{display:flex;flex-grow:1;overflow:hidden;padding-inline:calc(var(--spacing, .25rem) * 3)}.service-content .icon{position:relative;margin-right:calc(var(--spacing, .25rem) * 3);display:flex;align-items:center;color:var(--color-blue-500, oklch(62.3% .214 259.815))}.service-content .icon:before,.service-content .icon:after{position:absolute;left:50%;margin-left:calc(var(--spacing, .25rem) * -1);height:50%;width:calc(var(--spacing, .25rem) * 2);background-color:color-mix(in srgb,oklch(86.9% .022 252.894) 50%,transparent);--tw-content: \"\";content:var(--tw-content)}@supports (color: color-mix(in lab,red,red)){.service-content .icon:before,.service-content .icon:after{background-color:color-mix(in oklab,var(--color-slate-300, oklch(86.9% .022 252.894)) 50%,transparent)}}.service-content .icon:before{top:0}.service-content .icon:after{top:50%}.service-content .icon i{z-index:1}.service-content .information{display:flex;flex-grow:1;flex-direction:column;overflow:hidden;padding-block:var(--spacing, .25rem)}.service-content .information .service-name{--tw-font-weight: var(--font-weight-bold, 700);font-weight:var(--font-weight-bold, 700)}.service-content .information .details{display:flex;font-size:var(--text-sm, .875rem);line-height:var(--tw-leading, var(--text-sm--line-height, calc(1.25 / .875)))}.service-content .information .details i{color:var(--color-slate-400, oklch(70.4% .04 256.788))}.service-content .information .details .datetime{margin-right:calc(var(--spacing, .25rem) * 3)}.service-content .information .details .user{overflow:hidden;text-overflow:ellipsis}@property --tw-content{syntax: \"*\"; inherits: false; initial-value: \"\";}@property --tw-font-weight{syntax: \"*\"; inherits: false;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-content: \"\";--tw-font-weight: initial}}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"],
2063
+ dependencies: [
2064
+ {
2065
+ kind: "component",
2066
+ type: DataGridComponent,
2067
+ selector: "lib-data-grid",
2068
+ inputs: [
2069
+ "disabled",
2070
+ "lazyLoadRows",
2071
+ "showButtons"
2072
+ ]
2073
+ },
2074
+ {
2075
+ kind: "pipe",
2076
+ type: DatePipe,
2077
+ name: "date"
2078
+ },
2079
+ {
2080
+ kind: "pipe",
2081
+ type: UtcDatePipe,
2082
+ name: "utcDate"
2083
+ },
2084
+ {
2085
+ kind: "pipe",
2086
+ type: TranslatePipe,
2087
+ name: "translate"
2088
+ }
2089
+ ]
2090
+ });
2091
+ };
2092
+ i0.ɵɵngDeclareClassMetadata({
2093
+ minVersion: "12.0.0",
2094
+ version: "22.2.0",
2095
+ ngImport: i0,
2096
+ type: ServicesHistoryChildListComponent,
2097
+ decorators: [{
2098
+ type: Component,
2099
+ args: [{
2100
+ selector: "shared-services-history-child-list",
2101
+ imports: [
2102
+ DataGridComponent,
2103
+ DatePipe,
2104
+ UtcDatePipe,
2105
+ TranslatePipe
2106
+ ],
2107
+ template: "<lib-data-grid [lazyLoadRows]=\"true\"> </lib-data-grid>\n\n<ng-template #serviceTemplate let-rowData=\"rowData\">\n <div class=\"service-content\">\n <div class=\"icon\">\n <i class=\"fa-solid fa-circle fa-lg\"></i>\n </div>\n <div class=\"information\">\n <div class=\"service-name\">\n {{ rowData.name }}\n </div>\n <div class=\"details\">\n <span class=\"datetime\"\n ><i class=\"fa-solid fa-clock\"></i>\n {{ rowData.changedOn | utcDate | date: ('Format-DateTime' | translate) }}</span\n >\n <span class=\"user\"><i class=\"fa-solid fa-user\"></i> {{ rowData.changedByName }}</span>\n </div>\n </div>\n </div>\n</ng-template>\n",
2108
+ styles: ["@layer properties;:host{width:100%;max-width:100%;min-width:100%}lib-data-grid{height:100%}lib-data-grid ::ng-deep .body lib-data-grid-row{padding:0!important}.service-content{display:flex;flex-grow:1;overflow:hidden;padding-inline:calc(var(--spacing, .25rem) * 3)}.service-content .icon{position:relative;margin-right:calc(var(--spacing, .25rem) * 3);display:flex;align-items:center;color:var(--color-blue-500, oklch(62.3% .214 259.815))}.service-content .icon:before,.service-content .icon:after{position:absolute;left:50%;margin-left:calc(var(--spacing, .25rem) * -1);height:50%;width:calc(var(--spacing, .25rem) * 2);background-color:color-mix(in srgb,oklch(86.9% .022 252.894) 50%,transparent);--tw-content: \"\";content:var(--tw-content)}@supports (color: color-mix(in lab,red,red)){.service-content .icon:before,.service-content .icon:after{background-color:color-mix(in oklab,var(--color-slate-300, oklch(86.9% .022 252.894)) 50%,transparent)}}.service-content .icon:before{top:0}.service-content .icon:after{top:50%}.service-content .icon i{z-index:1}.service-content .information{display:flex;flex-grow:1;flex-direction:column;overflow:hidden;padding-block:var(--spacing, .25rem)}.service-content .information .service-name{--tw-font-weight: var(--font-weight-bold, 700);font-weight:var(--font-weight-bold, 700)}.service-content .information .details{display:flex;font-size:var(--text-sm, .875rem);line-height:var(--tw-leading, var(--text-sm--line-height, calc(1.25 / .875)))}.service-content .information .details i{color:var(--color-slate-400, oklch(70.4% .04 256.788))}.service-content .information .details .datetime{margin-right:calc(var(--spacing, .25rem) * 3)}.service-content .information .details .user{overflow:hidden;text-overflow:ellipsis}@property --tw-content{syntax: \"*\"; inherits: false; initial-value: \"\";}@property --tw-font-weight{syntax: \"*\"; inherits: false;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-content: \"\";--tw-font-weight: initial}}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"]
2109
+ }]
2110
+ }],
2111
+ propDecorators: {
2112
+ serviceTemplate: [{
2113
+ type: i0.ViewChild,
2114
+ args: ["serviceTemplate", { isSignal: true }]
2115
+ }],
2116
+ controllerName: [{ type: Input }],
2117
+ filtersChanged: [{
2118
+ type: i0.Output,
2119
+ args: ["filtersChanged"]
2120
+ }]
2121
+ }
2122
+ });
2123
+ var ServicesHistoryFilterComponent = class ServicesHistoryFilterComponent extends FiltersBase {
2124
+ usersCatalogEndpoint = input(...ngDevMode ? [void 0, { debugName: "usersCatalogEndpoint" }] : /* istanbul ignore next */ []);
2125
+ hasUsersCatalog = computed(() => !!this.usersCatalogEndpoint(), ...ngDevMode ? [{ debugName: "hasUsersCatalog" }] : /* istanbul ignore next */ []);
2126
+ get changedOnFromControl() {
2127
+ return this.filterForm.get("changedOnFrom");
2128
+ }
2129
+ get changedOnToControl() {
2130
+ return this.filterForm.get("changedOnTo");
2131
+ }
2132
+ ngOnInit() {
2133
+ super.ngOnInit();
2134
+ this.changedOnFromControl.valueChanges.pipe(takeUntil(this.destroy$)).subscribe((from) => {
2135
+ const to = this.changedOnToControl.value;
2136
+ if (!!from && !!to && to < from) this.changedOnToControl.setValue(from);
2137
+ });
2138
+ this.changedOnToControl.valueChanges.pipe(takeUntil(this.destroy$)).subscribe((to) => {
2139
+ const from = this.changedOnFromControl.value;
2140
+ if (!!from && !!to && to < from) this.changedOnFromControl.setValue(to);
2141
+ });
2142
+ }
2143
+ formSetup() {
2144
+ return this.formBuilder.group({
2145
+ changedByID: [null],
2146
+ changedOnFrom: [null],
2147
+ changedOnTo: [null],
2148
+ name: [null],
2149
+ onlyCurrentEntity: [false, { nonNullable: true }]
2150
+ });
2151
+ }
2152
+ static ɵfac = i0.ɵɵngDeclareFactory({
2153
+ minVersion: "12.0.0",
2154
+ version: "22.2.0",
2155
+ ngImport: i0,
2156
+ type: ServicesHistoryFilterComponent,
2157
+ deps: null,
2158
+ target: i0.ɵɵFactoryTarget.Component
2159
+ });
2160
+ static ɵcmp = i0.ɵɵngDeclareComponent({
2161
+ minVersion: "17.0.0",
2162
+ version: "22.2.0",
2163
+ type: ServicesHistoryFilterComponent,
2164
+ isStandalone: true,
2165
+ selector: "shared-services-history-filter",
2166
+ inputs: { usersCatalogEndpoint: {
2167
+ classPropertyName: "usersCatalogEndpoint",
2168
+ publicName: "usersCatalogEndpoint",
2169
+ isSignal: true,
2170
+ isRequired: false,
2171
+ transformFunction: null
2172
+ } },
2173
+ usesInheritance: true,
2174
+ ngImport: i0,
2175
+ template: "<framework-button-filters modalSize=\"2xl\" modalTitle=\"ServicesHistory-Filters-Title\" [formGroup]=\"filterForm\">\n <lib-form-group label=\"ServicesHistory-FormGroup-Service\">\n <lib-form-input-group controlName=\"name\" label=\"ServicesHistory-Field-Name\" [autofocus]=\"true\" [maxLength]=\"200\">\n </lib-form-input-group>\n\n @if (hasUsersCatalog()) {\n <lib-catalog-select\n controlName=\"changedByID\"\n displayControlName=\"changedByName\"\n label=\"ServicesHistory-Field-ChangedBy\"\n [readOnly]=\"false\"\n [searchEndpoint]=\"usersCatalogEndpoint()!\"\n >\n </lib-catalog-select>\n }\n </lib-form-group>\n\n <lib-form-group label=\"ServicesHistory-FormGroup-Period\">\n <lib-form-input-group controlName=\"changedOnFrom\" label=\"ServicesHistory-Field-ChangedOnFrom\" [type]=\"'date'\">\n </lib-form-input-group>\n\n <lib-form-input-group controlName=\"changedOnTo\" label=\"ServicesHistory-Field-ChangedOnTo\" [type]=\"'date'\">\n </lib-form-input-group>\n </lib-form-group>\n\n <lib-form-group label=\"ServicesHistory-FormGroup-Operations\">\n <lib-form-input-group\n controlName=\"onlyCurrentEntity\"\n label=\"ServicesHistory-Field-OnlyCurrentEntity\"\n notes=\"ServicesHistory-Field-OnlyCurrentEntity-Notes\"\n [type]=\"'checkbox'\"\n >\n </lib-form-input-group>\n </lib-form-group>\n</framework-button-filters>\n",
2176
+ styles: [""],
2177
+ dependencies: [
2178
+ {
2179
+ kind: "component",
2180
+ type: ButtonFiltersComponent,
2181
+ selector: "framework-button-filters",
2182
+ inputs: [
2183
+ "modalSize",
2184
+ "modalTitle",
2185
+ "validateFormFunction"
2186
+ ]
2187
+ },
2188
+ {
2189
+ kind: "component",
2190
+ type: CatalogSelectComponent,
2191
+ selector: "lib-catalog-select",
2192
+ inputs: [
2193
+ "autofocus",
2194
+ "controlName",
2195
+ "displayControlName",
2196
+ "displayProperty",
2197
+ "entriesList",
2198
+ "filters",
2199
+ "label",
2200
+ "maxEntries",
2201
+ "minimumLengthSearch",
2202
+ "notes",
2203
+ "readOnly",
2204
+ "searchable",
2205
+ "searchEndpoint",
2206
+ "validations",
2207
+ "valueProperty"
2208
+ ]
2209
+ },
2210
+ {
2211
+ kind: "component",
2212
+ type: FormGroupComponent,
2213
+ selector: "lib-form-group",
2214
+ inputs: ["shouldExpand", "label"]
2215
+ },
2216
+ {
2217
+ kind: "component",
2218
+ type: FormInputGroupComponent,
2219
+ selector: "lib-form-input-group",
2220
+ inputs: [
2221
+ "autofocus",
2222
+ "alignContent",
2223
+ "controlName",
2224
+ "fixedValue",
2225
+ "format",
2226
+ "label",
2227
+ "isDisabled",
2228
+ "isFullHeight",
2229
+ "maxLength",
2230
+ "min",
2231
+ "notes",
2232
+ "readOnly",
2233
+ "rows",
2234
+ "showLabel",
2235
+ "step",
2236
+ "template",
2237
+ "type",
2238
+ "validations"
2239
+ ]
2240
+ },
2241
+ {
2242
+ kind: "ngmodule",
2243
+ type: FormsModule
2244
+ },
2245
+ {
2246
+ kind: "directive",
2247
+ type: i1.NgControlStatusGroup,
2248
+ selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]"
2249
+ },
2250
+ {
2251
+ kind: "ngmodule",
2252
+ type: ReactiveFormsModule
2253
+ },
2254
+ {
2255
+ kind: "directive",
2256
+ type: i1.FormGroupDirective,
2257
+ selector: "[formGroup]",
2258
+ inputs: ["formGroup"],
2259
+ outputs: ["ngSubmit"],
2260
+ exportAs: ["ngForm"]
2261
+ }
2262
+ ]
2263
+ });
2264
+ };
2265
+ i0.ɵɵngDeclareClassMetadata({
2266
+ minVersion: "12.0.0",
2267
+ version: "22.2.0",
2268
+ ngImport: i0,
2269
+ type: ServicesHistoryFilterComponent,
2270
+ decorators: [{
2271
+ type: Component,
2272
+ args: [{
2273
+ selector: "shared-services-history-filter",
2274
+ imports: [
2275
+ ButtonFiltersComponent,
2276
+ CatalogSelectComponent,
2277
+ FormGroupComponent,
2278
+ FormInputGroupComponent,
2279
+ FormsModule,
2280
+ ReactiveFormsModule
2281
+ ],
2282
+ template: "<framework-button-filters modalSize=\"2xl\" modalTitle=\"ServicesHistory-Filters-Title\" [formGroup]=\"filterForm\">\n <lib-form-group label=\"ServicesHistory-FormGroup-Service\">\n <lib-form-input-group controlName=\"name\" label=\"ServicesHistory-Field-Name\" [autofocus]=\"true\" [maxLength]=\"200\">\n </lib-form-input-group>\n\n @if (hasUsersCatalog()) {\n <lib-catalog-select\n controlName=\"changedByID\"\n displayControlName=\"changedByName\"\n label=\"ServicesHistory-Field-ChangedBy\"\n [readOnly]=\"false\"\n [searchEndpoint]=\"usersCatalogEndpoint()!\"\n >\n </lib-catalog-select>\n }\n </lib-form-group>\n\n <lib-form-group label=\"ServicesHistory-FormGroup-Period\">\n <lib-form-input-group controlName=\"changedOnFrom\" label=\"ServicesHistory-Field-ChangedOnFrom\" [type]=\"'date'\">\n </lib-form-input-group>\n\n <lib-form-input-group controlName=\"changedOnTo\" label=\"ServicesHistory-Field-ChangedOnTo\" [type]=\"'date'\">\n </lib-form-input-group>\n </lib-form-group>\n\n <lib-form-group label=\"ServicesHistory-FormGroup-Operations\">\n <lib-form-input-group\n controlName=\"onlyCurrentEntity\"\n label=\"ServicesHistory-Field-OnlyCurrentEntity\"\n notes=\"ServicesHistory-Field-OnlyCurrentEntity-Notes\"\n [type]=\"'checkbox'\"\n >\n </lib-form-input-group>\n </lib-form-group>\n</framework-button-filters>\n"
2283
+ }]
2284
+ }],
2285
+ propDecorators: { usersCatalogEndpoint: [{
2286
+ type: i0.Input,
2287
+ args: [{
2288
+ isSignal: true,
2289
+ alias: "usersCatalogEndpoint",
2290
+ required: false
2291
+ }]
2292
+ }] }
2293
+ });
2294
+ var ServicesHistoryViewComponent = class ServicesHistoryViewComponent extends TabViewBase {
2295
+ controllerName = model("", ...ngDevMode ? [{ debugName: "controllerName" }] : /* istanbul ignore next */ []);
2296
+ entityID = model(...ngDevMode ? [void 0, { debugName: "entityID" }] : /* istanbul ignore next */ []);
2297
+ usersCatalogEndpoint = model(...ngDevMode ? [void 0, { debugName: "usersCatalogEndpoint" }] : /* istanbul ignore next */ []);
2298
+ operationsFilters = signal(void 0, ...ngDevMode ? [{ debugName: "operationsFilters" }] : /* istanbul ignore next */ []);
2299
+ activatedRoute = inject(ActivatedRoute);
2300
+ dataProviderService = inject(DataProviderService, { optional: true });
2301
+ constructor() {
2302
+ super();
2303
+ if (this.activatedRoute.snapshot.data["controllerName"]) this.controllerName.set(this.activatedRoute.snapshot.data["controllerName"]);
2304
+ if (this.activatedRoute.snapshot.data["usersCatalogEndpoint"]) this.usersCatalogEndpoint.set(this.activatedRoute.snapshot.data["usersCatalogEndpoint"]);
2305
+ if (this.dataProviderService) this.dataProviderService.getModel$().pipe(take(1)).subscribe((model) => {
2306
+ this.entityID.set(model.id);
2307
+ });
2308
+ }
2309
+ onFiltersChanged(filters) {
2310
+ this.operationsFilters.set(filters);
2311
+ }
2312
+ static ɵfac = i0.ɵɵngDeclareFactory({
2313
+ minVersion: "12.0.0",
2314
+ version: "22.2.0",
2315
+ ngImport: i0,
2316
+ type: ServicesHistoryViewComponent,
2317
+ deps: [],
2318
+ target: i0.ɵɵFactoryTarget.Component
2319
+ });
2320
+ static ɵcmp = i0.ɵɵngDeclareComponent({
2321
+ minVersion: "17.1.0",
2322
+ version: "22.2.0",
2323
+ type: ServicesHistoryViewComponent,
2324
+ isStandalone: true,
2325
+ selector: "shared-services-history-view",
2326
+ inputs: {
2327
+ controllerName: {
2328
+ classPropertyName: "controllerName",
2329
+ publicName: "controllerName",
2330
+ isSignal: true,
2331
+ isRequired: false,
2332
+ transformFunction: null
2333
+ },
2334
+ entityID: {
2335
+ classPropertyName: "entityID",
2336
+ publicName: "entityID",
2337
+ isSignal: true,
2338
+ isRequired: false,
2339
+ transformFunction: null
2340
+ },
2341
+ usersCatalogEndpoint: {
2342
+ classPropertyName: "usersCatalogEndpoint",
2343
+ publicName: "usersCatalogEndpoint",
2344
+ isSignal: true,
2345
+ isRequired: false,
2346
+ transformFunction: null
2347
+ }
2348
+ },
2349
+ outputs: {
2350
+ controllerName: "controllerNameChange",
2351
+ entityID: "entityIDChange",
2352
+ usersCatalogEndpoint: "usersCatalogEndpointChange"
2353
+ },
2354
+ providers: [{
2355
+ provide: DataGridDataset,
2356
+ useClass: ServicesHistoryDataset
2357
+ }],
2358
+ usesInheritance: true,
2359
+ ngImport: i0,
2360
+ template: "<ng-template #ribbon>\n <lib-ribbon-group [label]=\"'RibbonGroup-General' | translate\">\n <framework-button-refresh></framework-button-refresh>\n\n <shared-services-history-filter [usersCatalogEndpoint]=\"usersCatalogEndpoint()\"> </shared-services-history-filter>\n </lib-ribbon-group>\n</ng-template>\n\n<div class=\"history-container\">\n <div class=\"service-history-container\">\n <shared-services-history-child-list\n #service\n [controllerName]=\"controllerName()\"\n (filtersChanged)=\"onFiltersChanged($event)\"\n >\n </shared-services-history-child-list>\n </div>\n\n <div class=\"operations-history-container\">\n <shared-operations-history-child-list\n [controllerName]=\"controllerName()\"\n [filters]=\"operationsFilters()\"\n [serviceID]=\"service.selectedServiceID()\"\n >\n </shared-operations-history-child-list>\n </div>\n</div>\n",
2361
+ styles: [":host{display:flex;flex-grow:1;overflow:hidden}.history-container{display:flex;flex-grow:1;overflow:hidden;padding:calc(var(--spacing, .25rem) * 2)}.history-container .service-history-container,.history-container .operations-history-container{display:flex;flex-grow:1;overflow:hidden}.history-container .service-history-container lib-data-grid,.history-container .operations-history-container lib-data-grid{flex-grow:1}.history-container .service-history-container{width:calc(2 / 6 * 100%);padding-right:var(--spacing, .25rem)}.history-container .service-history-container ::ng-deep lib-data-grid-row:first-child .icon:before{display:none}.history-container .service-history-container ::ng-deep lib-data-grid-row:last-child .icon:after{display:none}.history-container .operations-history-container{width:calc(4 / 6 * 100%);padding-left:var(--spacing, .25rem)}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"],
2362
+ dependencies: [
2363
+ {
2364
+ kind: "component",
2365
+ type: ButtonRefreshComponent,
2366
+ selector: "framework-button-refresh"
2367
+ },
2368
+ {
2369
+ kind: "component",
2370
+ type: OperationsHistoryChildListComponent,
2371
+ selector: "shared-operations-history-child-list",
2372
+ inputs: [
2373
+ "controllerName",
2374
+ "filters",
2375
+ "serviceID"
2376
+ ]
2377
+ },
2378
+ {
2379
+ kind: "component",
2380
+ type: RibbonGroupComponent,
2381
+ selector: "lib-ribbon-group",
2382
+ inputs: ["label"]
2383
+ },
2384
+ {
2385
+ kind: "component",
2386
+ type: ServicesHistoryChildListComponent,
2387
+ selector: "shared-services-history-child-list",
2388
+ inputs: ["controllerName"],
2389
+ outputs: ["filtersChanged"]
2390
+ },
2391
+ {
2392
+ kind: "component",
2393
+ type: ServicesHistoryFilterComponent,
2394
+ selector: "shared-services-history-filter",
2395
+ inputs: ["usersCatalogEndpoint"]
2396
+ },
2397
+ {
2398
+ kind: "pipe",
2399
+ type: TranslatePipe,
2400
+ name: "translate"
2401
+ }
2402
+ ]
2403
+ });
2404
+ };
2405
+ i0.ɵɵngDeclareClassMetadata({
2406
+ minVersion: "12.0.0",
2407
+ version: "22.2.0",
2408
+ ngImport: i0,
2409
+ type: ServicesHistoryViewComponent,
2410
+ decorators: [{
2411
+ type: Component,
2412
+ args: [{
2413
+ selector: "shared-services-history-view",
2414
+ imports: [
2415
+ ButtonRefreshComponent,
2416
+ OperationsHistoryChildListComponent,
2417
+ RibbonGroupComponent,
2418
+ ServicesHistoryChildListComponent,
2419
+ ServicesHistoryFilterComponent,
2420
+ TranslatePipe
2421
+ ],
2422
+ providers: [{
2423
+ provide: DataGridDataset,
2424
+ useClass: ServicesHistoryDataset
2425
+ }],
2426
+ template: "<ng-template #ribbon>\n <lib-ribbon-group [label]=\"'RibbonGroup-General' | translate\">\n <framework-button-refresh></framework-button-refresh>\n\n <shared-services-history-filter [usersCatalogEndpoint]=\"usersCatalogEndpoint()\"> </shared-services-history-filter>\n </lib-ribbon-group>\n</ng-template>\n\n<div class=\"history-container\">\n <div class=\"service-history-container\">\n <shared-services-history-child-list\n #service\n [controllerName]=\"controllerName()\"\n (filtersChanged)=\"onFiltersChanged($event)\"\n >\n </shared-services-history-child-list>\n </div>\n\n <div class=\"operations-history-container\">\n <shared-operations-history-child-list\n [controllerName]=\"controllerName()\"\n [filters]=\"operationsFilters()\"\n [serviceID]=\"service.selectedServiceID()\"\n >\n </shared-operations-history-child-list>\n </div>\n</div>\n",
2427
+ styles: [":host{display:flex;flex-grow:1;overflow:hidden}.history-container{display:flex;flex-grow:1;overflow:hidden;padding:calc(var(--spacing, .25rem) * 2)}.history-container .service-history-container,.history-container .operations-history-container{display:flex;flex-grow:1;overflow:hidden}.history-container .service-history-container lib-data-grid,.history-container .operations-history-container lib-data-grid{flex-grow:1}.history-container .service-history-container{width:calc(2 / 6 * 100%);padding-right:var(--spacing, .25rem)}.history-container .service-history-container ::ng-deep lib-data-grid-row:first-child .icon:before{display:none}.history-container .service-history-container ::ng-deep lib-data-grid-row:last-child .icon:after{display:none}.history-container .operations-history-container{width:calc(4 / 6 * 100%);padding-left:var(--spacing, .25rem)}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"]
2428
+ }]
2429
+ }],
2430
+ ctorParameters: () => [],
2431
+ propDecorators: {
2432
+ controllerName: [{
2433
+ type: i0.Input,
2434
+ args: [{
2435
+ isSignal: true,
2436
+ alias: "controllerName",
2437
+ required: false
2438
+ }]
2439
+ }, {
2440
+ type: i0.Output,
2441
+ args: ["controllerNameChange"]
2442
+ }],
2443
+ entityID: [{
2444
+ type: i0.Input,
2445
+ args: [{
2446
+ isSignal: true,
2447
+ alias: "entityID",
2448
+ required: false
2449
+ }]
2450
+ }, {
2451
+ type: i0.Output,
2452
+ args: ["entityIDChange"]
2453
+ }],
2454
+ usersCatalogEndpoint: [{
2455
+ type: i0.Input,
2456
+ args: [{
2457
+ isSignal: true,
2458
+ alias: "usersCatalogEndpoint",
2459
+ required: false
2460
+ }]
2461
+ }, {
2462
+ type: i0.Output,
2463
+ args: ["usersCatalogEndpointChange"]
2464
+ }]
2465
+ }
2466
+ });
2467
+ const ZAMBON_SHARED_I18N_ASSET_PATH = "assets/i18n/zambon-dev/shared";
2468
+ const ZAMBON_SHARED_I18N_ASSET = {
2469
+ glob: "**/*.json",
2470
+ input: "node_modules/@zambon-dev/ui/i18n/shared",
2471
+ output: ZAMBON_SHARED_I18N_ASSET_PATH
2472
+ };
2473
+ const ZAMBON_SHARED_I18N_RESOURCES = [
2474
+ {
2475
+ prefix: `/${ZAMBON_SHARED_I18N_ASSET_PATH}/external-content/`,
2476
+ suffix: ".json"
2477
+ },
2478
+ {
2479
+ prefix: `/${ZAMBON_SHARED_I18N_ASSET_PATH}/language-selector/`,
2480
+ suffix: ".json"
2481
+ },
2482
+ {
2483
+ prefix: `/${ZAMBON_SHARED_I18N_ASSET_PATH}/login/`,
2484
+ suffix: ".json"
2485
+ },
2486
+ {
2487
+ prefix: `/${ZAMBON_SHARED_I18N_ASSET_PATH}/operations-history/`,
2488
+ suffix: ".json"
2489
+ },
2490
+ {
2491
+ prefix: `/${ZAMBON_SHARED_I18N_ASSET_PATH}/services-history/`,
2492
+ suffix: ".json"
2493
+ },
2494
+ {
2495
+ prefix: `/${ZAMBON_SHARED_I18N_ASSET_PATH}/top-bar/`,
2496
+ suffix: ".json"
2497
+ }
2498
+ ];
2499
+ function createZambonSharedTranslateLoader(httpBackend, appResources = []) {
2500
+ return new MultiTranslateHttpLoader(httpBackend, [...ZAMBON_SHARED_I18N_RESOURCES, ...appResources]);
2501
+ }
2502
+ function provideZambonSharedTranslateLoader(appResources = []) {
2503
+ return {
2504
+ provide: TranslateLoader,
2505
+ useFactory: (httpBackend) => createZambonSharedTranslateLoader(httpBackend, appResources),
2506
+ deps: [HttpBackend]
2507
+ };
2508
+ }
2509
+ function provideZambonSharedTranslateService(config = {}) {
2510
+ return provideTranslateService({
2511
+ defaultLanguage: config.defaultLanguage,
2512
+ loader: provideZambonSharedTranslateLoader(config.appResources)
2513
+ });
2514
+ }
2515
+ export { AuthGuard, AuthInterceptor, AuthenticationService, BrandComponent, BypassHtmlSanitizerPipe, EXTERNAL_CONTENT_CONFIGS, EXTERNAL_CONTENT_ROUTE_PATH, EnumLabelPipe, EnvironmentBadgeComponent, ExternalContentComponent, ExternalContentConfigs, ExternalContentService, ExternalUrlResolverService, FiltersBase, LoginLayoutComponent, MainLayoutComponent, NotificationsComponent, NotificationsService, OperationsHistoryChildListComponent, OperationsHistoryDataset, OperationsHistoryModalComponent, OperationsHistoryService, ServicesHistoryChildListComponent, ServicesHistoryDataset, ServicesHistoryFilterComponent, ServicesHistoryService, ServicesHistoryViewComponent, SharedAuthModule, TopBarComponent, UserProfileComponent, UtcDatePipe, ZAMBON_SHARED_I18N_ASSET, ZAMBON_SHARED_I18N_ASSET_PATH, ZAMBON_SHARED_I18N_RESOURCES, createZambonSharedTranslateLoader, externalContentRoutes, provideZambonSharedTranslateLoader, provideZambonSharedTranslateService };
2516
+
2517
+ //# sourceMappingURL=zambon-dev-ui-shared.mjs.map