Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
8 changes: 8 additions & 0 deletions web/client/actions/featuregrid.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ export const LOAD_MORE_FEATURES = "LOAD_MORE_FEATURES";
export const GRID_QUERY_RESULT = 'FEATUREGRID:QUERY_RESULT';
export const SET_TIME_SYNC = "FEATUREGRID:SET_TIME_SYNC";
export const SET_PAGINATION = "FEATUREGRID:SET_PAGINATION";
export const GRID_ROW_UPDATE = "FEATUREGRID:GRID_ROW_UPDATE";

export function toggleShowAgain() {
return {
Expand Down Expand Up @@ -262,6 +263,13 @@ export function featureModified(features, updated) {
updated
};
}
export function gridRowUpdate(features, updated) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • add jsdoc
  • this needs a unit test

return {
type: GRID_ROW_UPDATE,
features,
updated
};
}
export function createNewFeatures(features) {
return {
type: CREATE_NEW_FEATURE,
Expand Down
5 changes: 3 additions & 2 deletions web/client/components/TOC/fragments/LayerFields/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -59,12 +59,13 @@ const LayerFields = ({ layer, updateFields = () => {}, ...props }) => {
};
}, []);

const onChange = (name, attribute, value) => {
const onChange = (name, attribute, value, isGeometryType = false) => {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

where this 4th parameter being used?

const newFields = fields.map((field) => {
if (field.name === name) {
return {
...field,
[attribute]: value
[attribute]: value,
...(isGeometryType ? {isGeometry: true} : {})
};
}
return field;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ class AutocompleteEditor extends AttributeEditor {
autocompleteStreamFactory: PropTypes.func,
url: PropTypes.string,
typeName: PropTypes.string,
value: PropTypes.string
value: PropTypes.string,
disabled: PropTypes.bool
};
static defaultProps = {
isValid: () => true,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ class DateTimeEditor extends AttributeEditor {
calendar: PropTypes.bool,
time: PropTypes.bool,
onChange: PropTypes.func,
onBlur: PropTypes.func
onBlur: PropTypes.func,
disabled: PropTypes.bool
};

static contextTypes = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ class DropDownEditor extends AttributeEditor {
filter: PropTypes.string,
values: PropTypes.array,
labels: PropTypes.array,
emptyValue: PropTypes.string
emptyValue: PropTypes.string,
disabled: PropTypes.bool
};
static defaultProps = {
isValid: () => true,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ export default class FormatEditor extends React.Component {
dataType: PropTypes.string,
column: PropTypes.object,
formatRegex: PropTypes.string,
onTemporaryChanges: PropTypes.func
onTemporaryChanges: PropTypes.func,
disabled: PropTypes.bool
};

static defaultProps = {
Expand Down Expand Up @@ -61,6 +62,7 @@ export default class FormatEditor extends React.Component {
render() {
return (<input
{...this.props.inputProps}
disabled={this.props?.disabled}
style={!this.state.validated || this.state.isValid ? {} : {
borderColor: 'red'
}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ export default class NumberEditor extends React.Component {
minValue: PropTypes.number,
maxValue: PropTypes.number,
column: PropTypes.object,
onTemporaryChanges: PropTypes.func
onTemporaryChanges: PropTypes.func,
disabled: PropTypes.bool
};

static defaultProps = {
Expand Down Expand Up @@ -80,6 +81,7 @@ export default class NumberEditor extends React.Component {
render() {
return (<IntlNumberFormControl
{...this.props.inputProps}
disabled={this.props?.disabled}
style={!this.state.validated || this.state.isValid ? {} : {
borderColor: 'red'
}}
Expand Down
8 changes: 5 additions & 3 deletions web/client/components/data/featuregrid/enhancers/editor.js
Original file line number Diff line number Diff line change
Expand Up @@ -154,12 +154,13 @@ const featuresToGrid = compose(
options: props.options?.propertyName
}, {
getHeaderRenderer,
getEditor: (desc) => {
getEditor: (desc, field) => {
const generalProps = {
onTemporaryChanges: props.gridEvents && props.gridEvents.onTemporaryChanges,
autocompleteEnabled: props.autocompleteEnabled,
url: props.url,
typeName: props.typeName
typeName: props.typeName,
disabled: field && field?.editable === false
};
const regexProps = {attribute: desc.name, url: props.url, typeName: props.typeName};
const rules = props.customEditorsOptions && props.customEditorsOptions.rules || [];
Expand All @@ -169,7 +170,8 @@ const featuresToGrid = compose(
if (!isNil(editor)) {
return editor;
}
return props.editors(desc.localType, generalProps);
const typeEditor = props.editors(desc.localType, generalProps);
return typeEditor;
},
getFilterRenderer: getFilterRendererFunc,
getFormatter: (desc) => getFormatter(desc, (props.fields ?? []).find(f => f.name === desc.name)),
Expand Down
17 changes: 9 additions & 8 deletions web/client/components/data/featuregrid/toolbars/Toolbar.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -61,20 +61,20 @@ const standardButtons = {
visible={mode === "EDIT" && !hasChanges && !hasNewFeatures}
onClick={events.switchViewMode}
glyph="arrow-left"/>),
addFeature: ({disabled, mode, hasNewFeatures, hasChanges, hasSupportedGeometry = true, events = {}}) => (<TButton
addFeature: ({disabled, mode, hasNewFeatures, hasChanges, canEditGeometry, hasSupportedGeometry = true, events = {}}) => (<TButton
id="add-feature"
keyProp="add-feature"
tooltipId="featuregrid.toolbar.addNewFeatures"
disabled={disabled}
visible={mode === "EDIT" && !hasNewFeatures && !hasChanges && hasSupportedGeometry}
visible={mode === "EDIT" && canEditGeometry && !hasNewFeatures && !hasChanges && hasSupportedGeometry}
onClick={events.createFeature}
glyph="row-add"/>),
drawFeature: ({isDrawing = false, disabled, isSimpleGeom, mode, selectedCount, hasGeometry, hasSupportedGeometry = true, events = {}}) => (<TButton
drawFeature: ({isDrawing = false, disabled, isSimpleGeom, mode, selectedCount, canEditGeometry, hasGeometry, hasSupportedGeometry = true, events = {}}) => (<TButton
id="draw-feature"
keyProp="draw-feature"
tooltipId={getDrawFeatureTooltip(isDrawing, isSimpleGeom)}
disabled={disabled}
visible={mode === "EDIT" && selectedCount === 1 && (!hasGeometry || hasGeometry && !isSimpleGeom) && hasSupportedGeometry}
visible={mode === "EDIT" && selectedCount === 1 && canEditGeometry && (!hasGeometry || hasGeometry && !isSimpleGeom) && hasSupportedGeometry}
onClick={events.startDrawingFeature}
active={isDrawing}
glyph="pencil-add"/>),
Expand Down Expand Up @@ -103,12 +103,12 @@ const standardButtons = {
visible={mode === "EDIT" && hasChanges || hasNewFeatures}
onClick={events.clearFeatureEditing}
glyph="remove-square"/>),
deleteGeometry: ({disabled, mode, hasGeometry, selectedCount, hasSupportedGeometry = true, events = {}}) => (<TButton
deleteGeometry: ({disabled, mode, hasGeometry, selectedCount, canEditGeometry, hasSupportedGeometry = true, events = {}}) => (<TButton
id="delete-geometry"
keyProp="delete-geometry"
tooltipId="featuregrid.toolbar.deleteGeometry"
disabled={disabled}
visible={mode === "EDIT" && hasGeometry && selectedCount === 1 && hasSupportedGeometry}
visible={mode === "EDIT" && hasGeometry && selectedCount === 1 && hasSupportedGeometry && canEditGeometry}
onClick={events.deleteGeometry}
glyph="polygon-trash"/>),
gridSettings: ({disabled, isColumnsOpen, selectedCount, mode, events = {}}) => (<TButton
Expand Down Expand Up @@ -170,11 +170,11 @@ const standardButtons = {
active={timeSync}
onClick={() => events.setTimeSync && events.setTimeSync(!timeSync)}
glyph="time" />),
snapToFeature: ({snapping, availableSnappingLayers = [], isSnappingLoading, snappingConfig, mode, mapType, editorHeight, pluginCfg, events = {}}) => (<TSplitButton
snapToFeature: ({snapping, availableSnappingLayers = [], canEditGeometry, isSnappingLoading, snappingConfig, mode, mapType, editorHeight, pluginCfg, events = {}}) => (<TSplitButton
id="snap-button"
keyProp="snap-button"
tooltipId={snapping ? "featuregrid.toolbar.disableSnapping" : "featuregrid.toolbar.enableSnapping"}
visible={mode === "EDIT" && (pluginCfg?.snapTool ?? true) && mapType === MapLibraries.OPENLAYERS}
visible={mode === "EDIT" && (pluginCfg?.snapTool ?? true) && mapType === MapLibraries.OPENLAYERS && canEditGeometry}
onClick={() => {
events.toggleSnapping && events.toggleSnapping(!snapping);
}}
Expand Down Expand Up @@ -317,6 +317,7 @@ export default React.memo((props = {}) => {
setShowPopoverSync(getApi().getItem("showPopoverSync") !== null && pluginCfg?.showPopoverSync ? getApi().getItem("showPopoverSync") === "true" : pluginCfg?.showPopoverSync);
}
}, [props.mode]);
// const canEditGeometry = props.isEditingAllowed &&
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove comments

Suggested change
// const canEditGeometry = props.isEditingAllowed &&

return (<ButtonGroup id="featuregrid-toolbar" className="featuregrid-toolbar featuregrid-toolbar-margin">

{sortBy(buttons.concat(toolbarItems), ["position"]).map(({Component}) => <Component {...props} showPopoverSync={showPopover} hideSyncPopover={() => setShowPopoverSync(false)} mode={props?.mode ?? "VIEW"} disabled={props.disableToolbar} />)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -149,16 +149,21 @@ describe('Featuregrid toolbar component', () => {
createFeature: () => {}
};
spyOn(events, "createFeature");
ReactDOM.render(<Toolbar events={events} mode="VIEW" isEditingAllowed/>, document.getElementById("container"));
ReactDOM.render(<Toolbar events={events} mode="VIEW" isEditingAllowed canEditGeometry/>, document.getElementById("container"));
const el = document.getElementsByClassName("featuregrid-toolbar")[0];
expect(el).toExist();
let addButton = document.getElementById("fg-add-feature");
expect(isVisibleButton(addButton)).toBe(false);
addButton.click();
expect(events.createFeature).toHaveBeenCalled();
ReactDOM.render(<Toolbar events={events} mode="EDIT" isEditingAllowed/>, document.getElementById("container"));
ReactDOM.render(<Toolbar events={events} mode="EDIT" isEditingAllowed canEditGeometry/>, document.getElementById("container"));
addButton = document.getElementById("fg-add-feature");
ReactDOM.render(<Toolbar events={events} mode="EDIT" canEditGeometry/>, document.getElementById("container"));
addButton = document.getElementById("fg-add-feature");
expect(isVisibleButton(addButton)).toBe(true);
ReactDOM.render(<Toolbar events={events} mode="EDIT" isEditingAllowed canEditGeometry={false}/>, document.getElementById("container"));
addButton = document.getElementById("fg-add-feature");
expect(isVisibleButton(addButton)).toBe(false);
ReactDOM.render(<Toolbar events={events} mode="EDIT" hasChanges/>, document.getElementById("container"));
addButton = document.getElementById("fg-add-feature");
expect(isVisibleButton(addButton)).toBe(false);
Expand All @@ -172,26 +177,29 @@ describe('Featuregrid toolbar component', () => {
startDrawingFeature: () => {}
};
spyOn(events, "startDrawingFeature");
ReactDOM.render(<Toolbar events={events} mode="VIEW" isEditingAllowed/>, document.getElementById("container"));
ReactDOM.render(<Toolbar events={events} mode="VIEW" isEditingAllowed canEditGeometry/>, document.getElementById("container"));
const el = document.getElementsByClassName("featuregrid-toolbar")[0];
expect(el).toExist();
let button = document.getElementById("fg-draw-feature");
expect(isVisibleButton(button)).toBe(false);
button.click();
expect(events.startDrawingFeature).toHaveBeenCalled();
ReactDOM.render(<Toolbar events={events} mode="EDIT" selectedCount={1} hasGeometry isSimpleGeom={false} />, document.getElementById("container"));
ReactDOM.render(<Toolbar events={events} mode="EDIT" canEditGeometry selectedCount={1} hasGeometry isSimpleGeom={false} />, document.getElementById("container"));
button = document.getElementById("fg-draw-feature");
expect(isVisibleButton(button)).toBe(true);
ReactDOM.render(<Toolbar events={events} mode="EDIT" selectedCount={1} hasGeometry isSimpleGeom />, document.getElementById("container"));
ReactDOM.render(<Toolbar events={events} mode="EDIT" isEditingAllowed canEditGeometry={false} selectedCount={1} hasGeometry isSimpleGeom={false} />, document.getElementById("container"));
button = document.getElementById("fg-draw-feature");
expect(isVisibleButton(button)).toBe(false);
ReactDOM.render(<Toolbar events={events} mode="EDIT" selectedCount={1} hasGeometry={false} />, document.getElementById("container"));
ReactDOM.render(<Toolbar events={events} mode="EDIT" canEditGeometry selectedCount={1} hasGeometry isSimpleGeom />, document.getElementById("container"));
button = document.getElementById("fg-draw-feature");
expect(isVisibleButton(button)).toBe(false);
ReactDOM.render(<Toolbar events={events} mode="EDIT" canEditGeometry selectedCount={1} hasGeometry={false} />, document.getElementById("container"));
button = document.getElementById("fg-draw-feature");
expect(isVisibleButton(button)).toBe(true);
ReactDOM.render(<Toolbar events={events} mode="EDIT" selectedCount={1} hasGeometry={false} isSimpleGeom={false} isDrawing/>, document.getElementById("container"));
ReactDOM.render(<Toolbar events={events} mode="EDIT" canEditGeometry selectedCount={1} hasGeometry={false} isSimpleGeom={false} isDrawing/>, document.getElementById("container"));
button = document.getElementById("fg-draw-feature");
expect(isVisibleButton(button)).toBe(true);
ReactDOM.render(<Toolbar events={events} mode="EDIT" selectedCount={2}/>, document.getElementById("container"));
ReactDOM.render(<Toolbar events={events} mode="EDIT" canEditGeometry selectedCount={2}/>, document.getElementById("container"));
button = document.getElementById("fg-draw-feature");
expect(isVisibleButton(button)).toBe(false);
});
Expand Down Expand Up @@ -257,16 +265,19 @@ describe('Featuregrid toolbar component', () => {
expect(isVisibleButton(button)).toBe(false);
button.click();
expect(events.deleteGeometry).toHaveBeenCalled();
ReactDOM.render(<Toolbar events={events} mode="EDIT" selectedCount={1} />, document.getElementById("container"));
ReactDOM.render(<Toolbar events={events} mode="EDIT" canEditGeometry selectedCount={1} />, document.getElementById("container"));
button = document.getElementById("fg-delete-geometry");
expect(isVisibleButton(button)).toBe(false);
ReactDOM.render(<Toolbar events={events} mode="EDIT" selectedCount={1} hasGeometry />, document.getElementById("container"));
ReactDOM.render(<Toolbar events={events} mode="EDIT" canEditGeometry={false} selectedCount={1} hasGeometry />, document.getElementById("container"));
button = document.getElementById("fg-delete-geometry");
expect(isVisibleButton(button)).toBe(false);
ReactDOM.render(<Toolbar events={events} mode="EDIT" canEditGeometry selectedCount={1} hasGeometry />, document.getElementById("container"));
button = document.getElementById("fg-delete-geometry");
expect(isVisibleButton(button)).toBe(true);
ReactDOM.render(<Toolbar events={events} mode="VIEW" selectedCount={1} hasGeometry />, document.getElementById("container"));
ReactDOM.render(<Toolbar events={events} mode="VIEW" canEditGeometry ={1} hasGeometry />, document.getElementById("container"));
button = document.getElementById("fg-delete-geometry");
expect(isVisibleButton(button)).toBe(false);
ReactDOM.render(<Toolbar events={events} mode="EDIT" selectedCount={2} hasGeometry/>, document.getElementById("container"));
ReactDOM.render(<Toolbar events={events} mode="EDIT" canEditGeometry selectedCount={2} hasGeometry/>, document.getElementById("container"));
button = document.getElementById("fg-delete-geometry");
expect(isVisibleButton(button)).toBe(false);
});
Expand Down Expand Up @@ -390,26 +401,26 @@ describe('Featuregrid toolbar component', () => {
});
describe('snap tool button', () => {
it('visibility', () => {
ReactDOM.render(<Toolbar mapType="openlayers" pluginCfg={{ snapTool: true }} mode="EDIT" disableZoomAll />, document.getElementById("container"));
ReactDOM.render(<Toolbar mapType="openlayers" pluginCfg={{ snapTool: true }} canEditGeometry mode="EDIT" disableZoomAll />, document.getElementById("container"));
expect(document.getElementById("snap-button")).toExist();
ReactDOM.render(<Toolbar mode="VIEW" disableZoomAll />, document.getElementById("container"));
ReactDOM.render(<Toolbar mode="VIEW" canEditGeometry disableZoomAll />, document.getElementById("container"));
expect(document.getElementById("snap-button")).toNotExist();
});
it('active/inactive state', () => {
ReactDOM.render(<Toolbar mapType="openlayers" snapping pluginCfg={{ snapTool: true }} mode="EDIT" disableZoomAll />, document.getElementById("container"));
ReactDOM.render(<Toolbar mapType="openlayers" snapping pluginCfg={{ snapTool: true }} canEditGeometry mode="EDIT" disableZoomAll />, document.getElementById("container"));
expect(document.getElementById("snap-button").className.split(' ')).toInclude('btn-success');
ReactDOM.render(<Toolbar mapType="openlayers" pluginCfg={{ snapTool: true }} mode="EDIT" disableZoomAll />, document.getElementById("container"));
ReactDOM.render(<Toolbar mapType="openlayers" pluginCfg={{ snapTool: true }} mode="EDIT" canEditGeometry disableZoomAll />, document.getElementById("container"));
expect(document.getElementById("snap-button").className.split(' ')).toNotInclude('btn-success');
});
it('handler', () => {
const events = {
toggleSnapping: () => { }
};
const spy = spyOn(events, "toggleSnapping");
ReactDOM.render(<Toolbar mapType="openlayers" events={events} snapping pluginCfg={{ snapTool: true }} mode="EDIT" disableZoomAll />, document.getElementById("container"));
ReactDOM.render(<Toolbar mapType="openlayers" canEditGeometry events={events} snapping pluginCfg={{ snapTool: true }} mode="EDIT" disableZoomAll />, document.getElementById("container"));
document.getElementById("snap-button").click();
expect(spy.calls[0].arguments[0]).toBe(false);
ReactDOM.render(<Toolbar mapType="openlayers" events={events} pluginCfg={{ snapTool: true }} mode="EDIT" disableZoomAll />, document.getElementById("container"));
ReactDOM.render(<Toolbar mapType="openlayers" canEditGeometry events={events} pluginCfg={{ snapTool: true }} mode="EDIT" disableZoomAll />, document.getElementById("container"));
document.getElementById("snap-button").click();
expect(spy.calls[1].arguments[0]).toBe(true);
});
Expand Down
Loading