appbaseio/dejaVu

View on GitHub
packages/browser/src/components/DataBrowser/UpdateRow.js

Summary

Maintainability
C
1 day
Test Coverage
// @flow

import React, { Component, Fragment } from 'react';
import { Modal, Input, Row, Col, Button, Form } from 'antd';
import { EditOutlined } from '@ant-design/icons';
import { connect } from 'react-redux';
import AceEditor from 'react-ace';

import 'brace/mode/json';
import 'brace/theme/github';

import {
    setError,
    clearError,
    updateReactiveList,
    setUpdatingRow,
    setSelectedRows,
    fetchMappings,
} from '../../actions';
import { isVaildJSON, getOnlySource } from '../../utils';
import { getUpdatingRow } from '../../reducers/updatingRow';
import { getVersion } from '../../reducers/version';
import { getUrl } from '../../reducers/app';
import { updateDocument } from '../../apis/data';

const { Item } = Form;

type Props = {
    data: any,
    appUrl: string,
    setError: any => void,
    clearError: () => void,
    updateReactiveList: () => void,
    setSelectedRows: any => void,
    setUpdatingRow: any => void,
    fetchMappings: () => void,
    version: Number,
};

type State = {
    isShowingModal: boolean,
    dataError: boolean,
    jsonValue: string,
};

class UpdateRowModal extends Component<Props, State> {
    state = {
        isShowingModal: false,
        dataError: false,
        jsonValue: JSON.stringify(
            getOnlySource(this.props.data || {}),
            null,
            2,
        ),
    };

    handleAfterClose = () => {
        this.setState({
            dataError: false,
        });
    };

    handleJsonInput = (val: any) => {
        this.setState({
            dataError: !isVaildJSON(val),
            jsonValue: val,
        });
    };

    toggleModal = () => {
        this.setState(prevState => ({
            isShowingModal: !prevState.isShowingModal,
        }));
    };

    handleSubmit = async () => {
        const { dataError, jsonValue } = this.state;
        const { _id: documentId, _index: index } = this.props.data;

        if (!dataError) {
            const {
                appUrl,
                setError: onSetError,
                clearError: onClearError,
                updateReactiveList: onUpdateReactiveList,
                setSelectedRows: onSetSelectedRows,
                setUpdatingRow: onSetUpdatingRow,
                fetchMappings: onFetchMappings,
            } = this.props;

            try {
                onClearError();
                await updateDocument({
                    index,
                    id: documentId,
                    url: appUrl,
                    document: JSON.parse(jsonValue),
                });
                onUpdateReactiveList();
                onSetUpdatingRow(null);
                onSetSelectedRows([]);
                onFetchMappings();
            } catch (error) {
                onSetError(error);
            }
            this.toggleModal();
        }
    };

    render() {
        const { isShowingModal, dataError, jsonValue } = this.state;
        const { _id: documentId, _index: index, _type: type } = this.props.data;

        return (
            <Fragment>
                <Button
                    icon={<EditOutlined />}
                    type="primary"
                    css={{
                        margin: '0 3px',
                    }}
                    onClick={this.toggleModal}
                >
                    Update
                </Button>

                <Modal
                    open={isShowingModal}
                    onCancel={this.toggleModal}
                    afterClose={this.handleAfterClose}
                    onOk={this.handleSubmit}
                    okButtonProps={{ disabled: dataError }}
                    destroyOnClose
                    css={{
                        top: '10px',
                    }}
                    maskClosable={false}
                >
                    <Row>
                        <Col span={12}>
                            <Item label="Index" style={{ marginRight: '15px' }}>
                                <Input name="index" value={index} disabled />
                            </Item>
                        </Col>
                        <Col span={12}>
                            <Item label="Type" style={{ marginRight: '15px' }}>
                                <Input name="type" value={type} disabled />
                            </Item>
                        </Col>
                    </Row>
                    <Item label="Document Id">
                        <Input
                            name="document_id"
                            value={documentId}
                            disabled
                            placeholder="Enter document id"
                        />
                    </Item>
                    <Item label="JSON document" />
                    <AceEditor
                        tabSize={2}
                        mode="json"
                        theme="github"
                        onChange={this.handleJsonInput}
                        name="add-row-modal"
                        value={jsonValue}
                        height="auto"
                        width="100%"
                        css={{
                            minHeight: '200px',
                            maxHeight: '300px',
                        }}
                    />
                </Modal>
            </Fragment>
        );
    }
}

const mapStateToProps = state => ({
    appUrl: getUrl(state),
    data: getUpdatingRow(state),
    version: getVersion(state),
});

const mapDispatchToProps = {
    setError,
    clearError,
    updateReactiveList,
    setSelectedRows,
    setUpdatingRow,
    fetchMappings,
};

export default connect(mapStateToProps, mapDispatchToProps)(UpdateRowModal);