Skip to content

Commit

Permalink
feat(widget-builder): Add helper to convert widget to builder state
Browse files Browse the repository at this point in the history
This lets us put the widget builder state into the URL so it can be
parsed by the hook when the builder mounts.
  • Loading branch information
narsaynorath committed Nov 29, 2024
1 parent 8e45680 commit 7fba528
Show file tree
Hide file tree
Showing 5 changed files with 68 additions and 18 deletions.
8 changes: 7 additions & 1 deletion static/app/views/dashboards/dashboard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ type Props = {
isPreview?: boolean;
newWidget?: Widget;
onAddWidget?: (dataset?: DataSet) => void;
onEditWidget?: (widget: Widget) => void;
onSetNewWidget?: () => void;
paramDashboardId?: string;
paramTemplateId?: string;
Expand Down Expand Up @@ -373,7 +374,7 @@ class Dashboard extends Component<Props, State> {
};

handleEditWidget = (index: number) => () => {
const {organization, router, location, paramDashboardId} = this.props;
const {organization, router, location, paramDashboardId, onEditWidget} = this.props;
const widget = this.props.dashboard.widgets[index];

trackAnalytics('dashboards_views.widget.edit', {
Expand All @@ -385,6 +386,11 @@ class Dashboard extends Component<Props, State> {
return;
}

if (organization.features.includes('dashboards-widget-builder-redesign')) {
onEditWidget?.(widget);
return;
}

if (paramDashboardId) {
router.push(
normalizeUrl({
Expand Down
41 changes: 24 additions & 17 deletions static/app/views/dashboards/detail.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ import {MetricsCardinalityProvider} from 'sentry/utils/performance/contexts/metr
import {MetricsResultsMetaProvider} from 'sentry/utils/performance/contexts/metricsEnhancedPerformanceDataContext';
import {MEPSettingProvider} from 'sentry/utils/performance/contexts/metricsEnhancedSetting';
import {OnDemandControlProvider} from 'sentry/utils/performance/contexts/onDemandControl';
import {decodeScalar} from 'sentry/utils/queryString';
import normalizeUrl from 'sentry/utils/url/normalizeUrl';
import withApi from 'sentry/utils/withApi';
import withOrganization from 'sentry/utils/withOrganization';
Expand All @@ -57,9 +56,9 @@ import {
isWidgetUsingTransactionName,
resetPageFilters,
} from 'sentry/views/dashboards/utils';
import DevBuilder from 'sentry/views/dashboards/widgetBuilder/components/devBuilder';
import DevWidgetBuilder from 'sentry/views/dashboards/widgetBuilder/components/newWidgetBuilder';
import {DataSet} from 'sentry/views/dashboards/widgetBuilder/utils';
import {convertWidgetToBuilderStateParams} from 'sentry/views/dashboards/widgetBuilder/utils/convertWidgetToBuilderStateParams';
import WidgetLegendNameEncoderDecoder from 'sentry/views/dashboards/widgetLegendNameEncoderDecoder';
import {MetricsDataSwitcherAlert} from 'sentry/views/performance/landing/metricsDataSwitcherAlert';

Expand Down Expand Up @@ -726,6 +725,27 @@ class DashboardDetail extends Component<Props, State> {
);
};

onEditWidget = (widget: Widget) => {
const {router, organization, params, location, dashboard} = this.props;
const {dashboardId} = params;
const widgetIndex = dashboard.widgets.indexOf(widget);
this.setState({
isWidgetBuilderOpen: true,
});
const path = defined(dashboardId)
? `/organizations/${organization.slug}/dashboard/${dashboardId}/widget-builder/widget/${widgetIndex}/edit/`
: `/organizations/${organization.slug}/dashboards/new/widget-builder/widget/${widgetIndex}/edit/`;
router.push(
normalizeUrl({
pathname: path,
query: {
...location.query,
...convertWidgetToBuilderStateParams(widget),
},
})
);
};

/* Handles POST request for Edit Access Selector Changes */
onChangeEditAccess = (newDashboardPermissions: DashboardPermissions) => {
const {dashboard, api, organization} = this.props;
Expand Down Expand Up @@ -1218,6 +1238,7 @@ class DashboardDetail extends Component<Props, State> {
isPreview={this.isPreview}
widgetLegendState={this.state.widgetLegendState}
onAddWidget={this.onAddWidget}
onEditWidget={this.onEditWidget}
/>

<DevWidgetBuilder
Expand Down Expand Up @@ -1250,22 +1271,8 @@ class DashboardDetail extends Component<Props, State> {
);
}

/**
* This is a temporary component to test the new widget builder hook during development.
*/
renderDevWidgetBuilder() {
return <DevBuilder />;
}

render() {
const {organization, location} = this.props;

if (
organization.features.includes('dashboards-widget-builder-redesign') &&
decodeScalar(location.query?.devBuilder) === 'true'
) {
return this.renderDevWidgetBuilder();
}
const {organization} = this.props;

if (this.isWidgetBuilderRouter) {
return this.renderWidgetBuilder();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import Input from 'sentry/components/input';
import {space} from 'sentry/styles/space';
import {CustomMeasurementsProvider} from 'sentry/utils/customMeasurements/customMeasurementsProvider';
import {type Column, generateFieldAsString} from 'sentry/utils/discover/fields';
import {useLocalStorageState} from 'sentry/utils/useLocalStorageState';
import useOrganization from 'sentry/utils/useOrganization';
import {getDatasetConfig} from 'sentry/views/dashboards/datasetConfig/base';
import {DisplayType, WidgetType} from 'sentry/views/dashboards/types';
Expand All @@ -17,6 +18,11 @@ import useWidgetBuilderState, {

function DevBuilder() {
const {state, dispatch} = useWidgetBuilderState();
const [showDevBuilder] = useLocalStorageState('showDevBuilder', false);

if (!showDevBuilder) {
return null;
}

return (
<Body>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import SlideOverPanel from 'sentry/components/slideOverPanel';
import {IconClose} from 'sentry/icons';
import {t} from 'sentry/locale';
import {space} from 'sentry/styles/space';
import DevBuilder from 'sentry/views/dashboards/widgetBuilder/components/devBuilder';
import WidgetBuilderFilterBar from 'sentry/views/dashboards/widgetBuilder/components/filtersBar';

type WidgetBuilderSlideoutProps = {
Expand All @@ -30,6 +31,7 @@ function WidgetBuilderSlideout({isOpen, onClose}: WidgetBuilderSlideoutProps) {
</SlideoutHeaderWrapper>
<SlideoutBodyWrapper>
<WidgetBuilderFilterBar />
<DevBuilder />
</SlideoutBodyWrapper>
</SlideOverPanel>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import {DisplayType, type Widget, WidgetType} from 'sentry/views/dashboards/types';

type StringifiedWidgetBuilderState = {
dataset?: WidgetType;
description?: string;
displayType?: DisplayType;
fields?: string[];
title?: string;
yAxis?: string[];
};

/**
* Converts a widget to a set of query params that can be used to
* restore the widget builder state.
*/
export function convertWidgetToBuilderStateParams(
widget: Widget
): StringifiedWidgetBuilderState {
const yAxis = widget.queries.flatMap(q => q.aggregates);
const fields = widget.queries.flatMap(q => q.fields ?? []);
return {
title: widget.title,
description: widget.description ?? '',
dataset: widget.widgetType ?? WidgetType.ERRORS,
displayType: widget.displayType ?? DisplayType.TABLE,
fields,
yAxis,
};
}

0 comments on commit 7fba528

Please sign in to comment.