Skip to content
Snippets Groups Projects
Unverified Commit dd9ba07e authored by Kamil Mielnik's avatar Kamil Mielnik Committed by GitHub
Browse files

[MLv2] [FE] Migrate object detail (#37639)


* Migrate StructuredQuery.prototype.filter in ObjectDetailView

* [MLv2] Add `legacy-column->metadata` for converting `DatasetColumn`

The query and stage are unfortunately required to correctly handle
aggregation references.

Note that the JS version of this name is `legacy_column__GT_metadata`,
with the double underscore.

* Add TS wrapper

* Use fromLegacyColumn

* Make code more backwards-compatible

* Make code more backwards-compatible

* Remove type argument from startNewCard

* Migrate startNewcard in actions/object-detail to MLv2

* Fix filter clause

* Use numberFilterClause when dealing with numbers

* Use numberFilterClause when dealing with numbers in ObjectDetailView

* Update frontend/src/metabase/visualizations/components/ObjectDetail/ObjectDetailView.tsx

Co-authored-by: default avatarUladzimir Havenchyk <125459446+uladzimirdev@users.noreply.github.com>

* Do not pass tableId to Question.create

* Get databaseId from Question instea of raw dataset query

* Fix code order

* Allow Field to be passed to fromLegacyColumn

* Prettier

---------

Co-authored-by: default avatarBraden Shepherdson <braden@metabase.com>
Co-authored-by: default avatarAlexander Polyankin <alexander.polyankin@metabase.com>
Co-authored-by: default avatarUladzimir Havenchyk <125459446+uladzimirdev@users.noreply.github.com>
parent e5b19dd2
Branches
Tags
No related merge requests found
import * as ML from "cljs/metabase.lib.js";
import * as ML_MetadataCalculation from "cljs/metabase.lib.metadata.calculation";
import type { DatabaseId, DatasetColumn, TableId } from "metabase-types/api";
import type {
DatabaseId,
DatasetColumn,
Field,
TableId,
} from "metabase-types/api";
import type Metadata from "./metadata/Metadata";
import type {
AggregationClause,
......@@ -184,7 +189,7 @@ export function returnedColumns(
export function fromLegacyColumn(
query: Query,
stageIndex: number,
column: DatasetColumn,
columnOrField: DatasetColumn | Field,
): ColumnMetadata {
return ML.legacy_column__GT_metadata(query, stageIndex, column);
return ML.legacy_column__GT_metadata(query, stageIndex, columnOrField);
}
......@@ -14,10 +14,10 @@ export function createCard(name = null) {
}
// start a new card using the given query type and optional database and table selections
export function startNewCard(type, databaseId, tableId) {
export function startNewCard(databaseId, tableId) {
// create a brand new card to work from
const card = createCard();
card.dataset_query = Q_DEPRECATED.createQuery(type, databaseId, tableId);
card.dataset_query = Q_DEPRECATED.createQuery("query", databaseId, tableId);
return card;
}
......
import _ from "underscore";
import { startNewCard } from "metabase/lib/card";
import { createThunkAction } from "metabase/lib/redux";
import { getMetadata } from "metabase/selectors/metadata";
import { MetabaseApi } from "metabase/services";
import * as Lib from "metabase-lib";
import * as Q_DEPRECATED from "metabase-lib/queries/utils";
import { FieldDimension } from "metabase-lib/Dimension";
import Question from "metabase-lib/Question";
import {
getCard,
......@@ -56,13 +57,34 @@ export const followForeignKey = createThunkAction(
return false;
}
const newCard = startNewCard("query", card.dataset_query.database);
newCard.dataset_query.query["source-table"] = fk.origin.table.id;
newCard.dataset_query.query.filter = getFilterForFK(objectId, fk);
const metadata = getMetadata(getState());
const databaseId = new Question(card, metadata).databaseId();
const tableId = fk.origin.table.id;
const metadataProvider = Lib.metadataProvider(databaseId, metadata);
const table = Lib.tableOrCardMetadata(metadataProvider, tableId);
const query = Lib.queryFromTableOrCardMetadata(metadataProvider, table);
const stageIndex = -1;
const column = Lib.fromLegacyColumn(query, stageIndex, fk.origin);
const filterClause =
typeof objectId === "number"
? Lib.numberFilterClause({
operator: "=",
column,
values: [objectId],
})
: Lib.stringFilterClause({
operator: "=",
column,
values: [objectId],
options: {},
});
const queryWithFilter = Lib.filter(query, stageIndex, filterClause);
const question = Question.create({ databaseId, metadata }).setQuery(
queryWithFilter,
);
dispatch(resetRowZoom());
dispatch(setCardAndRun(newCard));
dispatch(setCardAndRun(question.card()));
};
},
);
......
......@@ -57,7 +57,7 @@ export const getQuestion = ({
visualization,
metadata,
}) => {
const newQuestion = startNewCard("query", dbId, tableId);
const newQuestion = startNewCard(dbId, tableId);
// consider taking a look at Ramda as a possible underscore alternative?
// http://ramdajs.com/0.21.0/index.html
......
......@@ -5,6 +5,7 @@ import _ from "underscore";
import type {
ConcreteTableId,
DatasetColumn,
DatasetData,
WritebackActionId,
} from "metabase-types/api";
......@@ -19,10 +20,10 @@ import { NotFound } from "metabase/containers/ErrorPages";
import { useDispatch } from "metabase/lib/redux";
import { runQuestionQuery } from "metabase/query_builder/actions";
import { ActionsApi, MetabaseApi } from "metabase/services";
import * as Lib from "metabase-lib";
import { isPK } from "metabase-lib/types/utils/isa";
import { isVirtualCardId } from "metabase-lib/metadata/utils/saved-questions";
import type ForeignKey from "metabase-lib/metadata/ForeignKey";
import { fieldRefForColumn } from "metabase-lib/queries/utils/dataset";
import { DeleteObjectModal } from "./DeleteObjectModal";
import { ObjectDetailBody } from "./ObjectDetailBody";
......@@ -32,7 +33,7 @@ import {
ObjectDetailContainer,
ObjectDetailWrapperDiv,
} from "./ObjectDetailView.styled";
import type { ObjectDetailProps } from "./types";
import type { ObjectDetailProps, ObjectId } from "./types";
import {
getActionItems,
getDisplayId,
......@@ -40,6 +41,34 @@ import {
getSinglePKIndex,
} from "./utils";
function filterByPk(
query: Lib.Query,
pkField: DatasetColumn,
zoomedRowID: ObjectId | undefined,
) {
if (typeof zoomedRowID === "undefined") {
return query;
}
const stageIndex = -1;
const column = Lib.fromLegacyColumn(query, stageIndex, pkField);
const filterClause =
typeof zoomedRowID === "number"
? Lib.numberFilterClause({
operator: "=",
column,
values: [zoomedRowID],
})
: Lib.stringFilterClause({
operator: "=",
column,
values: [zoomedRowID],
options: {},
});
return Lib.filter(query, stageIndex, filterClause);
}
export function ObjectDetailView({
data: passedData,
question,
......@@ -155,11 +184,12 @@ export function ObjectDetailView({
if (maybeLoading && pkIndex !== undefined) {
// if we don't have the row in the current data, try to fetch this single row
const pkField = passedData.cols[pkIndex];
const filteredQuestion = question
?.legacyQuery({ useStructuredQuery: true })
.filter(["=", fieldRefForColumn(pkField), zoomedRowID ?? null])
.question();
MetabaseApi.dataset(filteredQuestion?._card.dataset_query)
const query = question?.query();
const datasetQuery = query
? Lib.toLegacyQuery(filterByPk(query, pkField, zoomedRowID))
: undefined;
MetabaseApi.dataset(datasetQuery)
.then(result => {
if (result?.data?.rows?.length > 0) {
const newRow = result.data.rows[0];
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment