mirror of
https://github.com/scinote-eln/scinote-web.git
synced 2025-09-06 05:04:35 +08:00
Save input values into component state
This commit is contained in:
parent
0108d9ea19
commit
df44976fc6
7 changed files with 181 additions and 47 deletions
|
@ -7,11 +7,12 @@ const messages = defineMessages({
|
|||
placeholder: { id: "settings_page.new_team.name_placeholder" }
|
||||
});
|
||||
|
||||
const NameFormControl = ({intl}) =>
|
||||
const NameFormControl = ({ intl, ...props }) =>
|
||||
<FormControl
|
||||
type="text"
|
||||
placeholder={intl.formatMessage(messages.placeholder)}
|
||||
autoFocus={true}
|
||||
{...props}
|
||||
/>;
|
||||
|
||||
NameFormControl.PropTypes = {
|
||||
|
|
|
@ -11,6 +11,7 @@ export const SETTINGS_ACCOUNT_PREFERENCES_PATH =
|
|||
|
||||
// teams
|
||||
export const TEAMS_PATH = "/client_api/teams";
|
||||
export const TEAMS_NEW_PATH = "/client_api/teams/new";
|
||||
export const CHANGE_TEAM_PATH = "/client_api/teams/change_team";
|
||||
export const TEAM_DETAILS_PATH = "/client_api/teams/:team_id/details";
|
||||
export const TEAM_UPDATE_PATH = "/client_api/teams/update";
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
export const ENTER_KEY_CODE = 13;
|
||||
export const TEXT_MAX_LENGTH = 10000;
|
||||
export const NAME_MIN_LENGTH = 2;
|
||||
export const NAME_MAX_LENGTH = 255;
|
||||
export const TEXT_MAX_LENGTH = 10000;
|
||||
|
|
|
@ -8,6 +8,7 @@ export default {
|
|||
loading: "Loading ..."
|
||||
},
|
||||
error_messages: {
|
||||
text_too_short: "is too short (minimum is {min_length} characters)",
|
||||
text_too_long: "is too long (maximum is {max_length} characters)"
|
||||
},
|
||||
navbar: {
|
||||
|
|
|
@ -1,9 +1,17 @@
|
|||
import React from "react";
|
||||
import React, { Component } from "react";
|
||||
import update from "immutability-helper";
|
||||
import styled from "styled-components";
|
||||
import axios from "../../../../../app/axios";
|
||||
import { Breadcrumb, FormGroup, FormControl, ControlLabel, HelpBlock, Button } from "react-bootstrap";
|
||||
import { LinkContainer } from "react-router-bootstrap";
|
||||
import { FormattedMessage } from "react-intl";
|
||||
import { SETTINGS_TEAMS_ROUTE } from "../../../../../config/routes";
|
||||
import { TEAMS_NEW_PATH } from "../../../../../config/api_endpoints";
|
||||
import {
|
||||
NAME_MIN_LENGTH,
|
||||
NAME_MAX_LENGTH,
|
||||
TEXT_MAX_LENGTH
|
||||
} from "../../../../../config/constants/numeric";
|
||||
|
||||
import { BORDER_LIGHT_COLOR } from "../../../../../config/constants/colors";
|
||||
|
||||
|
@ -18,52 +26,167 @@ const Wrapper = styled.div`
|
|||
padding: 16px 15px 50px 15px;
|
||||
`;
|
||||
|
||||
const SettingsNewTeam = () =>
|
||||
<Wrapper>
|
||||
<Breadcrumb>
|
||||
<LinkContainer to={SETTINGS_TEAMS_ROUTE}>
|
||||
<Breadcrumb.Item>
|
||||
<FormattedMessage id="settings_page.all_teams" />
|
||||
</Breadcrumb.Item>
|
||||
</LinkContainer>
|
||||
<Breadcrumb.Item active={true}>
|
||||
<FormattedMessage id="settings_page.new_team.title" />
|
||||
</Breadcrumb.Item>
|
||||
</Breadcrumb>
|
||||
class SettingsNewTeam extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
team: {
|
||||
name: {
|
||||
value: "",
|
||||
errorMessage: "",
|
||||
},
|
||||
description: {
|
||||
value: "",
|
||||
errorMessage: "",
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
<form style={{ maxWidth: "500px" }}>
|
||||
this.getValidationState = this.getValidationState.bind(this);
|
||||
this.validateField = this.validateField.bind(this);
|
||||
this.handleChange = this.handleChange.bind(this);
|
||||
this.onSubmit = this.onSubmit.bind(this);
|
||||
}
|
||||
|
||||
<FormGroup controlId="formBasicText">
|
||||
<ControlLabel>
|
||||
<FormattedMessage id="settings_page.new_team.name_label" />
|
||||
</ControlLabel>
|
||||
<NameFormControl />
|
||||
<FormControl.Feedback />
|
||||
<HelpBlock>
|
||||
<FormattedMessage id="settings_page.new_team.name_sublabel" />
|
||||
</HelpBlock>
|
||||
</FormGroup>
|
||||
getValidationState(attr) {
|
||||
if (this.state.team[attr].errorMessage.length > 0) {
|
||||
return "error";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
<FormGroup>
|
||||
<ControlLabel>
|
||||
<FormattedMessage id="settings_page.new_team.description_label" />
|
||||
</ControlLabel>
|
||||
<FormControl componentClass="textarea" />
|
||||
<FormControl.Feedback />
|
||||
<HelpBlock>
|
||||
<FormattedMessage id="settings_page.new_team.description_sublabel" />
|
||||
</HelpBlock>
|
||||
</FormGroup>
|
||||
validateField(key, value) {
|
||||
let errorMessage;
|
||||
if (key === "name") {
|
||||
errorMessage = "";
|
||||
|
||||
<LinkContainer to={SETTINGS_TEAMS_ROUTE}>
|
||||
<Button>
|
||||
<FormattedMessage id="general.cancel" />
|
||||
</Button>
|
||||
</LinkContainer>
|
||||
<Button type="submit" className="btn-primary">
|
||||
<FormattedMessage id="settings_page.new_team.create" />
|
||||
</Button>
|
||||
</form>
|
||||
</Wrapper>;
|
||||
if (value.length < NAME_MIN_LENGTH) {
|
||||
errorMessage = <FormattedMessage id="error_messages.text_too_short" values={{ min_length: NAME_MIN_LENGTH }} />;
|
||||
} else if (value.length > NAME_MAX_LENGTH) {
|
||||
errorMessage = <FormattedMessage id="error_messages.text_too_long" values={{ max_length: NAME_MAX_LENGTH }} />;
|
||||
}
|
||||
|
||||
this.newState = update(
|
||||
this.newState,
|
||||
{ team: { name: { errorMessage: { $set: errorMessage } } } }
|
||||
);
|
||||
} else if (key === "description") {
|
||||
errorMessage = "";
|
||||
|
||||
if (value.length > TEXT_MAX_LENGTH) {
|
||||
errorMessage = <FormattedMessage id="error_messages.text_too_long" values={{ max_length: TEXT_MAX_LENGTH }} />;
|
||||
}
|
||||
|
||||
this.newState = update(
|
||||
this.newState,
|
||||
{ team: { description: { errorMessage: { $set: errorMessage } } } }
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
handleChange(e) {
|
||||
const key = e.target.name;
|
||||
const value = e.target.value;
|
||||
|
||||
this.newState = { ...this.state };
|
||||
|
||||
// Update value in the state
|
||||
this.newState = update(
|
||||
this.newState,
|
||||
{ team: { [key]: { value: { $set: value } } } }
|
||||
);
|
||||
|
||||
// Validate the input
|
||||
this.validateField(key, value);
|
||||
|
||||
// Refresh state
|
||||
this.setState(this.newState);
|
||||
}
|
||||
|
||||
onSubmit() {
|
||||
axios({
|
||||
method: "post",
|
||||
url: TEAMS_NEW_PATH,
|
||||
withCredentials: true,
|
||||
data: { team: this.state.team }
|
||||
})
|
||||
.then(response => {
|
||||
// TODO: Redirect to team page
|
||||
})
|
||||
.catch(error => this.setState({ errorMessage: error.message }));
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<Wrapper>
|
||||
<Breadcrumb>
|
||||
<LinkContainer to={SETTINGS_TEAMS_ROUTE}>
|
||||
<Breadcrumb.Item>
|
||||
<FormattedMessage id="settings_page.all_teams" />
|
||||
</Breadcrumb.Item>
|
||||
</LinkContainer>
|
||||
<Breadcrumb.Item active={true}>
|
||||
<FormattedMessage id="settings_page.new_team.title" />
|
||||
</Breadcrumb.Item>
|
||||
</Breadcrumb>
|
||||
|
||||
<form onSubmit={this.onSubmit} style={{ maxWidth: "500px" }}>
|
||||
|
||||
<FormGroup
|
||||
controlId="formTeamName"
|
||||
validationState={this.getValidationState("name")}
|
||||
>
|
||||
<ControlLabel>
|
||||
<FormattedMessage id="settings_page.new_team.name_label" />
|
||||
</ControlLabel>
|
||||
<NameFormControl
|
||||
value={this.state.team.name.value}
|
||||
onChange={this.handleChange}
|
||||
name="name"
|
||||
/>
|
||||
<FormControl.Feedback />
|
||||
<HelpBlock>{this.state.team.name.errorMessage}</HelpBlock>
|
||||
</FormGroup>
|
||||
<small>
|
||||
<FormattedMessage id="settings_page.new_team.name_sublabel" />
|
||||
</small>
|
||||
<br />
|
||||
<br />
|
||||
|
||||
<FormGroup
|
||||
controlId="formTeamDescription"
|
||||
validationState={this.getValidationState("description")}
|
||||
>
|
||||
<ControlLabel>
|
||||
<FormattedMessage id="settings_page.new_team.description_label" />
|
||||
</ControlLabel>
|
||||
<FormControl
|
||||
componentClass="textarea"
|
||||
value={this.state.team.description.value}
|
||||
onChange={this.handleChange}
|
||||
name="description"
|
||||
/>
|
||||
<FormControl.Feedback />
|
||||
<HelpBlock>{this.state.team.description.errorMessage}</HelpBlock>
|
||||
</FormGroup>
|
||||
<small>
|
||||
<FormattedMessage id="settings_page.new_team.description_sublabel" />
|
||||
</small>
|
||||
<br />
|
||||
<br />
|
||||
|
||||
<LinkContainer to={SETTINGS_TEAMS_ROUTE}>
|
||||
<Button>
|
||||
<FormattedMessage id="general.cancel" />
|
||||
</Button>
|
||||
</LinkContainer>
|
||||
<Button type="submit" className="btn-primary">
|
||||
<FormattedMessage id="settings_page.new_team.create" />
|
||||
</Button>
|
||||
</form>
|
||||
</Wrapper>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default SettingsNewTeam;
|
|
@ -51,6 +51,7 @@
|
|||
"extract-text-webpack-plugin": "^3.0.0",
|
||||
"file-loader": "^0.11.2",
|
||||
"glob": "^7.1.2",
|
||||
"immutability-helper": "^2.3.0",
|
||||
"js-yaml": "^3.9.0",
|
||||
"lodash": "^4.17.4",
|
||||
"moment": "^2.18.1",
|
||||
|
|
|
@ -2756,6 +2756,12 @@ ignore@^3.2.0:
|
|||
version "3.3.3"
|
||||
resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.3.3.tgz#432352e57accd87ab3110e82d3fea0e47812156d"
|
||||
|
||||
immutability-helper@^2.3.0:
|
||||
version "2.3.1"
|
||||
resolved "https://registry.yarnpkg.com/immutability-helper/-/immutability-helper-2.3.1.tgz#8ccfce92157208c120b2afad7ed05c11114c086e"
|
||||
dependencies:
|
||||
invariant "^2.2.0"
|
||||
|
||||
imurmurhash@^0.1.4:
|
||||
version "0.1.4"
|
||||
resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea"
|
||||
|
@ -2845,7 +2851,7 @@ intl-relativeformat@^1.3.0:
|
|||
dependencies:
|
||||
intl-messageformat "1.3.0"
|
||||
|
||||
invariant@^2.0.0, invariant@^2.1.0, invariant@^2.1.1, invariant@^2.2.1, invariant@^2.2.2:
|
||||
invariant@^2.0.0, invariant@^2.1.0, invariant@^2.1.1, invariant@^2.2.0, invariant@^2.2.1, invariant@^2.2.2:
|
||||
version "2.2.2"
|
||||
resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.2.tgz#9e1f56ac0acdb6bf303306f338be3b204ae60360"
|
||||
dependencies:
|
||||
|
|
Loading…
Add table
Reference in a new issue