Skip to content

Commit 5f54c38

Browse files
kappu72offtherailz
authored andcommitted
Fix #2773. First rules-editor implementation (#2845)
1 parent f595cde commit 5f54c38

76 files changed

Lines changed: 3918 additions & 92 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

docma-config.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,7 @@
218218
"web/client/plugins/WFSDownload.jsx",
219219
"web/client/plugins/ZoomIn.jsx",
220220
"web/client/plugins/ZoomOut.jsx"
221-
]
221+
]
222222
},
223223
"./docs/**/*md",
224224
{

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,7 @@
141141
"react-container-dimensions": "1.3.2",
142142
"react-copy-to-clipboard": "5.0.0",
143143
"react-data-grid": "2.0.59",
144+
"react-data-grid-addons": "3.0.11",
144145
"react-dnd": "2.4.0",
145146
"react-dnd-html5-backend": "2.4.1",
146147
"react-dock": "0.2.4",

web/client/actions/__tests__/rulesmanager-test.js

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,44 @@ const expect = require('expect');
1010
const { RULES_SELECTED, RULES_LOADED, UPDATE_ACTIVE_RULE,
1111
ACTION_ERROR, OPTIONS_LOADED, UPDATE_FILTERS_VALUES,
1212
rulesSelected, rulesLoaded, updateActiveRule,
13-
actionError, optionsLoaded, updateFiltersValues} = require('../rulesmanager');
13+
actionError, optionsLoaded, updateFiltersValues,
14+
SET_FILTER, setFilter,
15+
SAVE_RULE, saveRule, cleanEditing, CLEAN_EDITING,
16+
onEditRule, EDIT_RULE, delRules, DELETE_RULES} = require('../rulesmanager');
1417

