From bce4d0f864600a22197510e8b7acdc143f5e6d20 Mon Sep 17 00:00:00 2001 From: Tom Herold Date: Fri, 27 Oct 2017 11:52:10 +0200 Subject: [PATCH 1/8] reactified dataset upload view #2209 --- .../javascripts/admin/admin_rest_api.js | 19 ++ .../javascripts/admin/api_flow_types.js | 13 + .../admin/views/dataset/dataset_add_view.js | 62 ++-- .../views/dataset/dataset_remote_view.js | 182 +++++------ .../views/dataset/dataset_upload_view.js | 290 ++++++++++-------- app/assets/javascripts/messages.js | 2 + app/assets/javascripts/router.js | 6 +- 7 files changed, 305 insertions(+), 269 deletions(-) diff --git a/app/assets/javascripts/admin/admin_rest_api.js b/app/assets/javascripts/admin/admin_rest_api.js index 1602a141734..4ffc13142bb 100644 --- a/app/assets/javascripts/admin/admin_rest_api.js +++ b/app/assets/javascripts/admin/admin_rest_api.js @@ -11,6 +11,8 @@ import type { APIProjectType, APITaskType, APIAnnotationType, + APIDatastoreType, + NDStoreConfigType, } from "admin/api_flow_types"; import type { QueryObjectType } from "admin/views/task/task_search_form"; @@ -234,3 +236,20 @@ export async function deleteAnnotation(annotationId: string): Promise> { + const datastores = await Request.receiveJSON("/api/datastores"); + assertResponseLimit(datastores); + + return datastores; +} + +// ### Datasets +export async function addNDStoreDataset( + ndstoreConfig: NDStoreConfigType, +): Promise { + return Request.sendJSONReceiveJSON("/api/datasets?typ=ndstore", { + data: ndstoreConfig, + }); +} diff --git a/app/assets/javascripts/admin/api_flow_types.js b/app/assets/javascripts/admin/api_flow_types.js index a2799a8ee69..0583814f068 100644 --- a/app/assets/javascripts/admin/api_flow_types.js +++ b/app/assets/javascripts/admin/api_flow_types.js @@ -168,3 +168,16 @@ export type APIProjectType = { +assignmentConfiguration: { location: "webknossos" | "mturk" }, +numberOfOpenAssignments: number, }; + +export type APIDatastoreType = { + +name: string, + +url: string, + +typ: string, +}; + +export type NDStoreConfigType = { + +name: string, + +team: string, + +server: string, + +token: string, +}; diff --git a/app/assets/javascripts/admin/views/dataset/dataset_add_view.js b/app/assets/javascripts/admin/views/dataset/dataset_add_view.js index e601d84bbbc..4d0417a089e 100644 --- a/app/assets/javascripts/admin/views/dataset/dataset_add_view.js +++ b/app/assets/javascripts/admin/views/dataset/dataset_add_view.js @@ -1,51 +1,27 @@ -import _ from "lodash"; -import Marionette from "backbone.marionette"; +// @flow +/* eslint-disable react/prefer-stateless-function */ +import React from "react"; +import { Tabs } from "antd"; import DatasetUploadView from "admin/views/dataset/dataset_upload_view"; import DatasetRemoteView from "admin/views/dataset/dataset_remote_view"; -class DatasetAddView extends Marionette.View { - static initClass() { - this.prototype.className = "container"; - this.prototype.id = "dataset-add-view"; - this.prototype.template = _.template(`\ -
-
- -
-
-
-
-
\ -`); +const { TabPane } = Tabs; - this.prototype.regions = { tabPane: ".tab-pane" }; - - this.prototype.events = { - "click #tab-upload-dataset": "showUploadDataset", - "click #tab-remote-dataset": "showRemoteDataset", - }; - } - - initialize(options) { - this.options = options; - this.listenTo(this, "render", this.showUploadDataset); - } - - showUploadDataset() { - return this.showChildView("tabPane", new DatasetUploadView(this.options)); - } - - showRemoteDataset() { - return this.showChildView("tabPane", new DatasetRemoteView(this.options)); +class DatasetAddView extends React.PureComponent<*> { + render() { + return ( +
+ + + + + + + + +
+ ); } } -DatasetAddView.initClass(); export default DatasetAddView; diff --git a/app/assets/javascripts/admin/views/dataset/dataset_remote_view.js b/app/assets/javascripts/admin/views/dataset/dataset_remote_view.js index cac36535f2c..d0a724fefd2 100644 --- a/app/assets/javascripts/admin/views/dataset/dataset_remote_view.js +++ b/app/assets/javascripts/admin/views/dataset/dataset_remote_view.js @@ -1,101 +1,109 @@ -import _ from "lodash"; +// @flow +import React from "react"; +import { Form, Input, Select, Button, Card } from "antd"; +import { getTeams, addNDStoreDataset } from "admin/admin_rest_api"; import app from "app"; -import Marionette from "backbone.marionette"; import Toast from "libs/toast"; -import Request from "libs/request"; -import FormSyphon from "form-syphon"; -import SelectionView from "admin/views/selection_view"; -import TeamCollection from "admin/models/team/team_collection"; - -class DatasetRemoteView extends Marionette.View { - static initClass() { - this.prototype.template = _.template(`\ -
-
-

