@arsedizioni/ars-utils 22.5.1 → 22.5.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/README.md CHANGED
@@ -23,8 +23,10 @@ di vita proprio vive nel suo entry point. Importare sempre dal path specifico.
23
23
  | L0 | `core` | `SystemUtils`, models, definitions, pipe, direttive validator, servizi (broadcast, screen, theme, splash, environment), `LoginOAuthType` | nessuna dipendenza da Angular Material |
24
24
  | L0 | `core.date` | `provideArsDateFns`, `provideArsLocalDates`, `MAT_DATE_FNS_FORMATS`, `arsLocalDateInterceptor`, `ARS_TIME_ZONE` | isola `@angular/material/core` + `datepicker` |
25
25
  | L0 | `core.markdown` | `MarkdownUtils`, `FormatMarkdownPipe` | parser markdown, fuori dal percorso comune |
26
- | L1 | `ui` | `FlexLayoutModule`, `MediaObserver`, `UIService`, `PaginatorIntl`, tipi dei dialog | kernel: deve restare magro |
27
- | L1.5 | `ui.dialogs` | `DialogService` + busy, confirm, delete, info, toast | il set sempre usato |
26
+ | L0.5 | `ui.shell` | `ShellService` (`info`, `error`, `busy*`, `wait`, `BusyTimer`), `ShellMessageComponent`, `ShellBusyComponent` | zero Material e zero CDK: e' quello che shell, interceptor, guard e app initializer possono permettersi sul percorso di boot |
27
+ | L1 | `ui` | `FlexLayoutModule`, `MediaObserver`, `UIService`, tipi dei dialog | kernel: deve restare magro, e non importa nulla da Material |
28
+ | L1 | `ui.paginator` | `PaginatorIntl` | isola `@angular/material/paginator`, che si porta dietro `mat-select` e `mat-option` |
29
+ | L1.5 | `ui.dialogs` | `DialogService` (estende `ShellService`) + confirm, delete, toast, `open` | tutto cio' che chiede qualcosa all'utente, piu' il toast |
28
30
  | L2 | `ui.dialogs.auth` | credentials, reset-password, recover-password, prompt-otp, `OtpInputComponent`, `PasswordStrengthComponent` | solo route di login/account |
29
31
  | L2 | `ui.dialogs.prompt` | prompt, prompt-date, prompt-time | porta `@angular/material/datepicker` |
30
32
  | L2 | `ui.dialogs.select` | select, select-tree, send-to | porta `mat-tree`, `mat-list`, `mat-chips` |
@@ -54,13 +56,15 @@ solo a chi importa rispettivamente `ui.oauth` e `ui.tinymce`: sono dichiarati in
54
56
  ### Grafo delle dipendenze statiche
55
57
 
