Skip to content
Snippets Groups Projects
Commit 2d8b0ee2 authored by Atte Keinänen's avatar Atte Keinänen
Browse files

Show only metrics with compatible breakout table fields, use first field available

parent 224a0348
Branches
Tags
No related merge requests found
......@@ -175,7 +175,17 @@ export default class MultiQuery extends Query {
const firstQuery = this.childQueries()[0]
if (firstQuery instanceof StructuredQuery && firstQuery.breakouts().length === 1) {
return Dimension.parseMBQL(firstQuery.breakouts()[0]);
return Dimension.parseMBQL(firstQuery.breakouts()[0]).constructor;
} else {
throw new Error("Cannot infer the shared dimension from the first query of MultiQuery")
}
}
sharedDimensionBaseMBQL(): typeof Dimension {
const firstQuery = this.childQueries()[0]
if (firstQuery instanceof StructuredQuery && firstQuery.breakouts().length === 1) {
return firstQuery.breakouts()[0];
} else {
throw new Error("Cannot infer the shared dimension from the first query of MultiQuery")
}
......
......@@ -55,6 +55,7 @@ import type {
QueryMode
} from "metabase/meta/types/Visualization";
import { MetabaseApi, CardApi } from "metabase/services";
import { DatetimeFieldDimension } from "metabase-lib/lib/Dimension";
// TODO: move these
type DownloadFormat = "csv" | "json" | "xlsx";
......@@ -228,9 +229,15 @@ export default class Question {
}
}
availableSavedMetrics(): Metric[] {
@memoize availableSavedMetrics(): Metric[] {
this.assertIsMultiQuery();
return this._metadata.metricsList();
// $FlowFixMe
const multiQuery: MultiQuery = this.query();
const dimensionType = multiQuery.sharedDimensionType();
return this._metadata.metricsList().filter(
(metric) => metric.isCompatibleWithBreakoutDimension(dimensionType)
);
}
canAddMetric(): boolean {
this.assertIsMultiQuery();
......@@ -246,16 +253,37 @@ export default class Question {
return multiQuery.childQueries().length > 1;
}
addSavedMetric(metric: Metric): Question {
return this.addMetric(
({
type: "query",
database: metric.table.db.id,
query: {
source_table: metric.table.id,
aggregation: [["METRIC", metric.id]]
}
}: StructuredDatasetQueryObject)
);
this.assertIsMultiQuery();
// can't remove last metric
// $FlowFixMe
const multiQuery: MultiQuery = this.query();
// NOTE: Would be nice to have a proper API in metabase-lib for deriving a new breakout
// based on an existing breakout / datetime dimension
if (multiQuery.sharedDimensionType() === DatetimeFieldDimension) {
const breakout = [
"datetime-field",
metric.table.dateFields()[0].dimension().mbql(),
"as",
// use the same granularity as in other queries
multiQuery.sharedDimensionBaseMBQL()[3]
]
return this.addMetric(
({
type: "query",
database: metric.table.db.id,
query: {
source_table: metric.table.id,
aggregation: [["METRIC", metric.id]],
breakout
}
}: StructuredDatasetQueryObject)
);
} else {
throw new Error("Can't currently add a metric a question with a non-datetime breakout")
}
}
addMetric(datasetQuery: StructuredDatasetQueryObject): Question {
this.assertIsMultiQuery();
......
......@@ -4,6 +4,7 @@ import Base from "./Base";
import Question from "../Question";
import Database from "./Database";
import Table from "./Table";
import Dimension, { DatetimeFieldDimension } from "metabase-lib/lib/Dimension";
/**
* Wrapper class for a metric. Belongs to a {@link Database} and possibly a {@link Table}
......@@ -15,6 +16,23 @@ export default class Metric extends Base {
database: Database;
table: Table;
isCompatibleWithBreakoutDimension(dimensionType: typeof Dimension): boolean {
if (dimensionType === DatetimeFieldDimension) {
return this.table.dateFields().length > 0;
} else {
console.log('didnt match the selector :(', dimensionType);
return false;
}
}
breakoutDimensionOptions(dimensionType: typeof Dimension): Dimension[] {
if (dimensionType === DatetimeFieldDimension) {
return this.table.dateFields().map((field) => field.dimension());
} else {
return [];
}
}
newQuestion(): Question {
// $FlowFixMe
return new Question();
......
......@@ -35,6 +35,10 @@ export default class Table extends Base {
return this.fields.map(field => field.dimension());
}
dateFields(): Field[] {
return this.fields.filter(field => field.isDate());
}
aggregations() {
return this.aggregation_options || [];
}
......
......@@ -243,6 +243,7 @@ export const updateDateTimeFilter = (card, column, start, end) => {
start = moment(start);
end = moment(end);
if (column.unit) {
// start with the existing breakout unit
let unit = column.unit;
......
......@@ -120,6 +120,7 @@ export default class SavedMetricSelector extends Component {
});
};
// TODO Atte Keinänen 6/8/17: Consider moving the filtering logic to Redux selectors
filteredMetrics = () => {
const { searchValue, initialMetrics, currentQuestion } = this.state;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment