From e2522f4fa7874665a838e74cc95a89896d86f8e9 Mon Sep 17 00:00:00 2001 From: metamben <103100869+metamben@users.noreply.github.com> Date: Tue, 19 Nov 2024 19:39:35 +0300 Subject: [PATCH] Fix model conversion (#50215) --- .../reproductions-3.cy.spec.js | 49 +++++++++++++++++++ .../metabase/query_builder/actions/models.ts | 45 +++-------------- 2 files changed, 57 insertions(+), 37 deletions(-) diff --git a/e2e/test/scenarios/question-reproductions/reproductions-3.cy.spec.js b/e2e/test/scenarios/question-reproductions/reproductions-3.cy.spec.js index 6c743f13a56..5f1c8b9b2c5 100644 --- a/e2e/test/scenarios/question-reproductions/reproductions-3.cy.spec.js +++ b/e2e/test/scenarios/question-reproductions/reproductions-3.cy.spec.js @@ -28,6 +28,7 @@ import { openNotebook, openOrdersTable, openProductsTable, + openQuestionActions, openTable, popover, queryBuilderFooter, @@ -2436,3 +2437,51 @@ describe("issue 50038", () => { }); }); }); + +describe("issue 47940", () => { + const questionDetails = { + name: "Issue 47940", + query: { + "source-table": ORDERS_ID, + limit: 5, + }, + }; + + beforeEach(() => { + restore(); + cy.signInAsAdmin(); + cy.intercept("PUT", "/api/card/*").as("updateCard"); + cy.intercept("POST", "/api/card/*/query").as("cardQuery"); + }); + + it("should be able to convert a question with date casting to a model", () => { + cy.log("create a question without any column casting"); + createQuestion(questionDetails, { visitQuestion: true }); + cy.wait("@cardQuery"); + + cy.log("add coercion"); + cy.request("PUT", `/api/field/${ORDERS.PRODUCT_ID}`, { + semantic_type: "type/Category", + coercion_strategy: "Coercion/UNIXMicroSeconds->DateTime", + }); + + cy.log("get new query results with coercion applied"); + queryBuilderHeader().findByTestId("run-button").click(); + cy.wait("@cardQuery"); + queryBuilderHeader().button("Save").click(); + modal().button("Save").click(); + cy.wait("@updateCard"); + + cy.log("turn into a model"); + openQuestionActions(); + popover().findByText("Turn into a model").click(); + cy.findByRole("dialog").findByText("Turn this into a model").click(); + cy.wait("@updateCard"); + + cy.log("verify there is a table displayed"); + cy.findByTestId("visualization-root").should( + "contain", + "December 31, 1969, 4:00 PM", + ); + }); +}); diff --git a/frontend/src/metabase/query_builder/actions/models.ts b/frontend/src/metabase/query_builder/actions/models.ts index e02e20855d3..6f1ffe2cde3 100644 --- a/frontend/src/metabase/query_builder/actions/models.ts +++ b/frontend/src/metabase/query_builder/actions/models.ts @@ -2,16 +2,13 @@ import { push } from "react-router-redux"; import { createAction } from "redux-actions"; import { t } from "ttag"; -import Questions from "metabase/entities/questions"; -import { loadMetadataForCard } from "metabase/questions/actions"; import { addUndo } from "metabase/redux/undo"; -import { getMetadata } from "metabase/selectors/metadata"; import type { Dispatch, GetState } from "metabase-types/store"; import { getQuestion } from "../selectors"; -import { API_UPDATE_QUESTION, apiUpdateQuestion, updateQuestion } from "./core"; -import { runDirtyQuestionQuery, runQuestionQuery } from "./querying"; +import { apiUpdateQuestion, updateQuestion } from "./core"; +import { runDirtyQuestionQuery } from "./querying"; import { setQueryBuilderMode } from "./ui"; export const setDatasetEditorTab = @@ -29,41 +26,16 @@ export const onCancelCreateNewModel = () => async (dispatch: Dispatch) => { export const turnQuestionIntoModel = () => async (dispatch: Dispatch, getState: GetState) => { const question = getQuestion(getState()); - if (!question) { return; } - await dispatch( - Questions.actions.update( - { - id: question.id(), - }, - question - .setType("model") - .setPinned(true) - .setDisplay("table") - .setSettings({}) - .card(), - ), - ); - - const metadata = getMetadata(getState()); - const dataset = metadata.question(question.id()); - - if (!dataset) { - return; - } - - await dispatch(loadMetadataForCard(dataset.card())); - - await dispatch({ type: API_UPDATE_QUESTION, payload: dataset.card() }); - - await dispatch( - runQuestionQuery({ - shouldUpdateUrl: true, - }), - ); + const model = question + .setType("model") + .setPinned(true) + .setDisplay("table") + .setSettings({}); + await dispatch(apiUpdateQuestion(model, { rerunQuery: true })); dispatch( addUndo({ @@ -76,7 +48,6 @@ export const turnQuestionIntoModel = export const turnModelIntoQuestion = () => async (dispatch: Dispatch, getState: GetState) => { const model = getQuestion(getState()); - if (!model) { return; } -- GitLab