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

Close redlining from another button #566

Open
FerranMart opened this issue Jul 10, 2024 · 3 comments
Open

Close redlining from another button #566

FerranMart opened this issue Jul 10, 2024 · 3 comments

Comments

@FerranMart
Copy link

We have created a button to remove all temporary layers, but we have noticed a specific problem with the "Redlining" layer. If the Redlining task is active and we use our button, the selected feature remains visible (and the redlining layer isn't removed).

We have found that if we close the dialog before deleting the layers, this issue doesn't occur. Therefore, we modified the code to ensure that the Redlining dialog closes before deleting the layers. For this to work, we had to introduce a timer (setTimeout) so that the system has time to deselect the last entity before deleting it.

This is the solution we implemented:

clearLayers() {
        console.log(this.props.currentTask )
        if (this.props.currentTask === "Redlining"){
            this.props.setCurrentTask(null);
        }
        
        setTimeout(() => { this.props.layers.forEach(layer => {
            if (layer.role === LayerRole.USERLAYER) {
                this.props.removeLayer(layer.id);
            }
        }); }, 100);
        
        if (this.props.closeTasks) {
            this.props.setCurrentTask(null);
        }
    }

This works, but I'm almost certain that working with timeouts isn't ideal, because every computer is different and we worry that the time needed might vary from computer to computer.
Is there another way to solve without using a timeout?

Thanks!

@manisandro
Copy link
Member

Yes, in your own component, bin the state.task.current redux state variable to a prop, and in the componentDidUpdate lifecycle function, react on the this.props.task state change and perform the cleanup then.

@FerranMart
Copy link
Author

We believe we have implemented your instructions correctly, but it still does not work as expected; the selected feature remains visible. I leave here the code of the component, if you can look at it, it would be perfect

import React from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import Icon from 'qwc2/components/Icon';
import { removeLayer } from 'qwc2/actions/layers';
import 'qwc2/plugins/style/Buttons.css';
import { setCurrentTask } from 'qwc2/actions/task';
import { LayerRole } from 'qwc2/actions/layers';

class GwClearTempLayersButton extends React.Component {
    static propTypes = {
        closeTasks: PropTypes.bool,
        position: PropTypes.number,
        layers: PropTypes.array,
        removeLayer: PropTypes.func,
        setCurrentTask: PropTypes.func,
        currentTask: PropTypes.string
    };
    static defaultProps = {
        closeTasks: false
    };

    constructor(props) {
        super(props);
        this.redliningOpen = false;
    }

    componentDidUpdate(prevProps) {
        if (prevProps.currentTask === "Redlining" && this.props.currentTask !== "Redlining" && this.redliningOpen) {
            this.redliningOpen = false;
            this.clearLayers();
        }
    }

    clearLayers() {
        

        this.props.layers.forEach(layer => {
            if (layer.role === LayerRole.USERLAYER) {
                this.props.removeLayer(layer.id);
            }
        });

        if (this.props.closeTasks) {
            this.props.setCurrentTask(null);
        }
    }
    btnClicked(){
        if (this.props.currentTask === "Redlining"){
            this.props.setCurrentTask(null);
            this.redliningOpen = true
        }
        else{
            this.clearLayers();
        }
    }

    render() {
        return (
            <button className="map-button"
                onClick={() => this.btnClicked()}
                style={{ bottom: (5 + 4 * this.props.position) + 'em' }}
                title="Clear Temporal Layers"
            >
                <Icon icon="trash" title="Clear Temporal Layers" />
            </button>
        );
    }
}

export default connect(state => ({
    layers: state.layers.flat,
    currentTask: state.task.id
}), {
    removeLayer: removeLayer,
    setCurrentTask: setCurrentTask
})(GwClearTempLayersButton);

@jblanchg
Copy link

Hi!

I think we've finally found what's happening.

On the code above, we set the current task to null if the current task is 'Redlining'. Doing that should trigger the Redlining onHide function and set the selectedFeature to null before removing the user layers.

However, it seems that the reset funciton in RedliningSupport.jsx it's executed after the clearTempLayers function in our component, we can solve this by changing the Redlining state before setting the task to null in our component, like this:

    btnClicked(){
        if (this.props.currentTask === "Redlining"){
            this.props.changeRedliningState({action: null, geomType: null, numericInput: false});
            this.props.setCurrentTask(null);
            this.redliningOpen = true
        }
        else{
            this.clearLayers();
        }
    }

I believe this is not ideal, but we can't figure out any other way to get it working at the moment. Do you have any suggestion?

Thank you.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants