Skip to content
Snippets Groups Projects
Unverified Commit d5c8e999 authored by Ariya Hidayat's avatar Ariya Hidayat Committed by GitHub
Browse files

Complete the support for "All Time" in the time-series filter (#22308)

Its corresponding date picker needs to understand the idea that
a null filter is really "All Time" (i.e. apply not filter).
Because the need to convert from null filter and that null filter
does not carry any dimension information, we pass the dimension
explicitly as another prop.
parent 41da9c4d
No related branches found
No related tags found
No related merge requests found
......@@ -18,6 +18,7 @@ import _ from "underscore";
export default class TimeseriesFilterWidget extends Component {
state = {
dimension: null,
filter: null,
filterIndex: -1,
currentFilter: null,
......@@ -34,34 +35,34 @@ export default class TimeseriesFilterWidget extends Component {
const filters = query.filters();
const dimensions = breakouts.map(b => b.dimension());
const dimension = dimensions[0];
const firstDimension = dimensions[0];
const timeseriesDimension =
dimension instanceof FieldDimension
? dimension.withoutTemporalBucketing()
: dimension;
const dimension =
firstDimension instanceof FieldDimension
? firstDimension.withoutTemporalBucketing()
: firstDimension;
const filterIndex = _.findIndex(
filters,
filter =>
Filter.isFieldFilter(filter) &&
_.isEqual(filter[1], timeseriesDimension.mbql()),
_.isEqual(filter[1], dimension.mbql()),
);
let filter, currentFilter;
if (filterIndex >= 0) {
filter = currentFilter = filters[filterIndex];
} else {
filter = ["time-interval", timeseriesDimension.mbql(), -30, "day"];
filter = null; // All time
}
this.setState({ filter, filterIndex, currentFilter });
this.setState({ dimension, filter, filterIndex, currentFilter });
}
}
render() {
const { className, card, setDatasetQuery } = this.props;
const { filter, filterIndex, currentFilter } = this.state;
const { dimension, filter, filterIndex, currentFilter } = this.state;
let currentDescription;
if (currentFilter) {
......@@ -94,7 +95,8 @@ export default class TimeseriesFilterWidget extends Component {
>
<DatePicker
className="m2"
filter={this.state.filter}
dimension={dimension}
filter={filter}
onFilterChange={newFilter => {
this.setState({ filter: newFilter });
}}
......
......@@ -281,7 +281,8 @@ export default class DatePicker extends Component {
};
static propTypes = {
filter: PropTypes.array.isRequired,
dimension: PropTypes.array,
filter: PropTypes.array,
onFilterChange: PropTypes.func.isRequired,
className: PropTypes.string,
hideEmptinessOperators: PropTypes.bool,
......@@ -296,28 +297,41 @@ export default class DatePicker extends Component {
if (!this.props.hideEmptinessOperators) {
operators = operators.concat(EMPTINESS_OPERATORS);
}
if (this.props.includeAllTime) {
operators = [ALL_TIME_OPERATOR, ...operators];
}
const operator = getOperator(this.props.filter, operators) || operators[0];
this.props.onFilterChange(operator.init(this.props.filter));
const { filter } = this.props;
const operator = getOperator(filter, operators) || operators[0];
this.adjustFilter(operator);
this.setState({ operators });
}
adjustFilter(operator, timeFilter = null) {
const { onFilterChange } = this.props;
const filter = timeFilter || this.props.filter;
if (onFilterChange) {
if (filter) {
onFilterChange(operator.init(filter));
} else {
// from All Time (null filter)
const { dimension } = this.props;
onFilterChange(operator.init(["time-interval", dimension?.mbql()]));
}
}
}
render() {
const {
className,
filter,
onFilterChange,
includeAllTime,
isSidebar,
disableOperatorSelection,
} = this.props;
let { operators } = this.state;
if (includeAllTime) {
operators = [ALL_TIME_OPERATOR, ...operators];
}
const { operators } = this.state;
const operator = getOperator(this.props.filter, operators);
const Widget = operator && operator.widget;
......@@ -339,7 +353,7 @@ export default class DatePicker extends Component {
})}
operator={operator && operator.name}
operators={operators}
onOperatorChange={operator => onFilterChange(operator.init(filter))}
onOperatorChange={operator => this.adjustFilter(operator)}
/>
)}
{Widget && (
......@@ -350,7 +364,7 @@ export default class DatePicker extends Component {
hideHoursAndMinutes={this.props.hideTimeSelectors}
onFilterChange={filter => {
if (operator && operator.init) {
onFilterChange(operator.init(filter));
this.adjustFilter(operator, filter);
} else {
onFilterChange(filter);
}
......
import { restore, popover, openProductsTable } from "__support__/e2e/cypress";
describe("time-series filter widget", () => {
beforeEach(() => {
cy.intercept("POST", "/api/dataset").as("dataset");
restore();
cy.signInAsAdmin();
openProductsTable();
});
it("should properly display All Time as the initial filtering (metabase#22247)", () => {
cy.findAllByText("Summarize")
.first()
.click();
cy.findAllByText("Created At")
.last()
.click();
cy.wait("@dataset");
cy.findByText("Done").click();
cy.findByText("All Time").click();
popover().within(() => {
cy.findByText("Previous").should("not.exist");
cy.findByText("Next").should("not.exist");
cy.findByTextEnsureVisible("All Time");
cy.findByTextEnsureVisible("Apply");
});
});
it("should allow switching from All Time filter", () => {
cy.findAllByText("Summarize")
.first()
.click();
cy.findAllByText("Created At")
.last()
.click();
cy.wait("@dataset");
cy.findByText("Done").click();
// switch to previous 30 quarters
cy.findByText("All Time").click();
popover().within(() => {
cy.findByText("All Time").click();
});
cy.get(".List-item")
.contains("Previous")
.click();
cy.findByTextEnsureVisible("days").click();
cy.get(".List-item")
.contains("quarters")
.click();
cy.button("Apply").click();
cy.wait("@dataset");
cy.findByTextEnsureVisible("Created At Previous 30 Quarters");
cy.findByTextEnsureVisible("Previous 30 Quarters");
});
it("should stay in-sync with the actual filter", () => {
cy.findAllByText("Filter")
.first()
.click();
cy.findAllByText("Created At")
.last()
.click();
cy.findByText("Last 3 Months").click();
cy.wait("@dataset");
cy.findByText("Created At Previous 3 Months").click();
cy.findByText("months").click();
cy.findByText("years").click();
cy.button("Add filter").click();
cy.wait("@dataset");
cy.findAllByText("Summarize")
.first()
.click();
cy.findAllByText("Created At")
.last()
.click();
cy.wait("@dataset");
cy.findByText("Done").click();
cy.findByTextEnsureVisible("Created At Previous 3 Years");
cy.findByText("Previous 3 Years").click();
popover().within(() => {
cy.findByText("Previous").should("be.visible");
cy.findByText("All Time").should("not.exist");
cy.findByText("Next").should("not.exist");
});
// switch to All Time filter
popover().within(() => {
cy.findByText("Previous").click();
});
cy.findByText("All Time").click();
cy.button("Apply").click();
cy.wait("@dataset");
cy.findByText("Created At Previous 3 Years").should("not.exist");
cy.findByTextEnsureVisible("All Time");
});
});
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment