From e20c00b15523a313262c0977293d57c594421dd7 Mon Sep 17 00:00:00 2001 From: Alexander Polyankin <alexander.polyankin@metabase.com> Date: Fri, 25 Oct 2024 12:10:34 -0400 Subject: [PATCH] Fix actions without parameters (#49125) * Fix actions without parameters * Update frontend/src/metabase/actions/components/ActionViz/ActionDashcardSettings.unit.spec.tsx Co-authored-by: Kamil Mielnik <kamil@kamilmielnik.com> --------- Co-authored-by: Kamil Mielnik <kamil@kamilmielnik.com> --- frontend/src/metabase-types/api/actions.ts | 2 +- .../src/metabase-types/api/mocks/actions.ts | 4 ++-- .../ActionViz/ActionDashcardSettings.tsx | 4 ++-- .../ActionDashcardSettings.unit.spec.tsx | 10 ++++++++++ .../hooks/use-action-form/use-action-form.ts | 18 ++++++++++-------- 5 files changed, 25 insertions(+), 13 deletions(-) diff --git a/frontend/src/metabase-types/api/actions.ts b/frontend/src/metabase-types/api/actions.ts index cf69fdf9465..193458b91f3 100644 --- a/frontend/src/metabase-types/api/actions.ts +++ b/frontend/src/metabase-types/api/actions.ts @@ -18,7 +18,7 @@ export interface WritebackActionBase { model_id: CardId; name: string; description: string | null; - parameters: WritebackParameter[]; + parameters?: WritebackParameter[]; visualization_settings?: ActionFormSettings; archived: boolean; creator_id: UserId; diff --git a/frontend/src/metabase-types/api/mocks/actions.ts b/frontend/src/metabase-types/api/mocks/actions.ts index daba99ef685..5b62571d294 100644 --- a/frontend/src/metabase-types/api/mocks/actions.ts +++ b/frontend/src/metabase-types/api/mocks/actions.ts @@ -41,7 +41,7 @@ export const createMockQueryAction = ({ description: null, model_id: 1, database_id: 1, - parameters: [], + parameters: undefined, creator_id: creator.id, creator, archived: false, @@ -66,7 +66,7 @@ export const createMockImplicitQueryAction = ({ description: "", model_id: 1, database_id: 1, - parameters: [], + parameters: undefined, visualization_settings: undefined, creator_id: creator.id, creator, diff --git a/frontend/src/metabase/actions/components/ActionViz/ActionDashcardSettings.tsx b/frontend/src/metabase/actions/components/ActionViz/ActionDashcardSettings.tsx index 56056b3ed9b..30c79093cd5 100644 --- a/frontend/src/metabase/actions/components/ActionViz/ActionDashcardSettings.tsx +++ b/frontend/src/metabase/actions/components/ActionViz/ActionDashcardSettings.tsx @@ -71,8 +71,8 @@ export function ActionDashcardSettings({ ); const isFormInvalid = - !!action && - action.parameters.some(actionParameter => { + action != null && + action.parameters?.some(actionParameter => { const isHidden = isParameterHidden(action, actionParameter); const isRequired = isParameterRequired(action, actionParameter); const isParameterMapped = diff --git a/frontend/src/metabase/actions/components/ActionViz/ActionDashcardSettings.unit.spec.tsx b/frontend/src/metabase/actions/components/ActionViz/ActionDashcardSettings.unit.spec.tsx index 27b4ff6e4c4..440c7e1f21f 100644 --- a/frontend/src/metabase/actions/components/ActionViz/ActionDashcardSettings.unit.spec.tsx +++ b/frontend/src/metabase/actions/components/ActionViz/ActionDashcardSettings.unit.spec.tsx @@ -456,6 +456,16 @@ describe("ActionViz > ActionDashcardSettings", () => { ).toBeInTheDocument(); }); + it("should be valid and not crash when the action does not have parameters (metabase#32665)", async () => { + const { closeSpy } = setup({ + dashcard: createMockActionDashboardCard({ + action: createMockQueryAction(), + }), + }); + await userEvent.click(screen.getByRole("button", { name: "Done" })); + expect(closeSpy).toHaveBeenCalled(); + }); + it("shows parameters for an action", async () => { setup({ dashcard: actionDashcardWithAction, diff --git a/frontend/src/metabase/actions/hooks/use-action-form/use-action-form.ts b/frontend/src/metabase/actions/hooks/use-action-form/use-action-form.ts index cef65992305..95f904d3cfc 100644 --- a/frontend/src/metabase/actions/hooks/use-action-form/use-action-form.ts +++ b/frontend/src/metabase/actions/hooks/use-action-form/use-action-form.ts @@ -6,6 +6,7 @@ import type { ActionFormInitialValues, ParametersForActionExecution, WritebackAction, + WritebackParameter, } from "metabase-types/api"; import { @@ -22,27 +23,28 @@ type Opts = { }; const INITIAL_VALUES = {}; +const DEFAULT_PARAMETERS: WritebackParameter[] = []; function useActionForm({ - action, + action: { parameters = DEFAULT_PARAMETERS, visualization_settings }, initialValues = INITIAL_VALUES, prefetchesInitialValues, }: Opts) { const fieldSettings = useMemo(() => { return getOrGenerateFieldSettings( - action.parameters, - action.visualization_settings?.fields, + parameters, + visualization_settings?.fields, ); - }, [action]); + }, [parameters, visualization_settings]); const form = useMemo( - () => getForm(action.parameters, fieldSettings), - [action.parameters, fieldSettings], + () => getForm(parameters, fieldSettings), + [parameters, fieldSettings], ); const validationSchema = useMemo( - () => getFormValidationSchema(action.parameters, fieldSettings), - [action.parameters, fieldSettings], + () => getFormValidationSchema(parameters, fieldSettings), + [parameters, fieldSettings], ); const cleanedInitialValues = useMemo(() => { -- GitLab