diff --git a/enterprise/frontend/src/embedding-sdk/lib/interactive-question/run-question-on-navigate.ts b/enterprise/frontend/src/embedding-sdk/lib/interactive-question/run-question-on-navigate.ts index 69a1b64ea3be52171b8320466d03a07951a52b84..fc4e4cd35a6f3e3657544f82ffba8ba7d99ed723 100644 --- a/enterprise/frontend/src/embedding-sdk/lib/interactive-question/run-question-on-navigate.ts +++ b/enterprise/frontend/src/embedding-sdk/lib/interactive-question/run-question-on-navigate.ts @@ -3,7 +3,7 @@ import type { NavigateToNewCardParams, SdkQuestionState, } from "embedding-sdk/types/question"; -import { loadCard } from "metabase/lib/card"; +import { loadCard } from "metabase/query_builder/actions/core/card"; import { loadMetadataForCard } from "metabase/questions/actions"; import { getMetadata } from "metabase/selectors/metadata"; import { getCardAfterVisualizationClick } from "metabase/visualizations/lib/utils"; diff --git a/frontend/src/metabase/entities/questions.js b/frontend/src/metabase/entities/questions.js index 7bb73fddaab82de7078f3ee35e4d5ca8a69d7bc5..9f8c6043b18353da216fe9f6cc12c5da3d6112c2 100644 --- a/frontend/src/metabase/entities/questions.js +++ b/frontend/src/metabase/entities/questions.js @@ -17,7 +17,7 @@ import { undo, } from "metabase/lib/entities"; import { compose, withAction, withNormalize } from "metabase/lib/redux"; -import * as Urls from "metabase/lib/urls"; +import * as Urls from "metabase/lib/urls/questions"; import { PLUGIN_MODERATION } from "metabase/plugins"; import { API_UPDATE_QUESTION, diff --git a/frontend/src/metabase/lib/card.js b/frontend/src/metabase/lib/card.js index 7dcd280498e694248266cc6f50e715fc5c17c18f..1a2deaf46eb3fdb0f4cbc19dfd52b6225a127505 100644 --- a/frontend/src/metabase/lib/card.js +++ b/frontend/src/metabase/lib/card.js @@ -1,4 +1,3 @@ -import Questions from "metabase/entities/questions"; import { b64hash_to_utf8, utf8_to_b64url } from "metabase/lib/encoding"; import { equals } from "metabase/lib/utils"; @@ -11,35 +10,6 @@ export function createCard(name = null) { }; } -// load a card either by ID or from a base64 serialization. if both are present then they are merged, which the serialized version taking precedence -// TODO: move to redux -export async function loadCard(cardId, { dispatch, getState }) { - try { - await dispatch( - Questions.actions.fetch( - { id: cardId }, - { - properties: [ - "id", - "dataset_query", - "display", - "visualization_settings", - ], // complies with Card interface - }, - ), - ); - - const question = Questions.selectors.getObject(getState(), { - entityId: cardId, - }); - - return question?.card(); - } catch (error) { - console.error("error loading card", error); - throw error; - } -} - function getCleanCard(card) { return { name: card.name, diff --git a/frontend/src/metabase/parameters/components/ParameterValuePicker/ParameterValuePicker.tsx b/frontend/src/metabase/parameters/components/ParameterValuePicker/ParameterValuePicker.tsx index 5ac1b98e94297fa83d3b7da4d1765832d858d50d..8f58f3a6a842bc784242cb5b0ffc9c793891afc7 100644 --- a/frontend/src/metabase/parameters/components/ParameterValuePicker/ParameterValuePicker.tsx +++ b/frontend/src/metabase/parameters/components/ParameterValuePicker/ParameterValuePicker.tsx @@ -4,7 +4,7 @@ import _ from "underscore"; import { useDispatch } from "metabase/lib/redux"; import { fetchParameterValues } from "metabase/parameters/actions"; -import { DefaultParameterValueWidget } from "metabase/query_builder/components/template_tags/TagEditorParamParts"; +import { DefaultParameterValueWidget } from "metabase/query_builder/components/template_tags/TagEditorParamParts/TagEditorParam.styled"; import type { UiParameter } from "metabase-lib/v1/parameters/types"; import { isDateParameter } from "metabase-lib/v1/parameters/utils/parameter-type"; import type { Parameter, TemplateTag } from "metabase-types/api"; diff --git a/frontend/src/metabase/query_builder/actions/core/card.ts b/frontend/src/metabase/query_builder/actions/core/card.ts new file mode 100644 index 0000000000000000000000000000000000000000..6f40bb53852b45f35f24423e7709a43fb65f2d55 --- /dev/null +++ b/frontend/src/metabase/query_builder/actions/core/card.ts @@ -0,0 +1,34 @@ +import Questions from "metabase/entities/questions"; +import type { CardId } from "metabase-types/api"; +import type { Dispatch, GetState } from "metabase-types/store"; + +// load a card either by ID or from a base64 serialization. if both are present then they are merged, which the serialized version taking precedence +export async function loadCard( + cardId: CardId, + { dispatch, getState }: { dispatch: Dispatch; getState: GetState }, +) { + try { + await dispatch( + Questions.actions.fetch( + { id: cardId }, + { + properties: [ + "id", + "dataset_query", + "display", + "visualization_settings", + ], // complies with Card interface + }, + ), + ); + + const question = Questions.selectors.getObject(getState(), { + entityId: cardId, + }); + + return question?.card(); + } catch (error) { + console.error("error loading card", error); + throw error; + } +} diff --git a/frontend/src/metabase/query_builder/actions/core/core.js b/frontend/src/metabase/query_builder/actions/core/core.js index 1fc2852f6c15ce05cd9e57b853db927a5767ac31..946b1b53bf3a2ae2fc63a3fe2c191c5a3f456b42 100644 --- a/frontend/src/metabase/query_builder/actions/core/core.js +++ b/frontend/src/metabase/query_builder/actions/core/core.js @@ -6,7 +6,6 @@ import Databases from "metabase/entities/databases"; import { updateModelIndexes } from "metabase/entities/model-indexes/actions"; import Questions from "metabase/entities/questions"; import Revision from "metabase/entities/revisions"; -import { loadCard } from "metabase/lib/card"; import { shouldOpenInBlankWindow } from "metabase/lib/dom"; import { createThunkAction } from "metabase/lib/redux"; import * as Urls from "metabase/lib/urls"; @@ -39,6 +38,7 @@ import { zoomInRow } from "../object-detail"; import { clearQueryResult, runQuestionQuery } from "../querying"; import { onCloseSidebars } from "../ui"; +import { loadCard } from "./card"; import { API_UPDATE_QUESTION, SOFT_RELOAD_CARD } from "./types"; import { updateQuestion } from "./updateQuestion"; diff --git a/frontend/src/metabase/query_builder/actions/core/initializeQB.ts b/frontend/src/metabase/query_builder/actions/core/initializeQB.ts index 99482b906cb4551ce8751f1568660397ed165f82..678c67df453822fbb1c4d46246114018a04b9806 100644 --- a/frontend/src/metabase/query_builder/actions/core/initializeQB.ts +++ b/frontend/src/metabase/query_builder/actions/core/initializeQB.ts @@ -4,7 +4,7 @@ import querystring from "querystring"; import { fetchAlertsForQuestion } from "metabase/alert/alert"; import Questions from "metabase/entities/questions"; import Snippets from "metabase/entities/snippets"; -import { deserializeCardFromUrl, loadCard } from "metabase/lib/card"; +import { deserializeCardFromUrl } from "metabase/lib/card"; import { isNotNull } from "metabase/lib/types"; import * as Urls from "metabase/lib/urls"; import { @@ -35,6 +35,7 @@ import { getQueryBuilderModeFromLocation } from "../../typed-utils"; import { updateUrl } from "../navigation"; import { cancelQuery, runQuestionQuery } from "../querying"; +import { loadCard } from "./card"; import { resetQB } from "./core"; import { getParameterValuesForQuestion, diff --git a/frontend/src/metabase/query_builder/actions/core/initializeQB.unit.spec.ts b/frontend/src/metabase/query_builder/actions/core/initializeQB.unit.spec.ts index 403dcae6bb91adb8a1a7039d344ab643c43a55a9..6c2798e61cef06c9ce8d384ab378d9c9c777e8db 100644 --- a/frontend/src/metabase/query_builder/actions/core/initializeQB.unit.spec.ts +++ b/frontend/src/metabase/query_builder/actions/core/initializeQB.unit.spec.ts @@ -39,6 +39,7 @@ import { createMockState } from "metabase-types/store/mocks"; import * as querying from "../querying"; +import * as cardActions from "./card"; import * as core from "./core"; import { initializeQB } from "./initializeQB"; @@ -131,7 +132,9 @@ async function setup({ fetchMock.get(`path:/api/card/${card.id}`, card); } - jest.spyOn(CardLib, "loadCard").mockReturnValue(Promise.resolve({ ...card })); + jest + .spyOn(cardActions, "loadCard") + .mockReturnValue(Promise.resolve({ ...card })); return baseSetup({ location, params, ...opts }); } @@ -440,7 +443,7 @@ describe("QB Actions > initializeQB", () => { fetchMock.get(`path:/api/card/${originalCard.id}`, originalCard); jest - .spyOn(CardLib, "loadCard") + .spyOn(cardActions, "loadCard") .mockReturnValueOnce(Promise.resolve({ ...originalCard })); return setup({ card: q, ...opts }); diff --git a/frontend/src/metabase/query_builder/components/view/ViewHeader/components/AdHocQuestionLeftSide/AdHocQuestionLeftSide.tsx b/frontend/src/metabase/query_builder/components/view/ViewHeader/components/AdHocQuestionLeftSide/AdHocQuestionLeftSide.tsx index d9ae8a950ec71cede4c0de8efa26d119c6b90d26..982c1958dc7abfa9bb6124306c8b065383f0be73 100644 --- a/frontend/src/metabase/query_builder/components/view/ViewHeader/components/AdHocQuestionLeftSide/AdHocQuestionLeftSide.tsx +++ b/frontend/src/metabase/query_builder/components/view/ViewHeader/components/AdHocQuestionLeftSide/AdHocQuestionLeftSide.tsx @@ -7,15 +7,14 @@ import { ViewHeaderLeftSubHeading, ViewHeaderMainLeftContentContainer, } from "metabase/query_builder/components/view/ViewHeader/ViewTitleHeader.styled"; -import { - QuestionDataSource, - QuestionDescription, -} from "metabase/query_builder/components/view/ViewHeader/components"; import type { QueryModalType } from "metabase/query_builder/constants"; import { MODAL_TYPES } from "metabase/query_builder/constants"; import * as Lib from "metabase-lib"; import type Question from "metabase-lib/v1/Question"; +import { QuestionDataSource } from "../QuestionDataSource"; +import { QuestionDescription } from "../QuestionDescription"; + interface AdHocQuestionLeftSideProps { question: Question; originalQuestion?: Question; diff --git a/frontend/src/metabase/query_builder/components/view/ViewHeader/components/HeaderCollectionBadge/HeaderCollectionBadge.jsx b/frontend/src/metabase/query_builder/components/view/ViewHeader/components/HeaderCollectionBadge/HeaderCollectionBadge.jsx index 4f3871b004a1fcb19bfb7591baa615e551f6ab71..e03bd1bce8968c504a74058c204920b885a1a724 100644 --- a/frontend/src/metabase/query_builder/components/view/ViewHeader/components/HeaderCollectionBadge/HeaderCollectionBadge.jsx +++ b/frontend/src/metabase/query_builder/components/view/ViewHeader/components/HeaderCollectionBadge/HeaderCollectionBadge.jsx @@ -2,7 +2,8 @@ import PropTypes from "prop-types"; import { t } from "ttag"; import * as Urls from "metabase/lib/urls"; -import { HeadBreadcrumbs } from "metabase/query_builder/components/view/ViewHeader/components"; + +import { HeadBreadcrumbs } from "../HeaderBreadcrumbs"; HeaderCollectionBadge.propTypes = { question: PropTypes.object.isRequired, diff --git a/frontend/src/metabase/query_builder/components/view/ViewHeader/components/SavedQuestionLeftSide/SavedQuestionLeftSide.tsx b/frontend/src/metabase/query_builder/components/view/ViewHeader/components/SavedQuestionLeftSide/SavedQuestionLeftSide.tsx index 549bb1ecd78d321d8312e1e24e08834395565fca..eab493ce947d142c6be7d45c20c5282b207df5f0 100644 --- a/frontend/src/metabase/query_builder/components/view/ViewHeader/components/SavedQuestionLeftSide/SavedQuestionLeftSide.tsx +++ b/frontend/src/metabase/query_builder/components/view/ViewHeader/components/SavedQuestionLeftSide/SavedQuestionLeftSide.tsx @@ -11,13 +11,12 @@ import { ViewHeaderLeftSubHeading, ViewHeaderMainLeftContentContainer, } from "metabase/query_builder/components/view/ViewHeader/ViewTitleHeader.styled"; -import { - HeadBreadcrumbs, - QuestionDataSource, -} from "metabase/query_builder/components/view/ViewHeader/components"; -import { HeaderCollectionBadge } from "metabase/query_builder/components/view/ViewHeader/components/HeaderCollectionBadge/HeaderCollectionBadge"; import type Question from "metabase-lib/v1/Question"; +import { HeadBreadcrumbs } from "../HeaderBreadcrumbs"; +import { HeaderCollectionBadge } from "../HeaderCollectionBadge"; +import { QuestionDataSource } from "../QuestionDataSource"; + interface SavedQuestionLeftSideProps { question: Question; isObjectDetail?: boolean; diff --git a/frontend/src/metabase/query_builder/components/view/ViewHeader/components/ViewTitleHeaderRightSide/ViewTitleHeaderRightSide.tsx b/frontend/src/metabase/query_builder/components/view/ViewHeader/components/ViewTitleHeaderRightSide/ViewTitleHeaderRightSide.tsx index 3a67ecfcfd253430459757de257e8758e05fbde5..8ace53965851875a2167849740401daf5bf6fcba 100644 --- a/frontend/src/metabase/query_builder/components/view/ViewHeader/components/ViewTitleHeaderRightSide/ViewTitleHeaderRightSide.tsx +++ b/frontend/src/metabase/query_builder/components/view/ViewHeader/components/ViewTitleHeaderRightSide/ViewTitleHeaderRightSide.tsx @@ -12,14 +12,6 @@ import { ViewHeaderIconButtonContainer, ViewRunButtonWithTooltip, } from "metabase/query_builder/components/view/ViewHeader/ViewTitleHeader.styled"; -import { - ExploreResultsLink, - FilterHeaderButton, - QuestionActions, - QuestionNotebookButton, - QuestionSummarizeWidget, - ToggleNativeQueryPreview, -} from "metabase/query_builder/components/view/ViewHeader/components"; import { canExploreResults } from "metabase/query_builder/components/view/ViewHeader/utils"; import type { QueryModalType } from "metabase/query_builder/constants"; import { MODAL_TYPES } from "metabase/query_builder/constants"; @@ -30,6 +22,13 @@ import type Question from "metabase-lib/v1/Question"; import type { Dataset } from "metabase-types/api"; import type { DatasetEditorTab, QueryBuilderMode } from "metabase-types/store"; +import { ExploreResultsLink } from "../ExploreResultsLink"; +import { FilterHeaderButton } from "../FilterHeaderButton"; +import { QuestionActions } from "../QuestionActions"; +import { QuestionNotebookButton } from "../QuestionNotebookButton"; +import { QuestionSummarizeWidget } from "../QuestionSummarizeWidget"; +import { ToggleNativeQueryPreview } from "../ToggleNativeQueryPreview"; + interface ViewTitleHeaderRightSideProps { question: Question; result: Dataset;