diff --git a/ui-ngx/src/app/core/http/image.service.ts b/ui-ngx/src/app/core/http/image.service.ts index c714f728c0..896145b351 100644 --- a/ui-ngx/src/app/core/http/image.service.ts +++ b/ui-ngx/src/app/core/http/image.service.ts @@ -31,7 +31,7 @@ import { removeTbImagePrefix, ResourceSubType } from '@shared/models/resource.models'; -import { catchError, map, switchMap } from 'rxjs/operators'; +import { catchError, finalize, map, switchMap } from 'rxjs/operators'; import { DomSanitizer, SafeUrl } from '@angular/platform-browser'; import { blobToBase64, blobToText } from '@core/utils'; import { ResourcesService } from '@core/services/resources.service'; @@ -116,16 +116,15 @@ export class ImageService { request = new ReplaySubject(1); this.imagesLoading[imageLink] = request; const options = defaultHttpOptionsFromConfig({ignoreLoading: true, ignoreErrors: true}); - this.http.get(imageLink, {...options, ...{ responseType: 'blob' } }).subscribe({ + this.http.get(imageLink, {...options, ...{ responseType: 'blob' } }).pipe( + finalize(()=> delete this.imagesLoading[imageLink]) + ).subscribe({ next: (value) => { request.next(value); request.complete(); }, error: err => { request.error(err); - }, - complete: () => { - delete this.imagesLoading[imageLink]; } }); } diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/chart/bar-chart-with-labels-widget.component.scss b/ui-ngx/src/app/modules/home/components/widget/lib/chart/bar-chart-with-labels-widget.component.scss index 5eef2bf05f..b00409f41b 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/chart/bar-chart-with-labels-widget.component.scss +++ b/ui-ngx/src/app/modules/home/components/widget/lib/chart/bar-chart-with-labels-widget.component.scss @@ -20,9 +20,7 @@ display: flex; flex-direction: column; gap: 8px; - &.overlay { - padding: 20px 24px 24px 24px; - } + padding: 20px 24px 24px 24px; > div:not(.tb-bar-chart-overlay) { z-index: 1; } diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/chart/range-chart-widget.component.scss b/ui-ngx/src/app/modules/home/components/widget/lib/chart/range-chart-widget.component.scss index 1dfc386930..c1445ee6d0 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/chart/range-chart-widget.component.scss +++ b/ui-ngx/src/app/modules/home/components/widget/lib/chart/range-chart-widget.component.scss @@ -20,9 +20,7 @@ display: flex; flex-direction: column; gap: 8px; - &.overlay { - padding: 20px 24px 24px 24px; - } + padding: 20px 24px 24px 24px; > div:not(.tb-range-chart-overlay) { z-index: 1; } diff --git a/ui-ngx/src/app/shared/components/image/gallery-image-input.component.ts b/ui-ngx/src/app/shared/components/image/gallery-image-input.component.ts index 421d0ec559..9c5df854a5 100644 --- a/ui-ngx/src/app/shared/components/image/gallery-image-input.component.ts +++ b/ui-ngx/src/app/shared/components/image/gallery-image-input.component.ts @@ -171,9 +171,9 @@ export class GalleryImageInputComponent extends PageComponent implements OnInit, } } - private updateModel(value: string) { + private updateModel(value: string, forcedToUpdate = false): void { this.cd.markForCheck(); - if (this.imageUrl !== value) { + if (this.imageUrl !== value || forcedToUpdate) { this.imageUrl = value; this.propagateChange(prependTbImagePrefix(this.imageUrl)); } @@ -211,9 +211,10 @@ export class GalleryImageInputComponent extends PageComponent implements OnInit, } }).afterClosed().subscribe((image) => { if (image) { + const forcedToUpdate = this.imageUrl === image.link && this.imageResource?.descriptor?.etag !== image.descriptor.etag; this.linkType = ImageLinkType.resource; this.imageResource = image; - this.updateModel(image.link); + this.updateModel(image.link, forcedToUpdate); } }); } diff --git a/ui-ngx/src/app/shared/pipe/image.pipe.ts b/ui-ngx/src/app/shared/pipe/image.pipe.ts index d17ed0ab76..b570da5f24 100644 --- a/ui-ngx/src/app/shared/pipe/image.pipe.ts +++ b/ui-ngx/src/app/shared/pipe/image.pipe.ts @@ -38,7 +38,7 @@ export class ImagePipe implements PipeTransform { private sanitizer: DomSanitizer, private zone: NgZone) { } - transform(urlData: string | UrlHolder, args?: any): Observable { + transform(urlData: string | UrlHolder, args?: any, triggerUpdate?: number): Observable { const ignoreLoadingImage = !!args?.ignoreLoadingImage; const asString = !!args?.asString; const emptyUrl = args?.emptyUrl || NO_IMAGE_DATA_URI; diff --git a/ui-ngx/src/assets/locale/locale.constant-en_US.json b/ui-ngx/src/assets/locale/locale.constant-en_US.json index 6506f0ca58..116ff4b4c4 100644 --- a/ui-ngx/src/assets/locale/locale.constant-en_US.json +++ b/ui-ngx/src/assets/locale/locale.constant-en_US.json @@ -810,7 +810,7 @@ "no-assets-matching": "No assets matching '{{entity}}' were found.", "asset-required": "Asset is required.", "name-starts-with": "Asset name expression", - "help-text": "Use '%' according to need: '%asset_name_contains%', '%asset_name_ends', 'asset_starts_with'.", + "help-text": "Use '%' according to need: '%asset_name_contains%', '%asset_name_ends', 'asset_starts_with%'.", "import": "Import assets", "asset-file": "Asset file", "label": "Label", @@ -2131,7 +2131,7 @@ "remove-alias": "Remove device alias", "add-alias": "Add device alias", "name-starts-with": "Device name expression", - "help-text": "Use '%' according to need: '%device_name_contains%', '%device_name_ends', 'device_starts_with'.", + "help-text": "Use '%' according to need: '%device_name_contains%', '%device_name_ends', 'device_starts_with%'.", "device-list": "Device list", "use-device-name-filter": "Use filter", "device-list-empty": "No devices selected.", @@ -3048,7 +3048,7 @@ "no-entities-text": "No entities found", "no-entity-types-matching": "No entity types matching '{{entityType}}' were found.", "name-starts-with": "Name expression", - "help-text": "Use '%' according to need: '%entity_name_contains%', '%entity_name_ends', 'entity_starts_with'.", + "help-text": "Use '%' according to need: '%entity_name_contains%', '%entity_name_ends', 'entity_starts_with%'.", "use-entity-name-filter": "Use filter", "entity-list-empty": "No entities selected.", "entity-type-list-required": "At least one entity type should be selected.", @@ -3251,7 +3251,7 @@ "remove-alias": "Remove entity view alias", "add-alias": "Add entity view alias", "name-starts-with": "Entity View name expression", - "help-text": "Use '%' according to need: '%entity-view_name_contains%', '%entity-view_name_ends', 'entity-view_starts_with'.", + "help-text": "Use '%' according to need: '%entity-view_name_contains%', '%entity-view_name_ends', 'entity-view_starts_with%'.", "entity-view-list": "Entity View list", "use-entity-view-name-filter": "Use filter", "entity-view-list-empty": "No entity views selected.",