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

#10026: Interactive legend for TOC layers [Vector layer part] #10188

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
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
18 changes: 17 additions & 1 deletion web/client/actions/__tests__/layerFilter-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,11 @@ import {
DISCARD_CURRENT_FILTER,
discardCurrentFilter,
applyFilter,
APPLY_FILTER
APPLY_FILTER,
LAYER_FILTER_BY_LEGEND,
layerFilterByLegend,
RESET_LAYER_FILTER_BY_LEGEND,
resetLegendFilter
} from '../layerFilter';


Expand Down Expand Up @@ -64,4 +68,16 @@ describe('Test correctness of the layerFilter actions', () => {
expect(retval.type).toBe(APPLY_FILTER);
});

it('layerFilterByLegend', () => {
var retval = layerFilterByLegend();
expect(retval).toBeTruthy();
expect(retval.type).toBe(LAYER_FILTER_BY_LEGEND);
});

it('resetLegendFilter', () => {
var retval = resetLegendFilter();
expect(retval).toBeTruthy();
expect(retval.type).toBe(RESET_LAYER_FILTER_BY_LEGEND);
});

});
20 changes: 20 additions & 0 deletions web/client/actions/layerFilter.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ export const APPLY_FILTER = 'LAYER_FILTER:APPLY_FILTER';
*/
export const OPEN_QUERY_BUILDER = 'LAYER_FILTER:OPEN_QUERY_BUILDER';

export const LAYER_FILTER_BY_LEGEND = 'LAYER_FILTER:LAYER_FILTER_BY_LEGEND';

export const RESET_LAYER_FILTER_BY_LEGEND = 'LAYER_FILTER:RESET_LAYER_FILTER_BY_LEGEND';

export function storeCurrentFilter() {
return {
Expand Down Expand Up @@ -62,3 +65,20 @@ export function initLayerFilter(filter) {
};
}

export function layerFilterByLegend(layerId, nodeType, legendCQLFilter, filterArr) {
return {
type: LAYER_FILTER_BY_LEGEND,
legendCQLFilter,
nodeType,
layerId,
filterArr
};
}

export function resetLegendFilter(reason, value) {
return {
type: RESET_LAYER_FILTER_BY_LEGEND,
reason, // here the reason for reset is change 'style' or change the enable/disable interactive legend config 'disableEnableInteractiveLegend'
value
};
}
11 changes: 9 additions & 2 deletions web/client/api/catalog/WFS.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,13 @@ const searchAndPaginate = (json = {}, startPosition, maxRecords, text) => {
};
};

