Skip to content

Commit fcebddd

Browse files
gggritsoclaude
andauthored
fix(dashboards): Respect current time series interval in Widget Viewer (#109766)
Pass the dashboard's user-selected interval to the Widget Viewer Modal so that opening a widget in full screen preserves the chosen interval instead of reverting to the default. This is especially important when we remove our custom data cache. If the interval changes, TanStack will issue another network request to fetch the data! The interval selection feature lets users pick a chart interval (e.g. 1m, 15m) for all time series widgets on a dashboard. This value was already threaded through the main dashboard widget rendering path, but the Widget Viewer Modal never received it. When a widget was opened in full screen, its chart would re-fetch data without the interval override, causing a jarring change in granularity. Three changes: - Add `widgetInterval` to `WidgetViewerModalOptions` and pass it to the chart container and all table query components inside the modal - Add `widgetInterval` to `WidgetCardChartContainer` props so it can forward the value to `WidgetCardDataLoader` - Pass `this.props.widgetInterval` when opening the modal in `DashboardDetail.checkIfShouldMountWidgetViewerModal` Refs DAIN-1257 Co-authored-by: Claude <noreply@anthropic.com>
1 parent 5b9a5d2 commit fcebddd

File tree

3 files changed

+10
-0
lines changed

3 files changed

+10
-0
lines changed

static/app/components/modals/widgetViewerModal.tsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,7 @@ export interface WidgetViewerModalOptions {
136136
seriesResultsType?: Record<string, AggregationOutputType>;
137137
tableData?: TableDataWithTitle[];
138138
totalIssuesCount?: string;
139+
widgetInterval?: string;
139140
}
140141

141142
interface Props extends ModalRenderProps, WidgetViewerModalOptions {
@@ -210,6 +211,7 @@ function WidgetViewerModal(props: Props) {
210211
dashboardCreator,
211212
confidence,
212213
sampleCount,
214+
widgetInterval,
213215
} = props;
214216
const theme = useTheme();
215217
const location = useLocation();
@@ -560,6 +562,7 @@ function WidgetViewerModal(props: Props) {
560562
}
561563
cursor={cursor}
562564
dashboardFilters={dashboardFilters}
565+
widgetInterval={widgetInterval}
563566
>
564567
{renderIssuesTable}
565568
</IssueWidgetQueries>
@@ -583,6 +586,7 @@ function WidgetViewerModal(props: Props) {
583586
}
584587
cursor={cursor}
585588
dashboardFilters={dashboardFilters}
589+
widgetInterval={widgetInterval}
586590
>
587591
{renderTable}
588592
</ReleaseWidgetQueries>
@@ -607,6 +611,7 @@ function WidgetViewerModal(props: Props) {
607611
}
608612
cursor={cursor}
609613
dashboardFilters={dashboardFilters}
614+
widgetInterval={widgetInterval}
610615
>
611616
{({tableResults, loading, pageLinks}) => {
612617
return renderTable({tableResults, loading, pageLinks});
@@ -676,6 +681,7 @@ function WidgetViewerModal(props: Props) {
676681
noPadding
677682
widgetLegendState={widgetLegendState}
678683
showConfidenceWarning={widget.widgetType === WidgetType.SPANS}
684+
widgetInterval={widgetInterval}
679685
/>
680686
)}
681687
</Container>

static/app/views/dashboards/detail.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -308,6 +308,7 @@ class DashboardDetail extends Component<Props, State> {
308308
dashboardFilters: getDashboardFiltersFromURL(location) ?? dashboard.filters,
309309
dashboardPermissions: dashboard.permissions,
310310
dashboardCreator: dashboard.createdBy,
311+
widgetInterval: this.props.widgetInterval,
311312
onClose: () => {
312313
// Filter out Widget Viewer Modal query params when exiting the Modal
313314
const query = omit(location.query, Object.values(WidgetViewerQueryField));

static/app/views/dashboards/widgetCard/widgetCardChartContainer.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ type Props = {
5757
showConfidenceWarning?: boolean;
5858
showLoadingText?: boolean;
5959
tableItemLimit?: number;
60+
widgetInterval?: string;
6061
windowWidth?: number;
6162
};
6263

@@ -85,6 +86,7 @@ export function WidgetCardChartContainer({
8586
onWidgetTableSort,
8687
onWidgetTableResizeColumn,
8788
disableTableActions,
89+
widgetInterval,
8890
}: Props) {
8991
const keepLegendState: EChartLegendSelectChangeHandler = ({selected}) => {
9092
widgetLegendState.setWidgetSelectionState(selected, widget);
@@ -118,6 +120,7 @@ export function WidgetCardChartContainer({
118120
onWidgetSplitDecision={onWidgetSplitDecision}
119121
onDataFetchStart={onDataFetchStart}
120122
tableItemLimit={tableItemLimit}
123+
widgetInterval={widgetInterval}
121124
>
122125
{({
123126
tableResults,

0 commit comments

Comments
 (0)