Skip to content

Commit

Permalink
feat(widget-builder): Open widget builder slideout when adding widget (
Browse files Browse the repository at this point in the history
…#81470)

Under the `dashboards-widget-builder-redesign` feature flag, when the
"Add Widget" button is clicked (either in the header bar or the edit
dashboard state) then open up the widget builder.

This is achieved by:
- Add routes specifically for the new widget builder
- These aren't permanent and mostly for dev. We need to find a way to
transition this URL to the old widget builder at some point
- Handle URL management for the redesign in the `detail.tsx` component
  - Required me to pass down `onAddWidget`
- When cancelling/closing the modal, the URL should go back to the
dashboard with the right params from the page filters.

This doesn't support Edit Widget yet.
  • Loading branch information
narsaynorath authored Nov 29, 2024
1 parent 9bd46be commit 8e45680
Show file tree
Hide file tree
Showing 4 changed files with 244 additions and 65 deletions.
33 changes: 33 additions & 0 deletions static/app/routes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1070,6 +1070,17 @@ function buildRoutes() {
)}
key="orgless-dashboards-new-route"
>
{/* New widget builder routes */}
<Route
path="widget-builder/widget/:widgetIndex/edit/"
component={make(() => import('sentry/views/dashboards/view'))}
/>
<Route
path="widget-builder/widget/new/"
component={make(() => import('sentry/views/dashboards/view'))}
/>

{/* Old widget builder routes */}
<Route
path="widget/:widgetIndex/edit/"
component={make(() => import('sentry/views/dashboards/widgetBuilder'))}
Expand All @@ -1087,6 +1098,17 @@ function buildRoutes() {
)}
key="org-dashboards-new"
>
{/* New widget builder routes */}
<Route
path="widget-builder/widget/:widgetIndex/edit/"
component={make(() => import('sentry/views/dashboards/view'))}
/>
<Route
path="widget-builder/widget/new/"
component={make(() => import('sentry/views/dashboards/view'))}
/>

{/* Old widget builder routes */}
<Route
path="widget/:widgetIndex/edit/"
component={make(() => import('sentry/views/dashboards/widgetBuilder'))}
Expand Down Expand Up @@ -1137,6 +1159,17 @@ function buildRoutes() {
component={make(() => import('sentry/views/dashboards/view'))}
withOrgPath
>
{/* New widget builder routes */}
<Route
path="widget-builder/widget/:widgetIndex/edit/"
component={make(() => import('sentry/views/dashboards/view'))}
/>
<Route
path="widget-builder/widget/new/"
component={make(() => import('sentry/views/dashboards/view'))}
/>

{/* Old widget builder routes */}
<Route
path="widget/:widgetIndex/edit/"
component={make(() => import('sentry/views/dashboards/widgetBuilder'))}
Expand Down
42 changes: 27 additions & 15 deletions static/app/views/dashboards/dashboard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ type Props = {
handleChangeSplitDataset?: (widget: Widget, index: number) => void;
isPreview?: boolean;
newWidget?: Widget;
onAddWidget?: (dataset?: DataSet) => void;
onSetNewWidget?: () => void;
paramDashboardId?: string;
paramTemplateId?: string;
Expand Down Expand Up @@ -222,39 +223,50 @@ class Dashboard extends Component<Props, State> {
}

handleStartAdd = (dataset?: DataSet) => {
const {organization, router, location, paramDashboardId, handleAddMetricWidget} =
this.props;
const {
organization,
router,
location,
paramDashboardId,
handleAddMetricWidget,
onAddWidget,
} = this.props;

if (dataset === DataSet.METRICS) {
handleAddMetricWidget?.({...this.addWidgetLayout, ...METRIC_WIDGET_MIN_SIZE});
return;
}

if (paramDashboardId) {
if (!organization.features.includes('dashboards-widget-builder-redesign')) {
if (paramDashboardId) {
router.push(
normalizeUrl({
pathname: `/organizations/${organization.slug}/dashboard/${paramDashboardId}/widget/new/`,
query: {
...location.query,
source: DashboardWidgetSource.DASHBOARDS,
dataset,
},
})
);
return;
}

router.push(
normalizeUrl({
pathname: `/organizations/${organization.slug}/dashboard/${paramDashboardId}/widget/new/`,
pathname: `/organizations/${organization.slug}/dashboards/new/widget/new/`,
query: {
...location.query,
source: DashboardWidgetSource.DASHBOARDS,
dataset,
},
})
);

return;
}

router.push(
normalizeUrl({
pathname: `/organizations/${organization.slug}/dashboards/new/widget/new/`,
query: {
...location.query,
source: DashboardWidgetSource.DASHBOARDS,
dataset,
},
})
);

onAddWidget?.();
return;
};

Expand Down
56 changes: 55 additions & 1 deletion static/app/views/dashboards/detail.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,12 @@ import ProjectsStore from 'sentry/stores/projectsStore';
import TeamStore from 'sentry/stores/teamStore';
import {browserHistory} from 'sentry/utils/browserHistory';
import CreateDashboard from 'sentry/views/dashboards/create';
import {handleUpdateDashboardSplit} from 'sentry/views/dashboards/detail';
import DashboardDetail, {
handleUpdateDashboardSplit,
} from 'sentry/views/dashboards/detail';
import EditAccessSelector from 'sentry/views/dashboards/editAccessSelector';
import * as types from 'sentry/views/dashboards/types';
import {DashboardState} from 'sentry/views/dashboards/types';
import ViewEditDashboard from 'sentry/views/dashboards/view';
import {OrganizationContext} from 'sentry/views/organizationContext';

Expand Down Expand Up @@ -2017,6 +2020,57 @@ describe('Dashboards > Detail', function () {
);
});

describe('widget builder redesign', function () {
beforeEach(function () {
initialData = initializeOrg({
organization: OrganizationFixture({
features: [
'global-views',
'dashboards-basic',
'dashboards-edit',
'discover-query',
'performance-discover-dataset-selector',
'dashboards-widget-builder-redesign',
],
}),
});
});

it('opens the widget builder slideout when clicking add widget', async function () {
render(
<DashboardDetail
{...RouteComponentPropsFixture()}
initialState={DashboardState.VIEW}
dashboard={DashboardFixture([])}
dashboards={[]}
onDashboardUpdate={jest.fn()}
newWidget={undefined}
onSetNewWidget={() => {}}
/>,
{organization: initialData.organization}
);
await userEvent.click(await screen.findByRole('button', {name: 'Add Widget'}));
expect(await screen.findByText('Create Custom Widget')).toBeInTheDocument();
});

it('opens the widget builder slideout when clicking add widget in edit mode', async function () {
render(
<DashboardDetail
{...RouteComponentPropsFixture()}
initialState={DashboardState.EDIT}
dashboard={DashboardFixture([])}
dashboards={[]}
onDashboardUpdate={jest.fn()}
newWidget={undefined}
onSetNewWidget={() => {}}
/>,
{organization: initialData.organization}
);
await userEvent.click(await screen.findByTestId('widget-add'));
expect(await screen.findByText('Create Custom Widget')).toBeInTheDocument();
});
});

describe('discover split', function () {
it('calls the dashboard callbacks with the correct widgetType for discover split', function () {
const widget = {
Expand Down
Loading

0 comments on commit 8e45680

Please sign in to comment.