From 9af85bca4c07f2e4c06a9c363ba6cec176250838 Mon Sep 17 00:00:00 2001 From: Philipp Otto Date: Tue, 21 May 2019 17:05:52 +0200 Subject: [PATCH 1/3] tell user that the server suggests a new datasource json. also allow to see the old version + diff --- frontend/javascripts/admin/api_flow_types.js | 1 + .../dashboard/dataset/dataset_import_view.js | 98 ++++++++++++++++--- .../dataset/simple_advanced_data_form.js | 13 +-- frontend/javascripts/libs/utils.js | 23 +++++ .../controllers/DataSourceController.scala | 1 + 5 files changed, 116 insertions(+), 20 deletions(-) diff --git a/frontend/javascripts/admin/api_flow_types.js b/frontend/javascripts/admin/api_flow_types.js index c5571b0b638..c59feea472e 100644 --- a/frontend/javascripts/admin/api_flow_types.js +++ b/frontend/javascripts/admin/api_flow_types.js @@ -152,6 +152,7 @@ export type APISampleDataset = { export type APIDataSourceWithMessages = { +dataSource?: APIDataSource, + +previousDataSource?: APIDataSource, +messages: Array, }; diff --git a/frontend/javascripts/dashboard/dataset/dataset_import_view.js b/frontend/javascripts/dashboard/dataset/dataset_import_view.js index 89991450778..df4b6bbd4c1 100644 --- a/frontend/javascripts/dashboard/dataset/dataset_import_view.js +++ b/frontend/javascripts/dashboard/dataset/dataset_import_view.js @@ -1,18 +1,14 @@ // @flow -import { Button, Spin, Icon, Alert, Form, Card, Tabs, Tooltip } from "antd"; +import { Button, Spin, Icon, Alert, Form, Card, Tabs, Tooltip, Modal, Input } from "antd"; import * as React from "react"; import _ from "lodash"; import moment from "moment"; -import type { - APIDataset, - APIMessage, - APIDataSourceWithMessages, - APIDatasetId, -} from "admin/api_flow_types"; +import type { APIDataSource, APIDataset, APIDatasetId, APIMessage } from "admin/api_flow_types"; import type { DatasetConfiguration } from "oxalis/store"; import { datasetCache } from "dashboard/dataset_view"; +import { diffObjects, jsonStringify } from "libs/utils"; import { getDataset, updateDataset, @@ -24,12 +20,11 @@ import { updateDatasetTeams, } from "admin/admin_rest_api"; import { handleGenericError } from "libs/error_handling"; -import { jsonStringify } from "libs/utils"; +import { trackAction } from "oxalis/model/helpers/analytics"; import Toast from "libs/toast"; import messages from "messages"; -import { trackAction } from "oxalis/model/helpers/analytics"; -import { Hideable, confirmAsync, hasFormError } from "./helper_components"; +import { Hideable, confirmAsync, hasFormError, jsonEditStyle } from "./helper_components"; import DefaultConfigComponent from "./default_config_component"; import ImportGeneralComponent from "./import_general_component"; import SimpleAdvancedDataForm from "./simple_advanced_data_form"; @@ -54,10 +49,12 @@ type State = { isLoading: boolean, activeDataSourceEditMode: "simple" | "advanced", activeTabKey: TabKey, + previousDataSource: ?APIDataSource, + differenceBetweenDatasources: ?Object, }; export type FormData = { - dataSource: APIDataSourceWithMessages, + dataSource: APIDataSource, dataSourceJson: string, dataset: APIDataset, defaultConfiguration: DatasetConfiguration, @@ -76,6 +73,8 @@ class DatasetImportView extends React.PureComponent { messages: [], activeDataSourceEditMode: "simple", activeTabKey: "data", + differenceBetweenDatasources: null, + previousDataSource: null, }; componentDidMount() { @@ -87,11 +86,22 @@ class DatasetImportView extends React.PureComponent { this.setState({ isLoading: true }); const dataset = await getDataset(this.props.datasetId); let dataSource; + let previousDataSource; let dataSourceMessages = []; if (dataset.isForeign) { dataSource = await readDatasetDatasource(dataset); } else { - ({ dataSource, messages: dataSourceMessages } = await getDatasetDatasource(dataset)); + ({ + dataSource, + messages: dataSourceMessages, + previousDataSource, + } = await getDatasetDatasource(dataset)); + + this.setState({ previousDataSource }); + if (previousDataSource != null && dataSource != null) { + const diff = diffObjects(dataSource, previousDataSource); + this.setState({ differenceBetweenDatasources: diff }); + } } if (dataSource == null) { throw new Error("No datasource received from server."); @@ -148,6 +158,68 @@ class DatasetImportView extends React.PureComponent { } } + getDatasourceDiffAlert() { + if ( + this.state.previousDataSource == null || + _.size(this.state.differenceBetweenDatasources) === 0 + ) { + return null; + } + + function showJSONModal(title, object) { + Modal.info({ + title, + width: 800, + content: ( + + {JSON.stringify(object, null, 2)} + + ), + }); + } + + return ( +
+ + A datasource-properties.json file was found for this dataset. However, additional + information about the dataset could be inferred. Please review the following + properties and click “Save” to accept the suggestions. The original + datasource-properties.json file can be seen{" "} + + showJSONModal( + "Original datasource-properties.json", + this.state.previousDataSource, + ) + } + > + here + + . The JSON-encoded difference can be inspected{" "} + + showJSONModal( + "Difference to new datasource-properties.json", + this.state.differenceBetweenDatasources, + ) + } + > + here + + . +
+ } + type="info" + showIcon + /> + + ); + } + getFormValidationSummary = (): Object => { const err = this.props.form.getFieldsError(); const { dataset } = this.state; @@ -242,6 +314,7 @@ class DatasetImportView extends React.PureComponent { !this.state.dataset.dataStore.isConnector ) { await updateDatasetDatasource(this.props.datasetId.name, dataset.dataStore.url, dataSource); + this.setState({ previousDataSource: null, differenceBetweenDatasources: null }); } const verb = this.props.isEditingMode ? "updated" : "imported"; @@ -405,6 +478,7 @@ class DatasetImportView extends React.PureComponent { this.props.form.validateFields(); this.setState({ activeDataSourceEditMode: activeEditMode }); }} + additionalAlert={this.getDatasourceDiffAlert()} /> diff --git a/frontend/javascripts/dashboard/dataset/simple_advanced_data_form.js b/frontend/javascripts/dashboard/dataset/simple_advanced_data_form.js index 5e5c39d2f37..5fe64254271 100644 --- a/frontend/javascripts/dashboard/dataset/simple_advanced_data_form.js +++ b/frontend/javascripts/dashboard/dataset/simple_advanced_data_form.js @@ -20,11 +20,13 @@ export default function SimpleAdvancedDataForm({ form, activeDataSourceEditMode, onChange, + additionalAlert, }: { isReadOnlyDataset: boolean, form: Object, activeDataSourceEditMode: "simple" | "advanced", onChange: ("simple" | "advanced") => void, + additionalAlert: ?React.Node, }) { const { getFieldDecorator } = form; const dataSource = @@ -64,14 +66,9 @@ export default function SimpleAdvancedDataForm({ type="warning" showIcon /> - ) : ( - - )} + ) : null} + + {additionalAlert}