Skip to content

Commit d961709

Browse files
fix(dashboards): Widget Viewer edit button regression fix (#32182)
Edit button in the Widget Viewer stopped working since we added shareable links. This fixes by adding an onEdit handler to detail.tsx
1 parent c7209a3 commit d961709

File tree

5 files changed

+78
-4
lines changed

5 files changed

+78
-4
lines changed

static/app/components/modals/widgetViewerModal.tsx

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,17 @@ const HALF_TABLE_ITEM_LIMIT = 10;
4848
const GEO_COUNTRY_CODE = 'geo.country_code';
4949

5050
function WidgetViewerModal(props: Props) {
51-
const {organization, widget, selection, location, Footer, Body, Header, onEdit} = props;
51+
const {
52+
organization,
53+
widget,
54+
selection,
55+
location,
56+
Footer,
57+
Body,
58+
Header,
59+
closeModal,
60+
onEdit,
61+
} = props;
5262
const isTableWidget = widget.displayType === DisplayType.TABLE;
5363
const renderWidgetViewer = () => {
5464
const api = useApi();
@@ -202,9 +212,17 @@ function WidgetViewerModal(props: Props) {
202212
<Body>{renderWidgetViewer()}</Body>
203213
<StyledFooter>
204214
<ButtonBar gap={1}>
205-
<Button type="button" onClick={onEdit}>
206-
{t('Edit Widget')}
207-
</Button>
215+
{onEdit && (
216+
<Button
217+
type="button"
218+
onClick={() => {
219+
closeModal();
220+
onEdit();
221+
}}
222+
>
223+
{t('Edit Widget')}
224+
</Button>
225+
)}
208226
<Button to={path} priority="primary" type="button">
209227
{openLabel}
210228
</Button>

static/app/views/dashboardsV2/detail.tsx

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import {cloneElement, Component, isValidElement} from 'react';
22
import {browserHistory, PlainRoute, RouteComponentProps} from 'react-router';
33
import styled from '@emotion/styled';
4+
import cloneDeep from 'lodash/cloneDeep';
45
import isEqual from 'lodash/isEqual';
56
import omit from 'lodash/omit';
67

@@ -125,6 +126,19 @@ class DashboardDetail extends Component<Props, State> {
125126
query: location.query,
126127
});
127128
},
129+
onEdit: () => {
130+
openAddDashboardWidgetModal({
131+
organization,
132+
widget,
133+
onUpdateWidget: (nextWidget: Widget) => {
134+
const updateIndex = dashboard.widgets.indexOf(widget);
135+
const nextWidgetsList = cloneDeep(dashboard.widgets);
136+
nextWidgetsList[updateIndex] = nextWidget;
137+
this.handleUpdateWidgetList(nextWidgetsList);
138+
},
139+
source: DashboardWidgetSource.DASHBOARDS,
140+
});
141+
},
128142
});
129143
} else {
130144
// Replace the URL if the widget isn't found and raise an error in toast

static/app/views/dashboardsV2/widgetCard/index.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,7 @@ class WidgetCard extends React.Component<Props> {
145145
showWidgetViewerButton,
146146
router,
147147
isEditing,
148+
onEdit,
148149
} = this.props;
149150
return (
150151
<ErrorBoundary
@@ -168,6 +169,7 @@ class WidgetCard extends React.Component<Props> {
168169
openWidgetViewerModal({
169170
organization,
170171
widget,
172+
onEdit,
171173
});
172174
}
173175
}}

tests/js/spec/components/modals/widgetViewerModal.spec.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ function mountModal({initialData: {organization, routerContext}, widget}) {
3535
closeModal={() => undefined}
3636
organization={organization}
3737
widget={widget}
38+
onEdit={() => undefined}
3839
/>
3940
</div>,
4041
{

tests/js/spec/views/dashboardsV2/gridLayout/detail.spec.jsx

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import {enforceActOnUseLegacyStoreHook, mountWithTheme} from 'sentry-test/enzyme';
22
import {initializeOrg} from 'sentry-test/initializeOrg';
3+
import {mountGlobalModal} from 'sentry-test/modal';
34
import {
45
act,
56
mountWithTheme as rtlMountWithTheme,
@@ -11,6 +12,7 @@ import {
1112
import * as modals from 'sentry/actionCreators/modal';
1213
import ProjectsStore from 'sentry/stores/projectsStore';
1314
import {constructGridItemKey} from 'sentry/views/dashboardsV2/layoutUtils';
15+
import {DashboardWidgetSource} from 'sentry/views/dashboardsV2/types';
1416
import * as types from 'sentry/views/dashboardsV2/types';
1517
import ViewEditDashboard from 'sentry/views/dashboardsV2/view';
1618

@@ -654,5 +656,42 @@ describe('Dashboards > Detail', function () {
654656
})
655657
);
656658
});
659+
660+
it('opens the edit widget modal when clicking the edit button', async () => {
661+
const widget = TestStubs.Widget(
662+
[{name: '', conditions: 'event.type:error', fields: ['count()']}],
663+
{
664+
title: 'First Widget',
665+
interval: '1d',
666+
id: '1',
667+
layout: null,
668+
}
669+
);
670+
MockApiClient.addMockResponse({
671+
url: '/organizations/org-slug/dashboards/1/',
672+
body: TestStubs.Dashboard([widget], {id: '1', title: 'Custom Errors'}),
673+
});
674+
675+
rtlMountWithTheme(
676+
<ViewEditDashboard
677+
organization={initialData.organization}
678+
params={{orgId: 'org-slug', dashboardId: '1', widgetId: '1'}}
679+
router={initialData.router}
680+
location={{...initialData.router.location, pathname: '/widget/123/'}}
681+
/>,
682+
{context: initialData.routerContext}
683+
);
684+
685+
await mountGlobalModal();
686+
687+
userEvent.click(screen.getByRole('button', {name: 'Edit Widget'}));
688+
expect(openEditModal).toHaveBeenCalledWith(
689+
expect.objectContaining({
690+
widget,
691+
organization: initialData.organization,
692+
source: DashboardWidgetSource.DASHBOARDS,
693+
})
694+
);
695+
});
657696
});
658697
});

0 commit comments

Comments
 (0)