client/app/pages/data-sources/EditDataSource.jsx (147 lines of code) (raw):

import { get, find, toUpper } from "lodash"; import React from "react"; import PropTypes from "prop-types"; import Modal from "antd/lib/modal"; import routeWithUserSession from "@/components/ApplicationArea/routeWithUserSession"; import navigateTo from "@/components/ApplicationArea/navigateTo"; import LoadingState from "@/components/items-list/components/LoadingState"; import DynamicForm from "@/components/dynamic-form/DynamicForm"; import SchemaTable from "@/pages/data-sources/schema-table-components/SchemaTable"; import helper from "@/components/dynamic-form/dynamicFormHelper"; import HelpTrigger, { TYPES as HELP_TRIGGER_TYPES } from "@/components/HelpTrigger"; import wrapSettingsTab from "@/components/SettingsWrapper"; import DataSource, { IMG_ROOT } from "@/services/data-source"; import notification from "@/services/notification"; import routes from "@/services/routes"; class EditDataSource extends React.Component { static propTypes = { dataSourceId: PropTypes.string.isRequired, onError: PropTypes.func, }; static defaultProps = { onError: () => {}, }; state = { dataSource: null, type: null, loading: true, schema: null, }; componentDidMount() { DataSource.get({ id: this.props.dataSourceId }) .then(dataSource => { const { type } = dataSource; this.setState({ dataSource }); DataSource.types().then(types => this.setState({ type: find(types, { type }), loading: false })); DataSource.fetchSchema({ id: this.props.dataSourceId }).then(schema => this.setState({ schema: schema, loading: false })); }) .catch(error => this.props.onError(error)); } saveDataSource = (values, successCallback, errorCallback) => { const { dataSource } = this.state; helper.updateTargetWithValues(dataSource, values); DataSource.save(dataSource) .then(() => successCallback("Saved.")) .catch(error => { const message = get(error, "response.data.message", "Failed saving."); errorCallback(message); }); }; deleteDataSource = callback => { const { dataSource } = this.state; const doDelete = () => { DataSource.delete(dataSource) .then(() => { notification.success("Data source deleted successfully."); navigateTo("data_sources"); }) .catch(() => { callback(); }); }; Modal.confirm({ title: "Delete Data Source", content: "Are you sure you want to delete this data source?", okText: "Delete", okType: "danger", onOk: doDelete, onCancel: callback, maskClosable: true, autoFocusButton: null, }); }; updateSchema = (schema, tableId, columnId) => { const { dataSource } = this.state; const data = { tableId, columnId, schema }; DataSource.updateSchema({ id: dataSource.id, data: data }); }; testConnection = callback => { const { dataSource } = this.state; DataSource.test({ id: dataSource.id }) .then(httpResponse => { if (httpResponse.ok) { notification.success("Success"); } else { notification.error("Connection Test Failed:", httpResponse.message, { duration: 10 }); } callback(); }) .catch(() => { notification.error( "Connection Test Failed:", "Unknown error occurred while performing connection test. Please try again later.", { duration: 10 } ); callback(); }); }; renderForm() { const { dataSource, type } = this.state; const fields = helper.getFields(type, dataSource); const helpTriggerType = `DS_${toUpper(type.type)}`; const formProps = { fields, type, actions: [ { name: "Delete", type: "danger", callback: this.deleteDataSource }, { name: "Test Connection", pullRight: true, callback: this.testConnection, disableWhenDirty: true }, ], onSubmit: this.saveDataSource, feedbackIcons: true, defaultShowExtraFields: helper.hasFilledExtraField(type, dataSource), }; return ( <div className="row" data-test="DataSource"> <div className="text-right m-r-10"> {HELP_TRIGGER_TYPES[helpTriggerType] && ( <HelpTrigger className="f-13" type={helpTriggerType}> Setup Instructions <i className="fa fa-question-circle" /> </HelpTrigger> )} </div> <div className="text-center m-b-10"> <img className="p-5" src={`${IMG_ROOT}/${type.type}.png`} alt={type.name} width="64" /> <h3 className="m-0">{type.name}</h3> </div> <div className="col-md-4 col-md-offset-4 m-b-10"> <DynamicForm {...formProps} /> </div> <div className="col-md-12 admin-schema-editor"> <SchemaTable schema={this.state.schema} updateSchema={this.updateSchema} /> </div> </div> ); } render() { return this.state.loading ? <LoadingState className="" /> : this.renderForm(); } } const EditDataSourcePage = wrapSettingsTab("DataSources.Edit", null, EditDataSource); routes.register( "DataSources.Edit", routeWithUserSession({ path: "/data_sources/:dataSourceId", title: "Data Sources", render: pageProps => <EditDataSourcePage {...pageProps} />, }) );