1518
describe('test rules manager actions', () => {
16-
17-
it('rules slected', () => {
19+
it('save rule', () => {
20+
const rule = {};
21+
const action = saveRule(rule);
22+
expect(action).toExist();
23+
expect(action.type).toBe(SAVE_RULE);
24+
expect(action.rule).toBe(rule);
25+
});
26+
it('clean editing', () => {
27+
const action = cleanEditing();
28+
expect(action).toExist();
29+
expect(action.type).toBe(CLEAN_EDITING);
30+
});
31+
it('on edit rule', () => {
32+
const action = onEditRule();
33+
expect(action).toExist();
34+
expect(action.type).toBe(EDIT_RULE);
35+
expect(action.createNew).toBe(false);
36+
expect(action.targetPriority).toBe(0);
37+
});
38+
it('delete rules', () => {
39+
const action = delRules();
40+
expect(action).toExist();
41+
expect(action.type).toBe(DELETE_RULES);
42+
});
43+
it('set Filter', () => {
44+
const action = setFilter("key", "value");
45+
expect(action).toExist();
46+
expect(action.type).toBe(SET_FILTER);
47+
expect(action.key).toBe("key");
48+
expect(action.value).toBe("value");
49+
});
50+
it('rules selected', () => {
1851
const rules = [
1952
{ id: "rules1" },
2053
{ id: "rules2" }

web/client/actions/rulesmanager.js

Lines changed: 57 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,57 @@ const UPDATE_ACTIVE_RULE = 'UPDATE_ACTIVE_RULE';
1818
const UPDATE_FILTERS_VALUES = 'UPDATE_FILTERS_VALUES';
1919
const ACTION_ERROR = 'ACTION_ERROR';
2020
const OPTIONS_LOADED = 'OPTIONS_LOADED';
21+
const LOADING = 'RULES_MANAGER:LOADING';
22+
const SET_FILTER = "RULES_MANAGER:SET_FILTER";
23+
const EDIT_RULE = "RULES_MANAGER:EDIT_RULE";
24+
const CLEAN_EDITING = "RULES_MANAGER:CLEAN_EDITING";
25+
const SAVE_RULE = "RULES_MANAGER:SAVE_RULE";
26+
const RULE_SAVED = "RULES_MANAGER:RULE_SAVED";
27+
const DELETE_RULES = "RULES_MANAGER: DELETE_RULES";
2128

22-
function rulesSelected(rules, merge, unselect) {
29+
function delRules(ids) {
30+
return {
31+
type: DELETE_RULES,
32+
ids
33+
};
34+
}
35+
36+
function setFilter(key, value) {
37+
return {
38+
type: SET_FILTER,
39+
key,
40+
value
41+
};
42+
}
43+
44+
function onEditRule(targetPriority = 0, createNew = false) {
45+
return {
46+
type: EDIT_RULE,
47+
createNew,
48+
targetPriority
49+
};
50+
}
51+
52+
function cleanEditing() {
53+
return {
54+
type: CLEAN_EDITING
55+
};
56+
}
57+
58+
function setLoading(loading) {
59+
return {
60+
type: LOADING,
61+
loading
62+
};
63+
}
64+
65+
function rulesSelected(rules, merge, unselect, targetPosition) {
2366
return {
2467
type: RULES_SELECTED,
25-
rules: rules,
26-
merge: merge,
27-
unselect: unselect
68+
rules,
69+
merge,
70+
unselect,
71+
targetPosition
2872
};
2973
}
3074

@@ -203,6 +247,8 @@ function updateRule() {
203247
};
204248
}
205249

250+
const saveRule = (rule) => ({type: SAVE_RULE, rule});
251+
206252
module.exports = {
207253
RULES_SELECTED,
208254
RULES_LOADED,
@@ -225,5 +271,11 @@ module.exports = {
225271
loadWorkspaces,
226272
loadLayers,
227273
actionError,
228-
optionsLoaded
274+
optionsLoaded,
275+
LOADING, setLoading,
276+
SET_FILTER, setFilter,
277+
EDIT_RULE, onEditRule,
278+
CLEAN_EDITING, cleanEditing,
279+
SAVE_RULE, saveRule, RULE_SAVED,
280+
DELETE_RULES, delRules
229281
};

web/client/api/geoserver/GeoFence.js

Lines changed: 82 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -10,17 +10,27 @@ const axios = require('../../libs/ajax');
1010
const assign = require('object-assign');
1111

1212
const ConfigUtils = require('../../utils/ConfigUtils');
13-
13+
const EMPTY_RULE = {
14+
constraints: {},
15+
ipaddress: "",
16+
layer: "",
17+
request: "",
18+
rolename: "",
19+
service: "",
20+
username: "",
21+
workspace: ""
22+
};
1423
var Api = {
1524

16-
loadRules: function(rulesPage, rulesFiltersValues) {
17-
const options = {
18-
'params': {
19-
'page': rulesPage - 1,
20-
'entries': 10
21-
}
25+
loadRules: function(page, rulesFiltersValues, entries = 10) {
26+
const params = {
27+
page,
28+
entries,
29+
...this.assignFiltersValue(rulesFiltersValues)
2230
};
23-
this.assignFiltersValue(rulesFiltersValues, options);
31+
const options = {params, 'headers': {
32+
'Content': 'application/json'
33+
}};
2434
return axios.get('geofence/rest/rules', this.addBaseUrl(options))
2535
.then(function(response) {
2636
return response.data;
@@ -30,9 +40,8 @@ var Api = {
3040

3141
getRulesCount: function(rulesFiltersValues) {
3242
const options = {
33-
'params': {}
43+
'params': this.assignFiltersValue(rulesFiltersValues)
3444
};
35-
this.assignFiltersValue(rulesFiltersValues, options);
3645
return axios.get('geofence/rest/rules/count', this.addBaseUrl(options)).then(function(response) {
3746
return response.data;
3847
});
@@ -55,40 +64,50 @@ var Api = {
5564
},
5665

5766
addRule: function(rule) {
58-
if (!rule.access) {
59-
rule.access = "ALLOW";
67+
const newRule = {...rule};
68+
if (!newRule.instance) {
69+
const {id: instanceId} = ConfigUtils.getDefaults().geoFenceGeoServerInstance;
70+
newRule.instance = {id: instanceId};
71+
}
72+
if (!newRule.grant) {
73+
newRule.grant = "ALLOW";
6074
}
61-
return axios.post('geofence/rest/rules', rule, this.addBaseUrl({
75+
return axios.post('geofence/rest/rules', newRule, this.addBaseUrl({
6276
'headers': {
6377
'Content': 'application/json'
6478
}
6579
}));
6680
},
6781

6882
updateRule: function(rule) {
69-
return axios.post('geofence/rest/rules/id/' + rule.id, rule, this.addBaseUrl({
83+
// id, priority and grant aren't updatable
84+
const {id, priority, grant, position, ...others} = rule;
85+
const newRule = {...EMPTY_RULE, ...others};
86+
return axios.put(`geofence/rest/rules/id/${id}`, newRule, this.addBaseUrl({
7087
'headers': {
7188
'Content': 'application/json'
7289
}
7390
}));
7491
},
7592

76-
assignFiltersValue: function(rulesFiltersValues, options) {
77-
if (rulesFiltersValues) {
78-
assign(options.params, {"userName": this.normalizeFilterValue(rulesFiltersValues.userName)});
79-
assign(options.params, {"roleName": this.normalizeFilterValue(rulesFiltersValues.roleName)});
80-
assign(options.params, {"service": this.normalizeFilterValue(rulesFiltersValues.service)});
81-
assign(options.params, {"request": this.normalizeFilterValue(rulesFiltersValues.request)});
82-
assign(options.params, {"workspace": this.normalizeFilterValue(rulesFiltersValues.workspace)});
83-
assign(options.params, {"layer": this.normalizeFilterValue(rulesFiltersValues.layer)});
84-
}
85-
return options;
93+
assignFiltersValue: function(rulesFiltersValues = {}) {
94+
return Object.keys(rulesFiltersValues).map(key => ({key, normKey: this.normalizeKey(key)}))
95+
.reduce((params, {key, normKey}) => ({...params, [normKey]: this.normalizeFilterValue(rulesFiltersValues[key])}), {});
8696
},
8797

8898
normalizeFilterValue(value) {
8999
return value === "*" ? undefined : value;
90100
},
91-
101+
normalizeKey(key) {
102+
switch (key) {
103+
case 'username':
104+
return 'userName';
105+
case 'rolename':
106+
return 'groupName';
107+
default:
108+
return key;
109+
}
110+
},
92111
assignFilterValue: function(queryParameters, filterName, filterAny, filterValue) {
93112
if (!filterValue) {
94113
return;
@@ -99,29 +118,52 @@ var Api = {
99118
assign(queryParameters, {[filterName]: filterValue});
100119
}
101120
},
102-
103-
getGroups: function() {
104-
return axios.get('security/rest/roles', this.addBaseUrl({
121+
getGroupsCount: function(filter = " ") {
122+
const encodedFilter = encodeURIComponent(`%${filter}%`);
123+
return axios.get(`geofence/rest/groups/count/${encodedFilter}`, this.addBaseUrl({
105124
'headers': {
106-
'Accept': 'application/json'
125+
'Accept': 'text/plain'
107126
}
108127
})).then(function(response) {
109128
return response.data;
110129
});
111130
},
112-
113-
getUsers: function() {
114-
return axios.get('security/rest/usergroup/users', this.addBaseUrl({
131+
getGroups: function(filter, page, entries = 10) {
132+
const params = {
133+
page,
134+
entries,
135+
nameLike: `%${filter}%`
136+
};
137+
const options = {params};
138+
return axios.get(`geofence/rest/groups`, this.addBaseUrl(options)).then(function(response) {
139+
return response.data;
140+
});
141+
},
142+
getUsersCount: function(filter = " ") {
143+
const encodedFilter = encodeURIComponent(`%${filter}%`);
144+
return axios.get(`geofence/rest/users/count/${encodedFilter}`, this.addBaseUrl({
115145
'headers': {
116-
'Accept': 'application/json'
146+
'Accept': 'text/plain'
117147
}
118148
})).then(function(response) {
119149
return response.data;
120150
});
121151
},
122152

153+
getUsers: function(filter, page, entries = 10) {
154+
const params = {
155+
page,
156+
entries,
157+
nameLike: `%${filter}%`
158+
};
159+
const options = {params};
160+
return axios.get(`geofence/rest/users`, this.addBaseUrl(options)).then(function(response) {
161+
return response.data;
162+
});
163+
},
164+
123165
getWorkspaces: function() {
124-
return axios.get('rest/workspaces', this.addBaseUrl({
166+
return axios.get('rest/workspaces', this.addBaseUrlGS({
125167
'headers': {
126168
'Accept': 'application/json'
127169
}
@@ -134,8 +176,12 @@ var Api = {
134176
return !value ? '*' : value;
135177
},
136178

137-
addBaseUrl: function(options) {
138-
return assign(options, {baseURL: ConfigUtils.getDefaults().geoServerUrl});
179+
addBaseUrl: function(options = {}) {
180+
return assign(options, {baseURL: ConfigUtils.getDefaults().geoFenceUrl});
181+
},
182+
addBaseUrlGS: function(options = {}) {
183+
const {url: baseURL} = ConfigUtils.getDefaults().geoFenceGeoServerInstance || {};
184+
return assign(options, {baseURL});
139185
}
140186
};
141187

web/client/components/data/grid/DataGrid.jsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ class DataGrid extends Grid {
2727
componentWillUnmount() {
2828
if (this.canvas) {
2929
this.canvas.removeEventListener('scroll', this.scrollListener);
30+
this.canvas = null;
3031
}
3132
if (this.props.displayFilters) {
3233
this.onToggleFilter();

0 commit comments

Comments
 (0)