Skip to content

Commit

Permalink
#9325 enhancement: support for 'isNull' logical operator on date fiel…
Browse files Browse the repository at this point in the history
…d in layer filter (#9423) (#9573)
  • Loading branch information
mahmoudadel54 authored Oct 9, 2023
1 parent f250a21 commit 1d95e60
Show file tree
Hide file tree
Showing 5 changed files with 276 additions and 4 deletions.
4 changes: 2 additions & 2 deletions web/client/components/data/query/DateField.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -94,10 +94,10 @@ class DateField extends React.Component {
onChange={(date) => this.updateValueState({startDate: startdate, endDate: date})}/>
</div>
</div>)
:
(<div>
: (<div>
{this.props.showLabels && <Message msgId="queryform.date"/>}
<UTCDateTimePicker
disabled={this.props.operator === "isNull"}
type={this.props.attType}
defaultValue={startdate}
value={startdate}
Expand Down
2 changes: 1 addition & 1 deletion web/client/components/data/query/GroupField.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ class GroupField extends React.Component {
stringOperators: ["=", "<>", "like", "ilike", "isNull"],
arrayOperators: ["contains"],
booleanOperators: ["="],
defaultOperators: ["=", ">", "<", ">=", "<=", "<>", "><"],
defaultOperators: ["=", ">", "<", ">=", "<=", "<>", "><", "isNull"],
textFieldTooltipMessageId: 'queryform.attributefilter.tooltipTextField'
};

Expand Down
3 changes: 3 additions & 0 deletions web/client/components/data/query/NumberField.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ class NumberField extends React.Component {
<div className="query-field-value">
{lowLabel}
<NumberPicker
disabled={this.props.operator === "isNull"}
style={style}
value={this.props.fieldValue && (this.props.fieldValue.lowBound !== null && this.props.fieldValue.lowBound !== undefined) ? this.props.fieldValue.lowBound : null}
onChange={(value) => !isNaN(value) && this.changeNumber({lowBound: value, upBound: this.props.fieldValue && (this.props.fieldValue.upBound !== null && this.props.fieldValue.upBound !== undefined ) ? this.props.fieldValue.upBound : null})}
Expand All @@ -85,6 +86,7 @@ class NumberField extends React.Component {
<div className="query-field-value">
{upLabel}
<NumberPicker
disabled={this.props.operator === "isNull"}
style={style}
value={this.props.fieldValue && (this.props.fieldValue.upBound !== null && this.props.fieldValue.upBound !== undefined ) ? this.props.fieldValue.upBound : null}
onChange={(value) => !isNaN(value) && this.changeNumber({upBound: value, lowBound: this.props.fieldValue && (this.props.fieldValue.lowBound !== null && this.props.fieldValue.lowBound !== undefined) ? this.props.fieldValue.lowBound : null})}
Expand All @@ -96,6 +98,7 @@ class NumberField extends React.Component {
<div>
{label}
<NumberPicker
disabled={this.props.operator === "isNull"}
style={style}
value={this.props.fieldValue && (this.props.fieldValue.lowBound !== null && this.props.fieldValue.lowBound !== undefined) ? this.props.fieldValue.lowBound : this.props.fieldValue}
onChange={(value) => !isNaN(value) && this.changeNumber(value)}
Expand Down
269 changes: 269 additions & 0 deletions web/client/components/data/query/__tests__/FilterField-test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import FilterField, {AttributeNameField} from '../FilterField.jsx';
import ComboField from '../ComboField.jsx';
import DateField from '../DateField.jsx';
import expect from 'expect';
import NumberField from '../NumberField';

describe('FilterField', () => {

Expand Down Expand Up @@ -227,6 +228,274 @@ describe('FilterField', () => {

});

it('creates the FilterField component with date type and isNull operator', () => {
const filterField = {
rowId: 200,
attribute: "Date",
operator: "isNull",
value: null,
exception: null
};

const attributes = [
{
attribute: "Date",
label: "Date",
type: "date",
values: [],
valueId: "id",
valueLabel: "name"
}
];

const filterfield = ReactDOM.render(
<FilterField
attributes={attributes}
filterField={filterField}>
<ComboField
attType="list"
valueField={'id'}
textField={'name'}
fieldOptions={attributes[0] && attributes[0].type === "list" ? [null, ...attributes[0].values] : null}/>
<DateField
attType="date"
operator={filterField.operator}/>
</FilterField>,
document.getElementById("container"));

expect(filterfield).toExist();

expect(filterfield.props.children).toExist();
expect(filterfield.props.children.length).toBe(2);

expect(filterfield.props.attributes).toExist();
expect(filterfield.props.attributes.length).toBe(1);

expect(filterfield.props.filterField).toExist();

const filterFieldDOMNode = expect(ReactDOM.findDOMNode(filterfield));

expect(filterFieldDOMNode).toExist();

let childNodes = filterFieldDOMNode.actual.childNodes;

expect(childNodes.length).toBe(3);

const inputFields = filterFieldDOMNode.actual.getElementsByClassName('rw-input');
expect(inputFields.length).toBe(3);

const attributeSelect = filterFieldDOMNode.actual.getElementsByClassName('rw-input')[0];
expect(attributeSelect.childNodes[0].nodeValue).toBe("Date");

const operatorSelect = filterFieldDOMNode.actual.getElementsByClassName('rw-input')[1];
expect(operatorSelect.childNodes[0].nodeValue).toBe("isNull");

const valueSelectContainer = inputFields[2];
expect(valueSelectContainer).toExist();
expect(valueSelectContainer.disabled).toBe(true);

});
it('creates the FilterField component with time type and isNull operator', () => {
const filterField = {
rowId: 200,
attribute: "Time",
operator: "isNull",
value: null,
exception: null
};

const attributes = [
{
attribute: "Time",
label: "Time",
type: "time",
values: [],
valueId: "id",
valueLabel: "name"
}
];

const filterfield = ReactDOM.render(
<FilterField
attributes={attributes}
filterField={filterField}>
<ComboField
attType="list"
valueField={'id'}
textField={'name'}
fieldOptions={attributes[0] && attributes[0].type === "list" ? [null, ...attributes[0].values] : null}/>
<DateField
attType="time"
operator={filterField.operator}/>
</FilterField>,
document.getElementById("container"));

expect(filterfield).toExist();

expect(filterfield.props.children).toExist();
expect(filterfield.props.children.length).toBe(2);

expect(filterfield.props.attributes).toExist();
expect(filterfield.props.attributes.length).toBe(1);

expect(filterfield.props.filterField).toExist();

const filterFieldDOMNode = expect(ReactDOM.findDOMNode(filterfield));

expect(filterFieldDOMNode).toExist();

let childNodes = filterFieldDOMNode.actual.childNodes;

expect(childNodes.length).toBe(3);

const inputFields = filterFieldDOMNode.actual.getElementsByClassName('rw-input');
expect(inputFields.length).toBe(3);

const attributeSelect = filterFieldDOMNode.actual.getElementsByClassName('rw-input')[0];
expect(attributeSelect.childNodes[0].nodeValue).toBe("Time");

const operatorSelect = filterFieldDOMNode.actual.getElementsByClassName('rw-input')[1];
expect(operatorSelect.childNodes[0].nodeValue).toBe("isNull");

const valueSelectContainer = inputFields[2];
expect(valueSelectContainer).toExist();
expect(valueSelectContainer.disabled).toBe(true);

});
it('creates the FilterField component with date-time type and isNull operator', () => {
const filterField = {
rowId: 200,
attribute: "TimeDate",
operator: "isNull",
value: null,
exception: null
};

const attributes = [
{
attribute: "TimeDate",
label: "TimeDate",
type: "date-time",
values: [],
valueId: "id",
valueLabel: "name"
}
];

const filterfield = ReactDOM.render(
<FilterField
attributes={attributes}
filterField={filterField}>
<ComboField
attType="list"
valueField={'id'}
textField={'name'}
fieldOptions={attributes[0] && attributes[0].type === "list" ? [null, ...attributes[0].values] : null}/>
<DateField
attType="date-time"
operator={filterField.operator}/>
</FilterField>,
document.getElementById("container"));

expect(filterfield).toExist();

expect(filterfield.props.children).toExist();
expect(filterfield.props.children.length).toBe(2);

expect(filterfield.props.attributes).toExist();
expect(filterfield.props.attributes.length).toBe(1);

expect(filterfield.props.filterField).toExist();

const filterFieldDOMNode = expect(ReactDOM.findDOMNode(filterfield));

expect(filterFieldDOMNode).toExist();

let childNodes = filterFieldDOMNode.actual.childNodes;

expect(childNodes.length).toBe(3);

const inputFields = filterFieldDOMNode.actual.getElementsByClassName('rw-input');
expect(inputFields.length).toBe(3);

const attributeSelect = filterFieldDOMNode.actual.getElementsByClassName('rw-input')[0];
expect(attributeSelect.childNodes[0].nodeValue).toBe("TimeDate");

const operatorSelect = filterFieldDOMNode.actual.getElementsByClassName('rw-input')[1];
expect(operatorSelect.childNodes[0].nodeValue).toBe("isNull");

const valueSelectContainer = inputFields[2];
expect(valueSelectContainer).toExist();
expect(valueSelectContainer.disabled).toBe(true);

});
it('creates the FilterField component with number type and isNull operator', () => {
const filterField = {
rowId: 200,
attribute: "Number",
operator: "isNull",
value: null,
exception: null
};

const attributes = [
{
attribute: "Number",
label: "Number",
type: "number",
values: [],
valueId: "id",
valueLabel: "name"
}
];

const filterfield = ReactDOM.render(
<FilterField
attributes={attributes}
filterField={filterField}>
<ComboField
attType="list"
valueField={'id'}
textField={'name'}
fieldOptions={attributes[0] && attributes[0].type === "list" ? [null, ...attributes[0].values] : null}/>
<NumberField
attType="number"
operator={filterField.operator}/>
</FilterField>,
document.getElementById("container"));

expect(filterfield).toExist();

expect(filterfield.props.children).toExist();
expect(filterfield.props.children.length).toBe(2);

expect(filterfield.props.attributes).toExist();
expect(filterfield.props.attributes.length).toBe(1);

expect(filterfield.props.filterField).toExist();

const filterFieldDOMNode = expect(ReactDOM.findDOMNode(filterfield));

expect(filterFieldDOMNode).toExist();

let childNodes = filterFieldDOMNode.actual.childNodes;

expect(childNodes.length).toBe(3);

const inputFields = filterFieldDOMNode.actual.getElementsByClassName('rw-input');
expect(inputFields.length).toBe(3);

const attributeSelect = filterFieldDOMNode.actual.getElementsByClassName('rw-input')[0];
expect(attributeSelect.childNodes[0].nodeValue).toBe("Number");

const operatorSelect = filterFieldDOMNode.actual.getElementsByClassName('rw-input')[1];
expect(operatorSelect.childNodes[0].nodeValue).toBe("isNull");

const valueSelectContainer = inputFields[2];
expect(valueSelectContainer).toExist();
expect(valueSelectContainer.disabled).toBe(true);

});
it('tests the FilterField actions', () => {

const actions = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ describe('GroupField', () => {
const boolean = groupfield.getOperator({type: "boolean"});
expect(boolean).toEqual(["="]);
const noType = groupfield.getOperator();
expect(noType).toEqual(["=", ">", "<", ">=", "<=", "<>", "><"]);
expect(noType).toEqual(["=", ">", "<", ">=", "<=", "<>", "><", "isNull"]);

const noSelected = groupfield.getComboValues();
expect(noSelected).toBe(null);
Expand Down

0 comments on commit 1d95e60

Please sign in to comment.