Skip to content

Commit 2cd8c5f

Browse files
Migrate isNative to MLv2 (#37805)
* Migrate Question `isNative` and `isStructured` methods to MLv2 * Mark methods as deprecated * Add the guard to the `isNativeDashCard` util * Add additional guard to the `buildFieldFilterUiParameter` helper * Update all `isNative` method instances to MLv2 * Fix the negation logic 🤦 * Remove `isNative()` method altogether * Simplify the `shouldResolveFkField` check Co-authored-by: Kamil Mielnik <[email protected]> * Remove explicit Boolean conversion * Simplify conditional logic for `getTargetsForQuestion` --------- Co-authored-by: Kamil Mielnik <[email protected]>
1 parent 9723e46 commit 2cd8c5f

File tree

24 files changed

+114
-58
lines changed

24 files changed

+114
-58
lines changed

enterprise/frontend/src/metabase-enterprise/audit_app/components/QueryViewer/QueryViewer.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { useEffect, useMemo } from "react";
22
import _ from "underscore";
33

4+
import * as Lib from "metabase-lib";
45
import { useSelector, useDispatch } from "metabase/lib/redux";
56
import NativeQueryEditor from "metabase/query_builder/components/NativeQueryEditor";
67
import ReadOnlyNotebook from "metabase/query_builder/components/notebook/ReadOnlyNotebook";
@@ -28,7 +29,9 @@ export function QueryViewer({ datasetQuery }: { datasetQuery: DatasetQuery }) {
2829
}, [card, dispatch]);
2930

