Skip to content
Snippets Groups Projects
Commit f0d45ab9 authored by Allen Gilliland's avatar Allen Gilliland
Browse files

Merge pull request #1262 from metabase/null_date_filters

Re-enable null/not-null for dates.
parents 7b0d8aac b96a435c
Branches
Tags
No related merge requests found
......@@ -253,7 +253,9 @@ const OPERATORS_BY_TYPE_ORDERED = {
{ name: "=", verboseName: "Is" },
{ name: "<", verboseName: "Before" },
{ name: ">", verboseName: "After" },
{ name: "BETWEEN", verboseName: "Between" }
{ name: "BETWEEN", verboseName: "Between" },
{ name: "IS_NULL", verboseName: "Is empty", advanced: true },
{ name: "NOT_NULL",verboseName: "Not empty", advanced: true }
],
[LOCATION]: [
{ name: "=", verboseName: "Is" },
......
......@@ -226,8 +226,8 @@ export default class FilterPopover extends Component {
:
<div>
<OperatorSelector
filter={filter}
field={field}
operator={filter[0]}
operators={field.valid_operators}
onOperatorChange={this.setOperator}
/>
{ this.renderPicker(filter, field) }
......
......@@ -3,27 +3,28 @@ import React, { Component, PropTypes } from "react";
import Icon from "metabase/components/Icon.jsx";
import cx from "classnames";
import _ from "underscore";
export default class OperatorSelector extends Component {
constructor(props, context) {
super(props, context);
// if the initial operator is "advanced" expand the list
let operator = _.find(props.operators, o => o.name === props.operator);
this.state = {
expanded: false
expanded: operator && operator.advanced
};
}
static propTypes = {
filter: PropTypes.array.isRequired,
field: PropTypes.object.isRequired,
operator: PropTypes.string,
operators: PropTypes.array.isRequired,
onOperatorChange: PropTypes.func.isRequired
};
render() {
let { field, filter } = this.props;
let { operator, operators } = this.props;
let { expanded } = this.state;
let operators = field.valid_operators;
let defaultOperators = operators.filter(o => !o.advanced);
let expandedOperators = operators.filter(o => o.advanced);
......@@ -34,13 +35,13 @@ export default class OperatorSelector extends Component {
return (
<div className="border-bottom p1">
{ visibleOperators.map(operator =>
{ visibleOperators.map(o =>
<button
key={operator.name}
className={cx("Button Button-normal Button--medium mr1 mb1", { "Button--purple": operator.name === filter[0] })}
onClick={() => this.props.onOperatorChange(operator.name)}
key={o.name}
className={cx("Button Button-normal Button--medium mr1 mb1", { "Button--purple": o.name === operator })}
onClick={() => this.props.onOperatorChange(o.name)}
>
{operator.verboseName}
{o.verboseName}
</button>
)}
{ !expanded && expandedOperators.length > 0 ?
......
......@@ -2,8 +2,7 @@ import React, { Component, PropTypes } from "react";
import SpecificDatePicker from "./SpecificDatePicker.jsx";
import RelativeDatePicker from "./RelativeDatePicker.jsx";
import cx from "classnames";
import OperatorSelector from "../OperatorSelector.jsx";
export default class DatePicker extends Component {
constructor(props, context) {
......@@ -21,7 +20,9 @@ export default class DatePicker extends Component {
};
_detectPane(props) {
if (props.filter[0] !== "TIME_INTERVAL" && typeof props.filter[2] === "string") {
if (props.filter[0] === "IS_NULL" || props.filter[0] === "NOT_NULL") {
return props.filter[0]
} else if (props.filter[0] !== "TIME_INTERVAL" && typeof props.filter[2] === "string") {
return "specific";
} else {
return "relative";
......@@ -45,24 +46,37 @@ export default class DatePicker extends Component {
);
}
var operators = [
{ name: "relative", verboseName: "Relative date" },
{ name: "specific", verboseName: "Specific date" },
{ name: "IS_NULL", verboseName: "Is Empty", advanced: true },
{ name: "NOT_NULL", verboseName: "Not Empty", advanced: true }
];
return (
<div>
<div className="p1 border-bottom">
<button className={cx("Button Button--medium mr1", { "Button--purple": this.state.pane === "relative" })} onClick={this.selectPane.bind(this, "relative")}>Relative date</button>
<button className={cx("Button Button--medium", { "Button--purple": this.state.pane === "specific" })} onClick={this.selectPane.bind(this, "specific")}>Specific date</button>
</div>
<OperatorSelector
operator={this.state.pane}
operators={operators}
onOperatorChange={(operator) => {
this.setState({ pane: operator });
if (operator === "IS_NULL" || operator === "NOT_NULL") {
this.props.onOperatorChange(operator);
}
}}
/>
{ this.state.pane === "relative" ?
<RelativeDatePicker
filter={this.props.filter}
onFilterChange={this.props.onFilterChange}
/>
:
: this.state.pane === "specific" ?
<SpecificDatePicker
filter={this.props.filter}
onFilterChange={this.props.onFilterChange}
onOperatorChange={this.props.onOperatorChange}
/>
}
: null }
</div>
)
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment