appbaseio/reactivesearch

View on GitHub
packages/native/src/components/basic/DataController.js

Summary

Maintainability
C
1 day
Test Coverage
import React, { Component } from 'react';
import { View } from 'react-native';

import {
    addComponent,
    removeComponent,
    updateQuery,
    setQueryListener,
} from '@appbaseio/reactivecore/lib/actions';
import { isEqual, checkValueChange } from '@appbaseio/reactivecore/lib/utils/helper';

import types from '@appbaseio/reactivecore/lib/utils/types';

import { connect } from '../../utils';

class DataController extends Component {
    componentDidMount() {
        this.locked = false;
        this.props.addComponent(this.props.componentId);
        this.props.setQueryListener(this.props.componentId, this.props.onQueryChange, null);

        if (this.props.defaultSelected) {
            this.updateQuery(this.props.defaultSelected, this.props);
        } else {
            this.updateQuery(null, this.props);
        }
    }

    componentWillReceiveProps(nextProps) {
        if (!this.locked) {
            if (!isEqual(this.props.defaultSelected, nextProps.defaultSelected)) {
                this.updateQuery(nextProps.defaultSelected, nextProps);
            } else if (!isEqual(this.props.selectedValue, nextProps.selectedValue)) {
                this.updateQuery(nextProps.selectedValue, nextProps);
            }
        }
    }

    componentWillUnmount() {
        this.props.removeComponent(this.props.componentId);
    }

    defaultQuery() {
        return {
            match_all: {},
        };
    }

    updateQuery = (defaultSelected = null, props) => {
        this.locked = true;
        const query = props.customQuery ? props.customQuery : this.defaultQuery;

        const performUpdate = () => {
            props.updateQuery({
                componentId: props.componentId,
                query: query(defaultSelected, props),
                value: defaultSelected,
                label: props.filterLabel,
                showFilter: props.showFilter,
                URLParams: false,
            });
            this.locked = false;
            if (props.onValueChange) props.onValueChange(defaultSelected);
        };

        checkValueChange(
            props.componentId,
            defaultSelected,
            props.beforeValueChange,
            performUpdate,
        );
    };

    render() {
        return <View style={this.props.style}>{this.props.children}</View>;
    }
}

DataController.defaultProps = {
    showFilter: true,
    style: {},
};

DataController.propTypes = {
    componentId: types.stringRequired,
    addComponent: types.funcRequired,
    // DataController can accept any defaultSelected depending on the query used
    defaultSelected: types.any, // eslint-disable-line
    selectedValue: types.selectedValue,
    removeComponent: types.funcRequired,
    setQueryListener: types.funcRequired,
    beforeValueChange: types.func,
    onValueChange: types.func,
    customQuery: types.func,
    onQueryChange: types.func,
    updateQuery: types.funcRequired,
    filterLabel: types.string,
    showFilter: types.bool,
    children: types.children,
    style: types.style,
};

const mapStateToProps = (state, props) => ({
    selectedValue:
        (state.selectedValues[props.componentId]
            && state.selectedValues[props.componentId].value)
        || null,
});

const mapDispatchtoProps = dispatch => ({
    addComponent: component => dispatch(addComponent(component)),
    removeComponent: component => dispatch(removeComponent(component)),
    updateQuery: updateQueryObject => dispatch(updateQuery(updateQueryObject)),
    setQueryListener: (component, onQueryChange, beforeQueryChange) =>
        dispatch(setQueryListener(component, onQueryChange, beforeQueryChange)),
});

export default connect(
    mapStateToProps,
    mapDispatchtoProps,
)(DataController);