Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merging master to c125_annotations #2732

Merged
merged 32 commits into from
Mar 13, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
83d8717
Fix documentation issue (#2606)
offtherailz Feb 14, 2018
dbad778
Fixes #2608: custom mapOptions are not saved with maps (#2609)
mbarto Feb 15, 2018
90e2b13
Fix #2592 reorganized text widget into 1 page (#2614)
offtherailz Feb 16, 2018
b7aa476
Fixed sidegrid css for different screen resolutions (#2616)
offtherailz Feb 16, 2018
283d06f
Fixes #2542 Custom template for GetFeatureInfo (#2591)
allyoucanmap Feb 21, 2018
384a70e
(Partial) Chinese language translation (#2643)
mbarto Feb 27, 2018
3dc8b5a
Added onlink handler to openlayers overlay layer (#2644)
mbarto Feb 27, 2018
62ef950
Fix #2623. Implemented table widget (#2635)
offtherailz Feb 27, 2018
6549901
Closes geosolutions-it/austrocontrol-C125#26 (#2632)
kappu72 Feb 27, 2018
d54c857
Counter widget (#2645)
offtherailz Feb 27, 2018
225e8c0
Fixes #2547: upgraded openlayers to 4.6.4 (#2646)
mbarto Feb 28, 2018
b4e1dfc
MousePosition degrees template via plugin props (#2648)
mbarto Feb 28, 2018
4064803
Fix #2615. Avoid widgets clear while saving (#2649)
offtherailz Feb 28, 2018
a1ff7d2
Fixes #2665 Add an action to force resize of Map component (#2666)
allyoucanmap Mar 2, 2018
7ab512e
Austro#31# (#2683)
kappu72 Mar 2, 2018
34942ff
Fixes #2569: upgrade of leaflet version to 1.3.1 (and related depende…
mbarto Mar 5, 2018
9043050
Fixing leaflet randomly failing test (#2697)
mbarto Mar 5, 2018
d5d99bb
Closes #2637 (#2698)
kappu72 Mar 6, 2018
41fda25
Fixes #2703: openalayers WMTS layers ignore initial visibility (#2704)
mbarto Mar 6, 2018
dece305
2626 updates measure tool (#2701)
MV88 Mar 6, 2018
956845f
Fix #2685. Removed for of statements (#2714)
offtherailz Mar 7, 2018
3cdff74
DrawSupport:Replace does not add drawinteraction by default (#2581)
ndufrane Mar 8, 2018
eed05d1
Updated moment dependency to fix vulnerability of current version (#2…
mbarto Mar 8, 2018
3f2f00a
Fix #2561. Add DETAILS to default categories (#2717)
offtherailz Mar 8, 2018
ebb2dd1
Tentative fix of randomly failing tests (#2719)
mbarto Mar 8, 2018
55bdb6e
Fix #2668 Increase precision of Query Panel Circle/BBox Details (#2720)
kappu72 Mar 9, 2018
8f3eb98
Allow animation disable to support vertical toolbars (#2693)
offtherailz Mar 12, 2018
ff9646e
fix #2709 only fix for meaure tool reset (#2712)
MV88 Mar 12, 2018
6d3597a
Fixes #2605 Improve iframe on react quill textarea (#2641)
allyoucanmap Mar 12, 2018
d4e5e5b
Fix #2722 add a regex for travis build (#2723)
MV88 Mar 12, 2018
5fe67f5
Fix #2642. Removed entry from counter widget menu (#2729)
amusso01 Mar 12, 2018
67ef847
Merge branch 'master' into align_master_mar12
MV88 Mar 12, 2018
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,5 @@ before_install:
branches:
only:
- master
- /^[cC]\d{3}[\w-]*/
- /^\d{4}\.\d{2}.\d{2}$/
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@
"leaflet.locatecontrol": "0.62.0",
"leaflet.nontiledlayer": "1.0.7",
"lodash": "4.16.6",
"moment": "2.13.0",
"moment": "2.21.0",
"node-geo-distance": "1.2.0",
"object-assign": "4.1.1",
"ogc-schemas": "2.6.1",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,7 @@
<Category>
<name>THUMBNAIL</name>
</Category>
<Category>
<name>DETAILS</name>
</Category>
</CategoryList>
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,7 @@
<Category>
<name>THUMBNAIL</name>
</Category>
<Category>
<name>DETAILS</name>
</Category>
</CategoryList>
33 changes: 18 additions & 15 deletions web/client/api/GeoStoreDAO.js
Original file line number Diff line number Diff line change
Expand Up @@ -162,28 +162,31 @@ const Api = {
}
}, options)));
},
updateResourcePermissions: function(resourceId, securityRules) {
let payload = "<SecurityRuleList>";
for (let rule of securityRules.SecurityRuleList.SecurityRule) {
writeSecurityRules: function(SecurityRuleList = {}) {
return "<SecurityRuleList>" +
(_.castArray(SecurityRuleList.SecurityRule) || []).map( rule => {
if (rule.canRead || rule.canWrite) {
if (rule.user) {
payload = payload + "<SecurityRule>";
payload = payload + "<canRead>" + boolToString(rule.canRead || rule.canWrite) + "</canRead>";
payload = payload + "<canWrite>" + boolToString(rule.canWrite) + "</canWrite>";
payload = payload + "<user><id>" + (rule.user.id || "") + "</id><name>" + (rule.user.name || "") + "</name></user>";
payload = payload + "</SecurityRule>";
return "<SecurityRule>"
+ "<canRead>" + boolToString(rule.canRead || rule.canWrite) + "</canRead>"
+ "<canWrite>" + boolToString(rule.canWrite) + "</canWrite>"
+ "<user><id>" + (rule.user.id || "") + "</id><name>" + (rule.user.name || "") + "</name></user>"
+ "</SecurityRule>";
} else if (rule.group) {
payload = payload + "<SecurityRule>";
payload = payload + "<canRead>" + boolToString(rule.canRead || rule.canWrite) + "</canRead>";
payload = payload + "<canWrite>" + boolToString(rule.canWrite) + "</canWrite>";
payload = payload + "<group><id>" + (rule.group.id || "") + "</id><groupName>" + (rule.group.groupName || "") + "</groupName></group>";
payload = payload + "</SecurityRule>";
return "<SecurityRule>"
+ "<canRead>" + boolToString(rule.canRead || rule.canWrite) + "</canRead>"
+ "<canWrite>" + boolToString(rule.canWrite) + "</canWrite>"
+ "<group><id>" + (rule.group.id || "") + "</id><groupName>" + (rule.group.groupName || "") + "</groupName></group>"
+ "</SecurityRule>";
}
return "";
// NOTE: if rule has no group or user, it is skipped
// NOTE: if rule is "no read and no write", it is skipped
}
}
payload = payload + "</SecurityRuleList>";
}).join('') + "</SecurityRuleList>";
},
updateResourcePermissions: function(resourceId, securityRules) {
const payload = Api.writeSecurityRules(securityRules.SecurityRuleList);
return axios.post(
"resources/resource/" + resourceId + "/permissions",
payload,
Expand Down
61 changes: 60 additions & 1 deletion web/client/api/__tests__/GeoStoreDAO-test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,62 @@

const expect = require('expect');
const API = require('../GeoStoreDAO');
const SAMPLE_RULES = {
"SecurityRuleList": {
"SecurityRule": [
{
"canRead": true,
"canWrite": true,
"user": {
"id": 3,
"name": "admin"
}
},
{
"canRead": true,
"canWrite": true,
"group": {
"groupName": "geosolutions",
"id": 524
}
},
{
"canRead": true,
"canWrite": false,
"group": {
"groupName": "testers",
"id": 3956
}
}
]
}
};
const SAMPLE_XML_RULES = "<SecurityRuleList>"
+ "<SecurityRule>"
+ "<canRead>true</canRead>"
+ "<canWrite>true</canWrite>"
+ "<user>"
+ "<id>3</id>"
+ "<name>admin</name>"
+ "</user>"
+ "</SecurityRule>"
+ "<SecurityRule>"
+ "<canRead>true</canRead>"
+ "<canWrite>true</canWrite>"
+ "<group>"
+ "<id>524</id>"
+ "<groupName>geosolutions</groupName>"
+ "</group>"
+ "</SecurityRule>"
+ "<SecurityRule>"
+ "<canRead>true</canRead>"
+ "<canWrite>false</canWrite>"
+ "<group>"
+ "<id>3956</id>"
+ "<groupName>testers</groupName>"
+ "</group>"
+ "</SecurityRule>"
+ "</SecurityRuleList>";

describe('Test correctness of the GeoStore APIs', () => {

Expand All @@ -34,7 +90,6 @@ describe('Test correctness of the GeoStore APIs', () => {
const user2 = API.utils.initUser(originalUser2);
expect(user2.attribute.length).toBe(2);
});

it('test error parser', () => {
expect(API.errorParser.mapsError({status: 409})).toEqual({
title: 'map.mapError.errorTitle',
Expand All @@ -45,4 +100,8 @@ describe('Test correctness of the GeoStore APIs', () => {
message: 'map.mapError.errorDefault'
});
});
it('test security rules utils (writeSecurityRules)', () => {
const payload = API.writeSecurityRules(SAMPLE_RULES.SecurityRuleList);
expect(payload).toBe(SAMPLE_XML_RULES);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,13 @@ const ReactQuill = require('react-quill');
const ResizableModal = require('../../../misc/ResizableModal');
const Portal = require('../../../misc/Portal');
const Message = require('../../../I18N/Message');
const {Quill} = ReactQuill;
const {ResizeModule, IFrame, toolbarConfig} = require('../../../misc/quillmodules/ResizeModule')(Quill);

Quill.register({
'formats/video': IFrame,
'modules/resizeModule': ResizeModule
});

/**
* Component for rendering FeatureInfoEditor a modal editor to modify format template
Expand All @@ -21,9 +28,10 @@ const Message = require('../../../I18N/Message');
* @prop {bool} showEditor show/hide modal
* @prop {funciotn} onShowEditor called when click on close buttons
* @prop {function} onChange called when text in editor has been changed
* @prop {bool} enableIFrameModule enable iframe in editor, default true
*/

module.exports = ({onShowEditor = () => {}, showEditor, element = {}, onChange = () => {}}) =>(
module.exports = ({onShowEditor = () => {}, showEditor, element = {}, onChange = () => {}, enableIFrameModule = true}) =>(
<Portal>
<ResizableModal
fade
Expand All @@ -43,6 +51,10 @@ module.exports = ({onShowEditor = () => {}, showEditor, element = {}, onChange =
<div id="ms-template-editor" className="ms-editor">
<ReactQuill
bounds="#ms-template-editor"
modules={enableIFrameModule ? {
resizeModule: {},
toolbar: toolbarConfig
} : {}}
defaultValue={element.featureInfo && element.featureInfo.template || ' '}
onChange={template => {
onChange('featureInfo', {
Expand Down
67 changes: 38 additions & 29 deletions web/client/components/data/query/GeometryDetails.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,16 @@ const assign = require('object-assign');

const CoordinatesUtils = require("../../../utils/CoordinatesUtils");


class GeometryDetails extends React.Component {
static propTypes = {
useMapProjection: PropTypes.bool,
geometry: PropTypes.object,
type: PropTypes.string,
onShowPanel: PropTypes.func,
onChangeDrawingStatus: PropTypes.func,
onEndDrawing: PropTypes.func
onEndDrawing: PropTypes.func,
zoom: PropTypes.number
};

static defaultProps = {
Expand Down Expand Up @@ -101,7 +103,6 @@ class GeometryDetails extends React.Component {

onModifyGeometry = () => {
let geometry;

// Update the geometry
if (this.props.type === "BBOX") {
this.extent = this.tempExtent;
Expand Down Expand Up @@ -168,28 +169,27 @@ class GeometryDetails extends React.Component {
};

onClosePanel = () => {
if (this.props.type === "BBOX") {
this.resetBBOX();
} else if (this.props.type === "Circle") {
this.resetCircle();
}

this.resetGeom();
this.props.onShowPanel(false);
};

getStep = (zoom = 1) => Math.min(1 / Math.pow(10, Math.ceil(Math.min(zoom, 21) / 3) - 2), 1);
getStepCircle = (zoom, name) => {
const step = this.getStep(zoom);
return name === 'radius' && step * 10000 || step;
};
getBBOXDimensions = (geometry) => {
const extent = geometry.projection !== 'EPSG:4326' && !this.props.useMapProjection ?
CoordinatesUtils.reprojectBbox(geometry.extent, geometry.projection, 'EPSG:4326') : geometry.extent;

return {
// minx
west: Math.round(extent[0] * 100) / 100,
west: extent[0],
// miny
sud: Math.round(extent[1] * 100) / 100,
sud: extent[1],
// maxx
est: Math.round(extent[2] * 100) / 100,
est: extent[2],
// maxy
north: Math.round(extent[3] * 100) / 100
north: extent[3]
};
};
getCircleDimensions = (geometry) => {
Expand All @@ -201,9 +201,9 @@ class GeometryDetails extends React.Component {
center = (center.x === undefined) ? {x: center[0], y: center[1]} : center;

return {
x: Math.round(center.x * 100) / 100,
y: Math.round(center.y * 100) / 100,
radius: Math.round(geometry.radius * 100) / 100
x: center.x,
y: center.y,
radius: geometry.radius
};
};
renderCoordinateField = (value, name) => {
Expand All @@ -214,18 +214,19 @@ class GeometryDetails extends React.Component {
style={{minWidth: '105px', margin: 'auto'}}
type="number"
id={"queryform_bbox_" + name}
defaultValue={value}
step={!this.isWGS84() ? 1 : this.getStep(this.props.zoom)}
defaultValue={this.roundValue(value, !this.isWGS84() ? 100 : 1000000)}
onChange={(evt) => this.onUpdateBBOX(evt.target.value, name)}/>
</div>
);
};

renderCircleField = (value, name) => {
return (
<FormControl
type="number"
id={"queryform_circle_" + name}
defaultValue={value}
defaultValue={this.roundValue(value, !this.isWGS84() || name === 'radius' ? 100 : 1000000)}
step={!this.isWGS84() ? 1 : this.getStepCircle(this.props.zoom, name)}
onChange={(evt) => this.onUpdateCircle(evt.target.value, name)}/>
);
};
Expand Down Expand Up @@ -352,7 +353,7 @@ class GeometryDetails extends React.Component {
key: 'reset',
tooltipId: 'queryform.reset',
glyph: 'clear-filter',
onClick: () => this.resetBBOX()
onClick: () => this.resetGeom()
}, {
key: 'close',
glyph: '1-close',
Expand All @@ -362,29 +363,37 @@ class GeometryDetails extends React.Component {
</SwitchPanel>
);
}

isWGS84 = () => (this.props.geometry || {}).projection === 'EPSG:4326' || !this.props.useMapProjection;
roundValue = (val, prec = 1000000) => Math.round(val * prec) / prec;
resetGeom = () => {
if (this.props.type === "BBOX") {
this.resetBBOX();
} else if (this.props.type === "Circle") {
this.resetCircle();
}
};
resetBBOX = () => {
for (let prop in this.extent) {
if (prop) {
let coordinateInput = document.getElementById("queryform_bbox_" + prop);
coordinateInput.value = this.extent[prop];
this.onUpdateBBOX(coordinateInput.value, prop);
coordinateInput.value = this.roundValue(this.extent[prop], !this.isWGS84() ? 100 : 1000000);
this.onUpdateBBOX(this.extent[prop], prop);
}
}
};

resetCircle = () => {
let radiusInput = document.getElementById("queryform_circle_radius");
radiusInput.value = this.circle.radius;
this.onUpdateCircle(radiusInput.value, "radius");
radiusInput.value = this.roundValue(this.circle.radius, 100);
this.onUpdateCircle(this.circle.radius, "radius");

let coordinateXInput = document.getElementById("queryform_circle_x");
coordinateXInput.value = this.circle.x;
this.onUpdateCircle(coordinateXInput.value, "x");
coordinateXInput.value = this.roundValue(this.circle.x, !this.isWGS84() ? 100 : 1000000);
this.onUpdateCircle(this.circle.x, "x");

let coordinateYInput = document.getElementById("queryform_circle_y");
coordinateYInput.value = this.circle.y;
this.onUpdateCircle(coordinateYInput.value, "y");
coordinateYInput.value = this.roundValue(this.circle.y, !this.isWGS84() ? 100 : 1000000);
this.onUpdateCircle(this.circle.y, "y");
};
}

Expand Down
6 changes: 4 additions & 2 deletions web/client/components/data/query/QueryBuilder.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,8 @@ class QueryBuilder extends React.Component {
allowEmptyFilter: PropTypes.bool,
autocompleteEnabled: PropTypes.bool,
emptyFilterWarning: PropTypes.bool,
header: PropTypes.node
header: PropTypes.node,
zoom: PropTypes.number
};

static defaultProps = {
Expand Down Expand Up @@ -180,7 +181,8 @@ class QueryBuilder extends React.Component {
spatialMethodOptions={this.props.spatialMethodOptions}
spatialPanelExpanded={this.props.spatialPanelExpanded}
showDetailsPanel={this.props.showDetailsPanel}
actions={this.props.spatialFilterActions}/>
actions={this.props.spatialFilterActions}
zoom={this.props.zoom}/>
<CrossLayerFilter
spatialOperations={this.props.spatialOperations}
crossLayerExpanded={this.props.crossLayerExpanded}
Expand Down
Loading