Add Remote NDStore Dataset

-
-
- -
- - -
-
-
- -
- -
-
-
- -
- - -
-
-
- -
- - -
-
-
-
- -
-
-
-
-
\ -`); +import messages from "messages"; - this.prototype.className = "container"; +import type { APITeamType, NDStoreConfigType } from "admin/api_flow_types"; - this.prototype.regions = { team: ".team" }; +const FormItem = Form.Item; +const Option = Select.Option; - this.prototype.events = { "submit form": "addDataset" }; +type Props = { + form: Object, +}; - this.prototype.ui = { form: "form" }; - } +type State = { + teams: Array, +}; - initialize() { - this.teamSelectionView = new SelectionView({ - collection: new TeamCollection(), - name: "team", - childViewOptions: { - modelValue() { - return `${this.model.get("name")}`; - }, - }, - data: "amIAnAdmin=true", - }); +class DatasetRemoteView extends React.PureComponent { + state = { + teams: [], + }; + + componentDidMount() { + this.fetchData(); } - onRender() { - this.showChildView("team", this.teamSelectionView); + async fetchData() { + const teams = await getTeams(); + const currentUserAdminTeams = app.currentUser.teams + .filter(team => team.role.name === "admin") + .map(team => team.team); + + this.setState({ + teams: teams.filter(team => currentUserAdminTeams.includes(team.name)), + }); } - addDataset(evt) { + handleSubmit = evt => { evt.preventDefault(); - const { form } = this.ui; - - if (form[0].checkValidity()) { - Request.sendJSONReceiveJSON("/api/datasets?typ=ndstore", { - data: FormSyphon.serialize(form), - }).then( - () => { - Toast.success(); - app.router.navigate("/dashboard", { trigger: true }); - }, - () => {}, // NOOP - ); - } + + this.props.form.validateFields(async (err, formValues: NDStoreConfigType) => { + if (!err) { + await addNDStoreDataset(formValues); + + Toast.success(messages["dataset.ndstore_success"]); + app.router.navigate("/dashboard", { trigger: true }); + } + }); + }; + render() { + const { getFieldDecorator } = this.props.form; + + return ( +
+ Add Remote NDStore Dataset}> +
+ + {getFieldDecorator("name", { + rules: [{ required: true }, { min: 3 }, { pattern: /[0-9a-zA-Z_-]+$/ }], + })()} + + + + {getFieldDecorator("team", { + rules: [{ required: true }], + })( + , + )} + + + + {getFieldDecorator("server", { + rules: [{ required: true, type: "url" }], + })()} + + + + {getFieldDecorator("token", { + rules: [{ required: true }], + })()} + + + + + +
+
+
+ ); } } -DatasetRemoteView.initClass(); - -export default DatasetRemoteView; +export default Form.create()(DatasetRemoteView); diff --git a/app/assets/javascripts/admin/views/dataset/dataset_upload_view.js b/app/assets/javascripts/admin/views/dataset/dataset_upload_view.js index 4b3b2d4303f..b39ccc39799 100644 --- a/app/assets/javascripts/admin/views/dataset/dataset_upload_view.js +++ b/app/assets/javascripts/admin/views/dataset/dataset_upload_view.js @@ -1,150 +1,172 @@ -import _ from "lodash"; +// @flow +import React from "react"; +import { Form, Input, Select, Button, Card, Spin, Upload, Icon } from "antd"; import app from "app"; -import Marionette from "backbone.marionette"; +import { getTeams, getDatastores } from "admin/admin_rest_api"; import Toast from "libs/toast"; import Request from "libs/request"; -import SelectionView from "admin/views/selection_view"; -import TeamCollection from "admin/models/team/team_collection"; -import DatastoreCollection from "admin/models/datastore/datastore_collection"; import messages from "messages"; +import type { APITeamType, APIDatastoreType } from "admin/api_flow_types"; -class DatasetUploadView extends Marionette.View { - static initClass() { - this.prototype.template = _.template(`\ -
-
-

Upload Dataset

-
-
- -
- - -
-
-
- -
- -
-
-
- -
- -
-
-
- -
- -
-
- - -
- - Browse... - Change - - - Remove -
-
-
-
-
-