56
58
  ```
57
- core core.date core.markdown
58
- |
59
- ui ------------------------------------------------------------------
60
- | | | | | |
61
- | ui.controls ui.filters ui.navigation ui.dialogs.select clipper.common
62
- |
63
- ui.dialogs
59
+ core core.date core.markdown ui.paginator
60
+ | \
61
+ | ui.shell
62
+ | |
63
+ ui ------|-----------------------------------------------------------
64
+ | | | | | | |
65
+ | | ui.controls ui.filters ui.navigation ui.dialogs.select clipper.common
66
+ | |
67
+ ui.dialogs <-- DialogService extends ShellService: dipende da `ui` E da `ui.shell`
64
68
  | | | | | |
65
69
  | ui.dialogs.auth ui.dialogs.prompt ui.files ui.help ui.oauth
66
70
  | ui.notifications (+ support.common)
@@ -82,6 +86,53 @@ clipper.ui (+ clipper.common, ui.controls, ui.files, ui.dialogs.select)
82
86
  che tiene i dialog fuori dal bundle iniziale.
83
87
  4. Dopo una modifica, verificare che gli `import()` sopravvivano alla build:
84
88
  `grep -o "import('@arsedizioni[^']*')" dist/ars-utils/fesm2022/*ui.application.mjs`
89
+ 5. `ui.shell` non importa nulla da `@angular/material` ne' da `@angular/cdk`, e nemmeno da `ui`.
90
+ E' l'unica ragione per cui esiste: se ci finisce dentro un solo simbolo di Material, la shell
91
+ torna a pagare l'intero stack sul percorso di boot. Da verificare dopo ogni build:
92
+ `grep -oE "@angular/(material|cdk)[^'\"]*" dist/ars-utils/fesm2022/*ui.shell.mjs` non deve
93
+ stampare nulla.
94
+ 7. Le sovrapposizioni di `ui.shell` non stanno nello stack del CDK, quindi il loro ordine e' un
95
+ z-index fisso: `cdk-overlay-container` sta a 1000, il busy a 1090 e il messaggio a 1100. Un
96
+ errore che esce mentre un dialog Material e' aperto deve stargli sopra, ed e' cosi'. L'unico
97
+ caso che un numero fisso non sa esprimere e un dialog aperto mentre il busy e ancora su:
98
+ per questo `DialogService.open()` chiama `clearBusy(true)`, senza periodo di grazia.
99
+ 6. `ui` non importa valori da Material. `PaginatorIntl` e' uscito da li' proprio per questo: era
100
+ l'unico simbolo che ne dipendeva, e faceva pagare `mat-paginator` + `mat-select` + `mat-option`
101
+ a chiunque toccasse `ui.dialogs`. Restano due eccezioni, entrambe volute:
102
+ `MatFormFieldAppearance` in `dialog.definitions.ts`, che e' un `import type` e quindi sparisce
103
+ in compilazione, e `@angular/cdk/layout` (1 KB) di cui `MediaObserver` ha bisogno.
104
+
105
+ ### Da dove parte un'applicazione
106
+
107
+ `core` + `ui.shell`. Sono i due entry point che una applicazione ARS carica comunque prima di
108
+ avere una rotta, e gli unici due che non costano Material. `core` porta `SystemUtils`, i modelli,
109
+ `BroadcastService`, `SplashService`, `EnvironmentService`, `ThemeService`; `ui.shell` porta il modo
110
+ di dire all'utente che la sessione e' scaduta o che l'API non risponde.
111
+
112
+ Non sono un entry point solo, e non devono diventarlo: `core` e' L0 e ci dipendono anche
113
+ `clipper.common`, `evolution.common` e `support.common`, che di interfaccia non ne hanno. Fonderli
114
+ significherebbe far dipendere tre entry point headless da uno di UI, cioe' rompere la regola 1.
115
+
116
+ La conseguenza pratica per chi scrive l'applicazione:
117
+
118
+ - shell, interceptor, guard, `provideAppInitializer` -> `ShellService` di `ui.shell`
119
+ - componenti di rotta -> `DialogService` di `ui.dialogs`, e `ApplicationDialogService` di `ui.application` per i dialog pesanti
120
+
121
+ I tre servizi sono una catena, non tre servizi diversi:
122
+
123
+ ```
124
+ ShellService info, error, busy*, wait, busyTimer ui.shell
125
+ └ DialogService + open, confirm, delete, toast ui.dialogs
126
+ └ ApplicationDialogService + select, prompt, sendTo, ... ui.application
127
+ ```
128
+
129
+ Quindi chi inietta `DialogService` ha tutto quello che aveva prima: `info`, `error` e `busy` non
130
+ sono spariti, sono ereditati. E non esistono in due copie — c'e' una implementazione sola, quella
131
+ senza Material.
132
+
133
+ `ShellService.info()` e `ShellService.error()` hanno gli stessi parametri, nello stesso ordine,
134
+ delle omonime di `DialogService`: spostare una chiamata dall'una all'altra e' un cambio di servizio
135
+ iniettato e nient'altro.
85
136
 
86
137
  ## Differenze rispetto alla versione precedente (22.1.x monolitica)
87
138
 
@@ -92,6 +143,16 @@ clipper.ui (+ clipper.common, ui.controls, ui.files, ui.dialogs.select)
92
143
  - `SystemUtils.markdownToHtml` non esiste piu': usare `MarkdownUtils.toHtml` da `core.markdown`.
93
144
  - `SelectableModel` espone `first` e `selectedAny` al posto di `selectedFirst` e `selectedAll`.
94
145
  - `support.ui` si chiama `ui.notifications`, `help` si chiama `ui.help`, `tinymce` si chiama `ui.tinymce`.
146
+ - `PaginatorIntl` non sta piu' in `ui`: sta in `ui.paginator`.
147
+ - La shell non deve piu' iniettare `DialogService` per mostrare un errore: c'e' `ShellService` in `ui.shell`.
148
+ - `info`, `error`, `busy`, `busySpinner`, `busyHourglass`, `wait`, `busyTimer` e `clearBusy` sono
149
+ passati a `ShellService`. `DialogService` li eredita, quindi nessuna chiamata cambia.
150
+ - `info()` e `error()` restituiscono `ShellMessageRef` invece di `MatDialogRef<InfoDialogComponent>`.
151
+ In myARS nessun chiamante usava quel valore; controllare nelle altre applicazioni.
152
+ - `clearBusy()` accetta `immediate`: `clearBusy(true)` non aspetta i 500 ms di grazia.
153
+ - `BusyTimer` si importa da `ui.shell`, non piu' da `ui.dialogs`.
154
+ - `InfoDialogComponent` e `BusyDialogComponent` non esistono piu': li sostituiscono
155
+ `ShellMessageComponent` e `ShellBusyComponent`, senza Material.
95
156
 
96
157
  ## Authors
97
158
  Fabio Buscaroli, Alberto Doria
@@ -60,6 +60,7 @@ import { finalize as finalize$1 } from 'rxjs/operators';
60
60
  import * as i5$1 from '@angular/cdk/text-field';
61
61
  import { TextFieldModule } from '@angular/cdk/text-field';
62
62
  import { Router } from '@angular/router';
63
+ import { ShellService } from '@arsedizioni/ars-utils/ui.shell';
63
64
  import { FilePreviewComponent } from '@arsedizioni/ars-utils/ui.files';
64
65
  import * as i2$2 from '@angular/material/list';
65
66
  import { MatListModule } from '@angular/material/list';
@@ -3676,6 +3677,7 @@ class ClipperDocumentComponent extends ClipperDocumentManager {
3676
3677
  this.breakpointObserver = inject(BreakpointObserver);
3677
3678
  this.renderer = inject(Renderer2);
3678
3679
  this.router = inject(Router);
3680
+ this.shellService = inject(ShellService);
3679
3681
  this.dialogRef = inject((MatDialogRef));
3680
3682
  this.dialogData = inject(MAT_DIALOG_DATA) ?? { mode: ClipperQueryReferencesMode.ReferencesIn };
3681
3683
  this.url = signal(null, /* @ts-ignore */
@@ -4018,7 +4020,7 @@ class ClipperDocumentComponent extends ClipperDocumentManager {
4018
4020
  navigated(id, title1, title2, tags, model, moduleId, moduleName, date, number, author, origin, originDescription, bag, validityInfo, expiringInfo, primaryId, primaryModel, secondaryId, isTrial) {
4019
4021
  // Redirect to login when the session has expired
4020
4022
  if (title1 === 'Sessione non valida') {
4021
- this.dialogService
4023
+ this.shellService
4022
4024
  .error(title2, null, title1, 'Accedi di nuovo')
4023
4025
  .afterClosed()
4024
4026
  .subscribe(() => this.router.navigate(['login']));