Skip to content
Snippets Groups Projects
Unverified Commit f7caac7d authored by Uladzimir Havenchyk's avatar Uladzimir Havenchyk Committed by GitHub
Browse files

Show name in save action form model picker (#30990)

parent 95dab399
No related branches found
No related tags found
No related merge requests found
import { screen, getIcon, queryIcon } from "__support__/ui"; import userEvent from "@testing-library/user-event";
import { screen, getIcon, queryIcon, within } from "__support__/ui";
import { import {
createMockActionParameter, createMockActionParameter,
createMockCard,
createMockQueryAction, createMockQueryAction,
} from "metabase-types/api/mocks"; } from "metabase-types/api/mocks";
import { setup } from "./common"; import { setup } from "./common";
describe("ActionCreator > Query Actions", () => { describe("ActionCreator > Query Actions", () => {
describe("new action", () => { describe("New Action", () => {
it("renders correctly", async () => { it("renders correctly", async () => {
await setup(); await setup();
...@@ -45,9 +47,59 @@ describe("ActionCreator > Query Actions", () => { ...@@ -45,9 +47,59 @@ describe("ActionCreator > Query Actions", () => {
screen.getByRole("button", { name: "Action settings" }), screen.getByRole("button", { name: "Action settings" }),
).toBeInTheDocument(); ).toBeInTheDocument();
}); });
describe("Save Modal", () => {
it("should show default message in model picker", async () => {
await setup({ model: null });
// put query into textbox
const view = screen.getByTestId("mock-native-query-editor");
userEvent.paste(
within(view).getByRole("textbox"),
"select * from orders where {{paramNane}}",
);
userEvent.click(screen.getByRole("button", { name: "Save" }));
// form is rendered
expect(
screen.getByPlaceholderText("My new fantastic action"),
).toBeInTheDocument();
expect(screen.getByTestId("select-button-content")).toHaveTextContent(
"Select a model",
);
});
it("should preselect model", async () => {
const MODEL_NAME = "Awesome Model";
const model = createMockCard({
dataset: true,
can_write: true,
name: MODEL_NAME,
});
await setup({ model });
// put query into textbox
const view = screen.getByTestId("mock-native-query-editor");
userEvent.paste(
within(view).getByRole("textbox"),
"select * from orders where {{paramNane}}",
);
userEvent.click(screen.getByRole("button", { name: "Save" }));
// form is rendered
expect(
screen.getByPlaceholderText("My new fantastic action"),
).toBeInTheDocument();
// model is preselected
expect(screen.getByTestId("select-button-content")).toHaveTextContent(
MODEL_NAME,
);
});
});
}); });
describe("editing action", () => { describe("Editing Action", () => {
it("renders correctly", async () => { it("renders correctly", async () => {
const action = createMockQueryAction(); const action = createMockQueryAction();
await setup({ action }); await setup({ action });
......
...@@ -12,7 +12,7 @@ import { ...@@ -12,7 +12,7 @@ import {
setupDatabasesEndpoints, setupDatabasesEndpoints,
} from "__support__/server-mocks"; } from "__support__/server-mocks";
import type { WritebackAction } from "metabase-types/api"; import type { Card, WritebackAction } from "metabase-types/api";
import { import {
createMockCard, createMockCard,
createMockDatabase, createMockDatabase,
...@@ -33,6 +33,7 @@ export type SetupOpts = { ...@@ -33,6 +33,7 @@ export type SetupOpts = {
hasActionsEnabled?: boolean; hasActionsEnabled?: boolean;
isAdmin?: boolean; isAdmin?: boolean;
isPublicSharingEnabled?: boolean; isPublicSharingEnabled?: boolean;
model?: Card | null;
}; };
export async function setup({ export async function setup({
...@@ -41,17 +42,21 @@ export async function setup({ ...@@ -41,17 +42,21 @@ export async function setup({
hasActionsEnabled = true, hasActionsEnabled = true,
isAdmin = false, isAdmin = false,
isPublicSharingEnabled = false, isPublicSharingEnabled = false,
model,
}: SetupOpts = {}) { }: SetupOpts = {}) {
const model = createMockCard({ if (model === undefined) {
dataset: true, model = createMockCard({
can_write: canWrite, dataset: true,
}); can_write: canWrite,
});
}
const database = createMockDatabase({ const database = createMockDatabase({
settings: { "database-enable-actions": hasActionsEnabled }, settings: { "database-enable-actions": hasActionsEnabled },
}); });
setupDatabasesEndpoints([database]); setupDatabasesEndpoints([database]);
setupCardsEndpoints([model]); setupCardsEndpoints(model ? [model] : []);
if (action) { if (action) {
fetchMock.get(`path:/api/action/${action.id}`, action); fetchMock.get(`path:/api/action/${action.id}`, action);
...@@ -62,7 +67,11 @@ export async function setup({ ...@@ -62,7 +67,11 @@ export async function setup({
} }
renderWithProviders( renderWithProviders(
<ActionCreator actionId={action?.id} modelId={model.id} />, <ActionCreator
actionId={action?.id}
modelId={model?.id}
databaseId={database.id}
/>,
{ {
storeInitialState: createMockState({ storeInitialState: createMockState({
currentUser: createMockUser({ currentUser: createMockUser({
......
...@@ -9,13 +9,10 @@ import { t } from "ttag"; ...@@ -9,13 +9,10 @@ import { t } from "ttag";
import { useField } from "formik"; import { useField } from "formik";
import { useUniqueId } from "metabase/hooks/use-unique-id"; import { useUniqueId } from "metabase/hooks/use-unique-id";
import FormField from "metabase/core/components/FormField"; import FormField from "metabase/core/components/FormField";
import SelectButton from "metabase/core/components/SelectButton"; import SelectButton from "metabase/core/components/SelectButton";
import TippyPopoverWithTrigger from "metabase/components/PopoverWithTrigger/TippyPopoverWithTrigger"; import TippyPopoverWithTrigger from "metabase/components/PopoverWithTrigger/TippyPopoverWithTrigger";
import { useQuestionQuery } from "metabase/common/hooks";
import Models from "metabase/entities/questions";
import type { CardId } from "metabase-types/api"; import type { CardId } from "metabase-types/api";
import { PopoverItemPicker, MIN_POPOVER_WIDTH } from "./FormModelPicker.styled"; import { PopoverItemPicker, MIN_POPOVER_WIDTH } from "./FormModelPicker.styled";
...@@ -39,6 +36,11 @@ function FormModelPicker({ ...@@ -39,6 +36,11 @@ function FormModelPicker({
const [{ value }, { error, touched }, { setValue }] = useField(name); const [{ value }, { error, touched }, { setValue }] = useField(name);
const formFieldRef = useRef<HTMLDivElement>(null); const formFieldRef = useRef<HTMLDivElement>(null);
const [width, setWidth] = useState(MIN_POPOVER_WIDTH); const [width, setWidth] = useState(MIN_POPOVER_WIDTH);
const isModelSelected = typeof value === "number";
const { data: model } = useQuestionQuery({
id: value,
enabled: isModelSelected,
});
useEffect(() => { useEffect(() => {
const { width: formFieldWidth } = const { width: formFieldWidth } =
...@@ -59,11 +61,21 @@ function FormModelPicker({ ...@@ -59,11 +61,21 @@ function FormModelPicker({
ref={formFieldRef} ref={formFieldRef}
> >
<SelectButton onClick={handleShowPopover}> <SelectButton onClick={handleShowPopover}>
{typeof value === "number" ? <Models.Name id={value} /> : placeholder} {isModelSelected ? model?.displayName() : placeholder}
</SelectButton> </SelectButton>
</FormField> </FormField>
), ),
[id, value, title, placeholder, error, touched, className, style], [
id,
title,
placeholder,
error,
touched,
className,
style,
model,
isModelSelected,
],
); );
const renderContent = useCallback( const renderContent = useCallback(
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
import React from "react"; import React from "react";
import SyncedParametersList from "metabase/parameters/components/SyncedParametersList/SyncedParametersList"; import SyncedParametersList from "metabase/parameters/components/SyncedParametersList/SyncedParametersList";
import { ACE_ELEMENT_ID } from "metabase/query_builder/components/NativeQueryEditor/constants";
const MockNativeQueryEditor = ({ query, setParameterValue, ...props }) => { const MockNativeQueryEditor = ({ query, setParameterValue, ...props }) => {
const onChange = evt => { const onChange = evt => {
...@@ -9,7 +10,7 @@ const MockNativeQueryEditor = ({ query, setParameterValue, ...props }) => { ...@@ -9,7 +10,7 @@ const MockNativeQueryEditor = ({ query, setParameterValue, ...props }) => {
}; };
return ( return (
<div data-testid="mock-native-query-editor"> <div data-testid="mock-native-query-editor" id={ACE_ELEMENT_ID}>
{query.queryText && ( {query.queryText && (
<textarea value={query.queryText()} onChange={onChange} /> <textarea value={query.queryText()} onChange={onChange} />
)} )}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment