Skip to content

Commit

Permalink
Merge branch 'master' of github.com:scalableminds/webknossos into rea…
Browse files Browse the repository at this point in the history
…ct-task-create

* 'master' of github.com:scalableminds/webknossos:
  remove mongev plugin, fixes #2072
  pretty me
  bump libs version number
  fix token access; bump braingames version (#2085)
  removed unused backbone model #2009
  move dataset uploading into Rest API module #2009
  enabled file preview hint before upload new dataset #2009
  reactified dataset upload view #2209
  • Loading branch information
hotzenklotz committed Oct 31, 2017
2 parents cd5fb7b + 25d4286 commit faa334d
Show file tree
Hide file tree
Showing 11 changed files with 311 additions and 291 deletions.
28 changes: 28 additions & 0 deletions app/assets/javascripts/admin/admin_rest_api.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ import type {
APIProjectType,
APITaskType,
APIAnnotationType,
APIDatastoreType,
NDStoreConfigType,
DatasetConfigType,
APIRoleType,
APIDatasetType,
} from "admin/api_flow_types";
Expand Down Expand Up @@ -334,3 +337,28 @@ export async function getActiveDatasets(): Promise<Array<APIDatasetType>> {

return datasets;
}

export async function addNDStoreDataset(
ndstoreConfig: NDStoreConfigType,
): Promise<APIAnnotationType> {
return Request.sendJSONReceiveJSON("/api/datasets?typ=ndstore", {
data: ndstoreConfig,
});
}

export async function addDataset(datatsetConfig: DatasetConfigType): Promise<APIAnnotationType> {
const response = await Request.receiveJSON("/api/dataToken/generate");
return Request.sendMultipartFormReceiveJSON(`/data/datasets?token=${response.token}`, {
data: datatsetConfig,
host: datatsetConfig.datastore,
});
}

// #### Datastores
export async function getDatastores(): Promise<Array<APIDatastoreType>> {
const datastores = await Request.receiveJSON("/api/datastores");
assertResponseLimit(datastores);

return datastores;
}

20 changes: 20 additions & 0 deletions app/assets/javascripts/admin/api_flow_types.js
Original file line number Diff line number Diff line change
Expand Up @@ -167,3 +167,23 @@ 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,
};

export type DatasetConfigType = {
+name: string,
+team: string,
+datastore: string,
+zipFile: File,
};

This file was deleted.

11 changes: 0 additions & 11 deletions app/assets/javascripts/admin/models/datastore/datastore_model.js

This file was deleted.

62 changes: 19 additions & 43 deletions app/assets/javascripts/admin/views/dataset/dataset_add_view.js
Original file line number Diff line number Diff line change
@@ -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(`\
<div class="tabbable" id="tabbable-dataset-add">
<div class="col-md-8">
<ul class="nav nav-tabs">
<li class="active">
<a href="#" id="tab-upload-dataset" data-target="#placeholder" data-toggle="tab">Upload Dataset</a>
</li>
<li>
<a href="#" id="tab-remote-dataset" data-target="#placeholder" data-toggle="tab">Add NDStore Dataset</a>
</li>
</ul>
<div class="tab-content">
<div class="tab-pane active" id="placeholder"></div>
</div>
</div>
</div>\
`);
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 (
<div className="container">
<Tabs defaultActiveKey="1">
<TabPane tab="Upload Dataset" key="1">
<DatasetUploadView />
</TabPane>
<TabPane tab="Add NDStore Dataset" key="2">
<DatasetRemoteView />
</TabPane>
</Tabs>
</div>
);
}
}
DatasetAddView.initClass();

export default DatasetAddView;
182 changes: 95 additions & 87 deletions app/assets/javascripts/admin/views/dataset/dataset_remote_view.js
Original file line number Diff line number Diff line change
@@ -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(`\
<div class="row">
<div class="col-md-6">
<h3>Add Remote NDStore Dataset</h3>
<form action="/api/datasets?typ=ndstore" method="POST" class="form-horizontal">
<div class=" form-group">
<label class="col-sm-3 control-label" for="name">Name</label>
<div class="col-sm-9">
<input type="text" required name="name" value="" class="form-control">
<span class="help-block errors"></span>
</div>
</div>
<div class=" form-group">
<label class="col-sm-3 control-label" for="team">Team</label>
<div class="col-sm-9 team">
<span class="help-block errors"></span>
</div>
</div>
<div class=" form-group">
<label class="col-sm-3 control-label" for="server">Server Url</label>
<div class="col-sm-9">
<input type="url" required name="server" class="form-control" title="NDstore server location">
<span class="help-block errors"></span>
</div>
</div>
<div class=" form-group">
<label class="col-sm-3 control-label" for="token">Token</label>
<div class="col-sm-9">
<input type="text" required name="token" class="form-control" title="NDstore token">
<span class="help-block errors"></span>
</div>
</div>
<div class="form-group">
<div class="col-sm-9 col-sm-offset-3">
<button type="submit" class="form-control btn btn-primary">
Import
</button>
</div>
</div>
</form>
</div>
</div>\
`);
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<APITeamType>,
};

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<Props, State> {
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 (
<div style={{ padding: 5 }}>
<Card title={<h3>Add Remote NDStore Dataset</h3>}>
<Form onSubmit={this.handleSubmit} layout="vertical">
<FormItem label="Dataset Name" hasFeedback>
{getFieldDecorator("name", {
rules: [{ required: true }, { min: 3 }, { pattern: /[0-9a-zA-Z_-]+$/ }],
})(<Input autoFocus />)}
</FormItem>

<FormItem label="Team" hasFeedback>
{getFieldDecorator("team", {
rules: [{ required: true }],
})(
<Select
showSearch
placeholder="Select a Team"
optionFilterProp="children"
style={{ width: "100%" }}
>
{this.state.teams.map((team: APITeamType) => (
<Option key={team.id} value={team.name}>
{`${team.name}`}
</Option>
))}
</Select>,
)}
</FormItem>

<FormItem label="Server Url" hasFeedback>
{getFieldDecorator("server", {
rules: [{ required: true, type: "url" }],
})(<Input />)}
</FormItem>

<FormItem label="Token" hasFeedback>
{getFieldDecorator("token", {
rules: [{ required: true }],
})(<Input />)}
</FormItem>

<FormItem>
<Button type="primary" htmlType="submit">
Add Dataset from NDStore
</Button>
</FormItem>
</Form>
</Card>
</div>
);
}
}
DatasetRemoteView.initClass();

export default DatasetRemoteView;
export default Form.create()(DatasetRemoteView);
Loading

0 comments on commit faa334d

Please sign in to comment.