Skip to content

Commit 082441f

Browse files
authored
feat(widget-builder): Add error field in WidgetBuilderState (#82887)
Add an error field to the widget builder state. It is just a regular state, not a queryParamState so it is not stored in the URL. This will be used to keep track of the errors we get on validation so we can highlight the correct fields to prompt users to change the input. This PR is the baseline to set up that functionality. Contributes to #81729
1 parent 3b9baab commit 082441f

File tree

8 files changed

+26
-12
lines changed

8 files changed

+26
-12
lines changed

static/app/views/dashboards/widgetBuilder/components/nameAndDescFields.spec.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ describe('WidgetBuilder', () => {
3333

3434
render(
3535
<WidgetBuilderProvider>
36-
<WidgetBuilderNameAndDescription />
36+
<WidgetBuilderNameAndDescription error={{}} />
3737
</WidgetBuilderProvider>,
3838
{
3939
router,

static/app/views/dashboards/widgetBuilder/components/nameAndDescFields.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,11 @@ import {SectionHeader} from 'sentry/views/dashboards/widgetBuilder/components/co
1010
import {useWidgetBuilderContext} from 'sentry/views/dashboards/widgetBuilder/contexts/widgetBuilderContext';
1111
import {BuilderStateAction} from 'sentry/views/dashboards/widgetBuilder/hooks/useWidgetBuilderState';
1212

13-
function WidgetBuilderNameAndDescription() {
13+
interface WidgetBuilderNameAndDescriptionProps {
14+
error: Record<string, any>;
15+
}
16+
17+
function WidgetBuilderNameAndDescription({}: WidgetBuilderNameAndDescriptionProps) {
1418
const {state, dispatch} = useWidgetBuilderContext();
1519
const [isDescSelected, setIsDescSelected] = useState(state.description ? true : false);
1620

static/app/views/dashboards/widgetBuilder/components/queryFilterBuilder.spec.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ describe('QueryFilterBuilder', () => {
3333
it('renders a dataset-specific query filter bar', async () => {
3434
render(
3535
<WidgetBuilderProvider>
36-
<WidgetBuilderQueryFilterBuilder onQueryConditionChange={() => {}} />
36+
<WidgetBuilderQueryFilterBuilder onQueryConditionChange={() => {}} error={{}} />
3737
</WidgetBuilderProvider>,
3838
{
3939
organization,
@@ -54,7 +54,7 @@ describe('QueryFilterBuilder', () => {
5454

5555
render(
5656
<WidgetBuilderProvider>
57-
<WidgetBuilderQueryFilterBuilder onQueryConditionChange={() => {}} />
57+
<WidgetBuilderQueryFilterBuilder onQueryConditionChange={() => {}} error={{}} />
5858
</WidgetBuilderProvider>,
5959
{
6060
organization,
@@ -77,7 +77,7 @@ describe('QueryFilterBuilder', () => {
7777
it('renders a legend alias input for charts', async () => {
7878
render(
7979
<WidgetBuilderProvider>
80-
<WidgetBuilderQueryFilterBuilder onQueryConditionChange={() => {}} />
80+
<WidgetBuilderQueryFilterBuilder onQueryConditionChange={() => {}} error={{}} />
8181
</WidgetBuilderProvider>,
8282
{
8383
organization,

static/app/views/dashboards/widgetBuilder/components/queryFilterBuilder.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import {getDiscoverDatasetFromWidgetType} from 'sentry/views/dashboards/widgetBu
2222
import {convertBuilderStateToWidget} from 'sentry/views/dashboards/widgetBuilder/utils/convertBuilderStateToWidget';
2323

2424
interface WidgetBuilderQueryFilterBuilderProps {
25+
error: Record<string, any>;
2526
onQueryConditionChange: (valid: boolean) => void;
2627
}
2728

static/app/views/dashboards/widgetBuilder/components/saveButton.tsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,10 @@ import {convertBuilderStateToWidget} from 'sentry/views/dashboards/widgetBuilder
1414
interface SaveButtonProps {
1515
isEditing: boolean;
1616
onSave: ({index, widget}: {index: number; widget: Widget}) => void;
17+
setError: (error: Record<string, any>) => void;
1718
}
1819

19-
function SaveButton({isEditing, onSave}: SaveButtonProps) {
20+
function SaveButton({isEditing, onSave, setError}: SaveButtonProps) {
2021
const {state} = useWidgetBuilderContext();
2122
const {widgetIndex} = useParams();
2223
const api = useApi();
@@ -28,9 +29,11 @@ function SaveButton({isEditing, onSave}: SaveButtonProps) {
2829
await validateWidget(api, organization.slug, widget);
2930
onSave({index: Number(widgetIndex), widget});
3031
} catch (error) {
32+
const errorDetails = error.responseJSON || error;
33+
setError(errorDetails);
3134
addErrorMessage(t('Unable to save widget'));
3235
}
33-
}, [api, onSave, organization.slug, state, widgetIndex]);
36+
}, [api, onSave, organization.slug, state, widgetIndex, setError]);
3437

3538
return (
3639
<Button priority="primary" onClick={handleSave}>

static/app/views/dashboards/widgetBuilder/components/typeSelector.spec.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ describe('TypeSelector', () => {
2727

2828
render(
2929
<WidgetBuilderProvider>
30-
<TypeSelector />
30+
<TypeSelector error={{}} />
3131
</WidgetBuilderProvider>,
3232
{
3333
router,

static/app/views/dashboards/widgetBuilder/components/typeSelector.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,11 @@ const displayTypes = {
2828
[DisplayType.BIG_NUMBER]: t('Big Number'),
2929
};
3030

31-
function WidgetBuilderTypeSelector() {
31+
interface WidgetBuilderTypeSelectorProps {
32+
error: Record<string, any>;
33+
}
34+
35+
function WidgetBuilderTypeSelector({}: WidgetBuilderTypeSelectorProps) {
3236
const {state, dispatch} = useWidgetBuilderContext();
3337
const config = getDatasetConfig(state.dataset);
3438

static/app/views/dashboards/widgetBuilder/components/widgetBuilderSlideout.tsx

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ function WidgetBuilderSlideout({
5656
const organization = useOrganization();
5757
const {state} = useWidgetBuilderContext();
5858
const [initialState] = useState(state);
59+
const [error, setError] = useState<Record<string, any>>({});
5960
const {widgetIndex} = useParams();
6061
const theme = useTheme();
6162

@@ -128,7 +129,7 @@ function WidgetBuilderSlideout({
128129
</Section>
129130
)}
130131
<Section>
131-
<WidgetBuilderTypeSelector />
132+
<WidgetBuilderTypeSelector error={error} />
132133
</Section>
133134
<div ref={previewRef}>
134135
{isSmallScreen && (
@@ -147,6 +148,7 @@ function WidgetBuilderSlideout({
147148
<Section>
148149
<WidgetBuilderQueryFilterBuilder
149150
onQueryConditionChange={onQueryConditionChange}
151+
error={error}
150152
/>
151153
</Section>
152154
{isChartWidget && (
@@ -160,9 +162,9 @@ function WidgetBuilderSlideout({
160162
</Section>
161163
)}
162164
<Section>
163-
<WidgetBuilderNameAndDescription />
165+
<WidgetBuilderNameAndDescription error={error} />
164166
</Section>
165-
<SaveButton isEditing={isEditing} onSave={onSave} />
167+
<SaveButton isEditing={isEditing} onSave={onSave} setError={setError} />
166168
</SlideoutBodyWrapper>
167169
</SlideOverPanel>
168170
);

0 commit comments

Comments
 (0)