From c4f94e3b7bfd22eaf94e22aebf6d9f1b09a61b6f Mon Sep 17 00:00:00 2001 From: Suren Date: Wed, 2 Aug 2023 17:47:12 +0530 Subject: [PATCH] #9314: Fix - Enhance show/hide attribute edit option on Layer (#9317) --- .../TOC/fragments/settings/General.jsx | 9 +---- .../settings/__tests__/General-test.jsx | 12 +++--- web/client/plugins/TOCItemsSettings.jsx | 8 ++-- .../__tests__/TOCItemsSettings-test.jsx | 2 +- web/client/selectors/__tests__/map-test.js | 37 ++++++++++++++++++- web/client/selectors/map.js | 20 ++++++++++ 6 files changed, 69 insertions(+), 19 deletions(-) diff --git a/web/client/components/TOC/fragments/settings/General.jsx b/web/client/components/TOC/fragments/settings/General.jsx index d03a8aad35..48c74197e8 100644 --- a/web/client/components/TOC/fragments/settings/General.jsx +++ b/web/client/components/TOC/fragments/settings/General.jsx @@ -41,7 +41,7 @@ class General extends React.Component { allowNew: PropTypes.bool, enableLayerNameEditFeedback: PropTypes.bool, currentLocale: PropTypes.string, - mapInfo: PropTypes.object + showFeatureEditOption: PropTypes.bool }; static contextTypes = { @@ -167,7 +167,7 @@ class General extends React.Component { } - {supportsFeatureEditing(this.props.element) && this.canEditFeature() && + {supportsFeatureEditing(this.props.element) && this.props.showFeatureEditOption && isObject(key) ? this.props.onChange(key) : this.props.onChange(key, event.target.value); updateTitle = (title) => this.props.onChange("title", title); - canEditFeature = () => { - const {id, canEdit} = this.props.mapInfo ?? {}; - return id ? canEdit : true; - } - findGroupLabel = () => { const wholeGroups = this.props.groups && flattenGroups(this.props.groups, 0, true); const eleGroupName = this.props.element && this.props.element.group || "Default"; diff --git a/web/client/components/TOC/fragments/settings/__tests__/General-test.jsx b/web/client/components/TOC/fragments/settings/__tests__/General-test.jsx index 85a5acdf96..52c55b1f47 100644 --- a/web/client/components/TOC/fragments/settings/__tests__/General-test.jsx +++ b/web/client/components/TOC/fragments/settings/__tests__/General-test.jsx @@ -65,7 +65,7 @@ describe('test Layer Properties General module component', () => { expect(comp).toExist(); const inputs = ReactTestUtils.scryRenderedDOMComponentsWithTag( comp, "input" ); expect(inputs).toExist(); - expect(inputs.length).toBe(6); + expect(inputs.length).toBe(5); }); it('tests Layer Properties Display component events', () => { const l = { @@ -89,7 +89,7 @@ describe('test Layer Properties General module component', () => { expect(comp).toExist(); const inputs = ReactTestUtils.scryRenderedDOMComponentsWithTag( comp, "input" ); expect(inputs).toExist(); - expect(inputs.length).toBe(6); + expect(inputs.length).toBe(5); ReactTestUtils.Simulate.change(inputs[0]); ReactTestUtils.Simulate.blur(inputs[1]); expect(spy.calls.length).toBe(1); @@ -118,7 +118,7 @@ describe('test Layer Properties General module component', () => { expect(comp).toExist(); const forms = ReactTestUtils.scryRenderedDOMComponentsWithClass( comp, "form-group" ); expect(forms).toExist(); - expect(forms.length).toBe(5); + expect(forms.length).toBe(4); }); it('TEST showTooltipOptions = true', () => { @@ -233,7 +233,7 @@ describe('test Layer Properties General module component', () => { type: 'wms', url: 'fakeurl' }; - const comp = ReactDOM.render(, document.getElementById("container")); + const comp = ReactDOM.render(, document.getElementById("container")); expect(comp).toBeTruthy(); const disableFeaturesEditing = document.querySelector('[data-qa="general-read-only-attribute"]'); ReactTestUtils.Simulate.change(disableFeaturesEditing, { "target": { "checked": true }}); @@ -249,7 +249,7 @@ describe('test Layer Properties General module component', () => { type: 'wms', url: 'fakeurl' }; - const comp = ReactDOM.render(, document.getElementById("container")); + const comp = ReactDOM.render(, document.getElementById("container")); expect(comp).toBeTruthy(); const disableFeaturesEditing = document.querySelector('[data-qa="general-read-only-attribute"]'); expect(disableFeaturesEditing).toBeTruthy(); @@ -264,7 +264,7 @@ describe('test Layer Properties General module component', () => { url: 'fakeurl' }; const mapInfo = {canEdit: false, id: "1"}; - const comp = ReactDOM.render(, document.getElementById("container")); + const comp = ReactDOM.render(, document.getElementById("container")); expect(comp).toBeTruthy(); const disableFeaturesEditing = document.querySelector('[data-qa="general-read-only-attribute"]'); expect(disableFeaturesEditing).toBeFalsy(); diff --git a/web/client/plugins/TOCItemsSettings.jsx b/web/client/plugins/TOCItemsSettings.jsx index d329c34c0c..041a969773 100644 --- a/web/client/plugins/TOCItemsSettings.jsx +++ b/web/client/plugins/TOCItemsSettings.jsx @@ -29,7 +29,7 @@ import { import { createPlugin } from '../utils/PluginsUtils'; import defaultSettingsTabs from './tocitemssettings/defaultSettingsTabs'; import { isCesium } from '../selectors/maptype'; -import { mapInfoSelector } from "../selectors/map"; +import { showEditableFeatureCheckboxSelector } from "../selectors/map"; const tocItemsSettingsSelector = createSelector([ layerSettingSelector, @@ -42,8 +42,8 @@ const tocItemsSettingsSelector = createSelector([ elementSelector, isLocalizedLayerStylesEnabledSelector, isCesium, - mapInfoSelector -], (settings, groups, currentLocale, currentLocaleLanguage, dockStyle, isAdmin, activeTab, element, isLocalizedLayerStylesEnabled, isCesiumActive, mapInfo) => ({ + showEditableFeatureCheckboxSelector +], (settings, groups, currentLocale, currentLocaleLanguage, dockStyle, isAdmin, activeTab, element, isLocalizedLayerStylesEnabled, isCesiumActive, showFeatureEditOption) => ({ settings, element, groups, @@ -54,7 +54,7 @@ const tocItemsSettingsSelector = createSelector([ activeTab, isLocalizedLayerStylesEnabled, isCesiumActive, - mapInfo + showFeatureEditOption })); /** diff --git a/web/client/plugins/__tests__/TOCItemsSettings-test.jsx b/web/client/plugins/__tests__/TOCItemsSettings-test.jsx index ba67f680ea..357f3dac65 100644 --- a/web/client/plugins/__tests__/TOCItemsSettings-test.jsx +++ b/web/client/plugins/__tests__/TOCItemsSettings-test.jsx @@ -75,7 +75,7 @@ describe('TOCItemsSettings Plugin', () => { const tabIndexes = document.querySelectorAll(TAB_INDEX_SELECTOR); expect(tabIndexes.length).toBe(4); expect(tabIndexes[0].className).toBe("active"); // general tab active - expect(document.querySelectorAll(`${TAB_CONTENT_SELECTOR} div.form-group`).length).toBe(5); // check content is general settings tab. + expect(document.querySelectorAll(`${TAB_CONTENT_SELECTOR} div.form-group`).length).toBe(4); // check content is general settings tab. }); it('display panel', () => { diff --git a/web/client/selectors/__tests__/map-test.js b/web/client/selectors/__tests__/map-test.js index 0211dfda77..dfdddc98a4 100644 --- a/web/client/selectors/__tests__/map-test.js +++ b/web/client/selectors/__tests__/map-test.js @@ -26,7 +26,8 @@ import { isMouseMoveCoordinatesActiveSelector, isMouseMoveIdentifyActiveSelector, identifyFloatingToolSelector, - mapInfoAttributesSelector + mapInfoAttributesSelector, + showEditableFeatureCheckboxSelector } from '../map'; const center = {x: 1, y: 1}; @@ -198,4 +199,38 @@ describe('Test map selectors', () => { expect(mapInfoAttributes).toBeTruthy(); expect(mapInfoAttributes).toEqual(attributes); }); + describe('showEditableFeatureCheckboxSelector', () =>{ + it('test with user not logged in - map', () => { + const _state = {map: {present: {info: {id: 1, canEdit: false}}}}; + expect(showEditableFeatureCheckboxSelector(_state)).toBeFalsy(); + }); + it('test with user not logged in - context with map', () => { + const _state = {map: {present: {info: {id: 1, canEdit: true}}}, context: {resource: {id: 1, canEdit: true}}}; + expect(showEditableFeatureCheckboxSelector(_state)).toBeFalsy(); + }); + it('test with user not logged in - context', () => { + const _state = {map: {present: {info: {id: 1, canEdit: true}}}, context: {resource: {id: 1, canEdit: true}}}; + expect(showEditableFeatureCheckboxSelector(_state)).toBeFalsy(); + }); + it('test with user logged in - context', () => { + const _state = {map: {present: {info: null}}, context: {resource: {id: 1, canEdit: true}}, security: {user: {name: "Test"}}}; + expect(showEditableFeatureCheckboxSelector(_state)).toBeFalsy(); + }); + it('test with user logged in - context map', () => { + const _state = {map: {present: {info: {id: 1, canEdit: true}}}, context: {resource: {id: 1, canEdit: true}}, security: {user: {name: "Test"}}}; + expect(showEditableFeatureCheckboxSelector(_state)).toBeTruthy(); + }); + it('test with user logged in - map with only view permission', () => { + const _state = {map: {present: {info: {id: 1, canEdit: false}}}, security: {user: {name: "Test"}}}; + expect(showEditableFeatureCheckboxSelector(_state)).toBeFalsy(); + }); + it('test with user logged in - new map', () => { + const _state = {map: {present: {info: undefined}}, security: {user: {name: "Test"}}}; + expect(showEditableFeatureCheckboxSelector(_state)).toBeTruthy(); + }); + it('test with user logged in - context creator', () => { + const _state = {map: {present: {info: undefined}}, security: {user: {name: "Test"}}}; + expect(showEditableFeatureCheckboxSelector(_state)).toBeTruthy(); + }); + }); }); diff --git a/web/client/selectors/map.js b/web/client/selectors/map.js index dea074fdd2..9911aaf4c3 100644 --- a/web/client/selectors/map.js +++ b/web/client/selectors/map.js @@ -11,6 +11,7 @@ import CoordinatesUtils from '../utils/CoordinatesUtils'; import { createSelector } from 'reselect'; import {get, memoize} from 'lodash'; import {detectIdentifyInMapPopUp} from "../utils/MapUtils"; +import { isLoggedIn } from './security'; /** * selects map state @@ -45,6 +46,25 @@ export const mapIsEditableSelector = state => { }; export const mapInfoAttributesSelector = state => get(mapInfoSelector(state), 'attributes'); +/** + * Show editable feature checkbox based on user permission on the map resource + * @memberof selectors.map + * @param {object} state the state + * @returns {boolean} flag to show/hide the option + */ +export const showEditableFeatureCheckboxSelector = state => { + const { id: mapId, canEdit: mapCanEdit } = mapInfoSelector(state) ?? {}; + const { id: contextId } = get(state, 'context.resource', {}); + if (isLoggedIn(state)) { + // in case of context without a map hide the option + if (contextId && !mapId) { + return false; + } + return mapId ? mapCanEdit : true; + } + return false; +}; + // TODO: move these in selectors/localConfig.js or selectors/config.js export const projectionDefsSelector = (state) => state.localConfig && state.localConfig.projectionDefs || []; export const mapConstraintsSelector = state => state.localConfig && state.localConfig.mapConstraints || {};