diff --git a/web/client/actions/__tests__/featuregrid-test.js b/web/client/actions/__tests__/featuregrid-test.js
index 27eb6321e5..8eb9cb8a16 100644
--- a/web/client/actions/__tests__/featuregrid-test.js
+++ b/web/client/actions/__tests__/featuregrid-test.js
@@ -31,7 +31,8 @@ const {
openFeatureGrid, OPEN_FEATURE_GRID,
closeFeatureGrid, CLOSE_FEATURE_GRID,
closeFeatureGridConfirm, CLOSE_FEATURE_GRID_CONFIRM,
- closeFeatureGridConfirmed, FEATURE_GRID_CLOSE_CONFIRMED
+ closeFeatureGridConfirmed, FEATURE_GRID_CLOSE_CONFIRMED,
+ zoomAll, ZOOM_ALL
} = require('../featuregrid');
const idFeature = "2135";
@@ -198,5 +199,10 @@ describe('Test correctness of featurgrid actions', () => {
expect(retval).toExist();
expect(retval.type).toBe(SAVE_ERROR);
});
+ it('Test zoomAll', () => {
+ const retval = zoomAll();
+ expect(retval).toExist();
+ expect(retval.type).toBe(ZOOM_ALL);
+ });
});
diff --git a/web/client/actions/featuregrid.js b/web/client/actions/featuregrid.js
index c3e511c199..67afbfeae0 100644
--- a/web/client/actions/featuregrid.js
+++ b/web/client/actions/featuregrid.js
@@ -41,6 +41,7 @@ const FEATURE_GRID_CLOSE_CONFIRMED = 'FEATUREGRID:FEATURE_GRID_CLOSE_CONFIRMED';
const SET_PERMISSION = 'FEATUREGRID:SET_PERMISSION';
const DISABLE_TOOLBAR = 'FEATUREGRID:DISABLE_TOOLBAR';
const OPEN_ADVANCED_SEARCH = 'FEATUREGRID:ADVANCED_SEARCH';
+const ZOOM_ALL = 'FEATUREGRID:ZOOM_ALL';
const MODES = {
EDIT: "EDIT",
VIEW: "VIEW"
@@ -256,7 +257,11 @@ function openAdvancedSearch() {
type: OPEN_ADVANCED_SEARCH
};
}
-
+function zoomAll() {
+ return {
+ type: ZOOM_ALL
+ };
+}
module.exports = {
SELECT_FEATURES,
DESELECT_FEATURES,
@@ -294,6 +299,7 @@ module.exports = {
FEATURE_GRID_CLOSE_CONFIRMED, closeFeatureGridConfirmed,
DISABLE_TOOLBAR, disableToolbar,
OPEN_ADVANCED_SEARCH, openAdvancedSearch,
+ ZOOM_ALL, zoomAll,
setLayer,
selectFeatures,
deselectFeatures,
diff --git a/web/client/components/data/featuregrid/toolbars/Toolbar.jsx b/web/client/components/data/featuregrid/toolbars/Toolbar.jsx
index ef6179c826..72bef8ddfb 100644
--- a/web/client/components/data/featuregrid/toolbars/Toolbar.jsx
+++ b/web/client/components/data/featuregrid/toolbars/Toolbar.jsx
@@ -32,6 +32,13 @@ module.exports = ({events = {}, mode = "VIEW", selectedCount, hasChanges, hasGeo
visible={mode === "VIEW"}
onClick={events.showQueryPanel}
glyph="filter"/>
+ }
+ disabled={disableToolbar}
+ visible={mode === "VIEW"}
+ onClick={events.zoomAll}
+ glyph="zoom-to"/>
}
diff --git a/web/client/components/data/featuregrid/toolbars/__tests__/Toolbar-test.jsx b/web/client/components/data/featuregrid/toolbars/__tests__/Toolbar-test.jsx
index ea70531bfd..9765ad7124 100644
--- a/web/client/components/data/featuregrid/toolbars/__tests__/Toolbar-test.jsx
+++ b/web/client/components/data/featuregrid/toolbars/__tests__/Toolbar-test.jsx
@@ -54,6 +54,38 @@ describe('Featuregrid toolbar component', () => {
editButton = document.getElementById("fg-edit-mode");
expect(isVisibleButton(editButton)).toBe(false);
});
+ it('check search button', () => {
+ const events = {
+ showQueryPanel: () => {}
+ };
+ spyOn(events, "showQueryPanel");
+ ReactDOM.render(, document.getElementById("container"));
+ const el = document.getElementsByClassName("featuregrid-toolbar")[0];
+ expect(el).toExist();
+ let editButton = document.getElementById("fg-search");
+ expect(isVisibleButton(editButton)).toBe(true);
+ editButton.click();
+ expect(events.showQueryPanel).toHaveBeenCalled();
+ ReactDOM.render(, document.getElementById("container"));
+ editButton = document.getElementById("fg-search");
+ expect(isVisibleButton(editButton)).toBe(false);
+ });
+ it('check zoom-all button', () => {
+ const events = {
+ zoomAll: () => {}
+ };
+ spyOn(events, "zoomAll");
+ ReactDOM.render(, document.getElementById("container"));
+ const el = document.getElementsByClassName("featuregrid-toolbar")[0];
+ expect(el).toExist();
+ let editButton = document.getElementById("fg-zoom-all");
+ expect(isVisibleButton(editButton)).toBe(true);
+ editButton.click();
+ expect(events.zoomAll).toHaveBeenCalled();
+ ReactDOM.render(, document.getElementById("container"));
+ editButton = document.getElementById("fg-zoom-all");
+ expect(isVisibleButton(editButton)).toBe(false);
+ });
it('check back-view button', () => {
const events = {
switchViewMode: () => {}
diff --git a/web/client/epics/featuregrid.js b/web/client/epics/featuregrid.js
index 6f81d110e0..7d4089571f 100644
--- a/web/client/epics/featuregrid.js
+++ b/web/client/epics/featuregrid.js
@@ -9,6 +9,7 @@ const Rx = require('rxjs');
const {get, head, isEmpty, find} = require('lodash');
const { LOCATION_CHANGE } = require('react-router-redux');
const axios = require('../libs/ajax');
+const bbox = require('@turf/bbox');
const {fidFilter} = require('../utils/ogc/Filter/filter');
const {getDefaultFeatureProjection} = require('../utils/FeatureGridUtils');
const {isSimpleGeomType} = require('../utils/MapUtils');
@@ -19,6 +20,7 @@ const {findGeometryProperty} = require('../utils/ogc/WFS/base');
const {setControlProperty} = require('../actions/controls');
const {query, QUERY_CREATE, QUERY_RESULT, LAYER_SELECTED_FOR_SEARCH, FEATURE_TYPE_LOADED, featureTypeSelected, createQuery} = require('../actions/wfsquery');
const {reset, QUERY_FORM_RESET} = require('../actions/queryform');
+const {zoomToExtent} = require('../actions/map');
const {BROWSE_DATA} = require('../actions/layers');
const {parseString} = require('xml2js');
const {stripPrefix} = require('xml2js/lib/processors');
@@ -27,7 +29,7 @@ const {SORT_BY, CHANGE_PAGE, SAVE_CHANGES, SAVE_SUCCESS, DELETE_SELECTED_FEATURE
CLEAR_CHANGES, START_EDITING_FEATURE, TOGGLE_MODE, MODES, geometryChanged, DELETE_GEOMETRY, deleteGeometryFeature,
SELECT_FEATURES, DESELECT_FEATURES, START_DRAWING_FEATURE, CREATE_NEW_FEATURE,
CLEAR_CHANGES_CONFIRMED, FEATURE_GRID_CLOSE_CONFIRMED,
- openFeatureGrid, closeFeatureGrid, OPEN_FEATURE_GRID, CLOSE_FEATURE_GRID, CLOSE_FEATURE_GRID_CONFIRM, OPEN_ADVANCED_SEARCH} = require('../actions/featuregrid');
+ openFeatureGrid, closeFeatureGrid, OPEN_FEATURE_GRID, CLOSE_FEATURE_GRID, CLOSE_FEATURE_GRID_CONFIRM, OPEN_ADVANCED_SEARCH, ZOOM_ALL} = require('../actions/featuregrid');
const {TOGGLE_CONTROL} = require('../actions/controls');
const {setHighlightFeaturesPath} = require('../actions/highlight');
@@ -37,7 +39,7 @@ const {selectedFeaturesSelector, changesMapSelector, newFeaturesSelector, hasCha
isFeatureGridOpen} = require('../selectors/featuregrid');
const {error} = require('../actions/notifications');
-const {describeSelector, isDescribeLoaded, getFeatureById, wfsURL, wfsFilter} = require('../selectors/query');
+const {describeSelector, isDescribeLoaded, getFeatureById, wfsURL, wfsFilter, featureCollectionResultSelector} = require('../selectors/query');
const drawSupportReset = () => changeDrawingStatus("clean", "", "featureGrid", [], {});
/**
* Intercept OGC Exception (200 response with exceptionReport) to throw error in the stream
@@ -472,5 +474,9 @@ module.exports = {
)
).takeUntil(action$.ofType(OPEN_FEATURE_GRID, LOCATION_CHANGE))
)
- )
+ ),
+ onFeatureGridZoomAll: (action$, store) =>
+ action$.ofType(ZOOM_ALL).switchMap(() =>
+ Rx.Observable.of(zoomToExtent(bbox(featureCollectionResultSelector(store.getState())), "EPSG:4326"))
+ )
};
diff --git a/web/client/plugins/featuregrid/toolbarEvents.js b/web/client/plugins/featuregrid/toolbarEvents.js
index fada9952fa..6d5724bc50 100644
--- a/web/client/plugins/featuregrid/toolbarEvents.js
+++ b/web/client/plugins/featuregrid/toolbarEvents.js
@@ -8,7 +8,8 @@ const {toggleTool,
startEditingFeature,
startDrawingFeature,
deleteGeometry,
- openAdvancedSearch
+ openAdvancedSearch,
+ zoomAll
} = require('../../actions/featuregrid');
module.exports = {
@@ -24,5 +25,6 @@ module.exports = {
startDrawingFeature: () => startDrawingFeature(),
switchViewMode: () => toggleViewMode(),
onClose: () => closeFeatureGridConfirm(),
- showQueryPanel: () => openAdvancedSearch()
+ showQueryPanel: () => openAdvancedSearch(),
+ zoomAll: () => zoomAll()
};
diff --git a/web/client/selectors/__tests__/query-test.js b/web/client/selectors/__tests__/query-test.js
index 6d50497e25..a6a984a786 100644
--- a/web/client/selectors/__tests__/query-test.js
+++ b/web/client/selectors/__tests__/query-test.js
@@ -11,6 +11,7 @@ const {
wfsURL,
wfsFilter,
resultsSelector,
+ featureCollectionResultSelector,
paginationInfo,
featureLoadingSelector,
isDescribeLoaded,
@@ -339,6 +340,11 @@ describe('Test query selectors', () => {
expect(attr[0].label).toBe("name");
expect(attr[0].valueId).toBe("id");
});
+ it('test featureCollectionResultSelector selector', () => {
+ const fc = featureCollectionResultSelector(initialState);
+ expect(fc).toExist();
+ expect(fc.features.length).toBe(4);
+ });
});
diff --git a/web/client/selectors/query.js b/web/client/selectors/query.js
index 07cb0f8909..4ada8c57c6 100644
--- a/web/client/selectors/query.js
+++ b/web/client/selectors/query.js
@@ -4,6 +4,7 @@ module.exports = {
wfsFilter: state => state && state.query && state.query.filterObj,
attributesSelector: state => get(state, `query.featureTypes.${get(state, "query.filterObj.featureTypeName")}.attributes`),
resultsSelector: (state) => get(state, "query.result.features"),
+ featureCollectionResultSelector: state => get(state, "query.result"),
getFeatureById: (state, id) => {
let features = state && state.query && state.query.result && state.query.result.features;
return head(features.filter(f => f.id === id));
diff --git a/web/client/translations/data.de-DE b/web/client/translations/data.de-DE
index 145025639a..cbc3ffc45a 100644
--- a/web/client/translations/data.de-DE
+++ b/web/client/translations/data.de-DE
@@ -844,7 +844,8 @@
"cancelChanges": "Änderungen abbrechen",
"deleteGeometry": "Geometrie löschen",
"downloadGridData": "Daten herunterladen",
- "hideShowColumns": "Spalten ausblenden / anzeigen"
+ "hideShowColumns": "Spalten ausblenden / anzeigen",
+ "zoomAll": "Zoom zur Erweterung der Seite"
}
},
"wfsdownload": {
diff --git a/web/client/translations/data.en-US b/web/client/translations/data.en-US
index 080b555489..fa169079bd 100644
--- a/web/client/translations/data.en-US
+++ b/web/client/translations/data.en-US
@@ -843,7 +843,8 @@
"cancelChanges": "Cancel changes",
"deleteGeometry": "Delete geometry",
"downloadGridData": "Download grid data",
- "hideShowColumns": "Hide/show columns"
+ "hideShowColumns": "Hide/show columns",
+ "zoomAll": "Zoom to page extent"
}
},
"wfsdownload": {
diff --git a/web/client/translations/data.es-ES b/web/client/translations/data.es-ES
index e5c3214d62..2e9f00e751 100644
--- a/web/client/translations/data.es-ES
+++ b/web/client/translations/data.es-ES
@@ -847,7 +847,8 @@
"cancelChanges": "Cancelar cambios",
"deleteGeometry": "Eliminar geometría",
"downloadGridData": "Descargar datos",
- "hideShowColumns": "Ocultar / mostrar columnas"
+ "hideShowColumns": "Ocultar / mostrar columnas",
+ "zoomAll": "Zoom a la extensión de la página"
}
},
"wfsdownload": {
diff --git a/web/client/translations/data.fr-FR b/web/client/translations/data.fr-FR
index 81f299e454..e62674d1b6 100644
--- a/web/client/translations/data.fr-FR
+++ b/web/client/translations/data.fr-FR
@@ -848,7 +848,8 @@
"cancelChanges": "Annuler les modifications",
"deleteGeometry": "Supprimer la géométrie",
"downloadGridData": "Télécharger les données",
- "hideShowColumns": "Masquer / afficher les colonnes"
+ "hideShowColumns": "Masquer / afficher les colonnes",
+ "zoomAll": "Zoom sur la page"
}
},
"wfsdownload": {
diff --git a/web/client/translations/data.it-IT b/web/client/translations/data.it-IT
index cb321b7b5c..6f02d1d3e1 100644
--- a/web/client/translations/data.it-IT
+++ b/web/client/translations/data.it-IT
@@ -844,7 +844,8 @@
"cancelChanges": "Annulla i cambiamenti",
"deleteGeometry": "Elimina la geometria",
"downloadGridData": "Esporta i dati della griglia",
- "hideShowColumns": "Nascondi/mostra colonne"
+ "hideShowColumns": "Nascondi/mostra colonne",
+ "zoomAll": "Zoom all'estensione della pagina"
}
},
"wfsdownload": {