const recordToLayer = (record) => {
const recordToLayer = (record, {
service
}) => {
// this is for getting the configration of interactive legend
const {
layerOptions
} = service || {};
return {
type: record.type || "wfs",
search: {
Expand All @@ -90,7 +96,8 @@ const recordToLayer = (record) => {
description: record.description || "",
bbox: record.boundingBox,
links: getRecordLinks(record),
...record.layerOptions
...record.layerOptions,
...layerOptions
};
};

Expand Down
31 changes: 28 additions & 3 deletions web/client/components/TOC/fragments/settings/Display.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import { getSupportedFormat } from '../../../../api/WMS';
import WMSCacheOptions from './WMSCacheOptions';
import ThreeDTilesSettings from './ThreeDTilesSettings';
import ModelTransformation from './ModelTransformation';

export default class extends React.Component {
static propTypes = {
opacityText: PropTypes.node,
Expand All @@ -36,12 +37,14 @@ export default class extends React.Component {
isCesiumActive: PropTypes.bool,
projection: PropTypes.string,
resolutions: PropTypes.array,
zoom: PropTypes.number
zoom: PropTypes.number,
resetLegendFilter: PropTypes.func
};

static defaultProps = {
onChange: () => {},
opacityText: <Message msgId="opacity"/>
opacityText: <Message msgId="opacity"/>,
resetLegendFilter: () => {}
};

constructor(props) {
Expand Down Expand Up @@ -216,7 +219,29 @@ export default class extends React.Component {
layer={this.props.element}
onChange={this.props.onChange}
/>

{['wfs', 'vector'].includes(this.props.element.type) &&
<Row>
<div className={"legend-options"}>
<Col xs={12} className={"legend-label"}>
<label key="legend-options-title" className="control-label"><Message msgId="layerProperties.legendOptions.title" /></label>
</Col>
<Col xs={12}>
<Checkbox
data-qa="display-interactive-legend-option"
value="enableInteractiveLegend"
key="enableInteractiveLegend"
onChange={(e) => {
if (!e.target.checked) this.props.resetLegendFilter('disableEnableInteractiveLegend');
this.props.onChange("enableInteractiveLegend", e.target.checked);
}}
checked={this.props.element.enableInteractiveLegend} >
<Message msgId="layerProperties.enableInteractiveLegendInfo.label"/>
&nbsp;{this.props.element.type === 'wfs' && <InfoPopover text={<Message msgId="layerProperties.enableInteractiveLegendInfo.tooltip" />} />}
</Checkbox>
</Col>
</div>
</Row>
}
{this.props.element.type === "wms" &&
<Row>
<Col xs={12}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,9 @@ describe('test Layer Properties Display module component', () => {
// wrap in a stateful component, stateless components render return null
// see: https://facebook.github.io/react/docs/top-level-api.html#reactdom.render
const comp = ReactDOM.render(<Display element={l} settings={settings} />, document.getElementById("container"));
expect(comp).toExist();
expect(comp).toBeTruthy();
const inputs = ReactTestUtils.scryRenderedDOMComponentsWithTag( comp, "input" );
expect(inputs).toExist();
expect(inputs).toBeTruthy();
expect(inputs.length).toBe(5);
ReactTestUtils.Simulate.focus(inputs[0]);
expect(inputs[0].value).toBe('100');
Expand All @@ -71,9 +71,9 @@ describe('test Layer Properties Display module component', () => {
// wrap in a stateful component, stateless components render return null
// see: https://facebook.github.io/react/docs/top-level-api.html#reactdom.render
const comp = ReactDOM.render(<Display element={l} settings={settings} onChange={handlers.onChange}/>, document.getElementById("container"));
expect(comp).toExist();
expect(comp).toBeTruthy();
const inputs = ReactTestUtils.scryRenderedDOMComponentsWithTag( comp, "input" );
expect(inputs).toExist();
expect(inputs).toBeTruthy();
expect(inputs.length).toBe(13);
ReactTestUtils.Simulate.focus(inputs[2]);
expect(inputs[2].value).toBe('70');
Expand Down Expand Up @@ -109,7 +109,7 @@ describe('test Layer Properties Display module component', () => {
};

const comp = ReactDOM.render(<Display element={l} settings={settings} onChange={handlers.onChange}/>, document.getElementById("container"));
expect(comp).toExist();
expect(comp).toBeTruthy();
const formatRefresh = ReactTestUtils.scryRenderedDOMComponentsWithClass( comp, "format-refresh" );
ReactTestUtils.Simulate.click(formatRefresh[0]);
});
Expand Down Expand Up @@ -165,7 +165,7 @@ describe('test Layer Properties Display module component', () => {
};
ReactDOM.render(<Display isLocalizedLayerStylesEnabled element={l} settings={settings}/>, document.getElementById("container"));
const isLocalizedLayerStylesOption = document.querySelector('[data-qa="display-lacalized-layer-styles-option"]');
expect(isLocalizedLayerStylesOption).toExist();
expect(isLocalizedLayerStylesOption).toBeTruthy();
});

it('tests Display component for wms with force proxy option displayed', () => {
Expand Down Expand Up @@ -243,7 +243,7 @@ describe('test Layer Properties Display module component', () => {
onChange() {}
};
const comp = ReactDOM.render(<Display element={l} settings={settings} onChange={handlers.onChange}/>, document.getElementById("container"));
expect(comp).toExist();
expect(comp).toBeTruthy();
const labels = ReactTestUtils.scryRenderedDOMComponentsWithClass( comp, "control-label" );
const inputs = ReactTestUtils.scryRenderedDOMComponentsWithTag( comp, "input" );
const legendWidth = inputs[11];
Expand Down Expand Up @@ -281,11 +281,11 @@ describe('test Layer Properties Display module component', () => {
};
let spy = expect.spyOn(handlers, "onChange");
const comp = ReactDOM.render(<Display element={l} settings={settings} onChange={handlers.onChange}/>, document.getElementById("container"));
expect(comp).toExist();
expect(comp).toBeTruthy();
const inputs = ReactTestUtils.scryRenderedDOMComponentsWithTag( comp, "input" );
const legendPreview = ReactTestUtils.scryRenderedDOMComponentsWithClass( comp, "legend-preview" );
expect(legendPreview).toExist();
expect(inputs).toExist();
expect(legendPreview).toBeTruthy();
expect(inputs).toBeTruthy();
expect(inputs.length).toBe(13);
let legendWidth = inputs[11];
let legendHeight = inputs[12];
Expand Down Expand Up @@ -350,9 +350,9 @@ describe('test Layer Properties Display module component', () => {
}
};
const comp = ReactDOM.render(<Display element={l} settings={settings}/>, document.getElementById("container"));
expect(comp).toExist();
expect(comp).toBeTruthy();
const inputs = ReactTestUtils.scryRenderedDOMComponentsWithTag( comp, "input" );
expect(inputs).toExist();
expect(inputs).toBeTruthy();
expect(inputs.length).toBe(13);
expect(inputs[11].value).toBe("20");
expect(inputs[12].value).toBe("40");
Expand Down
19 changes: 15 additions & 4 deletions web/client/components/map/cesium/plugins/VectorLayer.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
} from '../../../../utils/VectorStyleUtils';
import { applyDefaultStyleToVectorLayer } from '../../../../utils/StyleUtils';
import GeoJSONStyledFeatures from '../../../../utils/cesium/GeoJSONStyledFeatures';
import { geoStylerStyleFilter as filterVectorLayerFeatures } from '../../../../utils/styleparser/StyleParserUtils';

const createLayer = (options, map) => {

Expand All @@ -26,8 +27,11 @@ const createLayer = (options, map) => {
};
}

const features = flattenFeatures(options?.features || [], ({ style, ...feature }) => feature);

let features = flattenFeatures(options?.features || [], ({ style, ...feature }) => feature);
const hasLegendFilter = options?.geoStylerFilter;
if (hasLegendFilter) {
features = features.filter(feat => filterVectorLayerFeatures(feat, hasLegendFilter));
}
let styledFeatures = new GeoJSONStyledFeatures({
features,
id: options?.id,
Expand Down Expand Up @@ -59,11 +63,18 @@ const createLayer = (options, map) => {
Layers.registerType('vector', {
create: createLayer,
update: (layer, newOptions, oldOptions, map) => {
if (!isEqual(newOptions.features, oldOptions.features)) {
const isStyleChanged = !isEqual(oldOptions.style, newOptions.style);
const areFeaturesChanged = !isEqual(oldOptions.features, newOptions.features);

const oldLegendFilter = oldOptions?.layerFilter?.filters?.find(f=>f.id === 'interactiveLegend');
const newLegendFilter = newOptions?.layerFilter?.filters?.find(f=>f.id === 'interactiveLegend');
const isLegendFilterChanged = !isEqual(oldLegendFilter, newLegendFilter);

if (areFeaturesChanged || isLegendFilterChanged) {
return createLayer(newOptions, map);
}

if (layer?.styledFeatures && !isEqual(newOptions.style, oldOptions.style)) {
if ((layer?.styledFeatures && isStyleChanged)) {
layerToGeoStylerStyle(newOptions)
.then((style) => {
getStyle(applyDefaultStyleToVectorLayer({ ...newOptions, style }), 'cesium')
Expand Down
Loading
Loading