@zambon-dev/shared 2.1.1 → 2.1.3

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.
package/CHANGELOG.md CHANGED
@@ -23,6 +23,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
23
23
 
24
24
  ### ⚠ Breaking Changes / Migration
25
25
 
26
+ ## [2.1.3] - 2026-09-21
27
+
28
+ - Maintenance release (no consumer-facing changes were documented).
29
+
30
+ ## [2.1.2] - 2026-09-20
31
+
32
+ ### Fixed
33
+
34
+ - Declared `rxjs` and `@angular/platform-browser` in `peerDependencies`. `DomSanitizer` is used by
35
+ `ExternalContentComponent` and `BypassHtmlSanitizerPipe`, but neither package was declared.
36
+ - Added a README to the published package.
37
+
26
38
  ## [2.1.1] - 2026-09-15
27
39
 
28
40
  ### Fixed
@@ -321,7 +333,9 @@ URL) in `AppConfig`, and implement a hub that pushes the notification list to cl
321
333
  available via [GitHub Releases](https://github.com/RicardoZambon/ZLibraries/releases) and the
322
334
  `shared-v*` tags.
323
335
 
324
- [Unreleased]: https://github.com/RicardoZambon/ZLibraries/compare/shared-v2.1.1...HEAD
336
+ [Unreleased]: https://github.com/RicardoZambon/ZLibraries/compare/shared-v2.1.3...HEAD
337
+ [2.1.3]: https://github.com/RicardoZambon/ZLibraries/releases/tag/shared-v2.1.3
338
+ [2.1.2]: https://github.com/RicardoZambon/ZLibraries/releases/tag/shared-v2.1.2
325
339
  [2.1.1]: https://github.com/RicardoZambon/ZLibraries/releases/tag/shared-v2.1.1
326
340
  [2.1.0]: https://github.com/RicardoZambon/ZLibraries/releases/tag/shared-v2.1.0
327
341
  [2.0.0]: https://github.com/RicardoZambon/ZLibraries/releases/tag/shared-v2.0.0
package/README.md ADDED
@@ -0,0 +1,107 @@
1
+ # @zambon-dev/shared
2
+
3
+ Shared Angular services, utilities, and styles for Zambon applications.
4
+
5
+ This is the top layer of [ZLibraries](https://github.com/RicardoZambon/ZLibraries). It supplies
6
+ authentication, layouts, history features and cross-cutting services, and builds on both
7
+ [`@zambon-dev/library`](https://www.npmjs.com/package/@zambon-dev/library) and
8
+ [`@zambon-dev/framework`](https://www.npmjs.com/package/@zambon-dev/framework).
9
+
10
+ ## Installation
11
+
12
+ ```bash
13
+ npm install @zambon-dev/shared
14
+ ```
15
+
16
+ ### Peer dependencies
17
+
18
+ All peers must be present in the consuming application:
19
+
20
+ | Package | Range |
21
+ | --- | --- |
22
+ | `@angular/common` | `^19.1.0` |
23
+ | `@angular/core` | `^19.1.0` |
24
+ | `@angular/forms` | `^19.1.0` |
25
+ | `@angular/platform-browser` | `^19.1.0` |
26
+ | `@angular/router` | `^19.1.0` |
27
+ | `@auth0/angular-jwt` | `^5.2.0` |
28
+ | `@microsoft/signalr` | `^10.0.0` |
29
+ | `@ngx-translate/core` | `^16.0.4` |
30
+ | `@zambon-dev/framework` | `^1.0.0` |
31
+ | `@zambon-dev/library` | `^1.0.0` |
32
+ | `ngx-translate-multi-http-loader` | `^19.0.2` |
33
+ | `rxjs` | `^7.8.0` |
34
+
35
+ ## Usage
36
+
37
+ ### Authentication
38
+
39
+ `SharedAuthModule` bundles the guard and HTTP interceptors. `AuthenticationService` handles sign-in, token
40
+ storage (`localStorage` or `sessionStorage` depending on "remember me") and refresh.
41
+
42
+ ```ts
43
+ import { AuthenticationService } from '@zambon-dev/shared';
44
+
45
+ const service = inject(AuthenticationService);
46
+ await firstValueFrom(service.authenticate(username, password, rememberMe));
47
+ ```
48
+
49
+ Route protection uses the exported guard:
50
+
51
+ ```ts
52
+ import { AuthGuard } from '@zambon-dev/shared';
53
+
54
+ export const routes: Routes = [
55
+ { path: 'orders', component: OrdersComponent, canActivate: [AuthGuard] },
56
+ ];
57
+ ```
58
+
59
+ Unauthenticated visitors are redirected to `/login` with a `returnUrl` query parameter.
60
+
61
+ ### Layouts and features
62
+
63
+ `MainLayoutComponent` provides the application shell. Self-contained features ship with their own routes —
64
+ for example `externalContentRoutes` for `ExternalContentComponent`.
65
+
66
+ ## Styles
67
+
68
+ ```scss
69
+ @use '@zambon-dev/shared/styles' as shared;
70
+ ```
71
+
72
+ That entry point resolves to `styles/common.scss`; design tokens are separately reachable at
73
+ `@zambon-dev/shared/styles/variables`.
74
+
75
+ ## Translations
76
+
77
+ ```ts
78
+ import translations from '@zambon-dev/shared/i18n/en.json';
79
+ ```
80
+
81
+ ## What's included
82
+
83
+ **Services** — `AuthenticationService`, `ExternalContentService`, `ExternalUrlResolverService`,
84
+ `NotificationsService` (SignalR-backed), `OperationsHistoryService`, `ServicesHistoryService`
85
+
86
+ **Auth** — `SharedAuthModule`, route guards, HTTP interceptors
87
+
88
+ **Features** — external content, operations history, services history
89
+
90
+ **Layouts** — `MainLayoutComponent` and supporting shell components
91
+
92
+ Components, models and pipes are exported from the package root as well.
93
+
94
+ ## Documentation
95
+
96
+ ```bash
97
+ npm run storybook:shared
98
+ ```
99
+
100
+ ## Contributing
101
+
102
+ See the [workspace README](https://github.com/RicardoZambon/ZLibraries#readme) for the development setup,
103
+ and [CHANGELOG.md](./CHANGELOG.md) for release history.
104
+
105
+ ## License
106
+
107
+ MIT © Ricardo Zambon
@@ -147,7 +147,7 @@ class ExternalContentService {
147
147
  /** Resolves the destination behind an embedded tab, or `undefined` when it cannot be recovered. */
148
148
  find(menuID) {
149
149
  const known = this.registry.get(menuID) ?? this.readFromStorage(menuID);
150
- if (!!known) {
150
+ if (known) {
151
151
  return of(known);
152
152
  }
153
153
  return this.sidebarService.getMenuFromUrl(`/${EXTERNAL_CONTENT_ROUTE_PATH}/${menuID}`)
@@ -738,7 +738,7 @@ class MainLayoutComponent {
738
738
  .pipe(take(1))
739
739
  .subscribe({
740
740
  next: (item) => {
741
- if (!!item) {
741
+ if (item) {
742
742
  this.tabService.updateTabTitle(url, item.label);
743
743
  }
744
744
  },
@@ -881,7 +881,7 @@ class LoginComponent {
881
881
  }
882
882
  }
883
883
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.6", ngImport: i0, type: LoginComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
884
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.1.6", type: LoginComponent, isStandalone: true, selector: "shared-login", viewQueries: [{ propertyName: "username", first: true, predicate: ["username"], descendants: true }], ngImport: i0, 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\n <div class=\"validations\" [class.hidden]=\"!formState.error\">\n \n <div *ngIf=\"formState.error === 'invalid'\">\n {{'Login-Errors-Invalid' | translate}}\n </div>\n \n <div *ngIf=\"formState.error === 'internalServerError'\">{{'Login-Errors-InternalServerError' | translate}}</div>\n </div>\n\n <div class=\"input-group inline\">\n <input type=\"text\" #username id=\"username\" formControlName=\"username\" class=\"form-input peer\" [placeholder]=\"'Login-Username' | translate\" autofocus />\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 <span *ngIf=\"form.get('username')?.hasError('required')\">{{ 'Login-Username-Required' | translate }}</span>\n </div>\n </div>\n \n <div class=\"input-group inline\">\n <input type=\"password\" id=\"password\" formControlName=\"password\" class=\"form-input\" [placeholder]=\"'Login-Password' | translate\" />\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 <span *ngIf=\"form.get('password')?.hasError('required')\">{{ 'Login-Password-Required' | translate }}</span>\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 type=\"submit\" class=\"btn\"\n [class.loading]=\"formState.loading && !formState.success && !formState.error\"\n [class.error]=\"formState.error\"\n [class.success]=\"formState.success\">\n <i *ngIf=\"!formState.loading\" class=\"fas fa-sign-in-alt fa-fw\"></i>\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>", styles: [":host{display:block}.content{margin-left:auto;margin-right:auto;width:83.333333%;border-radius:.5rem}@media (min-width: 768px){.content{width:66.666667%}}@media (min-width: 1280px){.content{width:41.666667%}}.content>:not([hidden])~:not([hidden]){--tw-divide-y-reverse: 0;border-top-width:calc(1px * calc(1 - var(--tw-divide-y-reverse)));border-bottom-width:calc(1px * var(--tw-divide-y-reverse));--tw-divide-opacity: 1;border-color:rgb(161 161 170 / var(--tw-divide-opacity, 1))}.content{--tw-shadow: 0 4px 8px 0 rgba(0,0,0,.2),0 6px 20px 0 rgba(0,0,0,.19);--tw-shadow-colored: 0 4px 8px 0 var(--tw-shadow-color), 0 6px 20px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.content .login{position:relative;z-index:10;margin-top:5rem;border-top-left-radius:.5rem;border-top-right-radius:.5rem;background-color:#fff9;padding:5rem 1.5rem 1.5rem;--tw-backdrop-blur: blur(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)}.content .login .logo-container{margin-top:-10rem;margin-left:auto;margin-right:auto;margin-bottom:1rem;width:fit-content;border-radius:1.5rem;padding:.5rem;--tw-bg-opacity: 1;background-color:rgb(255 255 255 / var(--tw-bg-opacity, 1));--tw-shadow: 0 4px 8px 0 rgba(0,0,0,.2),0 6px 20px 0 rgba(0,0,0,.19);--tw-shadow-colored: 0 4px 8px 0 var(--tw-shadow-color), 0 6px 20px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.content .login .logo-container .logo{width:fit-content;border-radius:1.5rem;padding:.5rem;border-width:2px;--tw-border-opacity: 1;border-color:rgb(252 211 77 / var(--tw-border-opacity, 1))}.content .login .logo-container .logo img{height:10rem;min-width:fit-content}.content .login .title{padding-bottom:1.25rem;text-align:center;font-size:1.875rem;line-height:2.25rem;font-weight:700}.content .login form>.validations{text-align:center;font-weight:700;--tw-text-opacity: 1;color:rgb(239 68 68 / var(--tw-text-opacity, 1))}.content .login form>.validations:after{margin-left:auto;margin-right:auto;margin-bottom:.5rem;display:block;border-bottom-width:1px;--tw-border-opacity: 1;border-color:rgb(239 68 68 / var(--tw-border-opacity, 1));--tw-content: \"\";content:var(--tw-content);animation:separator 1s ease-in-out forwards}.content .login form .options{margin-bottom:.75rem;display:flex;flex-direction:row;flex-wrap:wrap-reverse;justify-content:space-between}.content .login form .options shared-language-selector{margin-bottom:.75rem;width:100%}@media (min-width: 640px){.content .login form .options shared-language-selector{margin-bottom:0;width:auto}}.content .login form .buttons{display:flex;justify-content:center;gap:1rem}.content .footer{border-bottom-right-radius:.5rem;border-bottom-left-radius:.5rem;padding:.125rem .5rem;background-color:#e2e8f099;--tw-backdrop-blur: blur(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:.875rem;line-height:1.25rem;font-weight:600;letter-spacing:-.025em;display:flex;flex-wrap:wrap;justify-content:space-between}@keyframes separator{0%{width:0}to{width:100%}}\n"], dependencies: [{ kind: "component", type: LanguageSelectorComponent, selector: "shared-language-selector", inputs: ["showFlag", "title"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: RouterModule }, { kind: "pipe", type: TranslatePipe, name: "translate" }] });
884
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.1.6", type: LoginComponent, isStandalone: true, selector: "shared-login", viewQueries: [{ propertyName: "username", first: true, predicate: ["username"], descendants: true }], ngImport: i0, 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\n <div class=\"validations\" [class.hidden]=\"!formState.error\">\n \n <div *ngIf=\"formState.error === 'invalid'\">\n {{'Login-Errors-Invalid' | translate}}\n </div>\n \n <div *ngIf=\"formState.error === 'internalServerError'\">{{'Login-Errors-InternalServerError' | translate}}</div>\n </div>\n\n <div class=\"input-group inline\">\n <input type=\"text\" #username id=\"username\" formControlName=\"username\" class=\"form-input peer\" [placeholder]=\"'Login-Username' | translate\" />\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 <span *ngIf=\"form.get('username')?.hasError('required')\">{{ 'Login-Username-Required' | translate }}</span>\n </div>\n </div>\n \n <div class=\"input-group inline\">\n <input type=\"password\" id=\"password\" formControlName=\"password\" class=\"form-input\" [placeholder]=\"'Login-Password' | translate\" />\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 <span *ngIf=\"form.get('password')?.hasError('required')\">{{ 'Login-Password-Required' | translate }}</span>\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 type=\"submit\" class=\"btn\"\n [class.loading]=\"formState.loading && !formState.success && !formState.error\"\n [class.error]=\"formState.error\"\n [class.success]=\"formState.success\">\n <i *ngIf=\"!formState.loading\" class=\"fas fa-sign-in-alt fa-fw\"></i>\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>", styles: [":host{display:block}.content{margin-left:auto;margin-right:auto;width:83.333333%;border-radius:.5rem}@media (min-width: 768px){.content{width:66.666667%}}@media (min-width: 1280px){.content{width:41.666667%}}.content>:not([hidden])~:not([hidden]){--tw-divide-y-reverse: 0;border-top-width:calc(1px * calc(1 - var(--tw-divide-y-reverse)));border-bottom-width:calc(1px * var(--tw-divide-y-reverse));--tw-divide-opacity: 1;border-color:rgb(161 161 170 / var(--tw-divide-opacity, 1))}.content{--tw-shadow: 0 4px 8px 0 rgba(0,0,0,.2),0 6px 20px 0 rgba(0,0,0,.19);--tw-shadow-colored: 0 4px 8px 0 var(--tw-shadow-color), 0 6px 20px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.content .login{position:relative;z-index:10;margin-top:5rem;border-top-left-radius:.5rem;border-top-right-radius:.5rem;background-color:#fff9;padding:5rem 1.5rem 1.5rem;--tw-backdrop-blur: blur(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)}.content .login .logo-container{margin-top:-10rem;margin-left:auto;margin-right:auto;margin-bottom:1rem;width:fit-content;border-radius:1.5rem;padding:.5rem;--tw-bg-opacity: 1;background-color:rgb(255 255 255 / var(--tw-bg-opacity, 1));--tw-shadow: 0 4px 8px 0 rgba(0,0,0,.2),0 6px 20px 0 rgba(0,0,0,.19);--tw-shadow-colored: 0 4px 8px 0 var(--tw-shadow-color), 0 6px 20px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.content .login .logo-container .logo{width:fit-content;border-radius:1.5rem;padding:.5rem;border-width:2px;--tw-border-opacity: 1;border-color:rgb(252 211 77 / var(--tw-border-opacity, 1))}.content .login .logo-container .logo img{height:10rem;min-width:fit-content}.content .login .title{padding-bottom:1.25rem;text-align:center;font-size:1.875rem;line-height:2.25rem;font-weight:700}.content .login form>.validations{text-align:center;font-weight:700;--tw-text-opacity: 1;color:rgb(239 68 68 / var(--tw-text-opacity, 1))}.content .login form>.validations:after{margin-left:auto;margin-right:auto;margin-bottom:.5rem;display:block;border-bottom-width:1px;--tw-border-opacity: 1;border-color:rgb(239 68 68 / var(--tw-border-opacity, 1));--tw-content: \"\";content:var(--tw-content);animation:separator 1s ease-in-out forwards}.content .login form .options{margin-bottom:.75rem;display:flex;flex-direction:row;flex-wrap:wrap-reverse;justify-content:space-between}.content .login form .options shared-language-selector{margin-bottom:.75rem;width:100%}@media (min-width: 640px){.content .login form .options shared-language-selector{margin-bottom:0;width:auto}}.content .login form .buttons{display:flex;justify-content:center;gap:1rem}.content .footer{border-bottom-right-radius:.5rem;border-bottom-left-radius:.5rem;padding:.125rem .5rem;background-color:#e2e8f099;--tw-backdrop-blur: blur(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:.875rem;line-height:1.25rem;font-weight:600;letter-spacing:-.025em;display:flex;flex-wrap:wrap;justify-content:space-between}@keyframes separator{0%{width:0}to{width:100%}}\n"], dependencies: [{ kind: "component", type: LanguageSelectorComponent, selector: "shared-language-selector", inputs: ["showFlag", "title"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: RouterModule }, { kind: "pipe", type: TranslatePipe, name: "translate" }] });
885
885
  }
886
886
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.6", ngImport: i0, type: LoginComponent, decorators: [{
887
887
  type: Component,
@@ -891,7 +891,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.6", ngImpor
891
891
  ReactiveFormsModule,
892
892
  RouterModule,
893
893
  TranslatePipe,
894
- ], 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\n <div class=\"validations\" [class.hidden]=\"!formState.error\">\n \n <div *ngIf=\"formState.error === 'invalid'\">\n {{'Login-Errors-Invalid' | translate}}\n </div>\n \n <div *ngIf=\"formState.error === 'internalServerError'\">{{'Login-Errors-InternalServerError' | translate}}</div>\n </div>\n\n <div class=\"input-group inline\">\n <input type=\"text\" #username id=\"username\" formControlName=\"username\" class=\"form-input peer\" [placeholder]=\"'Login-Username' | translate\" autofocus />\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 <span *ngIf=\"form.get('username')?.hasError('required')\">{{ 'Login-Username-Required' | translate }}</span>\n </div>\n </div>\n \n <div class=\"input-group inline\">\n <input type=\"password\" id=\"password\" formControlName=\"password\" class=\"form-input\" [placeholder]=\"'Login-Password' | translate\" />\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 <span *ngIf=\"form.get('password')?.hasError('required')\">{{ 'Login-Password-Required' | translate }}</span>\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 type=\"submit\" class=\"btn\"\n [class.loading]=\"formState.loading && !formState.success && !formState.error\"\n [class.error]=\"formState.error\"\n [class.success]=\"formState.success\">\n <i *ngIf=\"!formState.loading\" class=\"fas fa-sign-in-alt fa-fw\"></i>\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>", styles: [":host{display:block}.content{margin-left:auto;margin-right:auto;width:83.333333%;border-radius:.5rem}@media (min-width: 768px){.content{width:66.666667%}}@media (min-width: 1280px){.content{width:41.666667%}}.content>:not([hidden])~:not([hidden]){--tw-divide-y-reverse: 0;border-top-width:calc(1px * calc(1 - var(--tw-divide-y-reverse)));border-bottom-width:calc(1px * var(--tw-divide-y-reverse));--tw-divide-opacity: 1;border-color:rgb(161 161 170 / var(--tw-divide-opacity, 1))}.content{--tw-shadow: 0 4px 8px 0 rgba(0,0,0,.2),0 6px 20px 0 rgba(0,0,0,.19);--tw-shadow-colored: 0 4px 8px 0 var(--tw-shadow-color), 0 6px 20px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.content .login{position:relative;z-index:10;margin-top:5rem;border-top-left-radius:.5rem;border-top-right-radius:.5rem;background-color:#fff9;padding:5rem 1.5rem 1.5rem;--tw-backdrop-blur: blur(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)}.content .login .logo-container{margin-top:-10rem;margin-left:auto;margin-right:auto;margin-bottom:1rem;width:fit-content;border-radius:1.5rem;padding:.5rem;--tw-bg-opacity: 1;background-color:rgb(255 255 255 / var(--tw-bg-opacity, 1));--tw-shadow: 0 4px 8px 0 rgba(0,0,0,.2),0 6px 20px 0 rgba(0,0,0,.19);--tw-shadow-colored: 0 4px 8px 0 var(--tw-shadow-color), 0 6px 20px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.content .login .logo-container .logo{width:fit-content;border-radius:1.5rem;padding:.5rem;border-width:2px;--tw-border-opacity: 1;border-color:rgb(252 211 77 / var(--tw-border-opacity, 1))}.content .login .logo-container .logo img{height:10rem;min-width:fit-content}.content .login .title{padding-bottom:1.25rem;text-align:center;font-size:1.875rem;line-height:2.25rem;font-weight:700}.content .login form>.validations{text-align:center;font-weight:700;--tw-text-opacity: 1;color:rgb(239 68 68 / var(--tw-text-opacity, 1))}.content .login form>.validations:after{margin-left:auto;margin-right:auto;margin-bottom:.5rem;display:block;border-bottom-width:1px;--tw-border-opacity: 1;border-color:rgb(239 68 68 / var(--tw-border-opacity, 1));--tw-content: \"\";content:var(--tw-content);animation:separator 1s ease-in-out forwards}.content .login form .options{margin-bottom:.75rem;display:flex;flex-direction:row;flex-wrap:wrap-reverse;justify-content:space-between}.content .login form .options shared-language-selector{margin-bottom:.75rem;width:100%}@media (min-width: 640px){.content .login form .options shared-language-selector{margin-bottom:0;width:auto}}.content .login form .buttons{display:flex;justify-content:center;gap:1rem}.content .footer{border-bottom-right-radius:.5rem;border-bottom-left-radius:.5rem;padding:.125rem .5rem;background-color:#e2e8f099;--tw-backdrop-blur: blur(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:.875rem;line-height:1.25rem;font-weight:600;letter-spacing:-.025em;display:flex;flex-wrap:wrap;justify-content:space-between}@keyframes separator{0%{width:0}to{width:100%}}\n"] }]
894
+ ], 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\n <div class=\"validations\" [class.hidden]=\"!formState.error\">\n \n <div *ngIf=\"formState.error === 'invalid'\">\n {{'Login-Errors-Invalid' | translate}}\n </div>\n \n <div *ngIf=\"formState.error === 'internalServerError'\">{{'Login-Errors-InternalServerError' | translate}}</div>\n </div>\n\n <div class=\"input-group inline\">\n <input type=\"text\" #username id=\"username\" formControlName=\"username\" class=\"form-input peer\" [placeholder]=\"'Login-Username' | translate\" />\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 <span *ngIf=\"form.get('username')?.hasError('required')\">{{ 'Login-Username-Required' | translate }}</span>\n </div>\n </div>\n \n <div class=\"input-group inline\">\n <input type=\"password\" id=\"password\" formControlName=\"password\" class=\"form-input\" [placeholder]=\"'Login-Password' | translate\" />\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 <span *ngIf=\"form.get('password')?.hasError('required')\">{{ 'Login-Password-Required' | translate }}</span>\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 type=\"submit\" class=\"btn\"\n [class.loading]=\"formState.loading && !formState.success && !formState.error\"\n [class.error]=\"formState.error\"\n [class.success]=\"formState.success\">\n <i *ngIf=\"!formState.loading\" class=\"fas fa-sign-in-alt fa-fw\"></i>\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>", styles: [":host{display:block}.content{margin-left:auto;margin-right:auto;width:83.333333%;border-radius:.5rem}@media (min-width: 768px){.content{width:66.666667%}}@media (min-width: 1280px){.content{width:41.666667%}}.content>:not([hidden])~:not([hidden]){--tw-divide-y-reverse: 0;border-top-width:calc(1px * calc(1 - var(--tw-divide-y-reverse)));border-bottom-width:calc(1px * var(--tw-divide-y-reverse));--tw-divide-opacity: 1;border-color:rgb(161 161 170 / var(--tw-divide-opacity, 1))}.content{--tw-shadow: 0 4px 8px 0 rgba(0,0,0,.2),0 6px 20px 0 rgba(0,0,0,.19);--tw-shadow-colored: 0 4px 8px 0 var(--tw-shadow-color), 0 6px 20px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.content .login{position:relative;z-index:10;margin-top:5rem;border-top-left-radius:.5rem;border-top-right-radius:.5rem;background-color:#fff9;padding:5rem 1.5rem 1.5rem;--tw-backdrop-blur: blur(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)}.content .login .logo-container{margin-top:-10rem;margin-left:auto;margin-right:auto;margin-bottom:1rem;width:fit-content;border-radius:1.5rem;padding:.5rem;--tw-bg-opacity: 1;background-color:rgb(255 255 255 / var(--tw-bg-opacity, 1));--tw-shadow: 0 4px 8px 0 rgba(0,0,0,.2),0 6px 20px 0 rgba(0,0,0,.19);--tw-shadow-colored: 0 4px 8px 0 var(--tw-shadow-color), 0 6px 20px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.content .login .logo-container .logo{width:fit-content;border-radius:1.5rem;padding:.5rem;border-width:2px;--tw-border-opacity: 1;border-color:rgb(252 211 77 / var(--tw-border-opacity, 1))}.content .login .logo-container .logo img{height:10rem;min-width:fit-content}.content .login .title{padding-bottom:1.25rem;text-align:center;font-size:1.875rem;line-height:2.25rem;font-weight:700}.content .login form>.validations{text-align:center;font-weight:700;--tw-text-opacity: 1;color:rgb(239 68 68 / var(--tw-text-opacity, 1))}.content .login form>.validations:after{margin-left:auto;margin-right:auto;margin-bottom:.5rem;display:block;border-bottom-width:1px;--tw-border-opacity: 1;border-color:rgb(239 68 68 / var(--tw-border-opacity, 1));--tw-content: \"\";content:var(--tw-content);animation:separator 1s ease-in-out forwards}.content .login form .options{margin-bottom:.75rem;display:flex;flex-direction:row;flex-wrap:wrap-reverse;justify-content:space-between}.content .login form .options shared-language-selector{margin-bottom:.75rem;width:100%}@media (min-width: 640px){.content .login form .options shared-language-selector{margin-bottom:0;width:auto}}.content .login form .buttons{display:flex;justify-content:center;gap:1rem}.content .footer{border-bottom-right-radius:.5rem;border-bottom-left-radius:.5rem;padding:.125rem .5rem;background-color:#e2e8f099;--tw-backdrop-blur: blur(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:.875rem;line-height:1.25rem;font-weight:600;letter-spacing:-.025em;display:flex;flex-wrap:wrap;justify-content:space-between}@keyframes separator{0%{width:0}to{width:100%}}\n"] }]
895
895
  }], propDecorators: { username: [{
896
896
  type: ViewChild,
897
897
  args: ['username']
@@ -1 +1 @@
1
- {"version":3,"file":"zambon-dev-shared.mjs","sources":["../../../../libs/shared/src/lib/layouts/login-layout/login-layout.component.ts","../../../../libs/shared/src/lib/layouts/login-layout/login-layout.component.html","../../../../libs/shared/src/lib/models/external-content.ts","../../../../libs/shared/src/lib/services/authentication.service.ts","../../../../libs/shared/src/lib/services/external-content.service.ts","../../../../libs/shared/src/lib/services/external-url-resolver.service.ts","../../../../libs/shared/src/lib/services/notifications.service.ts","../../../../libs/shared/src/lib/services/operations-history.service.ts","../../../../libs/shared/src/lib/services/services-history.service.ts","../../../../libs/shared/src/lib/layouts/top-bar/brand/brand.component.ts","../../../../libs/shared/src/lib/layouts/top-bar/brand/brand.component.html","../../../../libs/shared/src/lib/layouts/top-bar/environment-badge/environment-badge.component.ts","../../../../libs/shared/src/lib/layouts/top-bar/environment-badge/environment-badge.component.html","../../../../libs/shared/src/lib/layouts/top-bar/notifications/notifications.component.ts","../../../../libs/shared/src/lib/layouts/top-bar/notifications/notifications.component.html","../../../../libs/shared/src/lib/auth/components/language-selector/language-selector.component.ts","../../../../libs/shared/src/lib/auth/components/language-selector/language-selector.component.html","../../../../libs/shared/src/lib/layouts/top-bar/user-profile/user-profile.component.ts","../../../../libs/shared/src/lib/layouts/top-bar/user-profile/user-profile.component.html","../../../../libs/shared/src/lib/layouts/top-bar/top-bar.component.ts","../../../../libs/shared/src/lib/layouts/top-bar/top-bar.component.html","../../../../libs/shared/src/lib/layouts/main-layout/main-layout.component.ts","../../../../libs/shared/src/lib/layouts/main-layout/main-layout.component.html","../../../../libs/shared/src/lib/auth/components/login/login.component.ts","../../../../libs/shared/src/lib/auth/components/login/login.component.html","../../../../libs/shared/src/lib/auth/auth.module.ts","../../../../libs/shared/src/lib/auth/guards/auth-guard.ts","../../../../libs/shared/src/lib/auth/interceptors/auth-interceptors.ts","../../../../libs/shared/src/lib/components/filters-base.ts","../../../../libs/shared/src/lib/features/external-content/external-content.component.ts","../../../../libs/shared/src/lib/features/external-content/external-content.component.html","../../../../libs/shared/src/lib/features/external-content/external-content.routes.ts","../../../../libs/shared/src/lib/datasets/operations-history.dataset.ts","../../../../libs/shared/src/lib/datasets/services-history.dataset.ts","../../../../libs/shared/src/lib/features/operations-history/operations-history-modal/operations-history-modal.component.ts","../../../../libs/shared/src/lib/features/operations-history/operations-history-modal/operations-history-modal.component.html","../../../../libs/shared/src/lib/features/operations-history/operations-history-child-list/operations-history-child-list.component.ts","../../../../libs/shared/src/lib/features/operations-history/operations-history-child-list/operations-history-child-list.component.html","../../../../libs/shared/src/lib/pipes/bypass-html-sanitizer.pipe.ts","../../../../libs/shared/src/lib/pipes/enum-text.pipe.ts","../../../../libs/shared/src/lib/pipes/utc-date.pipe.ts","../../../../libs/shared/src/lib/features/services-history/services-history-child-list/services-history-child-list.component.ts","../../../../libs/shared/src/lib/features/services-history/services-history-child-list/services-history-child-list.component.html","../../../../libs/shared/src/lib/features/services-history/services-history-view/services-history-view.component.ts","../../../../libs/shared/src/lib/features/services-history/services-history-view/services-history-view.component.html","../../../../libs/shared/src/lib/i18n/shared-i18n.ts","../../../../libs/shared/src/zambon-dev-shared.ts"],"sourcesContent":["import { Component } from '@angular/core';\nimport { RouterModule } from '@angular/router';\n\n@Component({\n selector: 'shared-login-layout',\n templateUrl: './login-layout.component.html',\n styleUrls: ['./login-layout.component.scss'],\n imports: [\n RouterModule,\n ]\n})\nexport class LoginLayoutComponent {\n //#region ViewChilds, Inputs, Outputs\n //#endregion\n\n //#region Variables\n //#endregion\n\n //#region Properties\n //#endregion\n\n //#region Constructor and Angular life cycle methods\n //#endregion\n\n //#region Event handlers\n //#endregion\n\n //#region Public methods\n //#endregion\n\n //#region Private methods\n //#endregion\n}","<div class=\"background\"></div>\n\n<div class=\"container\">\n <router-outlet></router-outlet>\n</div>","import { InjectionToken } from '@angular/core';\n\n/** First segment of the route that hosts embedded external content. */\nexport const EXTERNAL_CONTENT_ROUTE_PATH: string = 'external-content';\n\n/**\n * Flat projection of an external menu item, used to restore an embedded tab.\n *\n * Deliberately not a `SidebarMenu`: that class carries a `parent` back-reference, so it is a\n * circular structure that `JSON.stringify` refuses, and holding one would pin the whole menu tree.\n */\nexport interface IExternalContentEntry {\n id: number;\n label: string;\n url: string;\n}\n\nexport class ExternalContentConfigs {\n /**\n * Origins an embedded menu item may point at, for example `['https://reports.example.com']`.\n * Empty — the default — allows any `http`/`https` origin.\n *\n * Populating it is the single highest-value control here after the scheme check: it narrows a\n * compromised menu row from \"frame anything on the internet\" to \"frame one of our report hosts\".\n */\n public allowedOrigins: string[] = [];\n\n /** Milliseconds to wait for the frame's first `load` before hinting that framing may be refused. */\n public slowFrameHintDelay: number = 5000;\n\n constructor(options: Partial<ExternalContentConfigs> = {}) {\n Object.assign(this, options);\n }\n}\n\nexport const EXTERNAL_CONTENT_CONFIGS: InjectionToken<ExternalContentConfigs> = new InjectionToken<ExternalContentConfigs>('Embedded external content configuration', {\n providedIn: 'root',\n factory: () => new ExternalContentConfigs(),\n});\n","import { HttpClient, HttpErrorResponse } from '@angular/common/http';\nimport { inject, Injectable } from '@angular/core';\nimport { JwtHelperService } from '@auth0/angular-jwt';\nimport { APP_CONFIG, AppConfig, AuthService, TabService } from '@zambon-dev/framework';\nimport { Observable, catchError, interval, map, mergeMap, tap } from 'rxjs';\nimport { IAuthResponse, ICurrentUserInfo } from '../models';\n\n@Injectable({\n providedIn: 'root'\n})\nexport class AuthenticationService extends AuthService {\n //#region ViewChilds, Inputs, Outputs\n //#endregion\n\n //#region Variables\n public adminAction: string = 'AdministrativeMaster';\n\n private config: AppConfig = inject(APP_CONFIG);\n\n private readonly BASE_URL: string = `${this.config.BASE_URL}/Authentication`;\n private http: HttpClient = inject(HttpClient);\n //#endregion\n\n //#region Properties\n //#endregion\n\n //#region Constructor and Angular life cycle methods\n constructor() {\n super(inject(JwtHelperService), inject(TabService));\n }\n //#endregion\n\n //#region Event handlers\n //#endregion\n\n //#region Public methods\n public authenticate(model: { username: string, password: string, rememberMe: boolean }): Observable<void> {\n return this.http\n .post<IAuthResponse>(`${this.BASE_URL}/SignIn`, model)\n .pipe(\n map((res: IAuthResponse) => {\n this.setStorage('username', res.username, model.rememberMe);\n this.setStorage('token', res.token, model.rememberMe);\n this.setStorage('refreshToken', res.refreshToken, model.rememberMe);\n this.setStorage('userInfo', window.btoa(JSON.stringify(res as ICurrentUserInfo)), model.rememberMe);\n }),\n catchError((error: HttpErrorResponse) =>\n interval(1000)\n .pipe(\n mergeMap(() => {\n switch(error.status) {\n case 401:\n throw 'InvalidUsernamePassword';\n default:\n throw 'InternalServerError';\n }\n })\n )\n )\n );\n }\n\n public getActions(): Observable<string[]> {\n return this.http.post<string[]>(`${this.BASE_URL}/GetActions`, {});\n }\n\n public getUserInfo(): ICurrentUserInfo | null {\n const userInfo: string | null = this.userInfo;\n if (userInfo) {\n return JSON.parse(window.atob(userInfo)) as ICurrentUserInfo;\n }\n return null;\n }\n\n public tryRefreshToken(): Observable<string> {\n return this.http\n .post<IAuthResponse>(`${this.BASE_URL}/RefreshToken`, {\n username: this.username ?? '',\n refreshToken: this.refreshToken ?? ''\n })\n .pipe(\n tap((res: IAuthResponse) => {\n this.setStorage('token', res.token);\n this.setStorage('refreshToken', res.refreshToken);\n this.setStorage('userInfo', window.btoa(JSON.stringify(res as ICurrentUserInfo)));\n }),\n map((res: IAuthResponse) => res.token ?? '')\n );\n }\n //#endregion\n\n //#region Private methods\n //#endregion\n}","import { inject, Injectable } from '@angular/core';\nimport { SidebarMenu, SidebarService } from '@zambon-dev/library';\nimport { catchError, map, Observable, of, take } from 'rxjs';\nimport { EXTERNAL_CONTENT_ROUTE_PATH, IExternalContentEntry } from '../models';\n\n/**\n * Remembers which external destination sits behind an embedded tab's `/external-content/:menuID`\n * route, and resolves it back when the view is created.\n *\n * The destination never travels in the route, so the id has to be resolved to a URL somehow. That\n * happens in three steps, cheapest first:\n *\n * 1. the in-memory registry — the item was clicked in this browsing session;\n * 2. `sessionStorage` — the user pressed F5 on the embedded tab;\n * 3. the application's `SidebarService.getMenuFromUrl()` — a cold deep link.\n *\n * Step 3 reuses the abstract hook every application already implements, so nothing new is required\n * of a consumer: an application whose menu endpoint cannot resolve `/external-content/:id` simply\n * gets the unavailable state on a cold deep link, which is the documented behaviour.\n */\n@Injectable({\n providedIn: 'root'\n})\nexport class ExternalContentService {\n //#region Variables\n private readonly maxEntries: number = 20;\n private readonly storageKey: string = 'zambon.externalContent';\n\n private registry: Map<number, IExternalContentEntry> = new Map<number, IExternalContentEntry>();\n private sidebarService: SidebarService = inject(SidebarService);\n //#endregion\n\n //#region Properties\n //#endregion\n\n //#region Constructor and Angular life cycle methods\n //#endregion\n\n //#region Public methods\n /** Resolves the destination behind an embedded tab, or `undefined` when it cannot be recovered. */\n public find(menuID: number): Observable<IExternalContentEntry | undefined> {\n const known: IExternalContentEntry | undefined = this.registry.get(menuID) ?? this.readFromStorage(menuID);\n\n if (!!known) {\n return of(known);\n }\n\n return this.sidebarService.getMenuFromUrl(`/${EXTERNAL_CONTENT_ROUTE_PATH}/${menuID}`)\n .pipe(\n take(1),\n map((menu: SidebarMenu) => !!menu && !!menu.url ? this.toEntry(menu) : undefined),\n // A menu endpoint that does not know this route shape answers 404, which is an expected\n // outcome here rather than a failure: the view falls back to its unavailable state.\n catchError(() => of(undefined)),\n );\n }\n\n /** Remembers a menu so its embedded tab survives a page refresh. */\n public register(menu: SidebarMenu): void {\n const entry: IExternalContentEntry = this.toEntry(menu);\n\n this.registry.set(entry.id, entry);\n this.writeToStorage(entry);\n }\n //#endregion\n\n //#region Private methods\n private readAllFromStorage(): IExternalContentEntry[] {\n try {\n const raw: string | null = window.sessionStorage.getItem(this.storageKey);\n\n if (!raw) {\n return [];\n }\n\n const parsed: unknown = JSON.parse(raw);\n\n return Array.isArray(parsed) ? <IExternalContentEntry[]>parsed : [];\n } catch {\n // A poisoned or unavailable storage entry must never take the application down; the view\n // degrades to asking the user to reopen the item from the menu.\n return [];\n }\n }\n\n private readFromStorage(menuID: number): IExternalContentEntry | undefined {\n const entry: IExternalContentEntry | undefined = this.readAllFromStorage()\n .find((candidate: IExternalContentEntry) => candidate?.id === menuID);\n\n if (!!entry && !!entry.url) {\n this.registry.set(entry.id, entry);\n return entry;\n }\n\n return undefined;\n }\n\n private toEntry(menu: SidebarMenu): IExternalContentEntry {\n return {\n id: menu.id,\n label: menu.label,\n url: menu.url ?? '',\n };\n }\n\n private writeToStorage(entry: IExternalContentEntry): void {\n try {\n const entries: IExternalContentEntry[] = [\n entry,\n ...this.readAllFromStorage().filter((candidate: IExternalContentEntry) => candidate?.id !== entry.id),\n ].slice(0, this.maxEntries);\n\n window.sessionStorage.setItem(this.storageKey, JSON.stringify(entries));\n } catch {\n // Storage can be unavailable (private mode, blocked site data). Losing refresh support is\n // acceptable; failing the click is not.\n }\n }\n //#endregion\n}\n","import { inject, Injectable } from '@angular/core';\nimport { TranslateService } from '@ngx-translate/core';\nimport { ICurrentUserInfo } from '../models';\nimport { AuthenticationService } from './authentication.service';\n\n/**\n * Resolves the runtime placeholders in an external menu URL, and vets the result before it is\n * handed to the browser.\n *\n * Placeholder syntax is `{name}`, case-sensitive, drawn from a **closed** set:\n *\n * | Token | Source |\n * |--------------|-----------------------------------------------------|\n * | `{email}` | `ICurrentUserInfo.email` |\n * | `{language}` | `TranslateService.currentLang`, then `defaultLang` |\n * | `{userId}` | `ICurrentUserInfo.userID` |\n * | `{userName}` | `ICurrentUserInfo.username` |\n *\n * The set is closed by construction rather than reflected off the stored user info, and that is a\n * security property, not a style choice: `AuthenticationService` persists the entire sign-in\n * response under `userInfo`, tokens included, so a reflective implementation would let a menu URL\n * configured as `?t={token}` hand the JWT to a third party. No authentication token is ever\n * substituted.\n */\n@Injectable({\n providedIn: 'root'\n})\nexport class ExternalUrlResolverService {\n //#region Variables\n private authenticationService: AuthenticationService = inject(AuthenticationService);\n private translate: TranslateService = inject(TranslateService);\n\n /** Placeholder grammar, used only to *detect* tokens this version does not know. */\n private readonly unknownPlaceholderPattern: RegExp = /\\{[A-Za-z][A-Za-z0-9_]*\\}/g;\n //#endregion\n\n //#region Properties\n //#endregion\n\n //#region Constructor and Angular life cycle methods\n //#endregion\n\n //#region Public methods\n /**\n * Whether `url` is an absolute `http`/`https` address.\n *\n * Rejects relative paths, malformed values, protocol-relative `//host/path` (which throws\n * without a base), and the schemes that would execute rather than navigate: `javascript:`,\n * `data:`, `blob:`, `file:`.\n */\n public isAllowed(url: string): boolean {\n let parsed: URL;\n\n try {\n parsed = new URL(url);\n } catch {\n return false;\n }\n\n return parsed.protocol === 'http:' || parsed.protocol === 'https:';\n }\n\n /**\n * Substitutes every known placeholder, URL-encoding each value.\n *\n * Because every value is percent-encoded, a placeholder must occupy one *whole* value — a full\n * path segment, or a full query-parameter value. Encoding is what stops a display name that\n * contains `&` from injecting an extra query parameter into the destination.\n *\n * A known placeholder with no value becomes an empty string; an unrecognized `{…}` is left\n * exactly as configured, so a report URL that legitimately contains braces is not corrupted.\n */\n public resolve(url: string): string {\n if (!url || url.indexOf('{') === -1) {\n return url;\n }\n\n const values: Map<string, string> = this.getPlaceholderValues();\n\n let resolved: string = url;\n\n values.forEach((value: string, token: string) => {\n if (resolved.indexOf(token) === -1) {\n return;\n }\n\n if (value.length === 0) {\n console.warn(`External URL placeholder ${token} has no value for the current user; substituting an empty string.`, url);\n }\n\n // split/join rather than String.replace: replace() interprets `$&` and `$1` in the\n // replacement text, and without a global regex it would only swap the first occurrence.\n resolved = resolved.split(token).join(encodeURIComponent(value));\n });\n\n this.warnAboutUnknownPlaceholders(url, resolved);\n\n return resolved;\n }\n //#endregion\n\n //#region Private methods\n private getPlaceholderValues(): Map<string, string> {\n const user: ICurrentUserInfo | null = this.authenticationService.getUserInfo();\n\n return new Map<string, string>([\n ['{email}', user?.email ?? ''],\n ['{language}', this.translate.currentLang || this.translate.defaultLang || ''],\n ['{userId}', user?.userID?.toString() ?? ''],\n ['{userName}', user?.username ?? ''],\n ]);\n }\n\n private warnAboutUnknownPlaceholders(url: string, resolved: string): void {\n const unknown: string[] = resolved.match(this.unknownPlaceholderPattern) ?? [];\n\n if (unknown.length > 0) {\n console.warn(`External URL contains unrecognized placeholders and was left as configured: ${unknown.join(', ')}`, url);\n }\n }\n //#endregion\n}\n","import { inject, Injectable } from '@angular/core';\nimport { HubConnection, HubConnectionBuilder, HubConnectionState } from '@microsoft/signalr';\nimport { APP_CONFIG, AppConfig, AuthService } from '@zambon-dev/framework';\nimport { BehaviorSubject, map, Observable } from 'rxjs';\nimport { INotification } from '../models';\n\n/**\n * Streams top-bar notifications from a SignalR hub.\n *\n * The hub is configured via `AppConfig.notificationsEnabled` and `AppConfig.notificationsUrl`.\n * When enabled, {@link start} opens a connection (authenticated with the current JWT) and\n * listens for the server to push the notification list via the `ReceiveNotifications` client\n * method. Consuming apps do not interact with this service directly — the top bar drives it.\n */\n@Injectable({\n providedIn: 'root',\n})\nexport class NotificationsService {\n //#region Variables\n private authService: AuthService = inject(AuthService);\n private config: AppConfig = inject(APP_CONFIG);\n\n private connection?: HubConnection;\n private notifications$: BehaviorSubject<INotification[]> = new BehaviorSubject<INotification[]>([]);\n //#endregion\n\n //#region Properties\n /** Whether the notifications feature is enabled (toggled on and given a hub URL). */\n public get isEnabled(): boolean {\n return this.config.notificationsEnabled && this.config.notificationsUrl.length > 0;\n }\n //#endregion\n\n //#region Public methods\n /** Emits the current list of notifications. */\n public getNotifications(): Observable<INotification[]> {\n return this.notifications$.asObservable();\n }\n\n /** Emits the number of unread notifications. */\n public getUnreadCount(): Observable<number> {\n return this.notifications$.pipe(\n map((notifications: INotification[]) => notifications.filter((n: INotification) => !n.isRead).length),\n );\n }\n\n /** Marks every notification as read and notifies the hub. */\n public markAllAsRead(): void {\n this.notifications$.next(this.notifications$.value.map((n: INotification) => ({ ...n, isRead: true })));\n\n if (this.connection?.state === HubConnectionState.Connected) {\n this.connection.invoke('MarkAllAsRead').catch((error: unknown) => {\n console.error('Failed to mark notifications as read on the hub.', error);\n });\n }\n }\n\n /** Marks a single notification as read (optimistically; the server reconciles on the next push). */\n public markAsRead(notification: INotification): void {\n this.notifications$.next(\n this.notifications$.value.map((n: INotification) => (n === notification ? { ...n, isRead: true } : n)),\n );\n }\n\n /** Opens the SignalR connection and starts receiving notifications. Idempotent and a no-op when disabled. */\n public start(): void {\n if (!this.isEnabled || !!this.connection) {\n return;\n }\n\n this.connection = new HubConnectionBuilder()\n .withUrl(this.config.notificationsUrl, {\n accessTokenFactory: () => this.authService.token ?? '',\n })\n .withAutomaticReconnect()\n .build();\n\n this.connection.on('ReceiveNotifications', (notifications: INotification[]) => {\n this.notifications$.next(notifications ?? []);\n });\n\n this.connection.start().catch((error: unknown) => {\n console.error('Failed to connect to the notifications hub.', error);\n });\n }\n\n /** Closes the SignalR connection. */\n public async stop(): Promise<void> {\n if (this.connection) {\n await this.connection.stop();\n this.connection = undefined;\n }\n }\n //#endregion\n}\n","import { HttpClient } from '@angular/common/http';\nimport { inject, Injectable } from '@angular/core';\nimport { APP_CONFIG, AppConfig } from '@zambon-dev/framework';\nimport { IListParameters } from '@zambon-dev/library';\nimport { Observable } from 'rxjs';\nimport { IOperationsHistoryList } from '../models';\n\n@Injectable({\n providedIn: 'root'\n})\nexport class OperationsHistoryService {\n //#region ViewChilds, Inputs, Outputs\n //#endregion\n\n //#region Variables\n private config: AppConfig = inject(APP_CONFIG);\n private http: HttpClient = inject(HttpClient);\n //#endregion\n\n //#region Properties\n //#endregion\n\n //#region Constructor and Angular life cycle methods\n //#endregion\n\n //#region Event handlers\n //#endregion\n\n //#region Public methods\n public list(controllerName: string, entityID: number, serviceHistoryID: number, parameters: IListParameters): Observable<IOperationsHistoryList[]> {\n return this.http.post<IOperationsHistoryList[]>(`${this.config.BASE_URL}/${controllerName}/${entityID}/Audit/${serviceHistoryID}`, parameters);\n }\n //#endregion\n\n //#region Private methods\n //#endregion\n}","import { HttpClient } from '@angular/common/http';\nimport { inject, Injectable } from '@angular/core';\nimport { APP_CONFIG, AppConfig } from '@zambon-dev/framework';\nimport { IListParameters } from '@zambon-dev/library';\nimport { Observable } from 'rxjs';\nimport { IServicesHistoryList } from '../models';\n\n@Injectable({\n providedIn: 'root'\n})\nexport class ServicesHistoryService {\n //#region ViewChilds, Inputs, Outputs\n //#endregion\n\n //#region Variables\n private config: AppConfig = inject(APP_CONFIG);\n private http: HttpClient = inject(HttpClient);\n //#endregion\n\n //#region Properties\n //#endregion\n\n //#region Constructor and Angular life cycle methods\n //#endregion\n\n //#region Event handlers\n //#endregion\n\n //#region Public methods\n public list(controllerName: string, entityID: number, parameters: IListParameters): Observable<IServicesHistoryList[]> {\n return this.http.post<IServicesHistoryList[]>(`${this.config.BASE_URL}/${controllerName}/${entityID}/Audit`, parameters);\n }\n //#endregion\n\n //#region Private methods\n //#endregion\n}","import { Component, inject } from '@angular/core';\nimport { APP_CONFIG, AppConfig } from '@zambon-dev/framework';\n\n@Component({\n selector: 'shared-brand',\n templateUrl: './brand.component.html',\n styleUrls: ['./brand.component.scss'],\n})\nexport class BrandComponent {\n //#region Variables\n private config: AppConfig = inject(APP_CONFIG);\n //#endregion\n\n //#region Properties\n protected get appName(): string {\n return this.config.appName;\n }\n\n protected get companyName(): string {\n return this.config.companyName;\n }\n\n protected get logoUrl(): string | undefined {\n return this.config.logoUrl;\n }\n //#endregion\n}\n","<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","import { Component, inject } from '@angular/core';\nimport { APP_CONFIG, AppConfig } from '@zambon-dev/framework';\n\n@Component({\n selector: 'shared-environment-badge',\n templateUrl: './environment-badge.component.html',\n styleUrls: ['./environment-badge.component.scss'],\n})\nexport class EnvironmentBadgeComponent {\n //#region Variables\n private config: AppConfig = inject(APP_CONFIG);\n //#endregion\n\n //#region Properties\n /** CSS modifier class for the current environment, falling back to a neutral style. */\n protected get badgeClass(): string {\n const colorByEnvironment: Record<string, string> = {\n DEV: 'env-dev',\n QA: 'env-qa',\n STG: 'env-stg',\n };\n return colorByEnvironment[this.environment] ?? 'env-neutral';\n }\n\n /** Normalized environment key (uppercase, trimmed). */\n protected get environment(): string {\n return (this.config.environment ?? '').trim().toUpperCase();\n }\n\n /** The badge is hidden in production and when no environment is configured. */\n protected get isVisible(): boolean {\n return this.environment.length > 0 && this.environment !== 'PROD';\n }\n //#endregion\n}\n","@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","import { AsyncPipe } from '@angular/common';\nimport { Component, ElementRef, HostListener, inject, OnInit, ViewChild } from '@angular/core';\nimport { Router } from '@angular/router';\nimport { TranslatePipe } from '@ngx-translate/core';\nimport { Observable } from 'rxjs';\nimport { INotification } from '../../../models';\nimport { NotificationsService } from '../../../services';\n\n@Component({\n selector: 'shared-notifications',\n templateUrl: './notifications.component.html',\n styleUrls: ['./notifications.component.scss'],\n imports: [\n AsyncPipe,\n TranslatePipe,\n ],\n})\nexport class NotificationsComponent implements OnInit {\n //#region ViewChilds, Inputs, Outputs\n @ViewChild('dropdown') public dropdown!: ElementRef<HTMLDivElement>;\n //#endregion\n\n //#region Variables\n private notificationsService: NotificationsService = inject(NotificationsService);\n private router: Router = inject(Router);\n\n protected notifications$: Observable<INotification[]> = this.notificationsService.getNotifications();\n protected showDropdown = false;\n protected unreadCount$: Observable<number> = this.notificationsService.getUnreadCount();\n //#endregion\n\n //#region Properties\n /** Whether the notifications feature is enabled; when false the bell is not rendered. */\n public get isEnabled(): boolean {\n return this.notificationsService.isEnabled;\n }\n //#endregion\n\n //#region Constructor and Angular life cycle methods\n public ngOnInit(): void {\n this.notificationsService.start();\n }\n //#endregion\n\n //#region Event handlers\n public onDropdownClick(): void {\n this.showDropdown = !this.showDropdown;\n }\n\n public onMarkAllAsRead(): void {\n this.notificationsService.markAllAsRead();\n }\n\n public onNotificationClick(notification: INotification): void {\n this.notificationsService.markAsRead(notification);\n this.showDropdown = false;\n\n const url: string | undefined = notification.callToActionUrl;\n if (!url) {\n return;\n }\n\n if (/^https?:\\/\\//i.test(url)) {\n window.open(url, '_blank', 'noopener');\n } else {\n this.router.navigateByUrl(url);\n }\n }\n //#endregion\n\n //#region Private methods\n @HostListener('window:click', ['$event'])\n private documentClick(event: MouseEvent): void {\n if (this.showDropdown) {\n let target: HTMLElement = <HTMLElement>event.target;\n while (target !== null && target.tagName?.toUpperCase() !== 'BODY') {\n if (target === this.dropdown.nativeElement) {\n return;\n }\n target = <HTMLElement>target.parentElement;\n }\n this.showDropdown = false;\n }\n }\n //#endregion\n}\n","@if (isEnabled) {\n <div #dropdown class=\"notifications\">\n <button class=\"btn gray-300 notifications-toggle\" type=\"button\" (click)=\"onDropdownClick()\"\n [attr.aria-label]=\"'TopBar-Notifications-Title' | translate\">\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 type=\"button\" class=\"notifications-item-btn\"\n [class.has-cta]=\"!!item.callToActionUrl\" (click)=\"onNotificationClick(item)\">\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","import { Component, ElementRef, HostListener, inject, Input, ViewChild } from '@angular/core';\nimport { TranslatePipe, TranslateService } from '@ngx-translate/core';\n\n@Component({\n selector: 'shared-language-selector',\n templateUrl: './language-selector.component.html',\n styleUrls: ['./language-selector.component.scss'],\n imports: [\n TranslatePipe,\n ]\n})\nexport class LanguageSelectorComponent {\n //#region ViewChilds, Inputs, Outputs\n @ViewChild('dropdown') public dropdown!: ElementRef<HTMLDivElement>;\n\n /** When true, the toggle shows the current language's flag (light-gray button) instead of text. */\n @Input() public showFlag = false;\n\n @Input() public title: string = 'LanguageSelector-Title';\n //#endregion\n\n //#region Variables\n private translate: TranslateService = inject(TranslateService);\n\n protected languages: string[] = this.translate.getLangs();\n protected showDropdown: boolean = false;\n //#endregion\n\n //#region Properties\n public get selectedLanguage(): string {\n return this.translate.currentLang;\n }\n //#endregion\n\n //#region Constructor and Angular life cycle methods\n //#endregion\n\n //#region Event handlers\n public onDropdownClick(): void {\n this.showDropdown = !this.showDropdown;\n }\n\n public onSelectLanguage(language: string): void {\n localStorage.setItem('language', language);\n this.translate.use(language);\n this.showDropdown = false;\n }\n //#endregion\n\n //#region Public methods\n //#endregion\n\n //#region Private methods\n @HostListener('window:click', ['$event'])\n private documentClick(event: MouseEvent): void {\n if (this.showDropdown) {\n let target: HTMLElement = <HTMLElement>event.target;\n while (target !== null && target.tagName?.toUpperCase() !== 'BODY') {\n if (target === this.dropdown.nativeElement) {\n return;\n }\n target = <HTMLElement>target.parentElement;\n }\n this.showDropdown = false;\n }\n }\n //#endregion\n}\n","<div #dropdown class=\"dropdown right\" [class.show]=\"showDropdown\">\n <button class=\"btn\" type=\"button\" (click)=\"onDropdownClick()\"\n [class.gray-300]=\"showFlag\" [class.lang-flag-toggle]=\"showFlag\"\n [attr.aria-label]=\"showFlag ? (title | translate) : null\">\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 type=\"button\" class=\"dropdown-item\" [class.selected]=\"lang === selectedLanguage\"\n (click)=\"onSelectLanguage(lang)\">\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","import { Component, inject, OnInit } from '@angular/core';\nimport { ICurrentUserInfo } from '../../../models';\nimport { AuthenticationService } from '../../../services';\n\n@Component({\n selector: 'shared-user-profile',\n templateUrl: './user-profile.component.html',\n styleUrls: ['./user-profile.component.scss'],\n})\nexport class UserProfileComponent implements OnInit {\n //#region Variables\n private authenticationService: AuthenticationService = inject(AuthenticationService);\n\n protected user: ICurrentUserInfo | null = null;\n //#endregion\n\n //#region Properties\n /** Up to two uppercase initials derived from the user's name, used when no picture is set. */\n protected get initials(): string {\n const parts: string[] = this.name.trim().split(/\\s+/).filter((p: string) => p.length > 0);\n if (parts.length === 0) {\n return '';\n }\n\n const first: string = parts[0].charAt(0);\n const last: string = parts.length > 1 ? parts[parts.length - 1].charAt(0) : '';\n return (first + last).toUpperCase();\n }\n\n protected get name(): string {\n return this.user?.name ?? '';\n }\n\n protected get pictureUrl(): string | undefined {\n return this.user?.pictureUrl;\n }\n\n protected get position(): string {\n return this.user?.position ?? '';\n }\n //#endregion\n\n //#region Constructor and Angular life cycle methods\n public ngOnInit(): void {\n this.user = this.authenticationService.getUserInfo();\n }\n //#endregion\n}\n","<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","import { Component, EventEmitter, Output } from '@angular/core';\nimport { TranslatePipe } from '@ngx-translate/core';\nimport { LanguageSelectorComponent } from '../../auth/components/language-selector/language-selector.component';\nimport { BrandComponent } from './brand/brand.component';\nimport { EnvironmentBadgeComponent } from './environment-badge/environment-badge.component';\nimport { NotificationsComponent } from './notifications/notifications.component';\nimport { UserProfileComponent } from './user-profile/user-profile.component';\n\n@Component({\n selector: 'shared-top-bar',\n templateUrl: './top-bar.component.html',\n styleUrls: ['./top-bar.component.scss'],\n imports: [\n BrandComponent,\n EnvironmentBadgeComponent,\n LanguageSelectorComponent,\n NotificationsComponent,\n TranslatePipe,\n UserProfileComponent,\n ],\n})\nexport class TopBarComponent {\n //#region ViewChilds, Inputs, Outputs\n /** Emitted when the logout button is clicked. */\n @Output() public logout: EventEmitter<void> = new EventEmitter<void>();\n //#endregion\n\n //#region Event handlers\n public onLogoutClick(): void {\n this.logout.emit();\n }\n //#endregion\n}\n","<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 class=\"btn gray-300 top-bar-logout\" type=\"button\" (click)=\"onLogoutClick()\"\n [attr.aria-label]=\"'Main-Logout' | translate\">\n <i class=\"fa-solid fa-arrow-right-from-bracket\"></i>\n </button>\n </div>\n</div>\n","import { Component, inject, OnDestroy, OnInit, ViewChild } from '@angular/core';\nimport { Router, RouterModule } from '@angular/router';\nimport { APP_CONFIG, ITab, Tab, TabsComponent, TabService } from '@zambon-dev/framework';\nimport { ModalComponent, SidebarComponent, SidebarMenu, SidebarMenuOpenMode, SidebarService, toSidebarMenuOpenMode } from '@zambon-dev/library';\nimport { TranslatePipe } from '@ngx-translate/core';\nimport { Subject, take, takeUntil } from 'rxjs';\nimport { EXTERNAL_CONTENT_ROUTE_PATH } from '../../models';\nimport { AuthenticationService, ExternalContentService, ExternalUrlResolverService } from '../../services';\nimport { TopBarComponent } from '../top-bar';\n\n@Component({\n selector: 'shared-main-layout',\n templateUrl: './main-layout.component.html',\n styleUrls: ['./main-layout.component.scss'],\n imports: [\n ModalComponent,\n RouterModule,\n SidebarComponent,\n TabsComponent,\n TopBarComponent,\n TranslatePipe,\n ]\n})\nexport class MainLayoutComponent implements OnInit, OnDestroy {\n //#region ViewChilds, Inputs, Outputs\n @ViewChild('logoutModal') private logoutModal!: ModalComponent;\n //#endregion\n\n //#region Variables\n private authenticationService: AuthenticationService = inject(AuthenticationService);\n private destroy$: Subject<boolean> = new Subject<boolean>();\n private externalContentService: ExternalContentService = inject(ExternalContentService);\n private externalUrlResolverService: ExternalUrlResolverService = inject(ExternalUrlResolverService);\n private router: Router = inject(Router);\n private sidebarService: SidebarService = inject(SidebarService);\n private tabService: TabService = inject(TabService);\n\n /** Application version (from AppConfig) projected into the sidebar footer. */\n protected appVersion: string = inject(APP_CONFIG).version;\n //#endregion\n\n //#region Properties\n //#endregion\n\n //#region Constructor and Angular life cycle methods\n\n public ngOnDestroy(): void {\n this.destroy$.next(true);\n this.destroy$.complete();\n }\n\n public ngOnInit(): void {\n const url: string = this.router.url;\n\n if (url !== '/' && !this.tabService.isUrlOpen(url)) {\n this.sidebarService.getMenuFromUrl(url)\n .pipe(take(1))\n .subscribe({\n next: (item: SidebarMenu) => {\n if (!!item) {\n this.tabService.updateTabTitle(url, item.label);\n }\n },\n // A deep-linked title is best-effort. Menu endpoints answer 404 for a URL they do not\n // know -- the embedded-content route among them -- and that must not surface as an\n // unhandled rejection.\n error: () => undefined,\n });\n }\n\n this.sidebarService.menuExternalUrlSelected\n .pipe(takeUntil(this.destroy$))\n .subscribe((item: SidebarMenu) => this.openExternalMenu(item));\n\n this.sidebarService.menuUrlSelected\n .pipe(takeUntil(this.destroy$))\n .subscribe((item: SidebarMenu) => {\n const tab: ITab = new Tab({\n title: item.label,\n url: item.url,\n });\n this.tabService.openTab(tab);\n });\n }\n //#endregion\n\n //#region Event handlers\n //#endregion\n\n //#region Public methods\n public onLogoutClick(): void {\n this.logoutModal.toggleModal();\n }\n\n public onLogoutConfirm(): void {\n this.authenticationService.signOut();\n this.router.navigate(['/login']);\n }\n //#endregion\n\n //#region Private methods\n private openExternalMenu(item: SidebarMenu): void {\n const rawUrl: string = item.url ?? '';\n\n if (rawUrl.length === 0) {\n return;\n }\n\n if (toSidebarMenuOpenMode(item.openMode) === SidebarMenuOpenMode.ExternalEmbedded) {\n // The tab has to be a real Angular route, so the destination travels by menu id and is\n // resolved by ExternalContentComponent. A `?url=` query string would collapse every\n // embedded tab into one -- TabService and CustomReuseStrategy key tabs on path segments\n // only -- and would also let anyone frame an arbitrary site inside our own chrome.\n this.externalContentService.register(item);\n\n const tab: ITab = new Tab({\n title: item.label,\n url: `/${EXTERNAL_CONTENT_ROUTE_PATH}/${item.id}`,\n });\n this.tabService.openTab(tab);\n\n return;\n }\n\n const url: string = this.externalUrlResolverService.resolve(rawUrl);\n\n if (!this.externalUrlResolverService.isAllowed(url)) {\n console.error(`Sidebar menu \"${item.label}\" points to an unsupported external address and was not opened.`, url);\n return;\n }\n\n window.open(url, '_blank', 'noopener,noreferrer');\n }\n //#endregion\n}","<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()\">{{ 'Main-Logout-Modal-Message-Confirm' | translate }}</button>\n </div>\n</lib-modal>","import { NgIf } from '@angular/common';\nimport { Component, ElementRef, inject, OnInit, ViewChild } from '@angular/core';\nimport { FormBuilder, FormGroup, ReactiveFormsModule, Validators } from '@angular/forms';\nimport { Router, RouterModule } from '@angular/router';\nimport { TranslatePipe } from '@ngx-translate/core';\nimport { finalize, tap } from 'rxjs';\nimport { AuthenticationService } from '../../../services';\nimport { LanguageSelectorComponent } from '../language-selector/language-selector.component';\n\n@Component({\n selector: 'shared-login',\n templateUrl: './login.component.html',\n styleUrls: ['./login.component.scss'],\n imports: [\n LanguageSelectorComponent,\n NgIf,\n ReactiveFormsModule,\n RouterModule,\n TranslatePipe,\n ]\n})\nexport class LoginComponent implements OnInit {\n //#region ViewChilds, Inputs, Outputs\n @ViewChild('username') public username!: ElementRef<HTMLInputElement>;\n //#endregion\n\n //#region Variables\n protected form!: FormGroup;\n protected formState: {\n error: string | null,\n loading: boolean,\n success: boolean,\n } = {\n error: null,\n loading: false,\n success: false\n };\n\n private authenticationService: AuthenticationService = inject(AuthenticationService);\n private formBuilder: FormBuilder = inject(FormBuilder);\n private router: Router = inject(Router);\n //#endregion\n\n //#region Properties\n //#endregion\n\n //#region Constructor and Angular life cycle methods\n\n public ngOnInit(): void {\n this.form = this.formBuilder.group({\n password: ['', Validators.required],\n rememberMe: [false, { nonNullable: true }],\n username: ['', Validators.required],\n });\n }\n //#endregion\n\n //#region Event handlers\n public onSubmit(): void {\n this.form.markAllAsTouched();\n\n if (this.form.valid) {\n this.form.disable();\n \n this.formState.loading = true;\n this.formState.error = null;\n\n this.authenticationService.authenticate({\n username: this.form.get('username')?.value.toString() ?? '',\n password: this.form.get('password')?.value.toString() ?? '',\n rememberMe: this.form.get('rememberMe')?.value ?? false\n })\n .pipe(\n tap(() => { \n this.formState.success = true\n }),\n finalize(() => this.formState.loading = false)\n )\n .subscribe({\n next: () => {\n const params: URLSearchParams = new URLSearchParams(window.location.search);\n \n this.router.navigate([params.get('returnUrl') ?? '/']);\n },\n error: (e: string) => {\n this.form.enable();\n\n this.form.controls['password'].setValue('');\n this.form.controls['password'].markAsUntouched();\n \n this.username.nativeElement.focus();\n\n switch(e) {\n case 'InvalidUsernamePassword':\n this.formState.error = 'invalid';\n break;\n default:\n this.formState.error = 'internalServerError';\n break;\n }\n }\n });\n }\n }\n //#endregion\n\n //#region Public methods\n //#endregion\n\n //#region Private methods\n //#endregion\n}","<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\n <div class=\"validations\" [class.hidden]=\"!formState.error\">\n \n <div *ngIf=\"formState.error === 'invalid'\">\n {{'Login-Errors-Invalid' | translate}}\n </div>\n \n <div *ngIf=\"formState.error === 'internalServerError'\">{{'Login-Errors-InternalServerError' | translate}}</div>\n </div>\n\n <div class=\"input-group inline\">\n <input type=\"text\" #username id=\"username\" formControlName=\"username\" class=\"form-input peer\" [placeholder]=\"'Login-Username' | translate\" autofocus />\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 <span *ngIf=\"form.get('username')?.hasError('required')\">{{ 'Login-Username-Required' | translate }}</span>\n </div>\n </div>\n \n <div class=\"input-group inline\">\n <input type=\"password\" id=\"password\" formControlName=\"password\" class=\"form-input\" [placeholder]=\"'Login-Password' | translate\" />\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 <span *ngIf=\"form.get('password')?.hasError('required')\">{{ 'Login-Password-Required' | translate }}</span>\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 type=\"submit\" class=\"btn\"\n [class.loading]=\"formState.loading && !formState.success && !formState.error\"\n [class.error]=\"formState.error\"\n [class.success]=\"formState.success\">\n <i *ngIf=\"!formState.loading\" class=\"fas fa-sign-in-alt fa-fw\"></i>\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>","import { NgModule } from '@angular/core';\nimport { RouterModule, Routes } from '@angular/router';\nimport { LoginLayoutComponent } from '../layouts';\nimport { LoginComponent } from './components';\n\n\nconst routes: Routes = [\n { path: '', component: LoginLayoutComponent, children: [\n { path: '', redirectTo: 'login', pathMatch: 'full' },\n { path: 'login', component: LoginComponent },\n ] },\n];\n\n@NgModule({\n imports: [\n RouterModule.forChild(routes),\n ]\n})\nexport class SharedAuthModule {}\n","import { inject, Injectable } from '@angular/core';\nimport { ActivatedRouteSnapshot, CanActivate, Router, RouterStateSnapshot } from '@angular/router';\nimport { AuthenticationService } from '../../services';\n\n@Injectable({\n providedIn: 'root'\n})\nexport class AuthGuard implements CanActivate {\n //#region ViewChilds, Inputs, Outputs\n //#endregion\n\n //#region Variables\n private authenticationService: AuthenticationService = inject(AuthenticationService);\n private router: Router = inject(Router);\n //#endregion\n\n //#region Properties\n //#endregion\n\n //#region Constructor and Angular life cycle methods\n //#endregion\n\n //#region Event handlers\n //#endregion\n\n //#region Public methods\n public canActivate(_: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {\n if (!this.authenticationService.isAuthenticated) {\n this.router.navigate(['/login'], { queryParams: { returnUrl: state.url } });\n return false;\n }\n return true;\n }\n //#endregion\n\n //#region Private methods\n //#endregion\n}","import { HttpErrorResponse, HttpEvent, HttpHandler, HttpInterceptor, HttpRequest } from '@angular/common/http';\nimport { inject, Injectable } from '@angular/core';\nimport { Router } from '@angular/router';\nimport { JwtInterceptor } from '@auth0/angular-jwt';\nimport { APP_CONFIG, AppConfig } from '@zambon-dev/framework';\nimport { catchError, Observable, shareReplay, switchMap, tap } from 'rxjs';\nimport { AuthenticationService } from '../../services';\n\n@Injectable()\nexport class AuthInterceptor implements HttpInterceptor {\n //#region ViewChilds, Inputs, Outputs\n //#endregion\n\n //#region Variables\n private authenticationService: AuthenticationService = inject(AuthenticationService);\n private config: AppConfig = inject(APP_CONFIG);\n private jwtInterceptor: JwtInterceptor = inject(JwtInterceptor);\n private refreshToken$?: Observable<string>;\n private router: Router = inject(Router);\n //#endregion\n\n //#region Properties\n //#endregion\n\n //#region Constructor and Angular life cycle methods\n //#endregion\n\n //#region Event handlers\n //#endregion\n\n //#region Public methods\n public intercept(request: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>> {\n if (\n request.url.indexOf(this.config.BASE_URL) >= 0 &&\n !this.jwtInterceptor.isDisallowedRoute(request) &&\n this.authenticationService.isTokenExpired\n ) {\n if (!this.refreshToken$) {\n this.refreshToken$ = this.authenticationService.tryRefreshToken()\n .pipe(\n shareReplay(),\n tap(() => {\n this.refreshToken$ = undefined;\n })\n );\n }\n\n return this.refreshToken$!\n .pipe(\n switchMap((token: string) => {\n return next.handle(\n request.clone({ setHeaders: { authorization: `Bearer ${token}` } })\n );\n }),\n catchError((err: HttpErrorResponse) => {\n if (err.status === 401) {\n this.authenticationService.signOut();\n this.router.navigate(['/login']);\n }\n throw err;\n })\n );\n }\n return next.handle(request);\n }\n //#endregion\n\n //#region Private methods\n //#endregion\n}","import { Component, inject, OnDestroy, OnInit, ViewChild } from '@angular/core';\nimport { FormBuilder, FormGroup } from '@angular/forms';\nimport { ButtonFiltersComponent } from '@zambon-dev/framework';\nimport { Subject } from 'rxjs';\n\n@Component({ template: '' })\nexport abstract class FiltersBase implements OnInit, OnDestroy {\n //#region ViewChilds, Inputs, Outputs\n @ViewChild(ButtonFiltersComponent) protected buttonFilters?: ButtonFiltersComponent;\n //#endregion\n\n //#region Variables\n protected destroy$: Subject<boolean> = new Subject<boolean>();\n protected filterForm!: FormGroup;\n protected formBuilder: FormBuilder = inject(FormBuilder);\n //#endregion\n\n //#region Properties\n //#endregion\n \n //#region Constructor and Angular life cycle methods\n\n public ngOnDestroy(): void {\n this.destroy$.next(true);\n this.destroy$.complete();\n }\n\n public ngOnInit(): void {\n this.filterForm = this.formSetup();\n }\n //#endregion\n\n //#region Event handlers\n //#endregion\n\n //#region Public methods\n public setFilters(filters: { [key: string ] : any }): void {\n this.filterForm.patchValue(filters);\n\n setTimeout(() => {\n if (this.buttonFilters) {\n this.buttonFilters.setFilters(filters);\n }\n });\n }\n //#endregion\n\n //#region Private methods\n //#endregion\n\n //#region Abstract methods\n protected abstract formSetup(): FormGroup<any>;\n //#endregion\n}\n","import { DOCUMENT } from '@angular/common';\nimport { Component, inject, OnInit } from '@angular/core';\nimport { DomSanitizer, SafeResourceUrl } from '@angular/platform-browser';\nimport { ActivatedRoute } from '@angular/router';\nimport { ButtonComponent, TabService, TabViewBase } from '@zambon-dev/framework';\nimport { RibbonGroupComponent } from '@zambon-dev/library';\nimport { TranslatePipe } from '@ngx-translate/core';\nimport { take, takeUntil } from 'rxjs';\nimport { EXTERNAL_CONTENT_CONFIGS, ExternalContentConfigs, IExternalContentEntry } from '../../models';\nimport { ExternalContentService, ExternalUrlResolverService } from '../../services';\n\n/**\n * Displays an external destination inside an application tab.\n *\n * Routed as `/external-content/:menuID` — the destination itself never travels in the URL, so no\n * one can hand-craft a link that makes the application frame an arbitrary site.\n *\n * A `TabViewBase` like any other screen, so its actions live in the ribbon rather than in a\n * bar of its own: it must be routed under `DefaultTabViewComponent`, which is what renders the\n * `#ribbon` template this view publishes. Use the exported `externalContentRoutes`.\n */\n@Component({\n selector: 'shared-external-content',\n templateUrl: './external-content.component.html',\n styleUrls: ['./external-content.component.scss'],\n imports: [\n ButtonComponent,\n RibbonGroupComponent,\n TranslatePipe,\n ]\n})\nexport class ExternalContentComponent extends TabViewBase implements OnInit {\n //#region ViewChilds, Inputs, Outputs\n //#endregion\n\n //#region Variables\n protected frameUrl?: SafeResourceUrl;\n protected isBlocked: boolean = false;\n protected isFrameLoading: boolean = false;\n protected isInsecure: boolean = false;\n protected isSlow: boolean = false;\n protected isUnavailable: boolean = false;\n protected label: string = '';\n protected resolvedUrl: string = '';\n\n private activatedRoute: ActivatedRoute = inject(ActivatedRoute);\n private configs: ExternalContentConfigs = inject(EXTERNAL_CONTENT_CONFIGS);\n private document: Document = inject(DOCUMENT);\n private externalContentService: ExternalContentService = inject(ExternalContentService);\n private externalUrlResolverService: ExternalUrlResolverService = inject(ExternalUrlResolverService);\n private sanitizer: DomSanitizer = inject(DomSanitizer);\n private slowHintTimeout?: ReturnType<typeof setTimeout>;\n private tabService: TabService = inject(TabService);\n //#endregion\n\n //#region Properties\n //#endregion\n\n //#region Constructor and Angular life cycle methods\n constructor() {\n super();\n }\n\n public override ngOnDestroy(): void {\n this.clearSlowHint();\n\n super.ngOnDestroy();\n }\n\n public ngOnInit(): void {\n const menuID: number = Number(this.activatedRoute.snapshot.paramMap.get('menuID'));\n\n if (!menuID) {\n this.isUnavailable = true;\n this.loading = false;\n\n return;\n }\n\n this.externalContentService.find(menuID)\n .pipe(take(1), takeUntil(this.destroy$))\n .subscribe((entry: IExternalContentEntry | undefined) => this.show(entry));\n }\n //#endregion\n\n //#region Event handlers\n protected onFrameLoad(): void {\n this.clearSlowHint();\n\n this.isFrameLoading = false;\n this.isSlow = false;\n }\n\n protected onOpenInNewTab(): void {\n window.open(this.resolvedUrl, '_blank', 'noopener,noreferrer');\n }\n\n protected onReload(): void {\n const url: SafeResourceUrl | undefined = this.frameUrl;\n\n if (!url || this.isFrameLoading) {\n return;\n }\n\n // The frame is cross-origin, so its location cannot be touched from here: destroying the\n // element and building a new one is the only way to make it navigate again. That also clears\n // the previous render, which is the point -- otherwise a reload leaves the old content on\n // screen and the user cannot tell whether anything happened.\n //\n // The rebuild has to wait for a macrotask, not a microtask. Angular coalesces changes within a\n // change-detection cycle, so setting frameUrl back before the next tick means @if sees the\n // value go A -> undefined -> A and never toggles: the element is never destroyed, nothing\n // navigates, no `load` ever fires, and the view spins until the timeout gives up. Yielding to\n // a timeout lets a cycle run with the frame unmounted, which is what really tears it down.\n this.frameUrl = undefined;\n this.isFrameLoading = true;\n\n setTimeout(() => this.displayFrame(url));\n }\n //#endregion\n\n //#region Public methods\n //#endregion\n\n //#region Private methods\n private clearSlowHint(): void {\n if (this.slowHintTimeout !== undefined) {\n clearTimeout(this.slowHintTimeout);\n this.slowHintTimeout = undefined;\n }\n }\n\n private isMixedContent(url: string): boolean {\n // A browser refuses to embed an http:// frame in an https:// page, unconditionally: an iframe\n // is active mixed content. Nothing on this side can permit it -- no attribute, no header, and\n // not CSP, which only ever restricts further. Left alone the frame renders empty, so this is\n // checked up front to say so instead.\n //\n // Unlike a site refusing to be framed, this one IS knowable before trying: both protocols are\n // in hand. `new URL` cannot throw here -- isAllowed has already parsed the same string -- and\n // it normalises the scheme's case, which a prefix test would not.\n return this.document.location.protocol === 'https:' && new URL(url).protocol === 'http:';\n }\n\n private isOriginAllowed(url: string): boolean {\n if (this.configs.allowedOrigins.length === 0) {\n return true;\n }\n\n try {\n return this.configs.allowedOrigins.indexOf(new URL(url).origin) !== -1;\n } catch {\n return false;\n }\n }\n\n private show(entry: IExternalContentEntry | undefined): void {\n // TabViewBase starts every screen loading so its ribbon buttons begin disabled; every exit\n // from here has to clear it or they never become usable.\n this.loading = false;\n\n if (!entry || !entry.url) {\n this.isUnavailable = true;\n\n return;\n }\n\n this.label = entry.label;\n\n // MainLayoutComponent only resolves a deep-linked title through getMenuFromUrl, and a Tab\n // starts with isTitleLoading true, so a tab re-created by TabsComponent after a refresh would\n // spin forever if nothing set its title. Setting it here is idempotent.\n this.tabService.updateActiveTabRootTitle(entry.label);\n\n // Order matters: resolve, then validate, then trust. What we vet has to be exactly what the\n // browser receives, and a placeholder is substituted before the scheme can be inspected.\n const url: string = this.externalUrlResolverService.resolve(entry.url);\n\n if (!this.externalUrlResolverService.isAllowed(url) || !this.isOriginAllowed(url)) {\n console.error(`Embedded menu item \"${entry.label}\" points to an address that is not allowed and was not displayed.`, url);\n this.isBlocked = true;\n\n return;\n }\n\n // Set before the mixed-content check, not after: that state still offers 'open in a new\n // browser tab', and the button reads this to decide whether it has anywhere to go.\n this.resolvedUrl = url;\n\n if (this.isMixedContent(url)) {\n this.isInsecure = true;\n\n return;\n }\n\n // Trusted once, into a field. From a getter or a pipe this would hand back a new\n // SafeResourceUrl on every change-detection pass, and Angular would re-set the iframe's src\n // and reload the destination each time.\n this.displayFrame(this.sanitizer.bypassSecurityTrustResourceUrl(url));\n }\n\n private displayFrame(url: SafeResourceUrl): void {\n this.isFrameLoading = true;\n this.frameUrl = url;\n\n this.startSlowHint();\n }\n\n private startSlowHint(): void {\n this.clearSlowHint();\n\n // Not detection, and it must never be turned into one: whether a site refuses to be framed\n // (X-Frame-Options, CSP frame-ancestors) is not observable from JavaScript. A refused frame\n // usually fires `load` immediately and renders the browser's own error page, in which case\n // this hint never appears -- the ribbon's \"open in a new browser tab\" button is the actual\n // way out, and it is always present.\n this.slowHintTimeout = setTimeout(() => {\n // Stop claiming it is loading. A destination that never reports `load` -- a refused frame\n // among them -- would otherwise spin forever and keep the actions disabled; hand the\n // controls back and let the hint do the explaining.\n this.isFrameLoading = false;\n this.isSlow = true;\n }, this.configs.slowFrameHintDelay);\n }\n //#endregion\n}\n","<!-- 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 </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 </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\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 class=\"opacity-75\" fill=\"currentColor\" 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\"></path>\n </svg>\n\n <span>{{ 'Loading' | translate }}</span>\n </div>\n }\n\n @if (frameUrl) {\n <iframe 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 </iframe>\n }\n </div>\n }\n}\n","import { Routes } from '@angular/router';\nimport { DefaultTabViewComponent, FRAMEWORK_VIEW_TYPE, FrameworkViewType } from '@zambon-dev/framework';\nimport { EXTERNAL_CONTENT_ROUTE_PATH } from '../../models';\nimport { ExternalContentComponent } from './external-content.component';\n\n/**\n * Route table for embedded external content. Spread it into `MainLayoutComponent`'s children:\n *\n * ```ts\n * { path: '', component: MainLayoutComponent, canActivate: [AuthGuard], children: [\n * ...externalContentRoutes,\n * // the application's own features\n * ] }\n * ```\n *\n * Three things about the shape are load-bearing and must not be \"simplified\" away:\n *\n * - The path is nested one segment per route. `RouteHelper.getRouteURL` and\n * `CustomReuseStrategy.getUrlFromRoute` collect segments walking up the parent chain and then\n * reverse the flat list, so a route declared `'external-content/:menuID'` rebuilds as\n * `/:menuID/external-content` and every tab URL is wrong.\n * - `DefaultTabViewComponent` hosts the view. It is what renders the `#ribbon` template the\n * component publishes, so dropping it leaves the Reload and Open-in-a-new-browser-tab actions\n * with nowhere to appear.\n * - `FRAMEWORK_VIEW_TYPE` must be present. `TabsComponent` re-creates the tab after a page refresh\n * by looking for a `Details` or `List` view in the activated route tree, and navigates to `/`\n * when it finds neither — the embedded tab would vanish on F5.\n */\nexport const externalContentRoutes: Routes = [\n {\n path: EXTERNAL_CONTENT_ROUTE_PATH,\n children: [\n {\n path: ':menuID',\n component: DefaultTabViewComponent,\n data: { [FRAMEWORK_VIEW_TYPE]: FrameworkViewType.List },\n children: [\n { path: '', component: ExternalContentComponent },\n ],\n },\n ],\n },\n];\n","import { inject, Injectable } from '@angular/core';\nimport { DataGridDataset, IGridColumn, IListParameters } from '@zambon-dev/library';\nimport { Observable, of } from 'rxjs';\nimport { IOperationsHistoryList } from '../models';\nimport { OperationsHistoryService } from '../services';\n\n@Injectable()\nexport class OperationsHistoryDataset extends DataGridDataset {\n //#region ViewChilds, Inputs, Outputs\n //#endregion\n\n //#region Variables\n public override columns: IGridColumn[] = [\n { field: '', headerName: '' },\n ];\n public controllerName?: string;\n\n protected operationsHistoryService: OperationsHistoryService = inject(OperationsHistoryService);\n\n private _serviceID?: number | undefined;\n //#endregion\n\n //#region Properties\n public set serviceId(value: number | undefined) {\n if (this._serviceID !== value) {\n this._serviceID = value;\n this.refresh();\n }\n }\n //#endregion\n\n //#region Constructor and Angular life cycle methods\n constructor() {\n super();\n\n this.configs.hideColumnHeaders = true;\n this.configs.showMessageOnEmpty = false;\n }\n //#endregion\n\n //#region Event handlers\n //#endregion\n\n //#region Public methods\n public getData(params: IListParameters): Observable<IOperationsHistoryList[]> {\n this.configs.showMessageOnEmpty = !!this._serviceID;\n\n return !!this.parentEntityId && !!this.controllerName && !!this._serviceID\n ? this.operationsHistoryService.list(this.controllerName, this.parentEntityId, this._serviceID, params)\n : of<IOperationsHistoryList[]>([]);\n }\n //#endregion\n\n //#region Private methods\n //#endregion\n}","import { inject, Injectable } from '@angular/core';\nimport { DataGridDataset, IGridColumn, IListParameters } from '@zambon-dev/library';\nimport { Observable, of } from 'rxjs';\nimport { IServicesHistoryList } from '../models';\nimport { ServicesHistoryService } from '../services';\n\n@Injectable()\nexport class ServicesHistoryDataset extends DataGridDataset {\n //#region ViewChilds, Inputs, Outputs\n //#endregion\n\n //#region Variables\n public override columns: IGridColumn[] = [\n { field: '', headerName: '' },\n ];\n\n public controllerName?: string;\n\n protected servicesHistoryService: ServicesHistoryService = inject(ServicesHistoryService);\n //#endregion\n\n //#region Properties\n //#endregion\n\n //#region Constructor and Angular life cycle methods\n constructor() {\n super();\n\n this.configs.hideColumnHeaders = true;\n this.configs.rowHeight = 52;\n }\n //#endregion\n\n //#region Event handlers\n //#endregion\n\n //#region Public methods\n public getData(params: IListParameters): Observable<IServicesHistoryList[]> {\n return !!this.parentEntityId && !!this.controllerName\n ? this.servicesHistoryService.list(this.controllerName, this.parentEntityId, params)\n : of<IServicesHistoryList[]>([]);\n }\n //#endregion\n\n //#region Private methods\n //#endregion\n}","import { JsonPipe } from '@angular/common';\nimport { Component, Input, ViewChild } from '@angular/core';\nimport { ModalBase } from '@zambon-dev/framework';\nimport { ModalComponent } from '@zambon-dev/library';\nimport { TranslatePipe } from '@ngx-translate/core';\n\n@Component({\n selector: 'shared-operations-history-modal',\n templateUrl: './operations-history-modal.component.html',\n styleUrls: ['./operations-history-modal.component.scss'],\n imports: [\n JsonPipe,\n ModalComponent,\n TranslatePipe,\n ],\n})\nexport class OperationsHistoryModalComponent extends ModalBase {\n //#region ViewChilds, Inputs, Outputs\n @ViewChild(ModalComponent) private modal!: ModalComponent;\n\n @Input() public newValues?: string;\n\n @Input() public oldValues?: string;\n //#endregion\n\n //#region Variables\n //#endregion\n\n //#region Properties\n public get isModalShown(): boolean {\n return this.modal.isShown;\n }\n //#endregion\n\n //#region Constructor and Angular life cycle methods\n //#endregion\n\n //#region Event handlers\n //#endregion\n\n //#region Public methods\n public toggle(): void {\n this.modal.toggleModal();\n }\n //#endregion\n\n //#region Private methods\n //#endregion\n}","<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>","import { AfterViewInit, Component, Input, TemplateRef, ViewChild } from '@angular/core';\nimport { ChildList } from '@zambon-dev/framework';\nimport { DataGridComponent, DataGridDataset } from '@zambon-dev/library';\nimport { OperationsHistoryDataset } from '../../../datasets';\nimport { IOperationsHistoryList } from '../../../models';\nimport { OperationsHistoryModalComponent } from '../operations-history-modal/operations-history-modal.component';\n\n@Component({\n selector: 'shared-operations-history-child-list',\n templateUrl: './operations-history-child-list.component.html',\n styleUrls: ['./operations-history-child-list.component.scss'],\n imports: [\n DataGridComponent,\n OperationsHistoryModalComponent,\n ],\n providers: [{ provide: DataGridDataset, useClass: OperationsHistoryDataset }]\n})\nexport class OperationsHistoryChildListComponent extends ChildList<any> implements AfterViewInit {\n //#region ViewChilds, Inputs, Outputs\n @ViewChild(OperationsHistoryModalComponent) private modal!: OperationsHistoryModalComponent;\n @ViewChild('operationTemplate') private operationTemplate!: TemplateRef<any>;\n\n @Input() public set controllerName(value: string) {\n (<OperationsHistoryDataset>this.dataGridDataset).controllerName = value;\n }\n\n @Input() public set serviceID(value: number | undefined) {\n (<OperationsHistoryDataset>this.dataGridDataset).serviceId = value;\n }\n //#endregion\n\n //#region Variables\n public selectedNewValues: any | null = null;\n public selectedOldValues: any | null = null;\n //#endregion\n\n //#region Properties\n //#endregion\n\n //#region Constructor and Angular life cycle methods\n public ngAfterViewInit(): void {\n this.dataGridDataset.columns[0].template = this.operationTemplate;\n }\n //#endregion\n\n //#region Event handlers\n public openModal(): void {\n if (!this.modal.isModalShown) {\n this.modal.toggle();\n }\n }\n //#endregion\n\n //#region Public methods\n public override selectedRowChanged(): void {\n super.selectedRowChanged();\n\n if (this.dataGridDataset.hasSelectedRows) {\n const key: string = this.dataGridDataset.selectedRowKeys[0];\n \n const data: IOperationsHistoryList = this.dataGridDataset.getRowData(key);\n this.selectedOldValues = JSON.parse(data.oldValues?.trim() ?? '');\n this.selectedNewValues = JSON.parse(data.newValues?.trim() ?? '');\n }\n }\n //#endregion\n\n //#region Private methods\n //#endregion\n}","<lib-data-grid [lazyLoadRows]=\"true\">\n</lib-data-grid>\n\n<ng-template #operationTemplate let-rowData=\"rowData\">\n <div class=\"operation-content\" (click)=\"openModal()\">\n <span 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 {{ rowData.operationType }}\n </span>\n {{ rowData.entityName }}\n </div>\n</ng-template>\n\n<shared-operations-history-modal\n[newValues]=\"selectedNewValues\"\n[oldValues]=\"selectedOldValues\">\n</shared-operations-history-modal>","import { inject, Pipe, PipeTransform } from '@angular/core';\nimport { DomSanitizer, SafeHtml } from '@angular/platform-browser';\n\n/**\n * Pipe that bypasses Angular's built-in HTML sanitization.\n *\n * **WARNING: This pipe introduces XSS (Cross-Site Scripting) risk.**\n * It marks the provided HTML string as trusted, meaning Angular will\n * render it without any sanitization. Malicious content such as\n * `<script>` tags, inline event handlers (`onerror`, `onclick`, etc.),\n * and `javascript:` URLs will be executed in the user's browser.\n *\n * ### Safe usage\n * - Server-rendered HTML from **trusted, internal APIs** that never\n * include user-generated content (e.g., admin-authored rich text\n * that is sanitized server-side before storage).\n * - Static HTML snippets defined in application code.\n *\n * ### Unsafe usage (DO NOT use for these)\n * - Any value that originates from user input (form fields, query\n * params, URL fragments, file uploads).\n * - Third-party API responses whose content you do not control.\n * - Database fields that may contain unsanitized user submissions.\n *\n * @example\n * // Safe — trusted server content\n * <div [innerHTML]=\"trustedServerHtml | bypassHtmlSanitizer\"></div>\n *\n * // UNSAFE — user-provided content (use Angular’s default sanitization instead)\n * <div [innerHTML]=\"comment.body | bypassHtmlSanitizer\"></div> // ❌ XSS risk\n * <div [innerHTML]=\"comment.body\"></div> // ✅ Angular sanitizes automatically\n */\n@Pipe({\n name: 'bypassHtmlSanitizer'\n})\nexport class BypassHtmlSanitizerPipe implements PipeTransform {\n private sanitizer: DomSanitizer = inject(DomSanitizer);\n\n public transform(html: string): SafeHtml {\n return this.sanitizer.bypassSecurityTrustHtml(html);\n }\n}\n","import { Pipe, PipeTransform } from '@angular/core';\n\n@Pipe({\n name: 'enumLabel'\n})\nexport class EnumLabelPipe implements PipeTransform {\n public transform(value?: number, enumType?: any): string {\n if (value === undefined || enumType === undefined) {\n return '';\n }\n\n const keys: string[] = Object.keys(enumType).filter((key: string) => !isNaN(Number(enumType[key])));\n const values: number[] = keys.map((key: string) => enumType[key]);\n\n const index: number = values.indexOf(value);\n if (index >= 0) {\n return keys[index];\n }\n return '';\n }\n}","import { Pipe, PipeTransform } from '@angular/core';\n\n@Pipe({\n name: 'utcDate'\n})\nexport class UtcDatePipe implements PipeTransform {\n transform(value?: Date): Date | null {\n if (!value) {\n return null;\n }\n\n const newDate: Date = new Date(value);\n\n let utcHour: number = newDate.getUTCHours();\n if (utcHour < newDate.getHours()) {\n utcHour += 24;\n }\n\n newDate.setHours(\n newDate.getHours() + newDate.getHours() - utcHour,\n newDate.getMinutes(),\n newDate.getSeconds()\n );\n\n return newDate;\n }\n}","import { DatePipe } from '@angular/common';\nimport { AfterViewInit, Component, Input, TemplateRef, ViewChild } from '@angular/core';\nimport { ChildList } from '@zambon-dev/framework';\nimport { DataGridComponent, DataGridDataset } from '@zambon-dev/library';\nimport { TranslatePipe } from '@ngx-translate/core';\nimport { ServicesHistoryDataset } from '../../../datasets';\nimport { UtcDatePipe } from '../../../pipes';\n\n@Component({\n selector: 'shared-services-history-child-list',\n templateUrl: './services-history-child-list.component.html',\n styleUrls: ['./services-history-child-list.component.scss'],\n imports: [\n DataGridComponent,\n DatePipe,\n UtcDatePipe,\n TranslatePipe,\n ],\n providers: [{ provide: DataGridDataset, useClass: ServicesHistoryDataset }]\n})\nexport class ServicesHistoryChildListComponent extends ChildList<any> implements AfterViewInit {\n //#region ViewChilds, Inputs, Outputs\n @ViewChild('serviceTemplate') private serviceTemplate!: TemplateRef<any>;\n\n @Input() public set controllerName(value: string) {\n (<ServicesHistoryDataset>this.dataGridDataset).controllerName = value;\n } \n //#endregion\n\n //#region Variables\n public selectedServiceID?: number;\n //#endregion\n\n //#region Properties\n //#endregion\n\n //#region Constructor and Angular life cycle methods\n public ngAfterViewInit(): void {\n this.dataGridDataset.columns[0].template = this.serviceTemplate;\n }\n //#endregion\n\n //#region Event handlers\n //#endregion\n\n //#region Public methods\n public override selectedRowChanged(): void {\n super.selectedRowChanged();\n\n if (this.dataGridDataset.hasSelectedRows) {\n const selectedKey: string = this.dataGridDataset.selectedRowKeys[0];;\n this.selectedServiceID = this.dataGridDataset.getRowID(selectedKey);\n }\n }\n //#endregion\n\n //#region Private methods\n //#endregion\n}","<lib-data-grid [lazyLoadRows]=\"true\">\n</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\"><i class=\"fa-solid fa-clock\"></i> {{ rowData.changedOn | utcDate | date: ('Format-DateTime' | translate) }}</span>\n <span class=\"user\"><i class=\"fa-solid fa-user\"></i> {{ rowData.changedByName }}</span>\n </div>\n </div>\n </div>\n</ng-template>","import { Component, inject, Input } from '@angular/core';\nimport { ActivatedRoute } from '@angular/router';\nimport { ViewBase } from '@zambon-dev/framework';\nimport { DataProviderService } from '@zambon-dev/library';\nimport { take } from 'rxjs';\nimport { OperationsHistoryChildListComponent } from '../../operations-history';\nimport { ServicesHistoryChildListComponent } from '../services-history-child-list/services-history-child-list.component';\n\n@Component({\n selector: 'shared-services-history-view',\n templateUrl: './services-history-view.component.html',\n styleUrls: ['./services-history-view.component.scss'],\n imports: [\n OperationsHistoryChildListComponent,\n ServicesHistoryChildListComponent,\n ]\n})\nexport class ServicesHistoryViewComponent extends ViewBase {\n //#region ViewChilds, Inputs, Outputs\n @Input({ required: true }) public controllerName!: string;\n\n @Input() public entityID?: number;\n //#endregion\n\n //#region Variables\n private activatedRoute: ActivatedRoute = inject(ActivatedRoute);\n private dataProviderService: DataProviderService<any> | null = inject(DataProviderService, { optional: true });\n //#endregion\n\n //#region Properties\n //#endregion\n\n //#region Constructor and Angular life cycle methods\n constructor() {\n super();\n\n if (this.activatedRoute.snapshot.data['controllerName']) {\n this.controllerName = this.activatedRoute.snapshot.data['controllerName'];\n }\n\n if (this.dataProviderService) {\n this.dataProviderService.getModel$()\n .pipe(take(1))\n .subscribe((model: any) => {\n this.entityID = model.id;\n });\n }\n }\n //#endregion\n\n //#region Event handlers\n //#endregion\n\n //#region Public methods\n //#endregion\n\n //#region Private methods\n //#endregion\n}","<div class=\"history-container\">\n <div class=\"service-history-container\">\n <shared-services-history-child-list #service\n [controllerName]=\"controllerName\">\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 [serviceID]=\"service.selectedServiceID\">\n </shared-operations-history-child-list>\n </div>\n</div>","import { HttpBackend } from '@angular/common/http';\nimport { EnvironmentProviders, Provider } from '@angular/core';\nimport { provideTranslateService, TranslateLoader } from '@ngx-translate/core';\nimport { MultiTranslateHttpLoader, TranslationResource } from 'ngx-translate-multi-http-loader';\n\nexport interface AngularAssetPattern {\n glob: string;\n input: string;\n output: string;\n}\n\nexport const ZAMBON_SHARED_I18N_ASSET_PATH = 'assets/i18n/zambon-dev/shared';\n\nexport const ZAMBON_SHARED_I18N_ASSET: AngularAssetPattern = {\n glob: '**/*.json',\n input: 'node_modules/@zambon-dev/shared/i18n',\n output: ZAMBON_SHARED_I18N_ASSET_PATH,\n};\n\nexport const ZAMBON_SHARED_I18N_RESOURCES: TranslationResource[] = [\n { prefix: `/${ZAMBON_SHARED_I18N_ASSET_PATH}/external-content/`, suffix: '.json' },\n { prefix: `/${ZAMBON_SHARED_I18N_ASSET_PATH}/language-selector/`, suffix: '.json' },\n { prefix: `/${ZAMBON_SHARED_I18N_ASSET_PATH}/login/`, suffix: '.json' },\n { prefix: `/${ZAMBON_SHARED_I18N_ASSET_PATH}/operations-history/`, suffix: '.json' },\n { prefix: `/${ZAMBON_SHARED_I18N_ASSET_PATH}/top-bar/`, suffix: '.json' },\n];\n\nexport interface ZambonSharedTranslateConfig {\n defaultLanguage?: string;\n appResources?: (string | TranslationResource)[];\n}\n\nexport function createZambonSharedTranslateLoader(\n httpBackend: HttpBackend,\n appResources: (string | TranslationResource)[] = [],\n): MultiTranslateHttpLoader {\n return new MultiTranslateHttpLoader(httpBackend, [\n ...ZAMBON_SHARED_I18N_RESOURCES,\n ...appResources,\n ]);\n}\n\nexport function provideZambonSharedTranslateLoader(\n appResources: (string | TranslationResource)[] = [],\n): Provider {\n return {\n provide: TranslateLoader,\n useFactory: (httpBackend: HttpBackend) => createZambonSharedTranslateLoader(httpBackend, appResources),\n deps: [HttpBackend],\n };\n}\n\nexport function provideZambonSharedTranslateService(\n config: ZambonSharedTranslateConfig = {},\n): EnvironmentProviders {\n return provideTranslateService({\n defaultLanguage: config.defaultLanguage,\n loader: provideZambonSharedTranslateLoader(config.appResources),\n });\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":["i1"],"mappings":"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"}
1
+ {"version":3,"file":"zambon-dev-shared.mjs","sources":["../../../../libs/shared/src/lib/layouts/login-layout/login-layout.component.ts","../../../../libs/shared/src/lib/layouts/login-layout/login-layout.component.html","../../../../libs/shared/src/lib/models/external-content.ts","../../../../libs/shared/src/lib/services/authentication.service.ts","../../../../libs/shared/src/lib/services/external-content.service.ts","../../../../libs/shared/src/lib/services/external-url-resolver.service.ts","../../../../libs/shared/src/lib/services/notifications.service.ts","../../../../libs/shared/src/lib/services/operations-history.service.ts","../../../../libs/shared/src/lib/services/services-history.service.ts","../../../../libs/shared/src/lib/layouts/top-bar/brand/brand.component.ts","../../../../libs/shared/src/lib/layouts/top-bar/brand/brand.component.html","../../../../libs/shared/src/lib/layouts/top-bar/environment-badge/environment-badge.component.ts","../../../../libs/shared/src/lib/layouts/top-bar/environment-badge/environment-badge.component.html","../../../../libs/shared/src/lib/layouts/top-bar/notifications/notifications.component.ts","../../../../libs/shared/src/lib/layouts/top-bar/notifications/notifications.component.html","../../../../libs/shared/src/lib/auth/components/language-selector/language-selector.component.ts","../../../../libs/shared/src/lib/auth/components/language-selector/language-selector.component.html","../../../../libs/shared/src/lib/layouts/top-bar/user-profile/user-profile.component.ts","../../../../libs/shared/src/lib/layouts/top-bar/user-profile/user-profile.component.html","../../../../libs/shared/src/lib/layouts/top-bar/top-bar.component.ts","../../../../libs/shared/src/lib/layouts/top-bar/top-bar.component.html","../../../../libs/shared/src/lib/layouts/main-layout/main-layout.component.ts","../../../../libs/shared/src/lib/layouts/main-layout/main-layout.component.html","../../../../libs/shared/src/lib/auth/components/login/login.component.ts","../../../../libs/shared/src/lib/auth/components/login/login.component.html","../../../../libs/shared/src/lib/auth/auth.module.ts","../../../../libs/shared/src/lib/auth/guards/auth-guard.ts","../../../../libs/shared/src/lib/auth/interceptors/auth-interceptors.ts","../../../../libs/shared/src/lib/components/filters-base.ts","../../../../libs/shared/src/lib/features/external-content/external-content.component.ts","../../../../libs/shared/src/lib/features/external-content/external-content.component.html","../../../../libs/shared/src/lib/features/external-content/external-content.routes.ts","../../../../libs/shared/src/lib/datasets/operations-history.dataset.ts","../../../../libs/shared/src/lib/datasets/services-history.dataset.ts","../../../../libs/shared/src/lib/features/operations-history/operations-history-modal/operations-history-modal.component.ts","../../../../libs/shared/src/lib/features/operations-history/operations-history-modal/operations-history-modal.component.html","../../../../libs/shared/src/lib/features/operations-history/operations-history-child-list/operations-history-child-list.component.ts","../../../../libs/shared/src/lib/features/operations-history/operations-history-child-list/operations-history-child-list.component.html","../../../../libs/shared/src/lib/pipes/bypass-html-sanitizer.pipe.ts","../../../../libs/shared/src/lib/pipes/enum-text.pipe.ts","../../../../libs/shared/src/lib/pipes/utc-date.pipe.ts","../../../../libs/shared/src/lib/features/services-history/services-history-child-list/services-history-child-list.component.ts","../../../../libs/shared/src/lib/features/services-history/services-history-child-list/services-history-child-list.component.html","../../../../libs/shared/src/lib/features/services-history/services-history-view/services-history-view.component.ts","../../../../libs/shared/src/lib/features/services-history/services-history-view/services-history-view.component.html","../../../../libs/shared/src/lib/i18n/shared-i18n.ts","../../../../libs/shared/src/zambon-dev-shared.ts"],"sourcesContent":["import { Component } from '@angular/core';\nimport { RouterModule } from '@angular/router';\n\n@Component({\n selector: 'shared-login-layout',\n templateUrl: './login-layout.component.html',\n styleUrls: ['./login-layout.component.scss'],\n imports: [\n RouterModule,\n ]\n})\nexport class LoginLayoutComponent {\n //#region ViewChilds, Inputs, Outputs\n //#endregion\n\n //#region Variables\n //#endregion\n\n //#region Properties\n //#endregion\n\n //#region Constructor and Angular life cycle methods\n //#endregion\n\n //#region Event handlers\n //#endregion\n\n //#region Public methods\n //#endregion\n\n //#region Private methods\n //#endregion\n}","<div class=\"background\"></div>\n\n<div class=\"container\">\n <router-outlet></router-outlet>\n</div>","import { InjectionToken } from '@angular/core';\n\n/** First segment of the route that hosts embedded external content. */\nexport const EXTERNAL_CONTENT_ROUTE_PATH = 'external-content';\n\n/**\n * Flat projection of an external menu item, used to restore an embedded tab.\n *\n * Deliberately not a `SidebarMenu`: that class carries a `parent` back-reference, so it is a\n * circular structure that `JSON.stringify` refuses, and holding one would pin the whole menu tree.\n */\nexport interface IExternalContentEntry {\n id: number;\n label: string;\n url: string;\n}\n\nexport class ExternalContentConfigs {\n /**\n * Origins an embedded menu item may point at, for example `['https://reports.example.com']`.\n * Empty — the default — allows any `http`/`https` origin.\n *\n * Populating it is the single highest-value control here after the scheme check: it narrows a\n * compromised menu row from \"frame anything on the internet\" to \"frame one of our report hosts\".\n */\n public allowedOrigins: string[] = [];\n\n /** Milliseconds to wait for the frame's first `load` before hinting that framing may be refused. */\n public slowFrameHintDelay = 5000;\n\n constructor(options: Partial<ExternalContentConfigs> = {}) {\n Object.assign(this, options);\n }\n}\n\nexport const EXTERNAL_CONTENT_CONFIGS: InjectionToken<ExternalContentConfigs> = new InjectionToken<ExternalContentConfigs>('Embedded external content configuration', {\n providedIn: 'root',\n factory: () => new ExternalContentConfigs(),\n});\n","import { HttpClient, HttpErrorResponse } from '@angular/common/http';\nimport { inject, Injectable } from '@angular/core';\nimport { JwtHelperService } from '@auth0/angular-jwt';\nimport { APP_CONFIG, AppConfig, AuthService, TabService } from '@zambon-dev/framework';\nimport { Observable, catchError, interval, map, mergeMap, tap } from 'rxjs';\nimport { IAuthResponse, ICurrentUserInfo } from '../models';\n\n@Injectable({\n providedIn: 'root'\n})\nexport class AuthenticationService extends AuthService {\n //#region ViewChilds, Inputs, Outputs\n //#endregion\n\n //#region Variables\n public adminAction = 'AdministrativeMaster';\n\n private config: AppConfig = inject(APP_CONFIG);\n\n private readonly BASE_URL: string = `${this.config.BASE_URL}/Authentication`;\n private http: HttpClient = inject(HttpClient);\n //#endregion\n\n //#region Properties\n //#endregion\n\n //#region Constructor and Angular life cycle methods\n constructor() {\n super(inject(JwtHelperService), inject(TabService));\n }\n //#endregion\n\n //#region Event handlers\n //#endregion\n\n //#region Public methods\n public authenticate(model: { username: string, password: string, rememberMe: boolean }): Observable<void> {\n return this.http\n .post<IAuthResponse>(`${this.BASE_URL}/SignIn`, model)\n .pipe(\n map((res: IAuthResponse) => {\n this.setStorage('username', res.username, model.rememberMe);\n this.setStorage('token', res.token, model.rememberMe);\n this.setStorage('refreshToken', res.refreshToken, model.rememberMe);\n this.setStorage('userInfo', window.btoa(JSON.stringify(res as ICurrentUserInfo)), model.rememberMe);\n }),\n catchError((error: HttpErrorResponse) =>\n interval(1000)\n .pipe(\n mergeMap(() => {\n switch(error.status) {\n case 401:\n throw 'InvalidUsernamePassword';\n default:\n throw 'InternalServerError';\n }\n })\n )\n )\n );\n }\n\n public getActions(): Observable<string[]> {\n return this.http.post<string[]>(`${this.BASE_URL}/GetActions`, {});\n }\n\n public getUserInfo(): ICurrentUserInfo | null {\n const userInfo: string | null = this.userInfo;\n if (userInfo) {\n return JSON.parse(window.atob(userInfo)) as ICurrentUserInfo;\n }\n return null;\n }\n\n public tryRefreshToken(): Observable<string> {\n return this.http\n .post<IAuthResponse>(`${this.BASE_URL}/RefreshToken`, {\n username: this.username ?? '',\n refreshToken: this.refreshToken ?? ''\n })\n .pipe(\n tap((res: IAuthResponse) => {\n this.setStorage('token', res.token);\n this.setStorage('refreshToken', res.refreshToken);\n this.setStorage('userInfo', window.btoa(JSON.stringify(res as ICurrentUserInfo)));\n }),\n map((res: IAuthResponse) => res.token ?? '')\n );\n }\n //#endregion\n\n //#region Private methods\n //#endregion\n}","import { inject, Injectable } from '@angular/core';\nimport { SidebarMenu, SidebarService } from '@zambon-dev/library';\nimport { catchError, map, Observable, of, take } from 'rxjs';\nimport { EXTERNAL_CONTENT_ROUTE_PATH, IExternalContentEntry } from '../models';\n\n/**\n * Remembers which external destination sits behind an embedded tab's `/external-content/:menuID`\n * route, and resolves it back when the view is created.\n *\n * The destination never travels in the route, so the id has to be resolved to a URL somehow. That\n * happens in three steps, cheapest first:\n *\n * 1. the in-memory registry — the item was clicked in this browsing session;\n * 2. `sessionStorage` — the user pressed F5 on the embedded tab;\n * 3. the application's `SidebarService.getMenuFromUrl()` — a cold deep link.\n *\n * Step 3 reuses the abstract hook every application already implements, so nothing new is required\n * of a consumer: an application whose menu endpoint cannot resolve `/external-content/:id` simply\n * gets the unavailable state on a cold deep link, which is the documented behaviour.\n */\n@Injectable({\n providedIn: 'root'\n})\nexport class ExternalContentService {\n //#region Variables\n private readonly maxEntries: number = 20;\n private readonly storageKey: string = 'zambon.externalContent';\n\n private registry: Map<number, IExternalContentEntry> = new Map<number, IExternalContentEntry>();\n private sidebarService: SidebarService = inject(SidebarService);\n //#endregion\n\n //#region Properties\n //#endregion\n\n //#region Constructor and Angular life cycle methods\n //#endregion\n\n //#region Public methods\n /** Resolves the destination behind an embedded tab, or `undefined` when it cannot be recovered. */\n public find(menuID: number): Observable<IExternalContentEntry | undefined> {\n const known: IExternalContentEntry | undefined = this.registry.get(menuID) ?? this.readFromStorage(menuID);\n\n if (known) {\n return of(known);\n }\n\n return this.sidebarService.getMenuFromUrl(`/${EXTERNAL_CONTENT_ROUTE_PATH}/${menuID}`)\n .pipe(\n take(1),\n map((menu: SidebarMenu) => !!menu && !!menu.url ? this.toEntry(menu) : undefined),\n // A menu endpoint that does not know this route shape answers 404, which is an expected\n // outcome here rather than a failure: the view falls back to its unavailable state.\n catchError(() => of(undefined)),\n );\n }\n\n /** Remembers a menu so its embedded tab survives a page refresh. */\n public register(menu: SidebarMenu): void {\n const entry: IExternalContentEntry = this.toEntry(menu);\n\n this.registry.set(entry.id, entry);\n this.writeToStorage(entry);\n }\n //#endregion\n\n //#region Private methods\n private readAllFromStorage(): IExternalContentEntry[] {\n try {\n const raw: string | null = window.sessionStorage.getItem(this.storageKey);\n\n if (!raw) {\n return [];\n }\n\n const parsed: unknown = JSON.parse(raw);\n\n return Array.isArray(parsed) ? <IExternalContentEntry[]>parsed : [];\n } catch {\n // A poisoned or unavailable storage entry must never take the application down; the view\n // degrades to asking the user to reopen the item from the menu.\n return [];\n }\n }\n\n private readFromStorage(menuID: number): IExternalContentEntry | undefined {\n const entry: IExternalContentEntry | undefined = this.readAllFromStorage()\n .find((candidate: IExternalContentEntry) => candidate?.id === menuID);\n\n if (!!entry && !!entry.url) {\n this.registry.set(entry.id, entry);\n return entry;\n }\n\n return undefined;\n }\n\n private toEntry(menu: SidebarMenu): IExternalContentEntry {\n return {\n id: menu.id,\n label: menu.label,\n url: menu.url ?? '',\n };\n }\n\n private writeToStorage(entry: IExternalContentEntry): void {\n try {\n const entries: IExternalContentEntry[] = [\n entry,\n ...this.readAllFromStorage().filter((candidate: IExternalContentEntry) => candidate?.id !== entry.id),\n ].slice(0, this.maxEntries);\n\n window.sessionStorage.setItem(this.storageKey, JSON.stringify(entries));\n } catch {\n // Storage can be unavailable (private mode, blocked site data). Losing refresh support is\n // acceptable; failing the click is not.\n }\n }\n //#endregion\n}\n","import { inject, Injectable } from '@angular/core';\nimport { TranslateService } from '@ngx-translate/core';\nimport { ICurrentUserInfo } from '../models';\nimport { AuthenticationService } from './authentication.service';\n\n/**\n * Resolves the runtime placeholders in an external menu URL, and vets the result before it is\n * handed to the browser.\n *\n * Placeholder syntax is `{name}`, case-sensitive, drawn from a **closed** set:\n *\n * | Token | Source |\n * |--------------|-----------------------------------------------------|\n * | `{email}` | `ICurrentUserInfo.email` |\n * | `{language}` | `TranslateService.currentLang`, then `defaultLang` |\n * | `{userId}` | `ICurrentUserInfo.userID` |\n * | `{userName}` | `ICurrentUserInfo.username` |\n *\n * The set is closed by construction rather than reflected off the stored user info, and that is a\n * security property, not a style choice: `AuthenticationService` persists the entire sign-in\n * response under `userInfo`, tokens included, so a reflective implementation would let a menu URL\n * configured as `?t={token}` hand the JWT to a third party. No authentication token is ever\n * substituted.\n */\n@Injectable({\n providedIn: 'root'\n})\nexport class ExternalUrlResolverService {\n //#region Variables\n private authenticationService: AuthenticationService = inject(AuthenticationService);\n private translate: TranslateService = inject(TranslateService);\n\n /** Placeholder grammar, used only to *detect* tokens this version does not know. */\n private readonly unknownPlaceholderPattern: RegExp = /\\{[A-Za-z][A-Za-z0-9_]*\\}/g;\n //#endregion\n\n //#region Properties\n //#endregion\n\n //#region Constructor and Angular life cycle methods\n //#endregion\n\n //#region Public methods\n /**\n * Whether `url` is an absolute `http`/`https` address.\n *\n * Rejects relative paths, malformed values, protocol-relative `//host/path` (which throws\n * without a base), and the schemes that would execute rather than navigate: `javascript:`,\n * `data:`, `blob:`, `file:`.\n */\n public isAllowed(url: string): boolean {\n let parsed: URL;\n\n try {\n parsed = new URL(url);\n } catch {\n return false;\n }\n\n return parsed.protocol === 'http:' || parsed.protocol === 'https:';\n }\n\n /**\n * Substitutes every known placeholder, URL-encoding each value.\n *\n * Because every value is percent-encoded, a placeholder must occupy one *whole* value — a full\n * path segment, or a full query-parameter value. Encoding is what stops a display name that\n * contains `&` from injecting an extra query parameter into the destination.\n *\n * A known placeholder with no value becomes an empty string; an unrecognized `{…}` is left\n * exactly as configured, so a report URL that legitimately contains braces is not corrupted.\n */\n public resolve(url: string): string {\n if (!url || url.indexOf('{') === -1) {\n return url;\n }\n\n const values: Map<string, string> = this.getPlaceholderValues();\n\n let resolved: string = url;\n\n values.forEach((value: string, token: string) => {\n if (resolved.indexOf(token) === -1) {\n return;\n }\n\n if (value.length === 0) {\n console.warn(`External URL placeholder ${token} has no value for the current user; substituting an empty string.`, url);\n }\n\n // split/join rather than String.replace: replace() interprets `$&` and `$1` in the\n // replacement text, and without a global regex it would only swap the first occurrence.\n resolved = resolved.split(token).join(encodeURIComponent(value));\n });\n\n this.warnAboutUnknownPlaceholders(url, resolved);\n\n return resolved;\n }\n //#endregion\n\n //#region Private methods\n private getPlaceholderValues(): Map<string, string> {\n const user: ICurrentUserInfo | null = this.authenticationService.getUserInfo();\n\n return new Map<string, string>([\n ['{email}', user?.email ?? ''],\n ['{language}', this.translate.currentLang || this.translate.defaultLang || ''],\n ['{userId}', user?.userID?.toString() ?? ''],\n ['{userName}', user?.username ?? ''],\n ]);\n }\n\n private warnAboutUnknownPlaceholders(url: string, resolved: string): void {\n const unknown: string[] = resolved.match(this.unknownPlaceholderPattern) ?? [];\n\n if (unknown.length > 0) {\n console.warn(`External URL contains unrecognized placeholders and was left as configured: ${unknown.join(', ')}`, url);\n }\n }\n //#endregion\n}\n","import { inject, Injectable } from '@angular/core';\nimport { HubConnection, HubConnectionBuilder, HubConnectionState } from '@microsoft/signalr';\nimport { APP_CONFIG, AppConfig, AuthService } from '@zambon-dev/framework';\nimport { BehaviorSubject, map, Observable } from 'rxjs';\nimport { INotification } from '../models';\n\n/**\n * Streams top-bar notifications from a SignalR hub.\n *\n * The hub is configured via `AppConfig.notificationsEnabled` and `AppConfig.notificationsUrl`.\n * When enabled, {@link start} opens a connection (authenticated with the current JWT) and\n * listens for the server to push the notification list via the `ReceiveNotifications` client\n * method. Consuming apps do not interact with this service directly — the top bar drives it.\n */\n@Injectable({\n providedIn: 'root',\n})\nexport class NotificationsService {\n //#region Variables\n private authService: AuthService = inject(AuthService);\n private config: AppConfig = inject(APP_CONFIG);\n\n private connection?: HubConnection;\n private notifications$: BehaviorSubject<INotification[]> = new BehaviorSubject<INotification[]>([]);\n //#endregion\n\n //#region Properties\n /** Whether the notifications feature is enabled (toggled on and given a hub URL). */\n public get isEnabled(): boolean {\n return this.config.notificationsEnabled && this.config.notificationsUrl.length > 0;\n }\n //#endregion\n\n //#region Public methods\n /** Emits the current list of notifications. */\n public getNotifications(): Observable<INotification[]> {\n return this.notifications$.asObservable();\n }\n\n /** Emits the number of unread notifications. */\n public getUnreadCount(): Observable<number> {\n return this.notifications$.pipe(\n map((notifications: INotification[]) => notifications.filter((n: INotification) => !n.isRead).length),\n );\n }\n\n /** Marks every notification as read and notifies the hub. */\n public markAllAsRead(): void {\n this.notifications$.next(this.notifications$.value.map((n: INotification) => ({ ...n, isRead: true })));\n\n if (this.connection?.state === HubConnectionState.Connected) {\n this.connection.invoke('MarkAllAsRead').catch((error: unknown) => {\n console.error('Failed to mark notifications as read on the hub.', error);\n });\n }\n }\n\n /** Marks a single notification as read (optimistically; the server reconciles on the next push). */\n public markAsRead(notification: INotification): void {\n this.notifications$.next(\n this.notifications$.value.map((n: INotification) => (n === notification ? { ...n, isRead: true } : n)),\n );\n }\n\n /** Opens the SignalR connection and starts receiving notifications. Idempotent and a no-op when disabled. */\n public start(): void {\n if (!this.isEnabled || !!this.connection) {\n return;\n }\n\n this.connection = new HubConnectionBuilder()\n .withUrl(this.config.notificationsUrl, {\n accessTokenFactory: () => this.authService.token ?? '',\n })\n .withAutomaticReconnect()\n .build();\n\n this.connection.on('ReceiveNotifications', (notifications: INotification[]) => {\n this.notifications$.next(notifications ?? []);\n });\n\n this.connection.start().catch((error: unknown) => {\n console.error('Failed to connect to the notifications hub.', error);\n });\n }\n\n /** Closes the SignalR connection. */\n public async stop(): Promise<void> {\n if (this.connection) {\n await this.connection.stop();\n this.connection = undefined;\n }\n }\n //#endregion\n}\n","import { HttpClient } from '@angular/common/http';\nimport { inject, Injectable } from '@angular/core';\nimport { APP_CONFIG, AppConfig } from '@zambon-dev/framework';\nimport { IListParameters } from '@zambon-dev/library';\nimport { Observable } from 'rxjs';\nimport { IOperationsHistoryList } from '../models';\n\n@Injectable({\n providedIn: 'root'\n})\nexport class OperationsHistoryService {\n //#region ViewChilds, Inputs, Outputs\n //#endregion\n\n //#region Variables\n private config: AppConfig = inject(APP_CONFIG);\n private http: HttpClient = inject(HttpClient);\n //#endregion\n\n //#region Properties\n //#endregion\n\n //#region Constructor and Angular life cycle methods\n //#endregion\n\n //#region Event handlers\n //#endregion\n\n //#region Public methods\n public list(controllerName: string, entityID: number, serviceHistoryID: number, parameters: IListParameters): Observable<IOperationsHistoryList[]> {\n return this.http.post<IOperationsHistoryList[]>(`${this.config.BASE_URL}/${controllerName}/${entityID}/Audit/${serviceHistoryID}`, parameters);\n }\n //#endregion\n\n //#region Private methods\n //#endregion\n}","import { HttpClient } from '@angular/common/http';\nimport { inject, Injectable } from '@angular/core';\nimport { APP_CONFIG, AppConfig } from '@zambon-dev/framework';\nimport { IListParameters } from '@zambon-dev/library';\nimport { Observable } from 'rxjs';\nimport { IServicesHistoryList } from '../models';\n\n@Injectable({\n providedIn: 'root'\n})\nexport class ServicesHistoryService {\n //#region ViewChilds, Inputs, Outputs\n //#endregion\n\n //#region Variables\n private config: AppConfig = inject(APP_CONFIG);\n private http: HttpClient = inject(HttpClient);\n //#endregion\n\n //#region Properties\n //#endregion\n\n //#region Constructor and Angular life cycle methods\n //#endregion\n\n //#region Event handlers\n //#endregion\n\n //#region Public methods\n public list(controllerName: string, entityID: number, parameters: IListParameters): Observable<IServicesHistoryList[]> {\n return this.http.post<IServicesHistoryList[]>(`${this.config.BASE_URL}/${controllerName}/${entityID}/Audit`, parameters);\n }\n //#endregion\n\n //#region Private methods\n //#endregion\n}","import { Component, inject } from '@angular/core';\nimport { APP_CONFIG, AppConfig } from '@zambon-dev/framework';\n\n@Component({\n selector: 'shared-brand',\n templateUrl: './brand.component.html',\n styleUrls: ['./brand.component.scss'],\n})\nexport class BrandComponent {\n //#region Variables\n private config: AppConfig = inject(APP_CONFIG);\n //#endregion\n\n //#region Properties\n protected get appName(): string {\n return this.config.appName;\n }\n\n protected get companyName(): string {\n return this.config.companyName;\n }\n\n protected get logoUrl(): string | undefined {\n return this.config.logoUrl;\n }\n //#endregion\n}\n","<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","import { Component, inject } from '@angular/core';\nimport { APP_CONFIG, AppConfig } from '@zambon-dev/framework';\n\n@Component({\n selector: 'shared-environment-badge',\n templateUrl: './environment-badge.component.html',\n styleUrls: ['./environment-badge.component.scss'],\n})\nexport class EnvironmentBadgeComponent {\n //#region Variables\n private config: AppConfig = inject(APP_CONFIG);\n //#endregion\n\n //#region Properties\n /** CSS modifier class for the current environment, falling back to a neutral style. */\n protected get badgeClass(): string {\n const colorByEnvironment: Record<string, string> = {\n DEV: 'env-dev',\n QA: 'env-qa',\n STG: 'env-stg',\n };\n return colorByEnvironment[this.environment] ?? 'env-neutral';\n }\n\n /** Normalized environment key (uppercase, trimmed). */\n protected get environment(): string {\n return (this.config.environment ?? '').trim().toUpperCase();\n }\n\n /** The badge is hidden in production and when no environment is configured. */\n protected get isVisible(): boolean {\n return this.environment.length > 0 && this.environment !== 'PROD';\n }\n //#endregion\n}\n","@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","import { AsyncPipe } from '@angular/common';\nimport { Component, ElementRef, HostListener, inject, OnInit, ViewChild } from '@angular/core';\nimport { Router } from '@angular/router';\nimport { TranslatePipe } from '@ngx-translate/core';\nimport { Observable } from 'rxjs';\nimport { INotification } from '../../../models';\nimport { NotificationsService } from '../../../services';\n\n@Component({\n selector: 'shared-notifications',\n templateUrl: './notifications.component.html',\n styleUrls: ['./notifications.component.scss'],\n imports: [\n AsyncPipe,\n TranslatePipe,\n ],\n})\nexport class NotificationsComponent implements OnInit {\n //#region ViewChilds, Inputs, Outputs\n @ViewChild('dropdown') public dropdown!: ElementRef<HTMLDivElement>;\n //#endregion\n\n //#region Variables\n private notificationsService: NotificationsService = inject(NotificationsService);\n private router: Router = inject(Router);\n\n protected notifications$: Observable<INotification[]> = this.notificationsService.getNotifications();\n protected showDropdown = false;\n protected unreadCount$: Observable<number> = this.notificationsService.getUnreadCount();\n //#endregion\n\n //#region Properties\n /** Whether the notifications feature is enabled; when false the bell is not rendered. */\n public get isEnabled(): boolean {\n return this.notificationsService.isEnabled;\n }\n //#endregion\n\n //#region Constructor and Angular life cycle methods\n public ngOnInit(): void {\n this.notificationsService.start();\n }\n //#endregion\n\n //#region Event handlers\n public onDropdownClick(): void {\n this.showDropdown = !this.showDropdown;\n }\n\n public onMarkAllAsRead(): void {\n this.notificationsService.markAllAsRead();\n }\n\n public onNotificationClick(notification: INotification): void {\n this.notificationsService.markAsRead(notification);\n this.showDropdown = false;\n\n const url: string | undefined = notification.callToActionUrl;\n if (!url) {\n return;\n }\n\n if (/^https?:\\/\\//i.test(url)) {\n window.open(url, '_blank', 'noopener');\n } else {\n this.router.navigateByUrl(url);\n }\n }\n //#endregion\n\n //#region Private methods\n @HostListener('window:click', ['$event'])\n private documentClick(event: MouseEvent): void {\n if (this.showDropdown) {\n let target: HTMLElement = <HTMLElement>event.target;\n while (target !== null && target.tagName?.toUpperCase() !== 'BODY') {\n if (target === this.dropdown.nativeElement) {\n return;\n }\n target = <HTMLElement>target.parentElement;\n }\n this.showDropdown = false;\n }\n }\n //#endregion\n}\n","@if (isEnabled) {\n <div #dropdown class=\"notifications\">\n <button class=\"btn gray-300 notifications-toggle\" type=\"button\" (click)=\"onDropdownClick()\"\n [attr.aria-label]=\"'TopBar-Notifications-Title' | translate\">\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 type=\"button\" class=\"notifications-item-btn\"\n [class.has-cta]=\"!!item.callToActionUrl\" (click)=\"onNotificationClick(item)\">\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","import { Component, ElementRef, HostListener, inject, Input, ViewChild } from '@angular/core';\nimport { TranslatePipe, TranslateService } from '@ngx-translate/core';\n\n@Component({\n selector: 'shared-language-selector',\n templateUrl: './language-selector.component.html',\n styleUrls: ['./language-selector.component.scss'],\n imports: [\n TranslatePipe,\n ]\n})\nexport class LanguageSelectorComponent {\n //#region ViewChilds, Inputs, Outputs\n @ViewChild('dropdown') public dropdown!: ElementRef<HTMLDivElement>;\n\n /** When true, the toggle shows the current language's flag (light-gray button) instead of text. */\n @Input() public showFlag = false;\n\n @Input() public title = 'LanguageSelector-Title';\n //#endregion\n\n //#region Variables\n private translate: TranslateService = inject(TranslateService);\n\n protected languages: string[] = this.translate.getLangs();\n protected showDropdown = false;\n //#endregion\n\n //#region Properties\n public get selectedLanguage(): string {\n return this.translate.currentLang;\n }\n //#endregion\n\n //#region Constructor and Angular life cycle methods\n //#endregion\n\n //#region Event handlers\n public onDropdownClick(): void {\n this.showDropdown = !this.showDropdown;\n }\n\n public onSelectLanguage(language: string): void {\n localStorage.setItem('language', language);\n this.translate.use(language);\n this.showDropdown = false;\n }\n //#endregion\n\n //#region Public methods\n //#endregion\n\n //#region Private methods\n @HostListener('window:click', ['$event'])\n private documentClick(event: MouseEvent): void {\n if (this.showDropdown) {\n let target: HTMLElement = <HTMLElement>event.target;\n while (target !== null && target.tagName?.toUpperCase() !== 'BODY') {\n if (target === this.dropdown.nativeElement) {\n return;\n }\n target = <HTMLElement>target.parentElement;\n }\n this.showDropdown = false;\n }\n }\n //#endregion\n}\n","<div #dropdown class=\"dropdown right\" [class.show]=\"showDropdown\">\n <button class=\"btn\" type=\"button\" (click)=\"onDropdownClick()\"\n [class.gray-300]=\"showFlag\" [class.lang-flag-toggle]=\"showFlag\"\n [attr.aria-label]=\"showFlag ? (title | translate) : null\">\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 type=\"button\" class=\"dropdown-item\" [class.selected]=\"lang === selectedLanguage\"\n (click)=\"onSelectLanguage(lang)\">\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","import { Component, inject, OnInit } from '@angular/core';\nimport { ICurrentUserInfo } from '../../../models';\nimport { AuthenticationService } from '../../../services';\n\n@Component({\n selector: 'shared-user-profile',\n templateUrl: './user-profile.component.html',\n styleUrls: ['./user-profile.component.scss'],\n})\nexport class UserProfileComponent implements OnInit {\n //#region Variables\n private authenticationService: AuthenticationService = inject(AuthenticationService);\n\n protected user: ICurrentUserInfo | null = null;\n //#endregion\n\n //#region Properties\n /** Up to two uppercase initials derived from the user's name, used when no picture is set. */\n protected get initials(): string {\n const parts: string[] = this.name.trim().split(/\\s+/).filter((p: string) => p.length > 0);\n if (parts.length === 0) {\n return '';\n }\n\n const first: string = parts[0].charAt(0);\n const last: string = parts.length > 1 ? parts[parts.length - 1].charAt(0) : '';\n return (first + last).toUpperCase();\n }\n\n protected get name(): string {\n return this.user?.name ?? '';\n }\n\n protected get pictureUrl(): string | undefined {\n return this.user?.pictureUrl;\n }\n\n protected get position(): string {\n return this.user?.position ?? '';\n }\n //#endregion\n\n //#region Constructor and Angular life cycle methods\n public ngOnInit(): void {\n this.user = this.authenticationService.getUserInfo();\n }\n //#endregion\n}\n","<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","import { Component, EventEmitter, Output } from '@angular/core';\nimport { TranslatePipe } from '@ngx-translate/core';\nimport { LanguageSelectorComponent } from '../../auth/components/language-selector/language-selector.component';\nimport { BrandComponent } from './brand/brand.component';\nimport { EnvironmentBadgeComponent } from './environment-badge/environment-badge.component';\nimport { NotificationsComponent } from './notifications/notifications.component';\nimport { UserProfileComponent } from './user-profile/user-profile.component';\n\n@Component({\n selector: 'shared-top-bar',\n templateUrl: './top-bar.component.html',\n styleUrls: ['./top-bar.component.scss'],\n imports: [\n BrandComponent,\n EnvironmentBadgeComponent,\n LanguageSelectorComponent,\n NotificationsComponent,\n TranslatePipe,\n UserProfileComponent,\n ],\n})\nexport class TopBarComponent {\n //#region ViewChilds, Inputs, Outputs\n /** Emitted when the logout button is clicked. */\n @Output() public logout: EventEmitter<void> = new EventEmitter<void>();\n //#endregion\n\n //#region Event handlers\n public onLogoutClick(): void {\n this.logout.emit();\n }\n //#endregion\n}\n","<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 class=\"btn gray-300 top-bar-logout\" type=\"button\" (click)=\"onLogoutClick()\"\n [attr.aria-label]=\"'Main-Logout' | translate\">\n <i class=\"fa-solid fa-arrow-right-from-bracket\"></i>\n </button>\n </div>\n</div>\n","import { Component, inject, OnDestroy, OnInit, ViewChild } from '@angular/core';\nimport { Router, RouterModule } from '@angular/router';\nimport { APP_CONFIG, ITab, Tab, TabsComponent, TabService } from '@zambon-dev/framework';\nimport { ModalComponent, SidebarComponent, SidebarMenu, SidebarMenuOpenMode, SidebarService, toSidebarMenuOpenMode } from '@zambon-dev/library';\nimport { TranslatePipe } from '@ngx-translate/core';\nimport { Subject, take, takeUntil } from 'rxjs';\nimport { EXTERNAL_CONTENT_ROUTE_PATH } from '../../models';\nimport { AuthenticationService, ExternalContentService, ExternalUrlResolverService } from '../../services';\nimport { TopBarComponent } from '../top-bar';\n\n@Component({\n selector: 'shared-main-layout',\n templateUrl: './main-layout.component.html',\n styleUrls: ['./main-layout.component.scss'],\n imports: [\n ModalComponent,\n RouterModule,\n SidebarComponent,\n TabsComponent,\n TopBarComponent,\n TranslatePipe,\n ]\n})\nexport class MainLayoutComponent implements OnInit, OnDestroy {\n //#region ViewChilds, Inputs, Outputs\n @ViewChild('logoutModal') private logoutModal!: ModalComponent;\n //#endregion\n\n //#region Variables\n private authenticationService: AuthenticationService = inject(AuthenticationService);\n private destroy$: Subject<boolean> = new Subject<boolean>();\n private externalContentService: ExternalContentService = inject(ExternalContentService);\n private externalUrlResolverService: ExternalUrlResolverService = inject(ExternalUrlResolverService);\n private router: Router = inject(Router);\n private sidebarService: SidebarService = inject(SidebarService);\n private tabService: TabService = inject(TabService);\n\n /** Application version (from AppConfig) projected into the sidebar footer. */\n protected appVersion: string = inject(APP_CONFIG).version;\n //#endregion\n\n //#region Properties\n //#endregion\n\n //#region Constructor and Angular life cycle methods\n\n public ngOnDestroy(): void {\n this.destroy$.next(true);\n this.destroy$.complete();\n }\n\n public ngOnInit(): void {\n const url: string = this.router.url;\n\n if (url !== '/' && !this.tabService.isUrlOpen(url)) {\n this.sidebarService.getMenuFromUrl(url)\n .pipe(take(1))\n .subscribe({\n next: (item: SidebarMenu) => {\n if (item) {\n this.tabService.updateTabTitle(url, item.label);\n }\n },\n // A deep-linked title is best-effort. Menu endpoints answer 404 for a URL they do not\n // know -- the embedded-content route among them -- and that must not surface as an\n // unhandled rejection.\n error: () => undefined,\n });\n }\n\n this.sidebarService.menuExternalUrlSelected\n .pipe(takeUntil(this.destroy$))\n .subscribe((item: SidebarMenu) => this.openExternalMenu(item));\n\n this.sidebarService.menuUrlSelected\n .pipe(takeUntil(this.destroy$))\n .subscribe((item: SidebarMenu) => {\n const tab: ITab = new Tab({\n title: item.label,\n url: item.url,\n });\n this.tabService.openTab(tab);\n });\n }\n //#endregion\n\n //#region Event handlers\n //#endregion\n\n //#region Public methods\n public onLogoutClick(): void {\n this.logoutModal.toggleModal();\n }\n\n public onLogoutConfirm(): void {\n this.authenticationService.signOut();\n this.router.navigate(['/login']);\n }\n //#endregion\n\n //#region Private methods\n private openExternalMenu(item: SidebarMenu): void {\n const rawUrl: string = item.url ?? '';\n\n if (rawUrl.length === 0) {\n return;\n }\n\n if (toSidebarMenuOpenMode(item.openMode) === SidebarMenuOpenMode.ExternalEmbedded) {\n // The tab has to be a real Angular route, so the destination travels by menu id and is\n // resolved by ExternalContentComponent. A `?url=` query string would collapse every\n // embedded tab into one -- TabService and CustomReuseStrategy key tabs on path segments\n // only -- and would also let anyone frame an arbitrary site inside our own chrome.\n this.externalContentService.register(item);\n\n const tab: ITab = new Tab({\n title: item.label,\n url: `/${EXTERNAL_CONTENT_ROUTE_PATH}/${item.id}`,\n });\n this.tabService.openTab(tab);\n\n return;\n }\n\n const url: string = this.externalUrlResolverService.resolve(rawUrl);\n\n if (!this.externalUrlResolverService.isAllowed(url)) {\n console.error(`Sidebar menu \"${item.label}\" points to an unsupported external address and was not opened.`, url);\n return;\n }\n\n window.open(url, '_blank', 'noopener,noreferrer');\n }\n //#endregion\n}","<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()\">{{ 'Main-Logout-Modal-Message-Confirm' | translate }}</button>\n </div>\n</lib-modal>","import { NgIf } from '@angular/common';\nimport { Component, ElementRef, inject, OnInit, ViewChild } from '@angular/core';\nimport { FormBuilder, FormGroup, ReactiveFormsModule, Validators } from '@angular/forms';\nimport { Router, RouterModule } from '@angular/router';\nimport { TranslatePipe } from '@ngx-translate/core';\nimport { finalize, tap } from 'rxjs';\nimport { AuthenticationService } from '../../../services';\nimport { LanguageSelectorComponent } from '../language-selector/language-selector.component';\n\n@Component({\n selector: 'shared-login',\n templateUrl: './login.component.html',\n styleUrls: ['./login.component.scss'],\n imports: [\n LanguageSelectorComponent,\n NgIf,\n ReactiveFormsModule,\n RouterModule,\n TranslatePipe,\n ]\n})\nexport class LoginComponent implements OnInit {\n //#region ViewChilds, Inputs, Outputs\n @ViewChild('username') public username!: ElementRef<HTMLInputElement>;\n //#endregion\n\n //#region Variables\n protected form!: FormGroup;\n protected formState: {\n error: string | null,\n loading: boolean,\n success: boolean,\n } = {\n error: null,\n loading: false,\n success: false\n };\n\n private authenticationService: AuthenticationService = inject(AuthenticationService);\n private formBuilder: FormBuilder = inject(FormBuilder);\n private router: Router = inject(Router);\n //#endregion\n\n //#region Properties\n //#endregion\n\n //#region Constructor and Angular life cycle methods\n\n public ngOnInit(): void {\n this.form = this.formBuilder.group({\n password: ['', Validators.required],\n rememberMe: [false, { nonNullable: true }],\n username: ['', Validators.required],\n });\n }\n //#endregion\n\n //#region Event handlers\n public onSubmit(): void {\n this.form.markAllAsTouched();\n\n if (this.form.valid) {\n this.form.disable();\n \n this.formState.loading = true;\n this.formState.error = null;\n\n this.authenticationService.authenticate({\n username: this.form.get('username')?.value.toString() ?? '',\n password: this.form.get('password')?.value.toString() ?? '',\n rememberMe: this.form.get('rememberMe')?.value ?? false\n })\n .pipe(\n tap(() => { \n this.formState.success = true\n }),\n finalize(() => this.formState.loading = false)\n )\n .subscribe({\n next: () => {\n const params: URLSearchParams = new URLSearchParams(window.location.search);\n \n this.router.navigate([params.get('returnUrl') ?? '/']);\n },\n error: (e: string) => {\n this.form.enable();\n\n this.form.controls['password'].setValue('');\n this.form.controls['password'].markAsUntouched();\n \n this.username.nativeElement.focus();\n\n switch(e) {\n case 'InvalidUsernamePassword':\n this.formState.error = 'invalid';\n break;\n default:\n this.formState.error = 'internalServerError';\n break;\n }\n }\n });\n }\n }\n //#endregion\n\n //#region Public methods\n //#endregion\n\n //#region Private methods\n //#endregion\n}","<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\n <div class=\"validations\" [class.hidden]=\"!formState.error\">\n \n <div *ngIf=\"formState.error === 'invalid'\">\n {{'Login-Errors-Invalid' | translate}}\n </div>\n \n <div *ngIf=\"formState.error === 'internalServerError'\">{{'Login-Errors-InternalServerError' | translate}}</div>\n </div>\n\n <div class=\"input-group inline\">\n <input type=\"text\" #username id=\"username\" formControlName=\"username\" class=\"form-input peer\" [placeholder]=\"'Login-Username' | translate\" />\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 <span *ngIf=\"form.get('username')?.hasError('required')\">{{ 'Login-Username-Required' | translate }}</span>\n </div>\n </div>\n \n <div class=\"input-group inline\">\n <input type=\"password\" id=\"password\" formControlName=\"password\" class=\"form-input\" [placeholder]=\"'Login-Password' | translate\" />\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 <span *ngIf=\"form.get('password')?.hasError('required')\">{{ 'Login-Password-Required' | translate }}</span>\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 type=\"submit\" class=\"btn\"\n [class.loading]=\"formState.loading && !formState.success && !formState.error\"\n [class.error]=\"formState.error\"\n [class.success]=\"formState.success\">\n <i *ngIf=\"!formState.loading\" class=\"fas fa-sign-in-alt fa-fw\"></i>\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>","import { NgModule } from '@angular/core';\nimport { RouterModule, Routes } from '@angular/router';\nimport { LoginLayoutComponent } from '../layouts';\nimport { LoginComponent } from './components';\n\n\nconst routes: Routes = [\n { path: '', component: LoginLayoutComponent, children: [\n { path: '', redirectTo: 'login', pathMatch: 'full' },\n { path: 'login', component: LoginComponent },\n ] },\n];\n\n@NgModule({\n imports: [\n RouterModule.forChild(routes),\n ]\n})\nexport class SharedAuthModule {}\n","import { inject, Injectable } from '@angular/core';\nimport { ActivatedRouteSnapshot, CanActivate, Router, RouterStateSnapshot } from '@angular/router';\nimport { AuthenticationService } from '../../services';\n\n@Injectable({\n providedIn: 'root'\n})\nexport class AuthGuard implements CanActivate {\n //#region ViewChilds, Inputs, Outputs\n //#endregion\n\n //#region Variables\n private authenticationService: AuthenticationService = inject(AuthenticationService);\n private router: Router = inject(Router);\n //#endregion\n\n //#region Properties\n //#endregion\n\n //#region Constructor and Angular life cycle methods\n //#endregion\n\n //#region Event handlers\n //#endregion\n\n //#region Public methods\n public canActivate(_: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {\n if (!this.authenticationService.isAuthenticated) {\n this.router.navigate(['/login'], { queryParams: { returnUrl: state.url } });\n return false;\n }\n return true;\n }\n //#endregion\n\n //#region Private methods\n //#endregion\n}","import { HttpErrorResponse, HttpEvent, HttpHandler, HttpInterceptor, HttpRequest } from '@angular/common/http';\nimport { inject, Injectable } from '@angular/core';\nimport { Router } from '@angular/router';\nimport { JwtInterceptor } from '@auth0/angular-jwt';\nimport { APP_CONFIG, AppConfig } from '@zambon-dev/framework';\nimport { catchError, Observable, shareReplay, switchMap, tap } from 'rxjs';\nimport { AuthenticationService } from '../../services';\n\n@Injectable()\nexport class AuthInterceptor implements HttpInterceptor {\n //#region ViewChilds, Inputs, Outputs\n //#endregion\n\n //#region Variables\n private authenticationService: AuthenticationService = inject(AuthenticationService);\n private config: AppConfig = inject(APP_CONFIG);\n private jwtInterceptor: JwtInterceptor = inject(JwtInterceptor);\n private refreshToken$?: Observable<string>;\n private router: Router = inject(Router);\n //#endregion\n\n //#region Properties\n //#endregion\n\n //#region Constructor and Angular life cycle methods\n //#endregion\n\n //#region Event handlers\n //#endregion\n\n //#region Public methods\n public intercept(request: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>> {\n if (\n request.url.indexOf(this.config.BASE_URL) >= 0 &&\n !this.jwtInterceptor.isDisallowedRoute(request) &&\n this.authenticationService.isTokenExpired\n ) {\n if (!this.refreshToken$) {\n this.refreshToken$ = this.authenticationService.tryRefreshToken()\n .pipe(\n shareReplay(),\n tap(() => {\n this.refreshToken$ = undefined;\n })\n );\n }\n\n return this.refreshToken$!\n .pipe(\n switchMap((token: string) => {\n return next.handle(\n request.clone({ setHeaders: { authorization: `Bearer ${token}` } })\n );\n }),\n catchError((err: HttpErrorResponse) => {\n if (err.status === 401) {\n this.authenticationService.signOut();\n this.router.navigate(['/login']);\n }\n throw err;\n })\n );\n }\n return next.handle(request);\n }\n //#endregion\n\n //#region Private methods\n //#endregion\n}","import { Component, inject, OnDestroy, OnInit, ViewChild } from '@angular/core';\nimport { FormBuilder, FormGroup } from '@angular/forms';\nimport { ButtonFiltersComponent } from '@zambon-dev/framework';\nimport { Subject } from 'rxjs';\n\n@Component({ template: '' })\nexport abstract class FiltersBase implements OnInit, OnDestroy {\n //#region ViewChilds, Inputs, Outputs\n @ViewChild(ButtonFiltersComponent) protected buttonFilters?: ButtonFiltersComponent;\n //#endregion\n\n //#region Variables\n protected destroy$: Subject<boolean> = new Subject<boolean>();\n protected filterForm!: FormGroup;\n protected formBuilder: FormBuilder = inject(FormBuilder);\n //#endregion\n\n //#region Properties\n //#endregion\n \n //#region Constructor and Angular life cycle methods\n\n public ngOnDestroy(): void {\n this.destroy$.next(true);\n this.destroy$.complete();\n }\n\n public ngOnInit(): void {\n this.filterForm = this.formSetup();\n }\n //#endregion\n\n //#region Event handlers\n //#endregion\n\n //#region Public methods\n public setFilters(filters: { [key: string ] : any }): void {\n this.filterForm.patchValue(filters);\n\n setTimeout(() => {\n if (this.buttonFilters) {\n this.buttonFilters.setFilters(filters);\n }\n });\n }\n //#endregion\n\n //#region Private methods\n //#endregion\n\n //#region Abstract methods\n protected abstract formSetup(): FormGroup<any>;\n //#endregion\n}\n","import { DOCUMENT } from '@angular/common';\nimport { Component, inject, OnInit, OnDestroy } from '@angular/core';\nimport { DomSanitizer, SafeResourceUrl } from '@angular/platform-browser';\nimport { ActivatedRoute } from '@angular/router';\nimport { ButtonComponent, TabService, TabViewBase } from '@zambon-dev/framework';\nimport { RibbonGroupComponent } from '@zambon-dev/library';\nimport { TranslatePipe } from '@ngx-translate/core';\nimport { take, takeUntil } from 'rxjs';\nimport { EXTERNAL_CONTENT_CONFIGS, ExternalContentConfigs, IExternalContentEntry } from '../../models';\nimport { ExternalContentService, ExternalUrlResolverService } from '../../services';\n\n/**\n * Displays an external destination inside an application tab.\n *\n * Routed as `/external-content/:menuID` — the destination itself never travels in the URL, so no\n * one can hand-craft a link that makes the application frame an arbitrary site.\n *\n * A `TabViewBase` like any other screen, so its actions live in the ribbon rather than in a\n * bar of its own: it must be routed under `DefaultTabViewComponent`, which is what renders the\n * `#ribbon` template this view publishes. Use the exported `externalContentRoutes`.\n */\n@Component({\n selector: 'shared-external-content',\n templateUrl: './external-content.component.html',\n styleUrls: ['./external-content.component.scss'],\n imports: [\n ButtonComponent,\n RibbonGroupComponent,\n TranslatePipe,\n ]\n})\nexport class ExternalContentComponent extends TabViewBase implements OnInit, OnDestroy {\n //#region ViewChilds, Inputs, Outputs\n //#endregion\n\n //#region Variables\n protected frameUrl?: SafeResourceUrl;\n protected isBlocked = false;\n protected isFrameLoading = false;\n protected isInsecure = false;\n protected isSlow = false;\n protected isUnavailable = false;\n protected label = '';\n protected resolvedUrl = '';\n\n private activatedRoute: ActivatedRoute = inject(ActivatedRoute);\n private configs: ExternalContentConfigs = inject(EXTERNAL_CONTENT_CONFIGS);\n private document: Document = inject(DOCUMENT);\n private externalContentService: ExternalContentService = inject(ExternalContentService);\n private externalUrlResolverService: ExternalUrlResolverService = inject(ExternalUrlResolverService);\n private sanitizer: DomSanitizer = inject(DomSanitizer);\n private slowHintTimeout?: ReturnType<typeof setTimeout>;\n private tabService: TabService = inject(TabService);\n //#endregion\n\n //#region Properties\n //#endregion\n\n //#region Constructor and Angular life cycle methods\n constructor() {\n super();\n }\n\n public override ngOnDestroy(): void {\n this.clearSlowHint();\n\n super.ngOnDestroy();\n }\n\n public ngOnInit(): void {\n const menuID = Number(this.activatedRoute.snapshot.paramMap.get('menuID'));\n\n if (!menuID) {\n this.isUnavailable = true;\n this.loading = false;\n\n return;\n }\n\n this.externalContentService.find(menuID)\n .pipe(take(1), takeUntil(this.destroy$))\n .subscribe((entry: IExternalContentEntry | undefined) => this.show(entry));\n }\n //#endregion\n\n //#region Event handlers\n protected onFrameLoad(): void {\n this.clearSlowHint();\n\n this.isFrameLoading = false;\n this.isSlow = false;\n }\n\n protected onOpenInNewTab(): void {\n window.open(this.resolvedUrl, '_blank', 'noopener,noreferrer');\n }\n\n protected onReload(): void {\n const url: SafeResourceUrl | undefined = this.frameUrl;\n\n if (!url || this.isFrameLoading) {\n return;\n }\n\n // The frame is cross-origin, so its location cannot be touched from here: destroying the\n // element and building a new one is the only way to make it navigate again. That also clears\n // the previous render, which is the point -- otherwise a reload leaves the old content on\n // screen and the user cannot tell whether anything happened.\n //\n // The rebuild has to wait for a macrotask, not a microtask. Angular coalesces changes within a\n // change-detection cycle, so setting frameUrl back before the next tick means @if sees the\n // value go A -> undefined -> A and never toggles: the element is never destroyed, nothing\n // navigates, no `load` ever fires, and the view spins until the timeout gives up. Yielding to\n // a timeout lets a cycle run with the frame unmounted, which is what really tears it down.\n this.frameUrl = undefined;\n this.isFrameLoading = true;\n\n setTimeout(() => this.displayFrame(url));\n }\n //#endregion\n\n //#region Public methods\n //#endregion\n\n //#region Private methods\n private clearSlowHint(): void {\n if (this.slowHintTimeout !== undefined) {\n clearTimeout(this.slowHintTimeout);\n this.slowHintTimeout = undefined;\n }\n }\n\n private isMixedContent(url: string): boolean {\n // A browser refuses to embed an http:// frame in an https:// page, unconditionally: an iframe\n // is active mixed content. Nothing on this side can permit it -- no attribute, no header, and\n // not CSP, which only ever restricts further. Left alone the frame renders empty, so this is\n // checked up front to say so instead.\n //\n // Unlike a site refusing to be framed, this one IS knowable before trying: both protocols are\n // in hand. `new URL` cannot throw here -- isAllowed has already parsed the same string -- and\n // it normalises the scheme's case, which a prefix test would not.\n return this.document.location.protocol === 'https:' && new URL(url).protocol === 'http:';\n }\n\n private isOriginAllowed(url: string): boolean {\n if (this.configs.allowedOrigins.length === 0) {\n return true;\n }\n\n try {\n return this.configs.allowedOrigins.indexOf(new URL(url).origin) !== -1;\n } catch {\n return false;\n }\n }\n\n private show(entry: IExternalContentEntry | undefined): void {\n // TabViewBase starts every screen loading so its ribbon buttons begin disabled; every exit\n // from here has to clear it or they never become usable.\n this.loading = false;\n\n if (!entry || !entry.url) {\n this.isUnavailable = true;\n\n return;\n }\n\n this.label = entry.label;\n\n // MainLayoutComponent only resolves a deep-linked title through getMenuFromUrl, and a Tab\n // starts with isTitleLoading true, so a tab re-created by TabsComponent after a refresh would\n // spin forever if nothing set its title. Setting it here is idempotent.\n this.tabService.updateActiveTabRootTitle(entry.label);\n\n // Order matters: resolve, then validate, then trust. What we vet has to be exactly what the\n // browser receives, and a placeholder is substituted before the scheme can be inspected.\n const url: string = this.externalUrlResolverService.resolve(entry.url);\n\n if (!this.externalUrlResolverService.isAllowed(url) || !this.isOriginAllowed(url)) {\n console.error(`Embedded menu item \"${entry.label}\" points to an address that is not allowed and was not displayed.`, url);\n this.isBlocked = true;\n\n return;\n }\n\n // Set before the mixed-content check, not after: that state still offers 'open in a new\n // browser tab', and the button reads this to decide whether it has anywhere to go.\n this.resolvedUrl = url;\n\n if (this.isMixedContent(url)) {\n this.isInsecure = true;\n\n return;\n }\n\n // Trusted once, into a field. From a getter or a pipe this would hand back a new\n // SafeResourceUrl on every change-detection pass, and Angular would re-set the iframe's src\n // and reload the destination each time.\n this.displayFrame(this.sanitizer.bypassSecurityTrustResourceUrl(url));\n }\n\n private displayFrame(url: SafeResourceUrl): void {\n this.isFrameLoading = true;\n this.frameUrl = url;\n\n this.startSlowHint();\n }\n\n private startSlowHint(): void {\n this.clearSlowHint();\n\n // Not detection, and it must never be turned into one: whether a site refuses to be framed\n // (X-Frame-Options, CSP frame-ancestors) is not observable from JavaScript. A refused frame\n // usually fires `load` immediately and renders the browser's own error page, in which case\n // this hint never appears -- the ribbon's \"open in a new browser tab\" button is the actual\n // way out, and it is always present.\n this.slowHintTimeout = setTimeout(() => {\n // Stop claiming it is loading. A destination that never reports `load` -- a refused frame\n // among them -- would otherwise spin forever and keep the actions disabled; hand the\n // controls back and let the hint do the explaining.\n this.isFrameLoading = false;\n this.isSlow = true;\n }, this.configs.slowFrameHintDelay);\n }\n //#endregion\n}\n","<!-- 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 </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 </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\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 class=\"opacity-75\" fill=\"currentColor\" 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\"></path>\n </svg>\n\n <span>{{ 'Loading' | translate }}</span>\n </div>\n }\n\n @if (frameUrl) {\n <iframe 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 </iframe>\n }\n </div>\n }\n}\n","import { Routes } from '@angular/router';\nimport { DefaultTabViewComponent, FRAMEWORK_VIEW_TYPE, FrameworkViewType } from '@zambon-dev/framework';\nimport { EXTERNAL_CONTENT_ROUTE_PATH } from '../../models';\nimport { ExternalContentComponent } from './external-content.component';\n\n/**\n * Route table for embedded external content. Spread it into `MainLayoutComponent`'s children:\n *\n * ```ts\n * { path: '', component: MainLayoutComponent, canActivate: [AuthGuard], children: [\n * ...externalContentRoutes,\n * // the application's own features\n * ] }\n * ```\n *\n * Three things about the shape are load-bearing and must not be \"simplified\" away:\n *\n * - The path is nested one segment per route. `RouteHelper.getRouteURL` and\n * `CustomReuseStrategy.getUrlFromRoute` collect segments walking up the parent chain and then\n * reverse the flat list, so a route declared `'external-content/:menuID'` rebuilds as\n * `/:menuID/external-content` and every tab URL is wrong.\n * - `DefaultTabViewComponent` hosts the view. It is what renders the `#ribbon` template the\n * component publishes, so dropping it leaves the Reload and Open-in-a-new-browser-tab actions\n * with nowhere to appear.\n * - `FRAMEWORK_VIEW_TYPE` must be present. `TabsComponent` re-creates the tab after a page refresh\n * by looking for a `Details` or `List` view in the activated route tree, and navigates to `/`\n * when it finds neither — the embedded tab would vanish on F5.\n */\nexport const externalContentRoutes: Routes = [\n {\n path: EXTERNAL_CONTENT_ROUTE_PATH,\n children: [\n {\n path: ':menuID',\n component: DefaultTabViewComponent,\n data: { [FRAMEWORK_VIEW_TYPE]: FrameworkViewType.List },\n children: [\n { path: '', component: ExternalContentComponent },\n ],\n },\n ],\n },\n];\n","import { inject, Injectable } from '@angular/core';\nimport { DataGridDataset, IGridColumn, IListParameters } from '@zambon-dev/library';\nimport { Observable, of } from 'rxjs';\nimport { IOperationsHistoryList } from '../models';\nimport { OperationsHistoryService } from '../services';\n\n@Injectable()\nexport class OperationsHistoryDataset extends DataGridDataset {\n //#region ViewChilds, Inputs, Outputs\n //#endregion\n\n //#region Variables\n public override columns: IGridColumn[] = [\n { field: '', headerName: '' },\n ];\n public controllerName?: string;\n\n protected operationsHistoryService: OperationsHistoryService = inject(OperationsHistoryService);\n\n private _serviceID?: number | undefined;\n //#endregion\n\n //#region Properties\n public set serviceId(value: number | undefined) {\n if (this._serviceID !== value) {\n this._serviceID = value;\n this.refresh();\n }\n }\n //#endregion\n\n //#region Constructor and Angular life cycle methods\n constructor() {\n super();\n\n this.configs.hideColumnHeaders = true;\n this.configs.showMessageOnEmpty = false;\n }\n //#endregion\n\n //#region Event handlers\n //#endregion\n\n //#region Public methods\n public getData(params: IListParameters): Observable<IOperationsHistoryList[]> {\n this.configs.showMessageOnEmpty = !!this._serviceID;\n\n return !!this.parentEntityId && !!this.controllerName && !!this._serviceID\n ? this.operationsHistoryService.list(this.controllerName, this.parentEntityId, this._serviceID, params)\n : of<IOperationsHistoryList[]>([]);\n }\n //#endregion\n\n //#region Private methods\n //#endregion\n}","import { inject, Injectable } from '@angular/core';\nimport { DataGridDataset, IGridColumn, IListParameters } from '@zambon-dev/library';\nimport { Observable, of } from 'rxjs';\nimport { IServicesHistoryList } from '../models';\nimport { ServicesHistoryService } from '../services';\n\n@Injectable()\nexport class ServicesHistoryDataset extends DataGridDataset {\n //#region ViewChilds, Inputs, Outputs\n //#endregion\n\n //#region Variables\n public override columns: IGridColumn[] = [\n { field: '', headerName: '' },\n ];\n\n public controllerName?: string;\n\n protected servicesHistoryService: ServicesHistoryService = inject(ServicesHistoryService);\n //#endregion\n\n //#region Properties\n //#endregion\n\n //#region Constructor and Angular life cycle methods\n constructor() {\n super();\n\n this.configs.hideColumnHeaders = true;\n this.configs.rowHeight = 52;\n }\n //#endregion\n\n //#region Event handlers\n //#endregion\n\n //#region Public methods\n public getData(params: IListParameters): Observable<IServicesHistoryList[]> {\n return !!this.parentEntityId && !!this.controllerName\n ? this.servicesHistoryService.list(this.controllerName, this.parentEntityId, params)\n : of<IServicesHistoryList[]>([]);\n }\n //#endregion\n\n //#region Private methods\n //#endregion\n}","import { JsonPipe } from '@angular/common';\nimport { Component, Input, ViewChild } from '@angular/core';\nimport { ModalBase } from '@zambon-dev/framework';\nimport { ModalComponent } from '@zambon-dev/library';\nimport { TranslatePipe } from '@ngx-translate/core';\n\n@Component({\n selector: 'shared-operations-history-modal',\n templateUrl: './operations-history-modal.component.html',\n styleUrls: ['./operations-history-modal.component.scss'],\n imports: [\n JsonPipe,\n ModalComponent,\n TranslatePipe,\n ],\n})\nexport class OperationsHistoryModalComponent extends ModalBase {\n //#region ViewChilds, Inputs, Outputs\n @ViewChild(ModalComponent) private modal!: ModalComponent;\n\n @Input() public newValues?: string;\n\n @Input() public oldValues?: string;\n //#endregion\n\n //#region Variables\n //#endregion\n\n //#region Properties\n public get isModalShown(): boolean {\n return this.modal.isShown;\n }\n //#endregion\n\n //#region Constructor and Angular life cycle methods\n //#endregion\n\n //#region Event handlers\n //#endregion\n\n //#region Public methods\n public toggle(): void {\n this.modal.toggleModal();\n }\n //#endregion\n\n //#region Private methods\n //#endregion\n}","<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>","import { AfterViewInit, Component, Input, TemplateRef, ViewChild } from '@angular/core';\nimport { ChildList } from '@zambon-dev/framework';\nimport { DataGridComponent, DataGridDataset } from '@zambon-dev/library';\nimport { OperationsHistoryDataset } from '../../../datasets';\nimport { IOperationsHistoryList } from '../../../models';\nimport { OperationsHistoryModalComponent } from '../operations-history-modal/operations-history-modal.component';\n\n@Component({\n selector: 'shared-operations-history-child-list',\n templateUrl: './operations-history-child-list.component.html',\n styleUrls: ['./operations-history-child-list.component.scss'],\n imports: [\n DataGridComponent,\n OperationsHistoryModalComponent,\n ],\n providers: [{ provide: DataGridDataset, useClass: OperationsHistoryDataset }]\n})\nexport class OperationsHistoryChildListComponent extends ChildList<any> implements AfterViewInit {\n //#region ViewChilds, Inputs, Outputs\n @ViewChild(OperationsHistoryModalComponent) private modal!: OperationsHistoryModalComponent;\n @ViewChild('operationTemplate') private operationTemplate!: TemplateRef<any>;\n\n @Input() public set controllerName(value: string) {\n (<OperationsHistoryDataset>this.dataGridDataset).controllerName = value;\n }\n\n @Input() public set serviceID(value: number | undefined) {\n (<OperationsHistoryDataset>this.dataGridDataset).serviceId = value;\n }\n //#endregion\n\n //#region Variables\n public selectedNewValues: any | null = null;\n public selectedOldValues: any | null = null;\n //#endregion\n\n //#region Properties\n //#endregion\n\n //#region Constructor and Angular life cycle methods\n public ngAfterViewInit(): void {\n this.dataGridDataset.columns[0].template = this.operationTemplate;\n }\n //#endregion\n\n //#region Event handlers\n public openModal(): void {\n if (!this.modal.isModalShown) {\n this.modal.toggle();\n }\n }\n //#endregion\n\n //#region Public methods\n public override selectedRowChanged(): void {\n super.selectedRowChanged();\n\n if (this.dataGridDataset.hasSelectedRows) {\n const key: string = this.dataGridDataset.selectedRowKeys[0];\n \n const data: IOperationsHistoryList = this.dataGridDataset.getRowData(key);\n this.selectedOldValues = JSON.parse(data.oldValues?.trim() ?? '');\n this.selectedNewValues = JSON.parse(data.newValues?.trim() ?? '');\n }\n }\n //#endregion\n\n //#region Private methods\n //#endregion\n}","<lib-data-grid [lazyLoadRows]=\"true\">\n</lib-data-grid>\n\n<ng-template #operationTemplate let-rowData=\"rowData\">\n <div class=\"operation-content\" (click)=\"openModal()\">\n <span 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 {{ rowData.operationType }}\n </span>\n {{ rowData.entityName }}\n </div>\n</ng-template>\n\n<shared-operations-history-modal\n[newValues]=\"selectedNewValues\"\n[oldValues]=\"selectedOldValues\">\n</shared-operations-history-modal>","import { inject, Pipe, PipeTransform } from '@angular/core';\nimport { DomSanitizer, SafeHtml } from '@angular/platform-browser';\n\n/**\n * Pipe that bypasses Angular's built-in HTML sanitization.\n *\n * **WARNING: This pipe introduces XSS (Cross-Site Scripting) risk.**\n * It marks the provided HTML string as trusted, meaning Angular will\n * render it without any sanitization. Malicious content such as\n * `<script>` tags, inline event handlers (`onerror`, `onclick`, etc.),\n * and `javascript:` URLs will be executed in the user's browser.\n *\n * ### Safe usage\n * - Server-rendered HTML from **trusted, internal APIs** that never\n * include user-generated content (e.g., admin-authored rich text\n * that is sanitized server-side before storage).\n * - Static HTML snippets defined in application code.\n *\n * ### Unsafe usage (DO NOT use for these)\n * - Any value that originates from user input (form fields, query\n * params, URL fragments, file uploads).\n * - Third-party API responses whose content you do not control.\n * - Database fields that may contain unsanitized user submissions.\n *\n * @example\n * // Safe — trusted server content\n * <div [innerHTML]=\"trustedServerHtml | bypassHtmlSanitizer\"></div>\n *\n * // UNSAFE — user-provided content (use Angular’s default sanitization instead)\n * <div [innerHTML]=\"comment.body | bypassHtmlSanitizer\"></div> // ❌ XSS risk\n * <div [innerHTML]=\"comment.body\"></div> // ✅ Angular sanitizes automatically\n */\n@Pipe({\n name: 'bypassHtmlSanitizer'\n})\nexport class BypassHtmlSanitizerPipe implements PipeTransform {\n private sanitizer: DomSanitizer = inject(DomSanitizer);\n\n public transform(html: string): SafeHtml {\n return this.sanitizer.bypassSecurityTrustHtml(html);\n }\n}\n","import { Pipe, PipeTransform } from '@angular/core';\n\n@Pipe({\n name: 'enumLabel'\n})\nexport class EnumLabelPipe implements PipeTransform {\n public transform(value?: number, enumType?: any): string {\n if (value === undefined || enumType === undefined) {\n return '';\n }\n\n const keys: string[] = Object.keys(enumType).filter((key: string) => !isNaN(Number(enumType[key])));\n const values: number[] = keys.map((key: string) => enumType[key]);\n\n const index: number = values.indexOf(value);\n if (index >= 0) {\n return keys[index];\n }\n return '';\n }\n}","import { Pipe, PipeTransform } from '@angular/core';\n\n@Pipe({\n name: 'utcDate'\n})\nexport class UtcDatePipe implements PipeTransform {\n transform(value?: Date): Date | null {\n if (!value) {\n return null;\n }\n\n const newDate: Date = new Date(value);\n\n let utcHour: number = newDate.getUTCHours();\n if (utcHour < newDate.getHours()) {\n utcHour += 24;\n }\n\n newDate.setHours(\n newDate.getHours() + newDate.getHours() - utcHour,\n newDate.getMinutes(),\n newDate.getSeconds()\n );\n\n return newDate;\n }\n}","import { DatePipe } from '@angular/common';\nimport { AfterViewInit, Component, Input, TemplateRef, ViewChild } from '@angular/core';\nimport { ChildList } from '@zambon-dev/framework';\nimport { DataGridComponent, DataGridDataset } from '@zambon-dev/library';\nimport { TranslatePipe } from '@ngx-translate/core';\nimport { ServicesHistoryDataset } from '../../../datasets';\nimport { UtcDatePipe } from '../../../pipes';\n\n@Component({\n selector: 'shared-services-history-child-list',\n templateUrl: './services-history-child-list.component.html',\n styleUrls: ['./services-history-child-list.component.scss'],\n imports: [\n DataGridComponent,\n DatePipe,\n UtcDatePipe,\n TranslatePipe,\n ],\n providers: [{ provide: DataGridDataset, useClass: ServicesHistoryDataset }]\n})\nexport class ServicesHistoryChildListComponent extends ChildList<any> implements AfterViewInit {\n //#region ViewChilds, Inputs, Outputs\n @ViewChild('serviceTemplate') private serviceTemplate!: TemplateRef<any>;\n\n @Input() public set controllerName(value: string) {\n (<ServicesHistoryDataset>this.dataGridDataset).controllerName = value;\n } \n //#endregion\n\n //#region Variables\n public selectedServiceID?: number;\n //#endregion\n\n //#region Properties\n //#endregion\n\n //#region Constructor and Angular life cycle methods\n public ngAfterViewInit(): void {\n this.dataGridDataset.columns[0].template = this.serviceTemplate;\n }\n //#endregion\n\n //#region Event handlers\n //#endregion\n\n //#region Public methods\n public override selectedRowChanged(): void {\n super.selectedRowChanged();\n\n if (this.dataGridDataset.hasSelectedRows) {\n const selectedKey: string = this.dataGridDataset.selectedRowKeys[0];;\n this.selectedServiceID = this.dataGridDataset.getRowID(selectedKey);\n }\n }\n //#endregion\n\n //#region Private methods\n //#endregion\n}","<lib-data-grid [lazyLoadRows]=\"true\">\n</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\"><i class=\"fa-solid fa-clock\"></i> {{ rowData.changedOn | utcDate | date: ('Format-DateTime' | translate) }}</span>\n <span class=\"user\"><i class=\"fa-solid fa-user\"></i> {{ rowData.changedByName }}</span>\n </div>\n </div>\n </div>\n</ng-template>","import { Component, inject, Input } from '@angular/core';\nimport { ActivatedRoute } from '@angular/router';\nimport { ViewBase } from '@zambon-dev/framework';\nimport { DataProviderService } from '@zambon-dev/library';\nimport { take } from 'rxjs';\nimport { OperationsHistoryChildListComponent } from '../../operations-history';\nimport { ServicesHistoryChildListComponent } from '../services-history-child-list/services-history-child-list.component';\n\n@Component({\n selector: 'shared-services-history-view',\n templateUrl: './services-history-view.component.html',\n styleUrls: ['./services-history-view.component.scss'],\n imports: [\n OperationsHistoryChildListComponent,\n ServicesHistoryChildListComponent,\n ]\n})\nexport class ServicesHistoryViewComponent extends ViewBase {\n //#region ViewChilds, Inputs, Outputs\n @Input({ required: true }) public controllerName!: string;\n\n @Input() public entityID?: number;\n //#endregion\n\n //#region Variables\n private activatedRoute: ActivatedRoute = inject(ActivatedRoute);\n private dataProviderService: DataProviderService<any> | null = inject(DataProviderService, { optional: true });\n //#endregion\n\n //#region Properties\n //#endregion\n\n //#region Constructor and Angular life cycle methods\n constructor() {\n super();\n\n if (this.activatedRoute.snapshot.data['controllerName']) {\n this.controllerName = this.activatedRoute.snapshot.data['controllerName'];\n }\n\n if (this.dataProviderService) {\n this.dataProviderService.getModel$()\n .pipe(take(1))\n .subscribe((model: any) => {\n this.entityID = model.id;\n });\n }\n }\n //#endregion\n\n //#region Event handlers\n //#endregion\n\n //#region Public methods\n //#endregion\n\n //#region Private methods\n //#endregion\n}","<div class=\"history-container\">\n <div class=\"service-history-container\">\n <shared-services-history-child-list #service\n [controllerName]=\"controllerName\">\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 [serviceID]=\"service.selectedServiceID\">\n </shared-operations-history-child-list>\n </div>\n</div>","import { HttpBackend } from '@angular/common/http';\nimport { EnvironmentProviders, Provider } from '@angular/core';\nimport { provideTranslateService, TranslateLoader } from '@ngx-translate/core';\nimport { MultiTranslateHttpLoader, TranslationResource } from 'ngx-translate-multi-http-loader';\n\nexport interface AngularAssetPattern {\n glob: string;\n input: string;\n output: string;\n}\n\nexport const ZAMBON_SHARED_I18N_ASSET_PATH = 'assets/i18n/zambon-dev/shared';\n\nexport const ZAMBON_SHARED_I18N_ASSET: AngularAssetPattern = {\n glob: '**/*.json',\n input: 'node_modules/@zambon-dev/shared/i18n',\n output: ZAMBON_SHARED_I18N_ASSET_PATH,\n};\n\nexport const ZAMBON_SHARED_I18N_RESOURCES: TranslationResource[] = [\n { prefix: `/${ZAMBON_SHARED_I18N_ASSET_PATH}/external-content/`, suffix: '.json' },\n { prefix: `/${ZAMBON_SHARED_I18N_ASSET_PATH}/language-selector/`, suffix: '.json' },\n { prefix: `/${ZAMBON_SHARED_I18N_ASSET_PATH}/login/`, suffix: '.json' },\n { prefix: `/${ZAMBON_SHARED_I18N_ASSET_PATH}/operations-history/`, suffix: '.json' },\n { prefix: `/${ZAMBON_SHARED_I18N_ASSET_PATH}/top-bar/`, suffix: '.json' },\n];\n\nexport interface ZambonSharedTranslateConfig {\n defaultLanguage?: string;\n appResources?: (string | TranslationResource)[];\n}\n\nexport function createZambonSharedTranslateLoader(\n httpBackend: HttpBackend,\n appResources: (string | TranslationResource)[] = [],\n): MultiTranslateHttpLoader {\n return new MultiTranslateHttpLoader(httpBackend, [\n ...ZAMBON_SHARED_I18N_RESOURCES,\n ...appResources,\n ]);\n}\n\nexport function provideZambonSharedTranslateLoader(\n appResources: (string | TranslationResource)[] = [],\n): Provider {\n return {\n provide: TranslateLoader,\n useFactory: (httpBackend: HttpBackend) => createZambonSharedTranslateLoader(httpBackend, appResources),\n deps: [HttpBackend],\n };\n}\n\nexport function provideZambonSharedTranslateService(\n config: ZambonSharedTranslateConfig = {},\n): EnvironmentProviders {\n return provideTranslateService({\n defaultLanguage: config.defaultLanguage,\n loader: provideZambonSharedTranslateLoader(config.appResources),\n });\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":["i1"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { OnInit } from '@angular/core';
1
+ import { OnInit, OnDestroy } from '@angular/core';
2
2
  import { SafeResourceUrl } from '@angular/platform-browser';
3
3
  import { TabViewBase } from '@zambon-dev/framework';
4
4
  import * as i0 from "@angular/core";
@@ -12,7 +12,7 @@ import * as i0 from "@angular/core";
12
12
  * bar of its own: it must be routed under `DefaultTabViewComponent`, which is what renders the
13
13
  * `#ribbon` template this view publishes. Use the exported `externalContentRoutes`.
14
14
  */
15
- export declare class ExternalContentComponent extends TabViewBase implements OnInit {
15
+ export declare class ExternalContentComponent extends TabViewBase implements OnInit, OnDestroy {
16
16
  protected frameUrl?: SafeResourceUrl;
17
17
  protected isBlocked: boolean;
18
18
  protected isFrameLoading: boolean;
@@ -1,6 +1,6 @@
1
1
  import { InjectionToken } from '@angular/core';
2
2
  /** First segment of the route that hosts embedded external content. */
3
- export declare const EXTERNAL_CONTENT_ROUTE_PATH: string;
3
+ export declare const EXTERNAL_CONTENT_ROUTE_PATH = "external-content";
4
4
  /**
5
5
  * Flat projection of an external menu item, used to restore an embedded tab.
6
6
  *
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zambon-dev/shared",
3
- "version": "2.1.1",
3
+ "version": "2.1.3",
4
4
  "description": "Shared Angular services, utilities, and styles for Zambon applications.",
5
5
  "keywords": [
6
6
  "angular",
@@ -25,13 +25,15 @@
25
25
  "@angular/common": "^19.1.0",
26
26
  "@angular/core": "^19.1.0",
27
27
  "@angular/forms": "^19.1.0",
28
+ "@angular/platform-browser": "^19.1.0",
28
29
  "@angular/router": "^19.1.0",
29
30
  "@auth0/angular-jwt": "^5.2.0",
30
31
  "@microsoft/signalr": "^10.0.0",
32
+ "@ngx-translate/core": "^16.0.4",
31
33
  "@zambon-dev/framework": "^1.0.0",
32
34
  "@zambon-dev/library": "^1.0.0",
33
- "@ngx-translate/core": "^16.0.4",
34
- "ngx-translate-multi-http-loader": "^19.0.2"
35
+ "ngx-translate-multi-http-loader": "^19.0.2",
36
+ "rxjs": "^7.8.0"
35
37
  },
36
38
  "publishConfig": {
37
39
  "access": "public"