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 {
createMockActionParameter,
createMockCard,
createMockQueryAction,
} from "metabase-types/api/mocks";
import { setup } from "./common";
describe("ActionCreator > Query Actions", () => {
describe("new action", () => {
describe("New Action", () => {
it("renders correctly", async () => {
await setup();
......@@ -45,9 +47,59 @@ describe("ActionCreator > Query Actions", () => {
screen.getByRole("button", { name: "Action settings" }),
).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 () => {
const action = createMockQueryAction();
await setup({ action });
......
......@@ -12,7 +12,7 @@ import {
setupDatabasesEndpoints,
} from "__support__/server-mocks";
import type { WritebackAction } from "metabase-types/api";
import type { Card, WritebackAction } from "metabase-types/api";
import {
createMockCard,
createMockDatabase,
......@@ -33,6 +33,7 @@ export type SetupOpts = {
hasActionsEnabled?: boolean;
isAdmin?: boolean;
isPublicSharingEnabled?: boolean;
model?: Card | null;
};
export async function setup({
......@@ -41,17 +42,21 @@ export async function setup({
hasActionsEnabled = true,
isAdmin = false,
isPublicSharingEnabled = false,
model,
}: SetupOpts = {}) {
const model = createMockCard({
dataset: true,
can_write: canWrite,
});
if (model === undefined) {
model = createMockCard({
dataset: true,
can_write: canWrite,
});
}
const database = createMockDatabase({
settings: { "database-enable-actions": hasActionsEnabled },
});
setupDatabasesEndpoints([database]);
setupCardsEndpoints([model]);
setupCardsEndpoints(model ? [model] : []);
if (action) {
fetchMock.get(`path:/api/action/${action.id}`, action);
......@@ -62,7 +67,11 @@ export async function setup({
}
renderWithProviders(
<ActionCreator actionId={action?.id} modelId={model.id} />,
<ActionCreator
actionId={action?.id}
modelId={model?.id}
databaseId={database.id}
/>,
{
storeInitialState: createMockState({
currentUser: createMockUser({
......
......@@ -9,13 +9,10 @@ import { t } from "ttag";
import { useField } from "formik";
import { useUniqueId } from "metabase/hooks/use-unique-id";
import FormField from "metabase/core/components/FormField";
import SelectButton from "metabase/core/components/SelectButton";
import TippyPopoverWithTrigger from "metabase/components/PopoverWithTrigger/TippyPopoverWithTrigger";
import Models from "metabase/entities/questions";
import { useQuestionQuery } from "metabase/common/hooks";
import type { CardId } from "metabase-types/api";
import { PopoverItemPicker, MIN_POPOVER_WIDTH } from "./FormModelPicker.styled";
......@@ -39,6 +36,11 @@ function FormModelPicker({
const [{ value }, { error, touched }, { setValue }] = useField(name);
const formFieldRef = useRef<HTMLDivElement>(null);
const [width, setWidth] = useState(MIN_POPOVER_WIDTH);
const isModelSelected = typeof value === "number";
const { data: model } = useQuestionQuery({
id: value,
enabled: isModelSelected,
});
useEffect(() => {
const { width: formFieldWidth } =
......@@ -59,11 +61,21 @@ function FormModelPicker({
ref={formFieldRef}
>
<SelectButton onClick={handleShowPopover}>
{typeof value === "number" ? <Models.Name id={value} /> : placeholder}
{isModelSelected ? model?.displayName() : placeholder}
</SelectButton>
</FormField>
),
[id, value, title, placeholder, error, touched, className, style],
[
id,
title,
placeholder,
error,
touched,
className,
style,
model,
isModelSelected,
],
);
const renderContent = useCallback(
......
......@@ -2,6 +2,7 @@
import React from "react";
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 onChange = evt => {
......@@ -9,7 +10,7 @@ const MockNativeQueryEditor = ({ query, setParameterValue, ...props }) => {
};
return (
<div data-testid="mock-native-query-editor">
<div data-testid="mock-native-query-editor" id={ACE_ELEMENT_ID}>
{query.queryText && (
<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