3031
const question = new Question(card, metadata);
31-
if (question.isNative()) {
32+
const { isNative } = Lib.queryDisplayInfo(question.query());
33+
34+
if (isNative) {
3235
return (
3336
<NativeQueryEditor
3437
question={question}

frontend/src/metabase-lib/Question.ts

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@ class Question {
184184
}
185185

186186
const isVirtualDashcard = !this._card.id;
187-
// `dataset_query` is null for questions on a dashboard the user don't have access to
187+
// The `dataset_query` is null for questions on a dashboard the user doesn't have access to
188188
!isVirtualDashcard &&
189189
console.warn("Unknown query type: " + datasetQuery?.type);
190190
});
@@ -203,16 +203,12 @@ class Question {
203203
return query;
204204
}
205205

206-
isNative(): boolean {
207-
return (
208-
this.legacyQuery({ useStructuredQuery: true }) instanceof NativeQuery
209-
);
210-
}
211-
206+
/**
207+
* @deprecated use MLv2
208+
*/
212209
isStructured(): boolean {
213-
return (
214-
this.legacyQuery({ useStructuredQuery: true }) instanceof StructuredQuery
215-
);
210+
const { isNative } = Lib.queryDisplayInfo(this.query());
211+
return !isNative;
216212
}
217213

218214
/**
@@ -1112,9 +1108,10 @@ class Question {
11121108
*/
11131109
canExploreResults() {
11141110
const canNest = Boolean(this.database()?.hasFeature("nested-queries"));
1111+
const { isNative } = Lib.queryDisplayInfo(this.query());
11151112

11161113
return (
1117-
this.isNative() &&
1114+
isNative &&
11181115
this.isSaved() &&
11191116
this.parameters().length === 0 &&
11201117
canNest &&

frontend/src/metabase-lib/metadata/utils/models.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import type {
88
StructuredDatasetQuery,
99
FieldId,
1010
} from "metabase-types/api";
11+
import * as Lib from "metabase-lib";
1112
import { getQuestionVirtualTableId } from "metabase-lib/metadata/utils/saved-questions";
1213
import type Database from "metabase-lib/metadata/Database";
1314
import type Question from "metabase-lib/Question";
@@ -101,7 +102,9 @@ export function checkCanBeModel(question: Question) {
101102
return false;
102103
}
103104

104-
if (!question.isNative()) {
105+
const { isNative } = Lib.queryDisplayInfo(question.query());
106+
107+
if (!isNative) {
105108
return true;
106109
}
107110

frontend/src/metabase-lib/parameters/utils/click-behavior.ts

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -132,15 +132,13 @@ function notRelativeDateOrRange({ type }: Parameter) {
132132
}
133133

134134
export function getTargetsForQuestion(question: Question): Target[] {
135-
if (question.isStructured()) {
136-
return getTargetsForStructuredQuestion(question);
137-
}
135+
const { isNative } = Lib.queryDisplayInfo(question.query());
138136

139-
if (question.isNative()) {
137+
if (isNative) {
140138
return getTargetsForNativeQuestion(question);
141139
}
142140

143-
return [];
141+
return getTargetsForStructuredQuestion(question);
144142
}
145143

146144
function getTargetsForStructuredQuestion(question: Question): Target[] {

frontend/src/metabase-lib/queries/drills/native-drill-fallback.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import * as Lib from "metabase-lib";
12
import type Question from "metabase-lib/Question";
23

34
interface FallbackNativeDrillProps {
@@ -6,7 +7,10 @@ interface FallbackNativeDrillProps {
67

78
export function nativeDrillFallback({ question }: FallbackNativeDrillProps) {
89
const database = question.database();
9-
if (!question.isNative() || !question.isQueryEditable() || !database) {
10+
const query = question.query();
11+
const { isNative } = Lib.queryDisplayInfo(query);
12+
13+
if (!isNative || !question.isQueryEditable() || !database) {
1014
return null;
1115
}
1216

frontend/src/metabase/dashboard/actions/navigation.js

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { createThunkAction } from "metabase/lib/redux";
22
import * as Urls from "metabase/lib/urls";
33

44
import { openUrl } from "metabase/redux/app";
5+
import * as Lib from "metabase-lib";
56
import { getParametersMappedToDashcard } from "metabase/parameters/utils/dashboards";
67
import { getMetadata } from "metabase/selectors/metadata";
78
import { getCardAfterVisualizationClick } from "metabase/visualizations/lib/utils";
@@ -14,7 +15,8 @@ export const editQuestion = createThunkAction(
1415
EDIT_QUESTION,
1516
question => (dispatch, getState) => {
1617
const dashboardId = getDashboardId(getState());
17-
const mode = question.isNative() ? "view" : "notebook";
18+
const { isNative } = Lib.queryDisplayInfo(question.query());
19+
const mode = isNative ? "view" : "notebook";
1820
const url = Urls.question(question.card(), { mode });
1921

2022
dispatch(openUrl(url));
@@ -73,8 +75,12 @@ export const navigateToNewCardFromDashboard = createThunkAction(
7375
// When building a question URL, it'll usually clean the query and
7476
// strip clauses referencing fields from tables without metadata
7577
const previousQuestion = new Question(previousCard, metadata);
78+
const { isNative: isPreviousNative } = Lib.queryDisplayInfo(
79+
previousQuestion.query(),
80+
);
81+
7682
const isDrillingFromNativeModel =
77-
previousQuestion.isDataset() && previousQuestion.isNative();
83+
previousQuestion.isDataset() && isPreviousNative;
7884

7985
const url = ML_Urls.getUrlWithParameters(
8086
question,

frontend/src/metabase/dashboard/components/ClickMappings.jsx

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { getIn, assocIn, dissocIn } from "icepick";
88
import { Icon } from "metabase/ui";
99
import Select from "metabase/core/components/Select";
1010

11+
import * as Lib from "metabase-lib";
1112
import MetabaseSettings from "metabase/lib/settings";
1213
import { isPivotGroupColumn } from "metabase/lib/data_grid";
1314
import { GTAPApi } from "metabase/services";
@@ -342,9 +343,10 @@ export function isMappableColumn(column) {
342343
export function clickTargetObjectType(object) {
343344
if (!(object instanceof Question)) {
344345
return "dashboard";
345-
} else if (object.isNative()) {
346-
return "native";
347-
} else {
348-
return "gui";
349346
}
347+
348+
const query = object.query();
349+
const { isNative } = Lib.queryDisplayInfo(query);
350+
351+
return isNative ? "native" : "gui";
350352
}

frontend/src/metabase/dashboard/utils.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ import type {
2323
DashCardDataMap,
2424
} from "metabase-types/api";
2525
import type { SelectedTabId } from "metabase-types/store";
26-
import Question from "metabase-lib/Question";
2726
import {
2827
isDateParameter,
2928
isNumberParameter,
@@ -97,7 +96,8 @@ export function isLinkDashCard(dashcard: DashboardCard) {
9796
}
9897

9998
export function isNativeDashCard(dashcard: DashboardCard) {
100-
return dashcard.card && new Question(dashcard.card).isNative();
99+
// The `dataset_query` is null for questions on a dashboard the user doesn't have access to
100+
return dashcard.card.dataset_query?.type === "native";
101101
}
102102

103103
// For a virtual (text) dashcard without any parameters, returns a boolean indicating whether we should display the

frontend/src/metabase/lib/click-behavior.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import { msgid, ngettext, t } from "ttag";
22
import { getIn } from "icepick";
33
import Questions from "metabase/entities/questions";
44
import Dashboards from "metabase/entities/dashboards";
5-
import Question from "metabase-lib/Question";
65

76
export function getClickBehaviorDescription(dashcard) {
87
const noBehaviorMessage = hasActionsMenu(dashcard)
@@ -42,7 +41,7 @@ export function getClickBehaviorDescription(dashcard) {
4241
export function hasActionsMenu(dashcard) {
4342
// This seems to work, but it isn't the right logic.
4443
// The right thing to do would be to check for any drills. However, we'd need a "clicked" object for that.
45-
return !new Question(dashcard.card).isNative();
44+
return dashcard.card.dataset_query?.type === "query";
4645
}
4746

4847
export function isTableDisplay(dashcard) {

frontend/src/metabase/metabot/selectors.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { createSelector } from "@reduxjs/toolkit";
22
import { getMetadata } from "metabase/selectors/metadata";
33
import type { State } from "metabase-types/store";
4+
import * as Lib from "metabase-lib";
45
import Question from "metabase-lib/Question";
56
import type NativeQuery from "metabase-lib/queries/NativeQuery";
67
import { DEFAULT_TABLE_SETTINGS } from "./constants";
@@ -57,7 +58,7 @@ export const getFeedbackType = (state: State) => {
5758
};
5859

5960
export const getNativeQueryText = createSelector([getQuestion], question => {
60-
return question?.isNative()
61+
return question && Lib.queryDisplayInfo(question.query()).isNative
6162
? (question.legacyQuery() as NativeQuery).queryText()
6263
: undefined;
6364
});

0 commit comments

Comments
 (0)