@zambon-dev/ui 0.0.1-bootstrap.0 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/CHANGELOG.md +177 -0
  2. package/README.md +81 -81
  3. package/fesm2022/zambon-dev-ui-framework.mjs +5995 -3980
  4. package/fesm2022/zambon-dev-ui-framework.mjs.map +1 -1
  5. package/fesm2022/zambon-dev-ui-library.mjs +6003 -4272
  6. package/fesm2022/zambon-dev-ui-library.mjs.map +1 -1
  7. package/fesm2022/zambon-dev-ui-shared.mjs +2758 -1790
  8. package/fesm2022/zambon-dev-ui-shared.mjs.map +1 -1
  9. package/fesm2022/zambon-dev-ui-testing.mjs +73 -77
  10. package/fesm2022/zambon-dev-ui-testing.mjs.map +1 -1
  11. package/fesm2022/zambon-dev-ui.mjs +6 -8
  12. package/i18n/framework/en.json +63 -63
  13. package/i18n/framework/pt.json +63 -63
  14. package/i18n/shared/external-content/en.json +12 -12
  15. package/i18n/shared/external-content/pt.json +12 -12
  16. package/i18n/shared/language-selector/en.json +5 -5
  17. package/i18n/shared/language-selector/pt.json +5 -5
  18. package/i18n/shared/login/en.json +16 -14
  19. package/i18n/shared/login/pt.json +16 -14
  20. package/i18n/shared/operations-history/en.json +5 -5
  21. package/i18n/shared/operations-history/pt.json +5 -5
  22. package/i18n/shared/services-history/en.json +14 -14
  23. package/i18n/shared/services-history/pt.json +14 -14
  24. package/i18n/shared/top-bar/en.json +10 -7
  25. package/i18n/shared/top-bar/pt.json +10 -7
  26. package/package.json +1 -1
  27. package/styles/common.scss +9 -10
  28. package/styles/components/card.scss +19 -13
  29. package/styles/components/dropdown-static.scss +33 -35
  30. package/styles/components/input-group.scss +48 -44
  31. package/styles/components/input.scss +120 -99
  32. package/styles/components/label.scss +6 -3
  33. package/styles/components/row.scss +48 -48
  34. package/styles/mixins/background.scss +31 -31
  35. package/styles/theme.css +307 -75
  36. package/styles/variables.scss +86 -60
  37. package/types/zambon-dev-ui-framework.d.ts +1470 -1029
  38. package/types/zambon-dev-ui-library.d.ts +1689 -1165
  39. package/types/zambon-dev-ui-shared.d.ts +630 -543
  40. package/types/zambon-dev-ui-testing.d.ts +25 -30
  41. package/types/zambon-dev-ui.d.ts +6 -3
  42. package/fesm2022/zambon-dev-ui.mjs.map +0 -1
  43. package/styles/components/button.scss +0 -101
