@@ -4,8 +4,9 @@ import { useState } from 'react';
44import { useMeasure } from 'react-use';
55
66import { GrafanaTheme2 } from '@grafana/data';
7+ import { Trans } from '@grafana/i18n';
78import { SceneQueryRunner } from '@grafana/scenes';
8- import { ScrollContainer, useSplitter, useStyles2 } from '@grafana/ui';
9+ import { Box, EmptyState, ScrollContainer, useSplitter, useStyles2 } from '@grafana/ui';
910import { DEFAULT_PER_PAGE_PAGINATION } from 'app/core/constants';
1011
1112import LoadMoreHelper from '../rule-list/LoadMoreHelper';
@@ -26,6 +27,7 @@ type WorkbenchProps = {
2627 groupBy?: string[];
2728 filterBy?: Filter[];
2829 queryRunner: SceneQueryRunner;
30+ hasActiveFilters?: boolean;
2931};
3032
3133const initialSize = 1 / 3;
@@ -116,14 +118,18 @@ function renderWorkbenchRow(
116118 │ │ │ │
117119 └─────────────────────────┘ └───────────────────────────────────┘
118120 */
119- export function Workbench({ domain, data, queryRunner, groupBy }: WorkbenchProps) {
121+ export function Workbench({ domain, data, queryRunner, groupBy, hasActiveFilters = false }: WorkbenchProps) {
120122 const styles = useStyles2(getStyles);
121123
122124 const isLoading = !queryRunner.isDataReadyToDisplay();
123125 const [pageIndex, setPageIndex] = useState<number>(1);
124126
125127 // Calculate once: show folder metadata only if not grouping by grafana_folder
126128 const enableFolderMeta = !groupBy?.includes('grafana_folder');
129+
130+ // Determine UI state
131+ const showEmptyState = !isLoading && data.length === 0;
132+ const showData = !isLoading && data.length > 0;
127133 // splitter for template and payload editor
128134 const splitter = useSplitter({
129135 direction: 'row',
@@ -149,42 +155,62 @@ export function Workbench({ domain, data, queryRunner, groupBy }: WorkbenchProps
149155 <div {...splitter.primaryProps}>
150156 <div ref={leftColumnRef} className={cx(styles.flexFull, styles.minColumnWidth)} />
151157 </div>
152- <div {...splitter.splitterProps} />
158+ {!showEmptyState && <div {...splitter.splitterProps} />}
153159 <div {...splitter.secondaryProps}>
154160 <div ref={rightColumnRef} className={cx(styles.flexFull, styles.minColumnWidth)} />
155161 </div>
156162 </div>
157163 {/* content goes here */}
158164 <div data-testid="groups-container" className={cx(splitter.containerProps.className, styles.groupsContainer)}>
159- <div className={cx(styles.groupItemWrapper(leftColumnWidth), styles.summaryContainer)}>
160- <SummaryStatsReact />
161- <SummaryChartReact />
162- </div>
163- {/* Render actual data */}
164- <div className={styles.virtualizedContainer}>
165- <WorkbenchProvider
166- leftColumnWidth={leftColumnWidth}
167- rightColumnWidth={rightColumnWidth}
168- domain={domain}
169- queryRunner={queryRunner}
170- >
171- <ScrollContainer height="100%" width="100%" scrollbarWidth="none" showScrollIndicators>
172- {isLoading ? (
173- <>
174- <GenericRowSkeleton key="skeleton-1" width={leftColumnWidth} depth={0} />
175- <GenericRowSkeleton key="skeleton-2" width={leftColumnWidth} depth={0} />
176- <GenericRowSkeleton key="skeleton-3" width={leftColumnWidth} depth={0} />
177- </>
165+ {showEmptyState ? (
166+ <Box display="flex" alignItems="center" justifyContent="center" width="100%" height="100%" minHeight="400px">
167+ <EmptyState
168+ variant="not-found"
169+ message={hasActiveFilters ? 'No matching instances found' : 'No firing or pending instances'}
170+ >
171+ {hasActiveFilters ? (
172+ <Trans i18nKey="alerting.triage.no-matching-instances-with-filters">
173+ No alert instances match your current set of filters for the selected time range.
174+ </Trans>
178175 ) : (
179- dataSlice.map((row, index) => {
180- const rowKey = generateRowKey(row, index);
181- return renderWorkbenchRow(row, leftColumnWidth, domain, rowKey, enableFolderMeta);
182- })
176+ <Trans i18nKey="alerting.triage.no-firing-or-pending-instances">
177+ You have no alert instances in a firing or pending state for the selected time range.
178+ </Trans>
183179 )}
184- {hasMore && <LoadMoreHelper handleLoad={() => setPageIndex((prevIndex) => prevIndex + 1)} />}
185- </ScrollContainer>
186- </WorkbenchProvider>
187- </div>
180+ </EmptyState>
181+ </Box>
182+ ) : (
183+ <>
184+ <div className={cx(styles.groupItemWrapper(leftColumnWidth), styles.summaryContainer)}>
185+ <SummaryStatsReact />
186+ <SummaryChartReact />
187+ </div>
188+ <div className={styles.virtualizedContainer}>
189+ <WorkbenchProvider
190+ leftColumnWidth={leftColumnWidth}
191+ rightColumnWidth={rightColumnWidth}
192+ domain={domain}
193+ queryRunner={queryRunner}
194+ >
195+ <ScrollContainer height="100%" width="100%" scrollbarWidth="none" showScrollIndicators={showData}>
196+ {isLoading && (
197+ <>
198+ <GenericRowSkeleton key="skeleton-1" width={leftColumnWidth} depth={0} />
199+ <GenericRowSkeleton key="skeleton-2" width={leftColumnWidth} depth={0} />
200+ <GenericRowSkeleton key="skeleton-3" width={leftColumnWidth} depth={0} />
201+ </>
202+ )}
203+ {showData &&
204+ dataSlice.map((row, index) => {
205+ const rowKey = generateRowKey(row, index);
206+ return renderWorkbenchRow(row, leftColumnWidth, domain, rowKey, enableFolderMeta);
207+ })}
208+ {hasMore && <LoadMoreHelper handleLoad={() => setPageIndex((prevIndex) => prevIndex + 1)} />}
209+ </ScrollContainer>
210+ </WorkbenchProvider>
211+ </div>
212+ </>
213+ )}
188214 </div>
189215 </div>
190216 );
0 commit comments