@truenas/ui-components 0.7.12 → 0.7.14
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.
|
@@ -3746,8 +3746,22 @@ const defaultSpriteConfigPath = `${defaultSpriteBasePath}/sprite-config.json`;
|
|
|
3746
3746
|
*/
|
|
3747
3747
|
class TnSpriteLoaderService {
|
|
3748
3748
|
spriteConfig;
|
|
3749
|
-
spriteLoaded = false;
|
|
3750
3749
|
spriteLoadPromise;
|
|
3750
|
+
/**
|
|
3751
|
+
* A signal rather than a plain field, because the fetch below starts from the
|
|
3752
|
+
* constructor and lands whenever it lands: anything that resolves an icon
|
|
3753
|
+
* before it does gets a miss, and needs to be told when to ask again (#341).
|
|
3754
|
+
*/
|
|
3755
|
+
spriteLoadedState = signal(false, ...(ngDevMode ? [{ debugName: "spriteLoadedState" }] : []));
|
|
3756
|
+
/**
|
|
3757
|
+
* Whether the sprite config has loaded, as a signal — read it inside a
|
|
3758
|
+
* `computed`/`effect` to re-resolve when the sprite arrives.
|
|
3759
|
+
*
|
|
3760
|
+
* `isSpriteLoaded()` reads the same state, so a caller that just wants the
|
|
3761
|
+
* current value needs nothing from here; this is for a caller that wants to
|
|
3762
|
+
* react to it changing.
|
|
3763
|
+
*/
|
|
3764
|
+
spriteLoaded = this.spriteLoadedState.asReadonly();
|
|
3751
3765
|
http = inject(HttpClient);
|
|
3752
3766
|
sanitizer = inject(DomSanitizer);
|
|
3753
3767
|
constructor() {
|
|
@@ -3764,8 +3778,10 @@ class TnSpriteLoaderService {
|
|
|
3764
3778
|
this.spriteLoadPromise = (async () => {
|
|
3765
3779
|
try {
|
|
3766
3780
|
const config = await firstValueFrom(this.http.get(defaultSpriteConfigPath));
|
|
3781
|
+
// Config first, then the flag: a reader woken by the signal below goes
|
|
3782
|
+
// straight to `getIconUrl`, which needs the config already there.
|
|
3767
3783
|
this.spriteConfig = config;
|
|
3768
|
-
this.
|
|
3784
|
+
this.spriteLoadedState.set(true);
|
|
3769
3785
|
}
|
|
3770
3786
|
catch (error) {
|
|
3771
3787
|
console.error('[TnSpriteLoader] Failed to load sprite config. Icons may not work:', error);
|
|
@@ -3778,7 +3794,7 @@ class TnSpriteLoaderService {
|
|
|
3778
3794
|
*/
|
|
3779
3795
|
async ensureSpriteLoaded() {
|
|
3780
3796
|
await this.loadSpriteConfig();
|
|
3781
|
-
return this.
|
|
3797
|
+
return this.spriteLoadedState();
|
|
3782
3798
|
}
|
|
3783
3799
|
/**
|
|
3784
3800
|
* Get the full URL for an icon in the sprite
|
|
@@ -3815,10 +3831,14 @@ class TnSpriteLoaderService {
|
|
|
3815
3831
|
return this.sanitizer.bypassSecurityTrustResourceUrl(url);
|
|
3816
3832
|
}
|
|
3817
3833
|
/**
|
|
3818
|
-
* Check if the sprite is loaded
|
|
3834
|
+
* Check if the sprite is loaded.
|
|
3835
|
+
*
|
|
3836
|
+
* Reads the `spriteLoaded` signal, so a call made from inside a `computed` or
|
|
3837
|
+
* an `effect` is tracked and that consumer re-runs when the sprite arrives —
|
|
3838
|
+
* which is how an icon resolved too early gets a second chance (#341).
|
|
3819
3839
|
*/
|
|
3820
3840
|
isSpriteLoaded() {
|
|
3821
|
-
return this.
|
|
3841
|
+
return this.spriteLoadedState();
|
|
3822
3842
|
}
|
|
3823
3843
|
/**
|
|
3824
3844
|
* Get the sprite config if loaded
|