Skip to content

Commit

Permalink
Fix geosolutions-it#9575 Avoid full rerender in filterRenderer
Browse files Browse the repository at this point in the history
  • Loading branch information
offtherailz committed Oct 10, 2023
1 parent 9eab5e3 commit c0f29f7
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 4 deletions.
13 changes: 12 additions & 1 deletion web/client/plugins/featuregrid/FeatureEditor.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,15 @@ import {gridTools, gridEvents, pageEvents, toolbarEvents} from './index';
const EMPTY_ARR = [];
const EMPTY_OBJ = {};

/**
* Custom check for filterRenderers useMemo function
* @param {object} prevProps previous props
* @param {object} nextProps next props
* @returns {boolean}
*/
export const checkFilterRendererProps = (prevProps, nextProps) => {
return isEqual(prevProps.describe, nextProps.describe) && isEqual(prevProps.fields, nextProps.fields);
};

const Dock = connect(createSelector(
getDockSize,
Expand Down Expand Up @@ -187,7 +196,9 @@ const FeatureDock = (props = {
};
const items = props?.items ?? [];
const toolbarItems = items.filter(({target}) => target === 'toolbar');
const filterRenderers = useMemo(() => getFilterRenderers(props.describe, props.fields), [props.describe, props.fields]);
// ensure to avoid re-rendering of the feature grid (lost focus on every render) in any case if for some
// reason the describeFeatureType or fields are generated but equal.
const filterRenderers = useMemo(() => getFilterRenderers(props.describe, props.fields), checkFilterRendererProps);
return (
<div className={"feature-grid-wrapper"}>
<Dock {...dockProps} onSizeChange={size => { props.onSizeChange(size, dockProps); }}>
Expand Down
21 changes: 20 additions & 1 deletion web/client/plugins/featuregrid/__tests__/FeatureEditor-test.jsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@

import expect from 'expect';
import {selector } from '../FeatureEditor';
import {selector, checkFilterRendererProps } from '../FeatureEditor';


describe('FeatureEditor plugin component', () => {
Expand Down Expand Up @@ -104,6 +104,25 @@ describe('FeatureEditor plugin component', () => {
expect(result.fields).toEqual(FIELDS);
});
});
describe('utility functions', () => {
it('checkFilterRendererProps', () => {
// check if the function returns true if the props are the same
expect(checkFilterRendererProps({
describe: {},
fields: []
}, {
describe: {},
fields: []
})).toBe(true);
expect(checkFilterRendererProps({
describe: {},
fields: []
}, {
describe: {},
fields: [{name: 'name', type: 'string'}]
})).toBe(false);
});
});
});


14 changes: 14 additions & 0 deletions web/client/selectors/__tests__/featuregrid-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -671,6 +671,20 @@ describe('Test featuregrid selectors', () => {
}
};
expect(selectedLayerFieldsSelector(state)).toEqual([FIELD]);
// check that fields are memoized when applying defaults
const stateEmptyFields = {
featuregrid: {
selectedLayer: 'TEST_LAYER'
},
layers: {
flat: [{
id: "TEST_LAYER",
title: "Test Layer",
name: 'editing:polygons.test'
}]
}
};
expect(selectedLayerFieldsSelector(stateEmptyFields)).toBe(selectedLayerFieldsSelector(stateEmptyFields));
});
it('editingAllowedGroupsSelector', () => {
const editingAllowedGroups = ['test'];
Expand Down
4 changes: 2 additions & 2 deletions web/client/selectors/featuregrid.js
Original file line number Diff line number Diff line change
Expand Up @@ -112,15 +112,15 @@ export const getTitleSelector = state => {
const title = getTitle(getLayerById(state, selectedLayerIdSelector(state)));
return isObject(title) ? title[currentLocaleSelector(state)] || title.default || '' : title;
};

const STANDARD_FIELDS = [];
/**
* Returns the current selected layer (featuregrid) fields, if any.
* @param {*} state
* @returns {object} the current selected layer fields, if any
*/
export const selectedLayerFieldsSelector = state => {
const layer = getLayerById(state, selectedLayerIdSelector(state));
const fields = get(layer, "fields", []);
const fields = get(layer, "fields", STANDARD_FIELDS);
return fields;
};
export const getCustomizedAttributes = state => {
Expand Down

0 comments on commit c0f29f7

Please sign in to comment.