@@ -1,164 +1,152 @@
1
- import * as i0 from '@angular/core';
2
- import { OnInit, OnDestroy, InjectionToken, WritableSignal, AfterViewInit, InputSignal, Signal, OutputEmitterRef, ModelSignal, Provider, EnvironmentProviders, ElementRef, PipeTransform } from '@angular/core';
3
- import * as i1 from '@angular/router';
4
- import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, Routes } from '@angular/router';
5
- import { HttpInterceptor, HttpRequest, HttpHandler, HttpEvent, HttpBackend } from '@angular/common/http';
6
- import { Observable, Subject } from 'rxjs';
7
- import { FormGroup, FormBuilder } from '@angular/forms';
8
- import { ButtonFiltersComponent, AuthService, TabViewBase, ChildList, ModalBase } from '@zambon-dev/ui/framework';
9
- import { SidebarMenu, IListParameters, DataGridDataset, IGridColumn, AngularAssetPattern } from '@zambon-dev/ui/library';
10
- import { SafeResourceUrl, SafeHtml } from '@angular/platform-browser';
11
- import { TranslationResource, MultiTranslateHttpLoader } from 'ngx-translate-multi-http-loader';
12
-
13
- declare class SharedAuthModule {
14
- static ɵfac: i0.ɵɵFactoryDeclaration<SharedAuthModule, never>;
15
- static ɵmod: i0.ɵɵNgModuleDeclaration<SharedAuthModule, never, [typeof i1.RouterModule], never>;
16
- static ɵinj: i0.ɵɵInjectorDeclaration<SharedAuthModule>;
17
- }
18
-
19
- declare class AuthGuard implements CanActivate {
20
- private authenticationService;
21
- private router;
22
- canActivate(_: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean;
23
- static ɵfac: i0.ɵɵFactoryDeclaration<AuthGuard, never>;
24
- static ɵprov: i0.ɵɵInjectableDeclaration<any>;
25
- }
26
-
27
- declare class AuthInterceptor implements HttpInterceptor {
28
- private authenticationService;
29
- private config;
30
- private jwtInterceptor;
31
- private refreshToken$?;
32
- private router;
33
- intercept(request: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>>;
34
- static ɵfac: i0.ɵɵFactoryDeclaration<AuthInterceptor, never>;
35
- static ɵprov: i0.ɵɵInjectableDeclaration<any>;
36
- }
37
-
38
- declare abstract class FiltersBase implements OnInit, OnDestroy {
39
- protected buttonFilters?: ButtonFiltersComponent;
40
- protected destroy$: Subject<boolean>;
41
- protected filterForm: FormGroup;
42
- protected formBuilder: FormBuilder;
43
- ngOnDestroy(): void;
44
- ngOnInit(): void;
45
- setFilters(filters: {
46
- [key: string]: any;
47
- }): void;
48
- protected abstract formSetup(): FormGroup<any>;
49
- static ɵfac: i0.ɵɵFactoryDeclaration<FiltersBase, never>;
50
- static ɵcmp: i0.ɵɵComponentDeclaration<FiltersBase, "ng-component", never, {}, {}, never, never, true, never>;
51
- }
52
-
53
- interface ICurrentUserInfo {
54
- costCenterName: string;
55
- /**
56
- * Optional e-mail address. Present only when the sign-in response includes it; it is one of the
57
- * values behind the `{email}` placeholder in an external menu URL.
58
- */
59
- email?: string;
60
- name: string;
61
- /** Optional avatar image URL. Falls back to initials when absent. */
62
- pictureUrl?: string;
63
- /** Optional job position/title shown under the user name. Line is hidden when absent. */
64
- position?: string;
65
- /**
66
- * Optional stable user identifier. Present only when the sign-in response includes it; it is
67
- * the value behind the `{userId}` placeholder in an external menu URL.
68
- */
69
- userID?: number;
70
- /**
71
- * Login user name. Already carried by the persisted sign-in response; declared here because it
72
- * is the value behind the `{userName}` placeholder in an external menu URL.
73
- */
74
- username?: string;
75
- }
76
-
77
- interface IAuthResponse extends ICurrentUserInfo {
78
- refreshToken: string;
79
- refreshTokenExpiration: string;
80
- token: string;
81
- username: string;
1
+ import * as i0 from "@angular/core";
2
+ import { AfterViewInit, ElementRef, EnvironmentProviders, InjectionToken, InputSignal, ModelSignal, OnDestroy, OnInit, OutputEmitterRef, PipeTransform, Provider, Signal, WritableSignal } from "@angular/core";
3
+ import * as i1 from "@angular/router";
4
+ import { ActivatedRouteSnapshot, CanActivate, RouterStateSnapshot, Routes } from "@angular/router";
5
+ import { HttpBackend, HttpEvent, HttpHandler, HttpInterceptor, HttpRequest } from "@angular/common/http";
6
+ import { Observable, Subject } from "rxjs";
7
+ import { FormBuilder, FormGroup } from "@angular/forms";
8
+ import { AuthService, ButtonFiltersComponent, ChildList, ModalBase, TabViewBase } from "@zambon-dev/ui/framework";
9
+ import { AngularAssetPattern, DataGridDataset, IGridColumn, IListParameters, SidebarMenu } from "@zambon-dev/ui/library";
10
+ import { SafeHtml, SafeResourceUrl } from "@angular/platform-browser";
11
+ import { MultiTranslateHttpLoader, TranslationResource } from "ngx-translate-multi-http-loader";
12
+ export declare class SharedAuthModule {
13
+ static ɵfac: i0.ɵɵFactoryDeclaration<SharedAuthModule, never>;
14
+ static ɵmod: i0.ɵɵNgModuleDeclaration<SharedAuthModule, never, [typeof i1.RouterModule], never>;
15
+ static ɵinj: i0.ɵɵInjectorDeclaration<SharedAuthModule>;
16
+ }
17
+ export declare class AuthGuard implements CanActivate {
18
+ private authenticationService;
19
+ private router;
20
+ canActivate(_: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean;
21
+ static ɵfac: i0.ɵɵFactoryDeclaration<AuthGuard, never>;
22
+ static ɵprov: i0.ɵɵInjectableDeclaration<any>;
23
+ }
24
+ export declare class AuthInterceptor implements HttpInterceptor {
25
+ private authenticationService;
26
+ private config;
27
+ private jwtInterceptor;
28
+ private refreshToken$?;
29
+ private router;
30
+ intercept(request: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>>;
31
+ static ɵfac: i0.ɵɵFactoryDeclaration<AuthInterceptor, never>;
32
+ static ɵprov: i0.ɵɵInjectableDeclaration<any>;
33
+ }
34
+ export declare abstract class FiltersBase implements OnInit, OnDestroy {
35
+ protected buttonFilters?: ButtonFiltersComponent;
36
+ protected destroy$: Subject<boolean>;
37
+ protected filterForm: FormGroup;
38
+ protected formBuilder: FormBuilder;
39
+ ngOnDestroy(): void;
40
+ ngOnInit(): void;
41
+ setFilters(filters: {
42
+ [key: string]: any;
43
+ }): void;
44
+ protected abstract formSetup(): FormGroup<any>;
45
+ static ɵfac: i0.ɵɵFactoryDeclaration<FiltersBase, never>;
46
+ static ɵcmp: i0.ɵɵComponentDeclaration<FiltersBase, "ng-component", never, {}, {}, never, never, true, never>;
47
+ }
48
+ export interface ICurrentUserInfo {
49
+ costCenterName: string;
50
+ /**
51
+ * Optional e-mail address. Present only when the sign-in response includes it; it is one of the
52
+ * values behind the `{email}` placeholder in an external menu URL.
53
+ */
54
+ email?: string;
55
+ name: string;
56
+ /** Optional avatar image URL. Falls back to initials when absent. */
57
+ pictureUrl?: string;
58
+ /** Optional job position/title shown under the user name. Line is hidden when absent. */
59
+ position?: string;
60
+ /**
61
+ * Optional stable user identifier. Present only when the sign-in response includes it; it is
62
+ * the value behind the `{userId}` placeholder in an external menu URL.
63
+ */
64
+ userID?: number;
65
+ /**
66
+ * Login user name. Already carried by the persisted sign-in response; declared here because it
67
+ * is the value behind the `{userName}` placeholder in an external menu URL.
68
+ */
69
+ username?: string;
70
+ }
71
+ export interface IAuthResponse extends ICurrentUserInfo {
72
+ refreshToken: string;
73
+ refreshTokenExpiration: string;
74
+ token: string;
75
+ username: string;
82
76
  }
83
-
84
77
  /** First segment of the route that hosts embedded external content. */
85
- declare const EXTERNAL_CONTENT_ROUTE_PATH = "external-content";
78
+ export declare const EXTERNAL_CONTENT_ROUTE_PATH = "external-content";
86
79
  /**
87
80
  * Flat projection of an external menu item, used to restore an embedded tab.
88
81
  *
89
82
  * Deliberately not a `SidebarMenu`: that class carries a `parent` back-reference, so it is a
90
83
  * circular structure that `JSON.stringify` refuses, and holding one would pin the whole menu tree.
91
84
  */
92
- interface IExternalContentEntry {
93
- id: number;
94
- label: string;
95
- url: string;
96
- }
97
- declare class ExternalContentConfigs {
98
- /**
99
- * Origins an embedded menu item may point at, for example `['https://reports.example.com']`.
100
- * Empty — the default — allows any `http`/`https` origin.
101
- *
102
- * Populating it is the single highest-value control here after the scheme check: it narrows a
103
- * compromised menu row from "frame anything on the internet" to "frame one of our report hosts".
104
- */
105
- allowedOrigins: string[];
106
- /** Milliseconds to wait for the frame's first `load` before hinting that framing may be refused. */
107
- slowFrameHintDelay: number;
108
- constructor(options?: Partial<ExternalContentConfigs>);
109
- }
110
- declare const EXTERNAL_CONTENT_CONFIGS: InjectionToken<ExternalContentConfigs>;
111
-
112
- interface INotification {
113
- /** Short heading for the notification. */
114
- title: string;
115
- /** Longer descriptive text. */
116
- description: string;
117
- /** Icon class shown next to the notification (e.g. a Font Awesome class like `fa-solid fa-envelope`). */
118
- icon: string;
119
- /** Optional call-to-action URL. When present, clicking the notification navigates to it. */
120
- callToActionUrl?: string;
121
- /** Whether the notification has been read. */
122
- isRead: boolean;
123
- }
124
-
125
- interface IOperationsHistoryList {
126
- /** Capitalised `ID` is intentional: the backend property is `EntityID`, and the camelCase
127
- * serialization policy only lowercases a leading run of capitals — so the trailing ones survive. */
128
- entityID?: number;
129
- entityName?: string;
130
- id: number;
131
- newValues?: string;
132
- oldValues?: string;
133
- operationType?: string;
134
- tableName?: string;
135
- }
136
-
137
- interface IServicesHistoryList {
138
- changedByName: string;
139
- changedOn: Date;
140
- id: number;
141
- name: string;
142
- }
143
-
144
- declare class AuthenticationService extends AuthService {
145
- adminAction: string;
146
- private config;
147
- private readonly BASE_URL;
148
- private http;
149
- constructor();
150
- authenticate(model: {
151
- username: string;
152
- password: string;
153
- rememberMe: boolean;
154
- }): Observable<void>;
155
- getActions(): Observable<string[]>;
156
- getUserInfo(): ICurrentUserInfo | null;
157
- tryRefreshToken(): Observable<string>;
158
- static ɵfac: i0.ɵɵFactoryDeclaration<AuthenticationService, never>;
159
- static ɵprov: i0.ɵɵInjectableDeclaration<any>;
160
- }
161
-
85
+ export interface IExternalContentEntry {
86
+ id: number;
87
+ label: string;
88
+ url: string;
89
+ }
90
+ export declare class ExternalContentConfigs {
91
+ /**
92
+ * Origins an embedded menu item may point at, for example `['https://reports.example.com']`.
93
+ * Empty — the default — allows any `http`/`https` origin.
94
+ *
95
+ * Populating it is the single highest-value control here after the scheme check: it narrows a
96
+ * compromised menu row from "frame anything on the internet" to "frame one of our report hosts".
97
+ */
98
+ allowedOrigins: string[];
99
+ /** Milliseconds to wait for the frame's first `load` before hinting that framing may be refused. */
100
+ slowFrameHintDelay: number;
101
+ constructor(options?: Partial<ExternalContentConfigs>);
102
+ }
103
+ export declare const EXTERNAL_CONTENT_CONFIGS: InjectionToken<ExternalContentConfigs>;
104
+ export interface INotification {
105
+ /** Short heading for the notification. */
106
+ title: string;
107
+ /** Longer descriptive text. */
108
+ description: string;
109
+ /** Icon class shown next to the notification (e.g. a Font Awesome class like `fa-solid fa-envelope`). */
110
+ icon: string;
111
+ /** Optional call-to-action URL. When present, clicking the notification navigates to it. */
112
+ callToActionUrl?: string;
113
+ /** Whether the notification has been read. */
114
+ isRead: boolean;
115
+ }
116
+ export interface IOperationsHistoryList {
117
+ /** Capitalised `ID` is intentional: the backend property is `EntityID`, and the camelCase
118
+ * serialization policy only lowercases a leading run of capitals — so the trailing ones survive. */
119
+ entityID?: number;
120
+ entityName?: string;
121
+ id: number;
122
+ newValues?: string;
123
+ oldValues?: string;
124
+ operationType?: string;
125
+ tableName?: string;
126
+ }
127
+ export interface IServicesHistoryList {
128
+ changedByName: string;
129
+ changedOn: Date;
130
+ id: number;
131
+ name: string;
132
+ }
133
+ export declare class AuthenticationService extends AuthService {
134
+ adminAction: string;
135
+ private config;
136
+ private readonly BASE_URL;
137
+ private http;
138
+ constructor();
139
+ authenticate(model: {
140
+ username: string;
141
+ password: string;
142
+ rememberMe: boolean;
143
+ }): Observable<void>;
144
+ getActions(): Observable<string[]>;
145
+ getUserInfo(): ICurrentUserInfo | null;
146
+ tryRefreshToken(): Observable<string>;
147
+ static ɵfac: i0.ɵɵFactoryDeclaration<AuthenticationService, never>;
148
+ static ɵprov: i0.ɵɵInjectableDeclaration<any>;
149
+ }
162
150
  /**
163
151
  * Remembers which external destination sits behind an embedded tab's `/external-content/:menuID`
164
152
  * route, and resolves it back when the view is created.
@@ -174,23 +162,22 @@ declare class AuthenticationService extends AuthService {
174
162
  * of a consumer: an application whose menu endpoint cannot resolve `/external-content/:id` simply
175
163
  * gets the unavailable state on a cold deep link, which is the documented behaviour.
176
164
  */
177
- declare class ExternalContentService {
178
- private readonly maxEntries;
179
- private readonly storageKey;
180
- private registry;
181
- private sidebarService;
182
- /** Resolves the destination behind an embedded tab, or `undefined` when it cannot be recovered. */
183
- find(menuID: number): Observable<IExternalContentEntry | undefined>;
184
- /** Remembers a menu so its embedded tab survives a page refresh. */
185
- register(menu: SidebarMenu): void;
186
- private readAllFromStorage;
187
- private readFromStorage;
188
- private toEntry;
189
- private writeToStorage;
190
- static ɵfac: i0.ɵɵFactoryDeclaration<ExternalContentService, never>;
191
- static ɵprov: i0.ɵɵInjectableDeclaration<any>;
192
- }
193
-
165
+ export declare class ExternalContentService {
166
+ private readonly maxEntries;
167
+ private readonly storageKey;
168
+ private registry;
169
+ private sidebarService;
170
+ /** Resolves the destination behind an embedded tab, or `undefined` when it cannot be recovered. */
171
+ find(menuID: number): Observable<IExternalContentEntry | undefined>;
172
+ /** Remembers a menu so its embedded tab survives a page refresh. */
173
+ register(menu: SidebarMenu): void;
174
+ private readAllFromStorage;
175
+ private readFromStorage;
176
+ private toEntry;
177
+ private writeToStorage;
178
+ static ɵfac: i0.ɵɵFactoryDeclaration<ExternalContentService, never>;
179
+ static ɵprov: i0.ɵɵInjectableDeclaration<any>;
180
+ }
194
181
  /**
195
182
  * Resolves the runtime placeholders in an external menu URL, and vets the result before it is
196
183
  * handed to the browser.
@@ -210,36 +197,35 @@ declare class ExternalContentService {
210
197
  * configured as `?t={token}` hand the JWT to a third party. No authentication token is ever
211
198
  * substituted.
212
199
  */
213
- declare class ExternalUrlResolverService {
214
- private authenticationService;
215
- private translate;
216
- /** Placeholder grammar, used only to *detect* tokens this version does not know. */
217
- private readonly unknownPlaceholderPattern;
218
- /**
219
- * Whether `url` is an absolute `http`/`https` address.
220
- *
221
- * Rejects relative paths, malformed values, protocol-relative `//host/path` (which throws
222
- * without a base), and the schemes that would execute rather than navigate: `javascript:`,
223
- * `data:`, `blob:`, `file:`.
224
- */
225
- isAllowed(url: string): boolean;
226
- /**
227
- * Substitutes every known placeholder, URL-encoding each value.
228
- *
229
- * Because every value is percent-encoded, a placeholder must occupy one *whole* value — a full
230
- * path segment, or a full query-parameter value. Encoding is what stops a display name that
231
- * contains `&` from injecting an extra query parameter into the destination.
232
- *
233
- * A known placeholder with no value becomes an empty string; an unrecognized `{…}` is left
234
- * exactly as configured, so a report URL that legitimately contains braces is not corrupted.
235
- */
236
- resolve(url: string): string;
237
- private getPlaceholderValues;
238
- private warnAboutUnknownPlaceholders;
239
- static ɵfac: i0.ɵɵFactoryDeclaration<ExternalUrlResolverService, never>;
240
- static ɵprov: i0.ɵɵInjectableDeclaration<any>;
241
- }
242
-
200
+ export declare class ExternalUrlResolverService {
201
+ private authenticationService;
202
+ private translate;
203
+ /** Placeholder grammar, used only to *detect* tokens this version does not know. */
204
+ private readonly unknownPlaceholderPattern;
205
+ /**
206
+ * Whether `url` is an absolute `http`/`https` address.
207
+ *
208
+ * Rejects relative paths, malformed values, protocol-relative `//host/path` (which throws
209
+ * without a base), and the schemes that would execute rather than navigate: `javascript:`,
210
+ * `data:`, `blob:`, `file:`.
211
+ */
212
+ isAllowed(url: string): boolean;
213
+ /**
214
+ * Substitutes every known placeholder, URL-encoding each value.
215
+ *
216
+ * Because every value is percent-encoded, a placeholder must occupy one *whole* value — a full
217
+ * path segment, or a full query-parameter value. Encoding is what stops a display name that
218
+ * contains `&` from injecting an extra query parameter into the destination.
219
+ *
220
+ * A known placeholder with no value becomes an empty string; an unrecognized `{…}` is left
221
+ * exactly as configured, so a report URL that legitimately contains braces is not corrupted.
222
+ */
223
+ resolve(url: string): string;
224
+ private getPlaceholderValues;
225
+ private warnAboutUnknownPlaceholders;
226
+ static ɵfac: i0.ɵɵFactoryDeclaration<ExternalUrlResolverService, never>;
227
+ static ɵprov: i0.ɵɵInjectableDeclaration<any>;
228
+ }
243
229
  /**
244
230
  * Streams top-bar notifications from a SignalR hub.
245
231
  *
@@ -248,90 +234,85 @@ declare class ExternalUrlResolverService {
248
234
  * listens for the server to push the notification list via the `ReceiveNotifications` client
249
235
  * method. Consuming apps do not interact with this service directly — the top bar drives it.
250
236
  */
251
- declare class NotificationsService {
252
- private authService;
253
- private config;
254
- private connection?;
255
- private notifications$;
256
- /** Whether the notifications feature is enabled (toggled on and given a hub URL). */
257
- get isEnabled(): boolean;
258
- /** Emits the current list of notifications. */
259
- getNotifications(): Observable<INotification[]>;
260
- /** Emits the number of unread notifications. */
261
- getUnreadCount(): Observable<number>;
262
- /** Marks every notification as read and notifies the hub. */
263
- markAllAsRead(): void;
264
- /** Marks a single notification as read (optimistically; the server reconciles on the next push). */
265
- markAsRead(notification: INotification): void;
266
- /** Opens the SignalR connection and starts receiving notifications. Idempotent and a no-op when disabled. */
267
- start(): void;
268
- /** Closes the SignalR connection. */
269
- stop(): Promise<void>;
270
- static ɵfac: i0.ɵɵFactoryDeclaration<NotificationsService, never>;
271
- static ɵprov: i0.ɵɵInjectableDeclaration<any>;
272
- }
273
-
274
- declare class OperationsHistoryService {
275
- private config;
276
- private http;
277
- list(controllerName: string, entityID: number, serviceHistoryID: number, parameters: IListParameters): Observable<IOperationsHistoryList[]>;
278
- static ɵfac: i0.ɵɵFactoryDeclaration<OperationsHistoryService, never>;
279
- static ɵprov: i0.ɵɵInjectableDeclaration<any>;
280
- }
281
-
282
- declare class ServicesHistoryService {
283
- private config;
284
- private http;
285
- list(controllerName: string, entityID: number, parameters: IListParameters): Observable<IServicesHistoryList[]>;
286
- static ɵfac: i0.ɵɵFactoryDeclaration<ServicesHistoryService, never>;
287
- static ɵprov: i0.ɵɵInjectableDeclaration<any>;
288
- }
289
-
290
- declare class OperationsHistoryDataset extends DataGridDataset {
291
- columns: IGridColumn[];
292
- controllerName?: string;
293
- protected operationsHistoryService: OperationsHistoryService;
294
- private _serviceID?;
295
- set serviceId(value: number | undefined);
296
- constructor();
297
- getData(params: IListParameters): Observable<IOperationsHistoryList[]>;
298
- static ɵfac: i0.ɵɵFactoryDeclaration<OperationsHistoryDataset, never>;
299
- static ɵprov: i0.ɵɵInjectableDeclaration<any>;
300
- }
301
-
302
- declare class ServicesHistoryDataset extends DataGridDataset {
303
- columns: IGridColumn[];
304
- controllerName?: string;
305
- protected servicesHistoryService: ServicesHistoryService;
306
- constructor();
307
- getData(params: IListParameters): Observable<IServicesHistoryList[]>;
308
- /**
309
- * Widens the picked dates to whole local days and sends them as UTC instants.
310
- *
311
- * A date input yields `YYYY-MM-DD` -- no time, no zone -- while the history stores UTC instants
312
- * and the backend compares what it is given. Sent as they are, "from the 5th to the 5th" is the
313
- * single instant at midnight and matches nothing, and in a zone behind UTC it does not even
314
- * cover the right day.
315
- *
316
- * Done here rather than in the filter form because the form is what the modal shows: reopening
317
- * it patches these values straight back into the fields, which have to keep reading as the dates
318
- * the person picked. This is the boundary where the request is built, so it is also the last
319
- * point that sees every caller.
320
- */
321
- private withUtcPeriod;
322
- /**
323
- * The UTC wall clock of one end of a local day, written without a zone designator.
324
- *
325
- * Without one on purpose. `DateTime.TryParse` on the server reads a trailing `Z` as an instant
326
- * and hands back the *machine's* local time for it, so the same request would mean different
327
- * things on a server in UTC and one in UTC-3, and the stored column is plain UTC either way.
328
- * Dropping the designator leaves the numbers alone, which is what the column holds.
329
- */
330
- private static toUtcInstant;
331
- static ɵfac: i0.ɵɵFactoryDeclaration<ServicesHistoryDataset, never>;
332
- static ɵprov: i0.ɵɵInjectableDeclaration<any>;
333
- }
334
-
237
+ export declare class NotificationsService {
238
+ private authService;
239
+ private config;
240
+ private connection?;
241
+ private notifications$;
242
+ /** Whether the notifications feature is enabled (toggled on and given a hub URL). */
243
+ get isEnabled(): boolean;
244
+ /** Emits the current list of notifications. */
245
+ getNotifications(): Observable<INotification[]>;
246
+ /** Emits the number of unread notifications. */
247
+ getUnreadCount(): Observable<number>;
248
+ /** Marks every notification as read and notifies the hub. */
249
+ markAllAsRead(): void;
250
+ /** Marks a single notification as read (optimistically; the server reconciles on the next push). */
251
+ markAsRead(notification: INotification): void;
252
+ /** Opens the SignalR connection and starts receiving notifications. Idempotent and a no-op when disabled. */
253
+ start(): void;
254
+ /** Closes the SignalR connection. */
255
+ stop(): Promise<void>;
256
+ static ɵfac: i0.ɵɵFactoryDeclaration<NotificationsService, never>;
257
+ static ɵprov: i0.ɵɵInjectableDeclaration<any>;
258
+ }
259
+ export declare class OperationsHistoryService {
260
+ private config;
261
+ private http;
262
+ list(controllerName: string, entityID: number, serviceHistoryID: number, parameters: IListParameters): Observable<IOperationsHistoryList[]>;
263
+ static ɵfac: i0.ɵɵFactoryDeclaration<OperationsHistoryService, never>;
264
+ static ɵprov: i0.ɵɵInjectableDeclaration<any>;
265
+ }
266
+ export declare class ServicesHistoryService {
267
+ private config;
268
+ private http;
269
+ list(controllerName: string, entityID: number, parameters: IListParameters): Observable<IServicesHistoryList[]>;
270
+ static ɵfac: i0.ɵɵFactoryDeclaration<ServicesHistoryService, never>;
271
+ static ɵprov: i0.ɵɵInjectableDeclaration<any>;
272
+ }
273
+ export declare class OperationsHistoryDataset extends DataGridDataset {
274
+ columns: IGridColumn[];
275
+ controllerName?: string;
276
+ protected operationsHistoryService: OperationsHistoryService;
277
+ private _serviceID?;
278
+ set serviceId(value: number | undefined);
279
+ constructor();
280
+ getData(params: IListParameters): Observable<IOperationsHistoryList[]>;
281
+ static ɵfac: i0.ɵɵFactoryDeclaration<OperationsHistoryDataset, never>;
282
+ static ɵprov: i0.ɵɵInjectableDeclaration<any>;
283
+ }
284
+ export declare class ServicesHistoryDataset extends DataGridDataset {
285
+ columns: IGridColumn[];
286
+ controllerName?: string;
287
+ protected servicesHistoryService: ServicesHistoryService;
288
+ constructor();
289
+ getData(params: IListParameters): Observable<IServicesHistoryList[]>;
290
+ /**
291
+ * Widens the picked dates to whole local days and sends them as UTC instants.
292
+ *
293
+ * A date input yields `YYYY-MM-DD` -- no time, no zone -- while the history stores UTC instants
294
+ * and the backend compares what it is given. Sent as they are, "from the 5th to the 5th" is the
295
+ * single instant at midnight and matches nothing, and in a zone behind UTC it does not even
296
+ * cover the right day.
297
+ *
298
+ * Done here rather than in the filter form because the form is what the modal shows: reopening
299
+ * it patches these values straight back into the fields, which have to keep reading as the dates
300
+ * the person picked. This is the boundary where the request is built, so it is also the last
301
+ * point that sees every caller.
302
+ */
303
+ private withUtcPeriod;
304
+ /**
305
+ * The UTC wall clock of one end of a local day, written without a zone designator.
306
+ *
307
+ * Without one on purpose. `DateTime.TryParse` on the server reads a trailing `Z` as an instant
308
+ * and hands back the *machine's* local time for it, so the same request would mean different
309
+ * things on a server in UTC and one in UTC-3, and the stored column is plain UTC either way.
310
+ * Dropping the designator leaves the numbers alone, which is what the column holds.
311
+ */
312
+ private static toUtcInstant;
313
+ static ɵfac: i0.ɵɵFactoryDeclaration<ServicesHistoryDataset, never>;
314
+ static ɵprov: i0.ɵɵInjectableDeclaration<any>;
315
+ }
335
316
  /**
336
317
  * Displays an external destination inside an application tab.
337
318
  *
@@ -342,39 +323,38 @@ declare class ServicesHistoryDataset extends DataGridDataset {
342
323
  * bar of its own: it must be routed under `DefaultTabViewComponent`, which is what renders the
343
324
  * `#ribbon` template this view publishes. Use the exported `externalContentRoutes`.
344
325
  */
345
- declare class ExternalContentComponent extends TabViewBase implements OnInit, OnDestroy {
346
- protected readonly frameUrl: WritableSignal<SafeResourceUrl | undefined>;
347
- protected readonly isBlocked: WritableSignal<boolean>;
348
- protected readonly isFrameLoading: WritableSignal<boolean>;
349
- protected readonly isInsecure: WritableSignal<boolean>;
350
- protected readonly isSlow: WritableSignal<boolean>;
351
- protected readonly isUnavailable: WritableSignal<boolean>;
352
- protected readonly label: WritableSignal<string>;
353
- protected readonly resolvedUrl: WritableSignal<string>;
354
- private activatedRoute;
355
- private configs;
356
- private document;
357
- private externalContentService;
358
- private externalUrlResolverService;
359
- private sanitizer;
360
- private slowHintTimeout?;
361
- private tabService;
362
- constructor();
363
- ngOnDestroy(): void;
364
- ngOnInit(): void;
365
- protected onFrameLoad(): void;
366
- protected onOpenInNewTab(): void;
367
- protected onReload(): void;
368
- private clearSlowHint;
369
- private isMixedContent;
370
- private isOriginAllowed;
371
- private show;
372
- private displayFrame;
373
- private startSlowHint;
374
- static ɵfac: i0.ɵɵFactoryDeclaration<ExternalContentComponent, never>;
375
- static ɵcmp: i0.ɵɵComponentDeclaration<ExternalContentComponent, "shared-external-content", never, {}, {}, never, never, true, never>;
376
- }
377
-
326
+ export declare class ExternalContentComponent extends TabViewBase implements OnInit, OnDestroy {
327
+ protected readonly frameUrl: WritableSignal<SafeResourceUrl | undefined>;
328
+ protected readonly isBlocked: WritableSignal<boolean>;
329
+ protected readonly isFrameLoading: WritableSignal<boolean>;
330
+ protected readonly isInsecure: WritableSignal<boolean>;
331
+ protected readonly isSlow: WritableSignal<boolean>;
332
+ protected readonly isUnavailable: WritableSignal<boolean>;
333
+ protected readonly label: WritableSignal<string>;
334
+ protected readonly resolvedUrl: WritableSignal<string>;
335
+ private activatedRoute;
336
+ private configs;
337
+ private document;
338
+ private externalContentService;
339
+ private externalUrlResolverService;
340
+ private sanitizer;
341
+ private slowHintTimeout?;
342
+ private tabService;
343
+ constructor();
344
+ ngOnDestroy(): void;
345
+ ngOnInit(): void;
346
+ protected onFrameLoad(): void;
347
+ protected onOpenInNewTab(): void;
348
+ protected onReload(): void;
349
+ private clearSlowHint;
350
+ private isMixedContent;
351
+ private isOriginAllowed;
352
+ private show;
353
+ private displayFrame;
354
+ private startSlowHint;
355
+ static ɵfac: i0.ɵɵFactoryDeclaration<ExternalContentComponent, never>;
356
+ static ɵcmp: i0.ɵɵComponentDeclaration<ExternalContentComponent, "shared-external-content", never, {}, {}, never, never, true, never>;
357
+ }
378
358
  /**
379
359
  * Route table for embedded external content. Spread it into `MainLayoutComponent`'s children:
380
360
  *
@@ -398,210 +378,258 @@ declare class ExternalContentComponent extends TabViewBase implements OnInit, On
398
378
  * by looking for a `Details` or `List` view in the activated route tree, and navigates to `/`
399
379
  * when it finds neither — the embedded tab would vanish on F5.
400
380
  */
401
- declare const externalContentRoutes: Routes;
402
-
403
- declare class OperationsHistoryChildListComponent extends ChildList<any> implements AfterViewInit {
404
- private readonly modal;
405
- private readonly operationTemplate;
406
- set controllerName(value: string);
407
- /**
408
- * Filters to send with the list.
409
- *
410
- * The audit view applies its filters to the services grid and hands the same set here, because
411
- * one of them -- whether to list only the audited record's own operations -- belongs to this
412
- * list. The rest mean nothing to it, and the backend reads only what it recognises.
413
- *
414
- * `setFilters` refreshes the grid itself. With no service selected the dataset answers with an
415
- * empty list rather than calling the backend, so a refresh then costs nothing.
416
- */
417
- set filters(value: {
418
- [key: string]: string;
419
- } | undefined);
420
- set serviceID(value: number | undefined);
421
- readonly selectedNewValues: WritableSignal<any | null>;
422
- readonly selectedOldValues: WritableSignal<any | null>;
423
- ngAfterViewInit(): void;
424
- openModal(): void;
425
- selectedRowChanged(): void;
426
- static ɵfac: i0.ɵɵFactoryDeclaration<OperationsHistoryChildListComponent, never>;
427
- static ɵcmp: i0.ɵɵComponentDeclaration<OperationsHistoryChildListComponent, "shared-operations-history-child-list", never, { "controllerName": { "alias": "controllerName"; "required": false; }; "filters": { "alias": "filters"; "required": false; }; "serviceID": { "alias": "serviceID"; "required": false; }; }, {}, never, never, true, never>;
428
- }
429
-
430
- declare class OperationsHistoryModalComponent extends ModalBase {
431
- private readonly modal;
432
- readonly newValues: InputSignal<string | undefined>;
433
- readonly oldValues: InputSignal<string | undefined>;
434
- /** Delegates to the inner modal; a signal query, so it re-runs once that child resolves. */
435
- readonly isModalShown: Signal<boolean>;
436
- toggle(): void;
437
- static ɵfac: i0.ɵɵFactoryDeclaration<OperationsHistoryModalComponent, never>;
438
- static ɵcmp: i0.ɵɵComponentDeclaration<OperationsHistoryModalComponent, "shared-operations-history-modal", never, { "newValues": { "alias": "newValues"; "required": false; "isSignal": true; }; "oldValues": { "alias": "oldValues"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
439
- }
440
-
441
- declare class ServicesHistoryChildListComponent extends ChildList<any> implements AfterViewInit, OnInit {
442
- private readonly serviceTemplate;
443
- set controllerName(value: string);
444
- /** Re-emits the grid's own filter changes, for a sibling list that has to follow them. */
445
- readonly filtersChanged: OutputEmitterRef<{
446
- [key: string]: string;
447
- } | undefined>;
448
- readonly selectedServiceID: WritableSignal<number | undefined>;
449
- ngAfterViewInit(): void;
450
- ngOnInit(): void;
451
- selectedRowChanged(): void;
452
- static ɵfac: i0.ɵɵFactoryDeclaration<ServicesHistoryChildListComponent, never>;
453
- static ɵcmp: i0.ɵɵComponentDeclaration<ServicesHistoryChildListComponent, "shared-services-history-child-list", never, { "controllerName": { "alias": "controllerName"; "required": false; }; }, { "filtersChanged": "filtersChanged"; }, never, never, true, never>;
454
- }
455
-
456
- declare class ServicesHistoryFilterComponent extends FiltersBase implements OnInit {
457
- /**
458
- * Catalog that resolves the people who can appear as the author of a change.
459
- *
460
- * There is no such catalog in this library -- who a user is belongs to the application -- so the
461
- * author filter is offered only when one is supplied.
462
- */
463
- readonly usersCatalogEndpoint: InputSignal<string | undefined>;
464
- protected readonly hasUsersCatalog: Signal<boolean>;
465
- private get changedOnFromControl();
466
- private get changedOnToControl();
467
- ngOnInit(): void;
468
- /**
469
- * The control names are the filter names the backend reads, case insensitively: `name`,
470
- * `changedByID`, `changedOnFrom`, `changedOnTo` and `onlyCurrentEntity` reach `AuditFilters` in
471
- * ZWebAPI. The two dates are sent as picked and turned into UTC instants by
472
- * {@link ServicesHistoryDataset}, which is the boundary where the request is built.
473
- */
474
- protected formSetup(): FormGroup<any>;
475
- static ɵfac: i0.ɵɵFactoryDeclaration<ServicesHistoryFilterComponent, never>;
476
- static ɵcmp: i0.ɵɵComponentDeclaration<ServicesHistoryFilterComponent, "shared-services-history-filter", never, { "usersCatalogEndpoint": { "alias": "usersCatalogEndpoint"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
477
- }
478
-
479
- declare class ServicesHistoryViewComponent extends TabViewBase {
480
- readonly controllerName: ModelSignal<string>;
481
- readonly entityID: ModelSignal<number | undefined>;
482
- /**
483
- * Catalog resolving the people who can appear as the author of a change, for the filter.
484
- *
485
- * Supplied through the route's `usersCatalogEndpoint` data, or bound directly. Without it the
486
- * author filter is not offered -- see {@link ServicesHistoryFilterComponent}.
487
- */
488
- readonly usersCatalogEndpoint: ModelSignal<string | undefined>;
489
- /**
490
- * The filters applied to the services grid, forwarded to the operations grid.
491
- *
492
- * Only `onlyCurrentEntity` means anything to the operations list, and the backend reads only what
493
- * it recognises, so the set is passed whole rather than picked apart here: a filter added later
494
- * then reaches both lists without this having to learn about it.
495
- */
496
- protected readonly operationsFilters: WritableSignal<{
497
- [key: string]: string;
498
- } | undefined>;
499
- private activatedRoute;
500
- private dataProviderService;
501
- constructor();
502
- protected onFiltersChanged(filters?: {
503
- [key: string]: string;
504
- }): void;
505
- static ɵfac: i0.ɵɵFactoryDeclaration<ServicesHistoryViewComponent, never>;
506
- static ɵcmp: i0.ɵɵComponentDeclaration<ServicesHistoryViewComponent, "shared-services-history-view", never, { "controllerName": { "alias": "controllerName"; "required": false; "isSignal": true; }; "entityID": { "alias": "entityID"; "required": false; "isSignal": true; }; "usersCatalogEndpoint": { "alias": "usersCatalogEndpoint"; "required": false; "isSignal": true; }; }, { "controllerName": "controllerNameChange"; "entityID": "entityIDChange"; "usersCatalogEndpoint": "usersCatalogEndpointChange"; }, never, never, true, never>;
507
- }
508
-
509
- declare const ZAMBON_SHARED_I18N_ASSET_PATH = "assets/i18n/zambon-dev/shared";
510
- declare const ZAMBON_SHARED_I18N_ASSET: AngularAssetPattern;
511
- declare const ZAMBON_SHARED_I18N_RESOURCES: TranslationResource[];
512
- interface ZambonSharedTranslateConfig {
513
- defaultLanguage?: string;
514
- appResources?: (string | TranslationResource)[];
515
- }
516
- declare function createZambonSharedTranslateLoader(httpBackend: HttpBackend, appResources?: (string | TranslationResource)[]): MultiTranslateHttpLoader;
517
- declare function provideZambonSharedTranslateLoader(appResources?: (string | TranslationResource)[]): Provider;
518
- declare function provideZambonSharedTranslateService(config?: ZambonSharedTranslateConfig): EnvironmentProviders;
519
-
520
- declare class LoginLayoutComponent {
521
- static ɵfac: i0.ɵɵFactoryDeclaration<LoginLayoutComponent, never>;
522
- static ɵcmp: i0.ɵɵComponentDeclaration<LoginLayoutComponent, "shared-login-layout", never, {}, {}, never, never, true, never>;
523
- }
524
-
525
- declare class MainLayoutComponent implements OnInit, OnDestroy {
526
- private readonly logoutModal;
527
- private authenticationService;
528
- private destroy$;
529
- private externalContentService;
530
- private externalUrlResolverService;
531
- private router;
532
- private sidebarService;
533
- private tabService;
534
- /** Application version (from AppConfig) projected into the sidebar footer. */
535
- protected appVersion: string;
536
- ngOnDestroy(): void;
537
- ngOnInit(): void;
538
- onLogoutClick(): void;
539
- onLogoutConfirm(): void;
540
- private openExternalMenu;
541
- static ɵfac: i0.ɵɵFactoryDeclaration<MainLayoutComponent, never>;
542
- static ɵcmp: i0.ɵɵComponentDeclaration<MainLayoutComponent, "shared-main-layout", never, {}, {}, never, never, true, never>;
543
- }
544
-
545
- declare class BrandComponent {
546
- private config;
547
- protected get appName(): string;
548
- protected get companyName(): string;
549
- protected get logoUrl(): string | undefined;
550
- static ɵfac: i0.ɵɵFactoryDeclaration<BrandComponent, never>;
551
- static ɵcmp: i0.ɵɵComponentDeclaration<BrandComponent, "shared-brand", never, {}, {}, never, never, true, never>;
552
- }
553
-
554
- declare class EnvironmentBadgeComponent {
555
- private config;
556
- /** CSS modifier class for the current environment, falling back to a neutral style. */
557
- protected get badgeClass(): string;
558
- /** Normalized environment key (uppercase, trimmed). */
559
- protected get environment(): string;
560
- /** The badge is hidden in production and when no environment is configured. */
561
- protected get isVisible(): boolean;
562
- static ɵfac: i0.ɵɵFactoryDeclaration<EnvironmentBadgeComponent, never>;
563
- static ɵcmp: i0.ɵɵComponentDeclaration<EnvironmentBadgeComponent, "shared-environment-badge", never, {}, {}, never, never, true, never>;
564
- }
565
-
566
- declare class NotificationsComponent implements OnInit {
567
- readonly dropdown: Signal<ElementRef<HTMLDivElement> | undefined>;
568
- private notificationsService;
569
- private router;
570
- protected notifications$: Observable<INotification[]>;
571
- protected readonly showDropdown: WritableSignal<boolean>;
572
- protected unreadCount$: Observable<number>;
573
- /** Whether the notifications feature is enabled; when false the bell is not rendered. */
574
- get isEnabled(): boolean;
575
- ngOnInit(): void;
576
- onDropdownClick(): void;
577
- onMarkAllAsRead(): void;
578
- onNotificationClick(notification: INotification): void;
579
- protected documentClick(event: MouseEvent): void;
580
- static ɵfac: i0.ɵɵFactoryDeclaration<NotificationsComponent, never>;
581
- static ɵcmp: i0.ɵɵComponentDeclaration<NotificationsComponent, "shared-notifications", never, {}, {}, never, never, true, never>;
582
- }
583
-
584
- declare class TopBarComponent {
585
- /** Emitted when the logout button is clicked. */
586
- readonly logout: OutputEmitterRef<void>;
587
- onLogoutClick(): void;
588
- static ɵfac: i0.ɵɵFactoryDeclaration<TopBarComponent, never>;
589
- static ɵcmp: i0.ɵɵComponentDeclaration<TopBarComponent, "shared-top-bar", never, {}, { "logout": "logout"; }, never, never, true, never>;
590
- }
591
-
592
- declare class UserProfileComponent implements OnInit {
593
- private authenticationService;
594
- protected readonly user: WritableSignal<ICurrentUserInfo | null>;
595
- /** Up to two uppercase initials derived from the user's name, used when no picture is set. */
596
- protected get initials(): string;
597
- protected get name(): string;
598
- protected get pictureUrl(): string | undefined;
599
- protected get position(): string;
600
- ngOnInit(): void;
601
- static ɵfac: i0.ɵɵFactoryDeclaration<UserProfileComponent, never>;
602
- static ɵcmp: i0.ɵɵComponentDeclaration<UserProfileComponent, "shared-user-profile", never, {}, {}, never, never, true, never>;
603
- }
604
-
381
+ export declare const externalContentRoutes: Routes;
382
+ export declare class OperationsHistoryChildListComponent extends ChildList<any> implements AfterViewInit {
383
+ private readonly modal;
384
+ private readonly operationTemplate;
385
+ set controllerName(value: string);
386
+ /**
387
+ * Filters to send with the list.
388
+ *
389
+ * The audit view applies its filters to the services grid and hands the same set here, because
390
+ * one of them -- whether to list only the audited record's own operations -- belongs to this
391
+ * list. The rest mean nothing to it, and the backend reads only what it recognises.
392
+ *
393
+ * `setFilters` refreshes the grid itself. With no service selected the dataset answers with an
394
+ * empty list rather than calling the backend, so a refresh then costs nothing.
395
+ */
396
+ set filters(value: {
397
+ [key: string]: string;
398
+ } | undefined);
399
+ set serviceID(value: number | undefined);
400
+ readonly selectedNewValues: WritableSignal<any | null>;
401
+ readonly selectedOldValues: WritableSignal<any | null>;
402
+ ngAfterViewInit(): void;
403
+ openModal(): void;
404
+ selectedRowChanged(): void;
405
+ static ɵfac: i0.ɵɵFactoryDeclaration<OperationsHistoryChildListComponent, never>;
406
+ static ɵcmp: i0.ɵɵComponentDeclaration<OperationsHistoryChildListComponent, "shared-operations-history-child-list", never, {
407
+ "controllerName": {
408
+ "alias": "controllerName";
409
+ "required": false;
410
+ };
411
+ "filters": {
412
+ "alias": "filters";
413
+ "required": false;
414
+ };
415
+ "serviceID": {
416
+ "alias": "serviceID";
417
+ "required": false;
418
+ };
419
+ }, {}, never, never, true, never>;
420
+ }
421
+ export declare class OperationsHistoryModalComponent extends ModalBase {
422
+ private readonly modal;
423
+ readonly newValues: InputSignal<string | undefined>;
424
+ readonly oldValues: InputSignal<string | undefined>;
425
+ /** Delegates to the inner modal; a signal query, so it re-runs once that child resolves. */
426
+ readonly isModalShown: Signal<boolean>;
427
+ toggle(): void;
428
+ static ɵfac: i0.ɵɵFactoryDeclaration<OperationsHistoryModalComponent, never>;
429
+ static ɵcmp: i0.ɵɵComponentDeclaration<OperationsHistoryModalComponent, "shared-operations-history-modal", never, {
430
+ "newValues": {
431
+ "alias": "newValues";
432
+ "required": false;
433
+ "isSignal": true;
434
+ };
435
+ "oldValues": {
436
+ "alias": "oldValues";
437
+ "required": false;
438
+ "isSignal": true;
439
+ };
440
+ }, {}, never, never, true, never>;
441
+ }
442
+ export declare class ServicesHistoryChildListComponent extends ChildList<any> implements AfterViewInit, OnInit {
443
+ private readonly serviceTemplate;
444
+ set controllerName(value: string);
445
+ /** Re-emits the grid's own filter changes, for a sibling list that has to follow them. */
446
+ readonly filtersChanged: OutputEmitterRef<{
447
+ [key: string]: string;
448
+ } | undefined>;
449
+ readonly selectedServiceID: WritableSignal<number | undefined>;
450
+ ngAfterViewInit(): void;
451
+ ngOnInit(): void;
452
+ selectedRowChanged(): void;
453
+ static ɵfac: i0.ɵɵFactoryDeclaration<ServicesHistoryChildListComponent, never>;
454
+ static ɵcmp: i0.ɵɵComponentDeclaration<ServicesHistoryChildListComponent, "shared-services-history-child-list", never, {
455
+ "controllerName": {
456
+ "alias": "controllerName";
457
+ "required": false;
458
+ };
459
+ }, {
460
+ "filtersChanged": "filtersChanged";
461
+ }, never, never, true, never>;
462
+ }
463
+ export declare class ServicesHistoryFilterComponent extends FiltersBase implements OnInit {
464
+ /**
465
+ * Catalog that resolves the people who can appear as the author of a change.
466
+ *
467
+ * There is no such catalog in this library -- who a user is belongs to the application -- so the
468
+ * author filter is offered only when one is supplied.
469
+ */
470
+ readonly usersCatalogEndpoint: InputSignal<string | undefined>;
471
+ protected readonly hasUsersCatalog: Signal<boolean>;
472
+ private get changedOnFromControl();
473
+ private get changedOnToControl();
474
+ ngOnInit(): void;
475
+ /**
476
+ * The control names are the filter names the backend reads, case insensitively: `name`,
477
+ * `changedByID`, `changedOnFrom`, `changedOnTo` and `onlyCurrentEntity` reach `AuditFilters` in
478
+ * ZWebAPI. The two dates are sent as picked and turned into UTC instants by
479
+ * {@link ServicesHistoryDataset}, which is the boundary where the request is built.
480
+ */
481
+ protected formSetup(): FormGroup<any>;
482
+ static ɵfac: i0.ɵɵFactoryDeclaration<ServicesHistoryFilterComponent, never>;
483
+ static ɵcmp: i0.ɵɵComponentDeclaration<ServicesHistoryFilterComponent, "shared-services-history-filter", never, {
484
+ "usersCatalogEndpoint": {
485
+ "alias": "usersCatalogEndpoint";
486
+ "required": false;
487
+ "isSignal": true;
488
+ };
489
+ }, {}, never, never, true, never>;
490
+ }
491
+ export declare class ServicesHistoryViewComponent extends TabViewBase {
492
+ readonly controllerName: ModelSignal<string>;
493
+ readonly entityID: ModelSignal<number | undefined>;
494
+ /**
495
+ * Catalog resolving the people who can appear as the author of a change, for the filter.
496
+ *
497
+ * Supplied through the route's `usersCatalogEndpoint` data, or bound directly. Without it the
498
+ * author filter is not offered -- see {@link ServicesHistoryFilterComponent}.
499
+ */
500
+ readonly usersCatalogEndpoint: ModelSignal<string | undefined>;
501
+ /**
502
+ * The filters applied to the services grid, forwarded to the operations grid.
503
+ *
504
+ * Only `onlyCurrentEntity` means anything to the operations list, and the backend reads only what
505
+ * it recognises, so the set is passed whole rather than picked apart here: a filter added later
506
+ * then reaches both lists without this having to learn about it.
507
+ */
508
+ protected readonly operationsFilters: WritableSignal<{
509
+ [key: string]: string;
510
+ } | undefined>;
511
+ private activatedRoute;
512
+ private dataProviderService;
513
+ constructor();
514
+ protected onFiltersChanged(filters?: {
515
+ [key: string]: string;
516
+ }): void;
517
+ static ɵfac: i0.ɵɵFactoryDeclaration<ServicesHistoryViewComponent, never>;
518
+ static ɵcmp: i0.ɵɵComponentDeclaration<ServicesHistoryViewComponent, "shared-services-history-view", never, {
519
+ "controllerName": {
520
+ "alias": "controllerName";
521
+ "required": false;
522
+ "isSignal": true;
523
+ };
524
+ "entityID": {
525
+ "alias": "entityID";
526
+ "required": false;
527
+ "isSignal": true;
528
+ };
529
+ "usersCatalogEndpoint": {
530
+ "alias": "usersCatalogEndpoint";
531
+ "required": false;
532
+ "isSignal": true;
533
+ };
534
+ }, {
535
+ "controllerName": "controllerNameChange";
536
+ "entityID": "entityIDChange";
537
+ "usersCatalogEndpoint": "usersCatalogEndpointChange";
538
+ }, never, never, true, never>;
539
+ }
540
+ export declare const ZAMBON_SHARED_I18N_ASSET_PATH = "assets/i18n/zambon-dev/shared";
541
+ export declare const ZAMBON_SHARED_I18N_ASSET: AngularAssetPattern;
542
+ export declare const ZAMBON_SHARED_I18N_RESOURCES: TranslationResource[];
543
+ export interface ZambonSharedTranslateConfig {
544
+ defaultLanguage?: string;
545
+ appResources?: (string | TranslationResource)[];
546
+ }
547
+ export declare function createZambonSharedTranslateLoader(httpBackend: HttpBackend, appResources?: (string | TranslationResource)[]): MultiTranslateHttpLoader;
548
+ export declare function provideZambonSharedTranslateLoader(appResources?: (string | TranslationResource)[]): Provider;
549
+ export declare function provideZambonSharedTranslateService(config?: ZambonSharedTranslateConfig): EnvironmentProviders;
550
+ export declare class LoginLayoutComponent {
551
+ private config;
552
+ /** Optional photograph behind the card. Absent leaves the app backdrop showing. */
553
+ protected get backgroundUrl(): string | undefined;
554
+ static ɵfac: i0.ɵɵFactoryDeclaration<LoginLayoutComponent, never>;
555
+ static ɵcmp: i0.ɵɵComponentDeclaration<LoginLayoutComponent, "shared-login-layout", never, {}, {}, never, ["*"], true, never>;
556
+ }
557
+ export declare class MainLayoutComponent implements OnInit, OnDestroy {
558
+ private readonly logoutModal;
559
+ private authenticationService;
560
+ private destroy$;
561
+ private externalContentService;
562
+ private externalUrlResolverService;
563
+ private router;
564
+ private sidebarService;
565
+ private tabService;
566
+ /** Application version (from AppConfig) projected into the sidebar footer. */
567
+ protected appVersion: string;
568
+ ngOnDestroy(): void;
569
+ ngOnInit(): void;
570
+ onLogoutClick(): void;
571
+ onLogoutConfirm(): void;
572
+ private openExternalMenu;
573
+ static ɵfac: i0.ɵɵFactoryDeclaration<MainLayoutComponent, never>;
574
+ static ɵcmp: i0.ɵɵComponentDeclaration<MainLayoutComponent, "shared-main-layout", never, {}, {}, never, never, true, never>;
575
+ }
576
+ export declare class BrandComponent {
577
+ private config;
578
+ protected get appName(): string;
579
+ protected get companyName(): string;
580
+ protected get logoUrl(): string | undefined;
581
+ static ɵfac: i0.ɵɵFactoryDeclaration<BrandComponent, never>;
582
+ static ɵcmp: i0.ɵɵComponentDeclaration<BrandComponent, "shared-brand", never, {}, {}, never, never, true, never>;
583
+ }
584
+ export declare class EnvironmentBadgeComponent {
585
+ private config;
586
+ /** CSS modifier class for the current environment, falling back to a neutral style. */
587
+ protected get badgeClass(): string;
588
+ /** Normalized environment key (uppercase, trimmed). */
589
+ protected get environment(): string;
590
+ /** The badge is hidden in production and when no environment is configured. */
591
+ protected get isVisible(): boolean;
592
+ static ɵfac: i0.ɵɵFactoryDeclaration<EnvironmentBadgeComponent, never>;
593
+ static ɵcmp: i0.ɵɵComponentDeclaration<EnvironmentBadgeComponent, "shared-environment-badge", never, {}, {}, never, never, true, never>;
594
+ }
595
+ export declare class NotificationsComponent implements OnInit {
596
+ readonly dropdown: Signal<ElementRef<HTMLDivElement> | undefined>;
597
+ private notificationsService;
598
+ private router;
599
+ protected notifications$: Observable<INotification[]>;
600
+ protected readonly showDropdown: WritableSignal<boolean>;
601
+ protected unreadCount$: Observable<number>;
602
+ /** Whether the notifications feature is enabled; when false the bell is not rendered. */
603
+ get isEnabled(): boolean;
604
+ ngOnInit(): void;
605
+ onDropdownClick(): void;
606
+ onMarkAllAsRead(): void;
607
+ onNotificationClick(notification: INotification): void;
608
+ protected documentClick(event: MouseEvent): void;
609
+ static ɵfac: i0.ɵɵFactoryDeclaration<NotificationsComponent, never>;
610
+ static ɵcmp: i0.ɵɵComponentDeclaration<NotificationsComponent, "shared-notifications", never, {}, {}, never, never, true, never>;
611
+ }
612
+ export declare class TopBarComponent {
613
+ /** Emitted when the logout button is clicked. */
614
+ readonly logout: OutputEmitterRef<void>;
615
+ onLogoutClick(): void;
616
+ static ɵfac: i0.ɵɵFactoryDeclaration<TopBarComponent, never>;
617
+ static ɵcmp: i0.ɵɵComponentDeclaration<TopBarComponent, "shared-top-bar", never, {}, {
618
+ "logout": "logout";
619
+ }, never, never, true, never>;
620
+ }
621
+ export declare class UserProfileComponent implements OnInit {
622
+ private authenticationService;
623
+ protected readonly user: WritableSignal<ICurrentUserInfo | null>;
624
+ /** Up to two uppercase initials derived from the user's name, used when no picture is set. */
625
+ protected get initials(): string;
626
+ protected get name(): string;
627
+ protected get pictureUrl(): string | undefined;
628
+ protected get position(): string;
629
+ ngOnInit(): void;
630
+ static ɵfac: i0.ɵɵFactoryDeclaration<UserProfileComponent, never>;
631
+ static ɵcmp: i0.ɵɵComponentDeclaration<UserProfileComponent, "shared-user-profile", never, {}, {}, never, never, true, never>;
632
+ }
605
633
  /**
606
634
  * Pipe that bypasses Angular's built-in HTML sanitization.
607
635
  *
@@ -631,25 +659,84 @@ declare class UserProfileComponent implements OnInit {
631
659
  * <div [innerHTML]="comment.body | bypassHtmlSanitizer"></div> // ❌ XSS risk
632
660
  * <div [innerHTML]="comment.body"></div> // ✅ Angular sanitizes automatically
633
661
  */
634
- declare class BypassHtmlSanitizerPipe implements PipeTransform {
635
- private sanitizer;
636
- transform(html: string): SafeHtml;
637
- static ɵfac: i0.ɵɵFactoryDeclaration<BypassHtmlSanitizerPipe, never>;
638
- static ɵpipe: i0.ɵɵPipeDeclaration<BypassHtmlSanitizerPipe, "bypassHtmlSanitizer", true>;
639
- }
640
-
641
- declare class EnumLabelPipe implements PipeTransform {
642
- transform(value?: number, enumType?: any): string;
643
- static ɵfac: i0.ɵɵFactoryDeclaration<EnumLabelPipe, never>;
644
- static ɵpipe: i0.ɵɵPipeDeclaration<EnumLabelPipe, "enumLabel", true>;
645
- }
646
-
647
- declare class UtcDatePipe implements PipeTransform {
648
- private static readonly timeZoneMarker;
649
- transform(value?: Date | string): Date | null;
650
- static ɵfac: i0.ɵɵFactoryDeclaration<UtcDatePipe, never>;
651
- static ɵpipe: i0.ɵɵPipeDeclaration<UtcDatePipe, "utcDate", true>;
652
- }
653
-
654
- export { AuthGuard, AuthInterceptor, AuthenticationService, BrandComponent, BypassHtmlSanitizerPipe, EXTERNAL_CONTENT_CONFIGS, EXTERNAL_CONTENT_ROUTE_PATH, EnumLabelPipe, EnvironmentBadgeComponent, ExternalContentComponent, ExternalContentConfigs, ExternalContentService, ExternalUrlResolverService, FiltersBase, LoginLayoutComponent, MainLayoutComponent, NotificationsComponent, NotificationsService, OperationsHistoryChildListComponent, OperationsHistoryDataset, OperationsHistoryModalComponent, OperationsHistoryService, ServicesHistoryChildListComponent, ServicesHistoryDataset, ServicesHistoryFilterComponent, ServicesHistoryService, ServicesHistoryViewComponent, SharedAuthModule, TopBarComponent, UserProfileComponent, UtcDatePipe, ZAMBON_SHARED_I18N_ASSET, ZAMBON_SHARED_I18N_ASSET_PATH, ZAMBON_SHARED_I18N_RESOURCES, createZambonSharedTranslateLoader, externalContentRoutes, provideZambonSharedTranslateLoader, provideZambonSharedTranslateService };
655
- export type { IAuthResponse, ICurrentUserInfo, IExternalContentEntry, INotification, IOperationsHistoryList, IServicesHistoryList, ZambonSharedTranslateConfig };
662
+ export declare class BypassHtmlSanitizerPipe implements PipeTransform {
663
+ private sanitizer;
664
+ transform(html: string): SafeHtml;
665
+ static ɵfac: i0.ɵɵFactoryDeclaration<BypassHtmlSanitizerPipe, never>;
666
+ static ɵpipe: i0.ɵɵPipeDeclaration<BypassHtmlSanitizerPipe, "bypassHtmlSanitizer", true>;
667
+ }
668
+ export declare class EnumLabelPipe implements PipeTransform {
669
+ transform(value?: number, enumType?: any): string;
670
+ static ɵfac: i0.ɵɵFactoryDeclaration<EnumLabelPipe, never>;
671
+ static ɵpipe: i0.ɵɵPipeDeclaration<EnumLabelPipe, "enumLabel", true>;
672
+ }
673
+ export declare class UtcDatePipe implements PipeTransform {
674
+ private static readonly timeZoneMarker;
675
+ transform(value?: Date | string): Date | null;
676
+ static ɵfac: i0.ɵɵFactoryDeclaration<UtcDatePipe, never>;
677
+ static ɵpipe: i0.ɵɵPipeDeclaration<UtcDatePipe, "utcDate", true>;
678
+ }
679
+ /** What the user chose. `system` follows the operating system and keeps following it. */
680
+ export type ThemePreference = 'light' | 'dark' | 'system';
681
+ /** What the stylesheet is actually asked for. The CSS never sees `system`. */
682
+ export type ResolvedTheme = 'light' | 'dark';
683
+ /** Key the preference is stored under, and the one the pre-paint snippet has to read. */
684
+ export declare const THEME_STORAGE_KEY = "zambon-theme";
685
+ /**
686
+ * Owns the light/dark choice and writes it to `<html>`.
687
+ *
688
+ * The CSS switch is an attribute rather than `prefers-color-scheme` so that both sides keep a
689
+ * choice: an application can leave the attribute unwritten and never have a dark theme, and a user
690
+ * can pick light on a dark machine. Following the operating system is still a supported choice --
691
+ * it is resolved here, in TypeScript, and written out as a concrete `light` or `dark`. That is why
692
+ * `theme.css` holds one dark block instead of two that would have to be kept identical.
693
+ *
694
+ * The attribute is normally written before this service exists, by the snippet in `index.html`
695
+ * documented in the design-tokens guide -- an Angular service cannot run before the first paint,
696
+ * and a frame of the wrong theme is worse than no theme. This picks up from there.
697
+ */
698
+ export declare class ThemeService {
699
+ private readonly document;
700
+ private readonly preferenceState;
701
+ private readonly systemPrefersDark;
702
+ /** What the user chose, including `system`. */
703
+ readonly preference: import("@angular/core").Signal<ThemePreference>;
704
+ /** What is actually applied right now. `system` is already resolved here. */
705
+ readonly resolved: import("@angular/core").Signal<ResolvedTheme>;
706
+ constructor();
707
+ /** Records a choice and applies it. Persisting is best-effort: a blocked store is not an error. */
708
+ setPreference(preference: ThemePreference): void;
709
+ /** Steps light -> dark -> system -> light, which is what a single-button switch needs. */
710
+ cyclePreference(): void;
711
+ private readStoredPreference;
712
+ private readSystemPrefersDark;
713
+ /**
714
+ * Keeps following the operating system after the first read. Without this, choosing `system` and
715
+ * then switching the machine to dark would leave the application on light until a reload.
716
+ */
717
+ private watchSystemPreference;
718
+ static ɵfac: i0.ɵɵFactoryDeclaration<ThemeService, never>;
719
+ static ɵprov: i0.ɵɵInjectableDeclaration<any>;
720
+ }
721
+ /**
722
+ * The top bar's light/dark control.
723
+ *
724
+ * One button stepping light -> dark -> system rather than three, because the bar is tight and this
725
+ * is not a setting people change often. The icon shows the choice that is in force, not the one a
726
+ * click would bring: a control that displays its own next state cannot be read at a glance.
727
+ *
728
+ * It has no stylesheet: a ghost `lib-button` is already the icon-button treatment, and a second
729
+ * copy of it here would drift from the one in the top bar beside it.
730
+ */
731
+ export declare class ThemeSwitchComponent {
732
+ private readonly theme;
733
+ /** The choice in force, including `system`. */
734
+ protected readonly preference: import("@angular/core").Signal<ThemePreference>;
735
+ /** Full Font Awesome classes for the current choice -- the style prefix is not optional. */
736
+ protected readonly icon: import("@angular/core").Signal<string>;
737
+ /** Translation key naming the current choice, used for the label and the tooltip. */
738
+ protected readonly label: import("@angular/core").Signal<string>;
739
+ protected onClick(): void;
740
+ static ɵfac: i0.ɵɵFactoryDeclaration<ThemeSwitchComponent, never>;
741
+ static ɵcmp: i0.ɵɵComponentDeclaration<ThemeSwitchComponent, "shared-theme-switch", never, {}, {}, never, never, true, never>;
742
+ }