diff --git a/frontend/src/metabase-lib/lib/queries/utils/segments.js b/frontend/src/metabase-lib/lib/queries/utils/segments.js new file mode 100644 index 0000000000000000000000000000000000000000..6b176b5346f5bdf9b5dfd6b480ed4bb19fd65b9e --- /dev/null +++ b/frontend/src/metabase-lib/lib/queries/utils/segments.js @@ -0,0 +1,24 @@ +import Question from "metabase-lib/lib/Question"; + +export function getSegmentOrMetricQuestion(query, table, metadata) { + return table + ? metadata.table(table.id).query(query).question() + : Question.create({ metadata }); +} + +export function getDefaultSegmentOrMetricQuestion(table, metadata) { + const question = metadata.table(table.id).question(); + + if (table.entity_type === "entity/GoogleAnalyticsTable") { + const dateField = table.fields.find(f => f.name === "ga:date"); + if (dateField) { + return question + .filter(["time-interval", ["field", dateField.id, null], -365, "day"]) + .aggregate(["metric", "ga:users"]); + } + } else { + return question.aggregate(["count"]); + } + + return null; +} diff --git a/frontend/src/metabase/admin/datamodel/components/PartialQueryBuilder.jsx b/frontend/src/metabase/admin/datamodel/components/PartialQueryBuilder.jsx index 943b6f3b012b4b62e0215c1d4d86e108cdc10f69..96d6aa1126b5422a021e1b40e282a83d51f679af 100644 --- a/frontend/src/metabase/admin/datamodel/components/PartialQueryBuilder.jsx +++ b/frontend/src/metabase/admin/datamodel/components/PartialQueryBuilder.jsx @@ -10,8 +10,11 @@ import { getMetadata } from "metabase/selectors/metadata"; import Tables from "metabase/entities/tables"; import GuiQueryEditor from "metabase/query_builder/components/GuiQueryEditor"; import * as Urls from "metabase/lib/urls"; -import Question from "metabase-lib/lib/Question"; import Query from "metabase-lib/lib/queries/Query"; +import { + getSegmentOrMetricQuestion, + getDefaultSegmentOrMetricQuestion, +} from "metabase-lib/lib/queries/utils/segments"; import withTableMetadataLoaded from "../hoc/withTableMetadataLoaded"; @@ -45,33 +48,21 @@ class PartialQueryBuilder extends Component { maybeSetDefaultQuery() { const { metadata, table, value } = this.props; - if (value != null && !_.isEqual(Object.keys(value), ["source-table"])) { - // only set the query if it doesn't already have an aggregation or filter - return; - } + // we need metadata and a table to generate a default query if (!metadata || !table) { - // we need metadata and a table to generate a default question return; } - const { id: tableId, db_id: databaseId } = table; - const query = Question.create({ databaseId, tableId, metadata }).query(); - // const table = query.table(); - let queryWithFilters; - if (table.entity_type === "entity/GoogleAnalyticsTable") { - const dateField = table.fields.find(f => f.name === "ga:date"); - if (dateField) { - queryWithFilters = query - .filter(["time-interval", ["field", dateField.id, null], -365, "day"]) - .aggregate(["metric", "ga:users"]); - } - } else { - queryWithFilters = query.aggregate(["count"]); + // only set the query if it doesn't already have an aggregation or filter + const question = getSegmentOrMetricQuestion(value, table, metadata); + if (!question.query().isRaw()) { + return; } - if (queryWithFilters) { - this.setDatasetQuery(queryWithFilters.datasetQuery()); + const defaultQuestion = getDefaultSegmentOrMetricQuestion(table, metadata); + if (defaultQuestion) { + this.setDatasetQuery(defaultQuestion.datasetQuery()); } } @@ -87,26 +78,9 @@ class PartialQueryBuilder extends Component { render() { const { features, value, metadata, table, previewSummary } = this.props; - const datasetQuery = table - ? { - type: "query", - database: table.db_id, - query: value, - } - : { - type: "query", - query: {}, - }; - - const query = new Question( - { dataset_query: datasetQuery }, - metadata, - ).query(); - - const previewCard = { - dataset_query: datasetQuery, - }; - const previewUrl = Urls.serializedQuestion(previewCard); + const question = getSegmentOrMetricQuestion(value, table, metadata); + const query = question.query(); + const previewUrl = Urls.serializedQuestion(question.card()); return ( <div className="py1">