diff --git a/packages/pluggableWidgets/gallery-web/CHANGELOG.md b/packages/pluggableWidgets/gallery-web/CHANGELOG.md index 7b53818115..39a2fed332 100644 --- a/packages/pluggableWidgets/gallery-web/CHANGELOG.md +++ b/packages/pluggableWidgets/gallery-web/CHANGELOG.md @@ -6,6 +6,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), ## [Unreleased] +### Added + +- We added a refresh intervel property, to allow defining an interval (in seconds) for refreshing the content in Gallery + ## [3.7.0] - 2025-11-11 ### Added diff --git a/packages/pluggableWidgets/gallery-web/src/Gallery.xml b/packages/pluggableWidgets/gallery-web/src/Gallery.xml index 1c9a0b931e..ffe357ae00 100644 --- a/packages/pluggableWidgets/gallery-web/src/Gallery.xml +++ b/packages/pluggableWidgets/gallery-web/src/Gallery.xml @@ -16,6 +16,10 @@ Data source + + Refresh time (in seconds) + + Selection diff --git a/packages/pluggableWidgets/gallery-web/src/controllers/DerivedLoaderController.ts b/packages/pluggableWidgets/gallery-web/src/controllers/DerivedLoaderController.ts index c4ff2931d0..0585e621db 100644 --- a/packages/pluggableWidgets/gallery-web/src/controllers/DerivedLoaderController.ts +++ b/packages/pluggableWidgets/gallery-web/src/controllers/DerivedLoaderController.ts @@ -4,20 +4,39 @@ import { computed, makeObservable } from "mobx"; export class DerivedLoaderController { constructor( private datasourceService: DatasourceService, - private refreshIndicator: boolean + private refreshIndicator: boolean, + private showSilentRefresh: boolean ) { makeObservable(this, { - isRefreshing: computed, - showRefreshIndicator: computed + isFirstLoad: computed, + isFetchingNextBatch: computed, + isRefreshing: computed }); } + get isFirstLoad(): boolean { + return this.datasourceService.isFirstLoad; + } + + get isFetchingNextBatch(): boolean { + return this.datasourceService.isFetchingNextBatch; + } + get isRefreshing(): boolean { const { isSilentRefresh, isRefreshing } = this.datasourceService; + + if (this.showSilentRefresh) { + return isSilentRefresh || isRefreshing; + } + return !isSilentRefresh && isRefreshing; } get showRefreshIndicator(): boolean { - return this.refreshIndicator && this.isRefreshing; + if (!this.refreshIndicator) { + return false; + } + + return this.isRefreshing; } } diff --git a/packages/pluggableWidgets/gallery-web/src/stores/GalleryStore.ts b/packages/pluggableWidgets/gallery-web/src/stores/GalleryStore.ts index c92645b252..68d5d9cd9e 100644 --- a/packages/pluggableWidgets/gallery-web/src/stores/GalleryStore.ts +++ b/packages/pluggableWidgets/gallery-web/src/stores/GalleryStore.ts @@ -36,6 +36,7 @@ interface StaticProps { storeFilters: boolean; storeSort: boolean; refreshIndicator: boolean; + refreshInterval: number; } export type GalleryPropsGate = DerivedPropsGate; @@ -63,7 +64,7 @@ export class GalleryStore extends SetupHost { this.name = spec.name; - this._query = new DatasourceService(this, spec.gate, 0 * 1000); + this._query = new DatasourceService(this, spec.gate, spec.refreshInterval * 1000); this.paging = new PaginationController({ query: this._query, @@ -95,7 +96,7 @@ export class GalleryStore extends SetupHost { host: this._sortHost }; - this.loaderCtrl = new DerivedLoaderController(this._query, spec.refreshIndicator); + this.loaderCtrl = new DerivedLoaderController(this._query, spec.refreshIndicator, spec.refreshInterval > 1); const useStorage = spec.storeFilters || spec.storeSort; if (useStorage) { diff --git a/packages/pluggableWidgets/gallery-web/src/utils/test-utils.tsx b/packages/pluggableWidgets/gallery-web/src/utils/test-utils.tsx index 4fc8a0b41b..0d5ac84aa3 100644 --- a/packages/pluggableWidgets/gallery-web/src/utils/test-utils.tsx +++ b/packages/pluggableWidgets/gallery-web/src/utils/test-utils.tsx @@ -58,7 +58,8 @@ export function createMockGalleryContext(): GalleryRootScope { storeSort: false, refreshIndicator: false, keepSelection: false, - selectionCountPosition: "bottom" + selectionCountPosition: "bottom", + refreshInterval: 0 }; // Create a proper gate provider and gate @@ -76,7 +77,8 @@ export function createMockGalleryContext(): GalleryRootScope { stateStorageType: "localStorage", storeFilters: false, storeSort: false, - refreshIndicator: false + refreshIndicator: false, + refreshInterval: 0 }); const mockSelectHelper = new SelectActionHandler("None", undefined); diff --git a/packages/pluggableWidgets/gallery-web/typings/GalleryProps.d.ts b/packages/pluggableWidgets/gallery-web/typings/GalleryProps.d.ts index b0cfa98317..8f5b2b1f24 100644 --- a/packages/pluggableWidgets/gallery-web/typings/GalleryProps.d.ts +++ b/packages/pluggableWidgets/gallery-web/typings/GalleryProps.d.ts @@ -29,6 +29,7 @@ export interface GalleryContainerProps { tabIndex?: number; filtersPlaceholder?: ReactNode; datasource: ListValue; + refreshInterval: number; itemSelection?: SelectionSingleValue | SelectionMultiValue; itemSelectionMode: ItemSelectionModeEnum; keepSelection: boolean; @@ -76,6 +77,7 @@ export interface GalleryPreviewProps { translate: (text: string) => string; filtersPlaceholder: { widgetCount: number; renderer: ComponentType<{ children: ReactNode; caption?: string }> }; datasource: {} | { caption: string } | { type: string } | null; + refreshInterval: number | null; itemSelection: "None" | "Single" | "Multi"; itemSelectionMode: ItemSelectionModeEnum; keepSelection: boolean;