diff --git a/app/javascript/packs/src/settings/components/teams/new/components/NameFormControl.jsx b/app/javascript/packs/src/settings/components/teams/new/components/NameFormControl.jsx index 37c0541ad..4bfea4456 100644 --- a/app/javascript/packs/src/settings/components/teams/new/components/NameFormControl.jsx +++ b/app/javascript/packs/src/settings/components/teams/new/components/NameFormControl.jsx @@ -7,11 +7,12 @@ const messages = defineMessages({ placeholder: { id: "settings_page.new_team.name_placeholder" } }); -const NameFormControl = ({intl}) => +const NameFormControl = ({ intl, ...props }) => ; NameFormControl.PropTypes = { diff --git a/app/javascript/src/config/api_endpoints.js b/app/javascript/src/config/api_endpoints.js index b0837e8d6..6b243daef 100644 --- a/app/javascript/src/config/api_endpoints.js +++ b/app/javascript/src/config/api_endpoints.js @@ -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"; diff --git a/app/javascript/src/config/constants/numeric.js b/app/javascript/src/config/constants/numeric.js index 1ed90ac4d..601d72a10 100644 --- a/app/javascript/src/config/constants/numeric.js +++ b/app/javascript/src/config/constants/numeric.js @@ -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; diff --git a/app/javascript/src/config/locales/messages.js b/app/javascript/src/config/locales/messages.js index c17319fb7..798c7bebd 100644 --- a/app/javascript/src/config/locales/messages.js +++ b/app/javascript/src/config/locales/messages.js @@ -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: { diff --git a/app/javascript/src/scenes/SettingsPage/scenes/teams/new/index.jsx b/app/javascript/src/scenes/SettingsPage/scenes/teams/new/index.jsx index 5b5e84f40..b4c4f64df 100644 --- a/app/javascript/src/scenes/SettingsPage/scenes/teams/new/index.jsx +++ b/app/javascript/src/scenes/SettingsPage/scenes/teams/new/index.jsx @@ -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 = () => - - - - - - - - - - - +class SettingsNewTeam extends Component { + constructor(props) { + super(props); + this.state = { + team: { + name: { + value: "", + errorMessage: "", + }, + description: { + value: "", + errorMessage: "", + } + } + }; -
+ this.getValidationState = this.getValidationState.bind(this); + this.validateField = this.validateField.bind(this); + this.handleChange = this.handleChange.bind(this); + this.onSubmit = this.onSubmit.bind(this); + } - - - - - - - - - - + getValidationState(attr) { + if (this.state.team[attr].errorMessage.length > 0) { + return "error"; + } + return null; + } - - - - - - - - - - + validateField(key, value) { + let errorMessage; + if (key === "name") { + errorMessage = ""; - - - - -
-
; + if (value.length < NAME_MIN_LENGTH) { + errorMessage = ; + } else if (value.length > NAME_MAX_LENGTH) { + errorMessage = ; + } + + this.newState = update( + this.newState, + { team: { name: { errorMessage: { $set: errorMessage } } } } + ); + } else if (key === "description") { + errorMessage = ""; + + if (value.length > TEXT_MAX_LENGTH) { + errorMessage = ; + } + + 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 ( + + + + + + + + + + + + +
+ + + + + + + + {this.state.team.name.errorMessage} + + + + +
+
+ + + + + + + + {this.state.team.description.errorMessage} + + + + +
+
+ + + + + +
+
+ ); + } +} export default SettingsNewTeam; \ No newline at end of file diff --git a/package.json b/package.json index ad2c953f7..0371cd7c3 100644 --- a/package.json +++ b/package.json @@ -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", diff --git a/yarn.lock b/yarn.lock index 9e8f9b798..c0ce92ca1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -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: