Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Experience domain field in task creation as select component #3233

Merged
merged 13 commits into from
Sep 19, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ For upgrade instructions, please check the [migration guide](MIGRATIONS.md).
### Changed

- The modal used to change the experience of users by admins got a rework. [#3077](https://github.com/scalableminds/webknossos/pull/3077)
- During task creation, specifying an experience domain is now possible by choosing from existing domains. [#3233](https://github.com/scalableminds/webknossos/pull/3233)
- Unified the search functionality within webKnossos to implement an AND logic everyhwere. [#3228](https://github.com/scalableminds/webknossos/pull/3228)
- Renamed "Soma Clicking" to "Single-Node-Tree Mode". [#3141](https://github.com/scalableminds/webknossos/pull/3141/files)
- The fallback segmentation layer attribute of volume tracings is now persisted to NML/ZIP files. Upon re-upload, only volume tracings with this attribute will show a fallback layer. Use `tools/volumeAddFallbackLayer.py` to add this attribute to existing volume tracings. [#3088](https://github.com/scalableminds/webknossos/pull/3088)
Expand Down
27 changes: 12 additions & 15 deletions app/assets/javascripts/admin/task/task_create_form_view.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,7 @@
import _ from "lodash";
import React from "react";
import { withRouter } from "react-router-dom";
import {
Form,
Input,
Select,
Button,
Card,
Radio,
Upload,
Modal,
Icon,
InputNumber,
Spin,
} from "antd";
import { Form, Select, Button, Card, Radio, Upload, Modal, Icon, InputNumber, Spin } from "antd";
import {
getActiveDatasets,
getProjects,
Expand All @@ -26,6 +14,8 @@ import {
updateTask,
} from "admin/admin_rest_api";
import { Vector3Input, Vector6Input } from "libs/vector_input";
import SelectExperienceDomain from "components/select_experience_domain";
import messages from "messages";

import type {
APIDatasetType,
Expand Down Expand Up @@ -232,8 +222,15 @@ class TaskCreateFormView extends React.PureComponent<Props, State> {

<FormItem label="Experience Domain" hasFeedback>
{getFieldDecorator("neededExperience.domain", {
rules: [{ required: true }, { min: 3 }],
})(<Input disabled={isEditingMode} />)}
rules: [{ required: true }],
})(
<SelectExperienceDomain
disabled={isEditingMode}
placeholder="Select an Experience Domain"
notFoundContent={messages["task.domain_does_not_exist"]}
width={100}
/>,
)}
</FormItem>

<FormItem label="Experience Value" hasFeedback>
Expand Down
8 changes: 7 additions & 1 deletion app/assets/javascripts/admin/user/experience_modal_view.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import * as Utils from "libs/utils";
import { updateUser } from "admin/admin_rest_api";
import { handleGenericError } from "libs/error_handling";
import type { APIUserType, ExperienceDomainListType } from "admin/api_flow_types";
import Toast from "libs/toast";
import SelectExperienceDomain from "components/select_experience_domain";

const { Column } = Table;
Expand Down Expand Up @@ -203,6 +204,10 @@ class ExperienceModalView extends React.PureComponent<Props, State> {
};

addEnteredExperience = (domain: string) => {
if (domain.length < 3) {
Toast.warning("An experience domain needs at least 3 letters.");
return;
}
if (this.state.tableEntries.findIndex(entry => entry.domain === domain) > -1) {
return;
}
Expand Down Expand Up @@ -388,10 +393,11 @@ class ExperienceModalView extends React.PureComponent<Props, State> {
) : null}
<SelectExperienceDomain
disabled={false}
mode="tags"
placeholder="New Experience Domain"
value={[]}
width={50}
onSelect={this.addEnteredExperience}
onDeselect={() => {}}
alreadyUsedDomains={this.getDomainsOfTable()}
/>
</Modal>
Expand Down
26 changes: 19 additions & 7 deletions app/assets/javascripts/components/select_experience_domain.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
// @flow

import * as React from "react";
import { Select } from "antd";
import type { ExperienceDomainListType } from "admin/api_flow_types";
Expand All @@ -6,10 +8,14 @@ import { getExistingExperienceDomains } from "admin/admin_rest_api";
const Option = Select.Option;

type Props = {
value: string,
value?: string | Array<string>,
width: number,
placeholder: string,
notFoundContent?: string,
disabled: boolean,
onSelect: () => void,
onDeselect: () => void,
mode?: string,
onSelect?: string => void,
onChange?: () => void,
alreadyUsedDomains: ExperienceDomainListType,
};

Expand All @@ -18,6 +24,10 @@ type State = {
};

class SelectExperienceDomain extends React.PureComponent<Props, State> {
static defaultProps = {
alreadyUsedDomains: [],
};

state = {
domains: [],
};
Expand All @@ -37,14 +47,16 @@ class SelectExperienceDomain extends React.PureComponent<Props, State> {
render() {
return (
<Select
mode="tags"
showSearch
mode={this.props.mode}
value={this.props.value}
maxTagCount={1}
optionFilterProp="children"
notFoundContent={this.props.notFoundContent}
style={{ width: `${this.props.width}%` }}
disabled={this.props.disabled}
placeholder="New Experience Domain"
placeholder={this.props.placeholder}
onSelect={this.props.onSelect}
onDeselect={this.props.onDeselect}
onChange={this.props.onChange}
>
{this.getUnusedDomains().map(domain => <Option key={domain}>{domain}</Option>)}
</Select>
Expand Down
2 changes: 2 additions & 0 deletions app/assets/javascripts/messages.js
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ In order to restore the current window, a reload is necessary.`,
"The next task will most likely be part of project <%- projectName %>",
),
"task.confirm_reset": "Do you really want to reset this task?",
"task.domain_does_not_exist":
"No matching experience domain. Assign this domain to a user to add it to the listed options.",
"annotation.reset_success": "Annotation was successfully reset.",
"task.bulk_create_invalid":
"Can not parse task specification. It includes at least one invalid task.",
Expand Down