From df7aed2a95d8946d8633e0e4bf0f988d3a614135 Mon Sep 17 00:00:00 2001 From: Mauro Bartolomeoli Date: Mon, 3 Apr 2017 12:38:25 +0200 Subject: [PATCH] Fixes #1441: allow query with no filter set --- .../components/data/query/QueryBuilder.jsx | 8 +- .../components/data/query/QueryToolbar.jsx | 28 +++-- .../query/__tests__/QueryBuilder-test.jsx | 106 ++++++++++++++++++ web/client/plugins/TOC.jsx | 2 + web/client/translations/data.de-DE | 1 + web/client/translations/data.en-US | 1 + web/client/translations/data.fr-FR | 1 + web/client/translations/data.it-IT | 1 + 8 files changed, 139 insertions(+), 9 deletions(-) diff --git a/web/client/components/data/query/QueryBuilder.jsx b/web/client/components/data/query/QueryBuilder.jsx index e2106dc40d..aa5a723d10 100644 --- a/web/client/components/data/query/QueryBuilder.jsx +++ b/web/client/components/data/query/QueryBuilder.jsx @@ -48,7 +48,9 @@ const QueryBuilder = React.createClass({ pagination: React.PropTypes.object, sortOptions: React.PropTypes.object, hits: React.PropTypes.bool, - maxHeight: React.PropTypes.number + maxHeight: React.PropTypes.number, + allowEmptyFilter: React.PropTypes.bool, + emptyFilterWarning: React.PropTypes.bool }, getDefaultProps() { return { @@ -74,6 +76,8 @@ const QueryBuilder = React.createClass({ sortOptions: null, hits: false, maxHeight: 830, + allowEmptyFilter: false, + emptyFilterWarning: false, attributeFilterActions: { onAddGroupField: () => {}, onAddFilterField: () => {}, @@ -138,6 +142,8 @@ const QueryBuilder = React.createClass({ pagination={this.props.pagination} sortOptions={this.props.sortOptions} hits={this.props.hits} + allowEmptyFilter={this.props.allowEmptyFilter} + emptyFilterWarning={this.props.emptyFilterWarning} />
{}, onReset: () => {}, @@ -59,14 +64,24 @@ const QueryToolbar = React.createClass({ render() { let fieldsExceptions = this.props.filterFields.filter((field) => field.exception).length > 0; // let fieldsWithoutValues = this.props.filterFields.filter((field) => !field.value).length > 0; - let fieldsWithValues = this.props.filterFields.filter((field) => field.value).length > 0; + let fieldsWithValues = this.props.filterFields.filter((field) => field.value).length > 0 || this.props.allowEmptyFilter; let queryDisabled = // fieldsWithoutValues || fieldsExceptions || !this.props.toolbarEnabled || (!fieldsWithValues && !this.props.spatialField.geometry); - + const tooltip = ; + const btn = (); + const showTooltip = this.props.emptyFilterWarning && this.props.filterFields.filter((field) => field.value).length === 0 && !this.props.spatialField.geometry; + const queryButton = showTooltip ? ( + + {btn} + + ) : btn; return (
@@ -75,10 +90,7 @@ const QueryToolbar = React.createClass({ - + {queryButton} diff --git a/web/client/components/data/query/__tests__/QueryBuilder-test.jsx b/web/client/components/data/query/__tests__/QueryBuilder-test.jsx index 4e8c4c7941..1ad5fdaffe 100644 --- a/web/client/components/data/query/__tests__/QueryBuilder-test.jsx +++ b/web/client/components/data/query/__tests__/QueryBuilder-test.jsx @@ -94,6 +94,55 @@ describe('QueryBuilder', () => { expect(childNodes.length).toBe(2); }); + it('creates the QueryBuilder component no filter set', () => { + const groupLevels = 5; + + const groupFields = []; + + const filterFields = [{ + rowId: 100, + groupId: 1, + attribute: "", + operator: null, + value: null, + exception: null + }]; + + const attributes = [{ + id: "Attribute", + type: "list", + values: [ + "attribute1", + "attribute2", + "attribute3", + "attribute4", + "attribute5" + ] + }]; + + const querybuilder = ReactDOM.render( + , + document.getElementById("container") + ); + + expect(querybuilder).toExist(); + + const queryBuilderDOMNode = expect(ReactDOM.findDOMNode(querybuilder)); + + expect(queryBuilderDOMNode).toExist(); + let childNodes = queryBuilderDOMNode.actual.childNodes; + expect(childNodes.length).toBe(2); + + const queryButton = document.getElementById('query-toolbar-query'); + expect(queryButton).toExist(); + expect(queryButton.getAttribute("disabled")).toBe(''); + }); + it('creates the QueryBuilder component in error state', () => { let attributeFilterActions = { @@ -111,4 +160,61 @@ describe('QueryBuilder', () => { expect(querybuilder).toExist(); expect(spy.calls.length).toEqual(1); }); + + it('creates the QueryBuilder component with empty filter support', () => { + const groupLevels = 5; + + const groupFields = [{ + id: 1, + logic: "OR", + index: 0 + }]; + + const filterFields = [{ + rowId: 100, + groupId: 1, + attribute: "", + operator: null, + value: null, + exception: null + }, { + rowId: 200, + groupId: 1, + attribute: "Attribute", + operator: "=", + value: "attribute1", + exception: null + }]; + + const attributes = [{ + id: "Attribute", + type: "list", + values: [ + "attribute1", + "attribute2", + "attribute3", + "attribute4", + "attribute5" + ] + }]; + + const querybuilder = ReactDOM.render( + , + document.getElementById("container") + ); + + expect(querybuilder).toExist(); + + const queryBuilderDOMNode = expect(ReactDOM.findDOMNode(querybuilder)); + expect(queryBuilderDOMNode).toExist(); + const queryButton = document.getElementById('query-toolbar-query'); + expect(queryButton).toExist(); + expect(queryButton.getAttribute("disabled")).toNotExist(); + }); }); diff --git a/web/client/plugins/TOC.jsx b/web/client/plugins/TOC.jsx index 4214680339..84c24d2f55 100644 --- a/web/client/plugins/TOC.jsx +++ b/web/client/plugins/TOC.jsx @@ -82,6 +82,8 @@ const SmartQueryForm = connect((state) => { params: {typeName: state.query && state.query.typeName}, resultTitle: "Query Result", showGeneratedFilter: false, + allowEmptyFilter: true, + emptyFilterWarning: true, maxHeight: state.map && state.map.present && state.map.present.size && state.map.present.size.height }; }, dispatch => { diff --git a/web/client/translations/data.de-DE b/web/client/translations/data.de-DE index 6465137ea9..8e3cb92158 100644 --- a/web/client/translations/data.de-DE +++ b/web/client/translations/data.de-DE @@ -389,6 +389,7 @@ "header": "Finde im Datensatz", "dataset_header": "Datensatz" }, + "emptyfilter": "Kein Filtersatz. Die Suche nach dem Timeout, wenn die Paginierung vom Server nicht unterstützt wird.", "attributefilter":{ "add_condition": " Füge Bedingung hinzu", "add_group": " Füge Gruppe hinzu", diff --git a/web/client/translations/data.en-US b/web/client/translations/data.en-US index b8aadcfa4e..3b2b84991c 100644 --- a/web/client/translations/data.en-US +++ b/web/client/translations/data.en-US @@ -389,6 +389,7 @@ "header": "Find in the dataset", "dataset_header": "Dataset" }, + "emptyfilter": "No filter set. Searching could timeout if pagination is not supported by the server.", "attributefilter":{ "add_condition": " Add Condition", "add_group": " Add Group", diff --git a/web/client/translations/data.fr-FR b/web/client/translations/data.fr-FR index c96b299313..0d1ee0c40a 100644 --- a/web/client/translations/data.fr-FR +++ b/web/client/translations/data.fr-FR @@ -391,6 +391,7 @@ "header": "Rechercher dans les données", "dataset_header": "Ensemble des données" }, + "emptyfilter": "Aucun ensemble de filtres. La recherche pourrait expirer si la pagination n'est pas prise en charge par le serveur.", "attributefilter":{ "add_condition": " Ajouter une condition", "add_group": " Ajouter un groupe", diff --git a/web/client/translations/data.it-IT b/web/client/translations/data.it-IT index 9eba02a033..dc310cdb0a 100644 --- a/web/client/translations/data.it-IT +++ b/web/client/translations/data.it-IT @@ -389,6 +389,7 @@ "header": "Cerca nel dataset", "dataset_header": "Dataset" }, + "emptyfilter": "Nessun filtro selezionato. La ricerca potrebbe andare in timeout se il server non supporta la paginazione.", "attributefilter":{ "add_condition": " Aggiungi Condizione", "add_group": " Aggiungi Gruppo",