adds edit team name modal

This commit is contained in:
zmagod 2017-09-15 14:00:48 +02:00
parent 1a00b53034
commit 83647d81b4
6 changed files with 191 additions and 13 deletions

View file

@ -40,7 +40,7 @@ module ClientApi
private
def team_params
params.require(:team).permit(:description)
params.require(:team).permit(:description, :name)
end
def success_response(template, locals)

View file

@ -1,2 +1,3 @@
export const ENTER_KEY_CODE = 13;
export const TEXT_MAX_LENGTH = 10000;
export const NAME_MAX_LENGTH = 255;

View file

@ -83,6 +83,10 @@ export default {
title: "Edit team description",
label: "Description"
},
update_team_name_modal: {
title: "Edit team name",
label: "Name"
},
single_team: {
created_on: "Created on: <strong>{created_at}</strong>",
created_by: "Created by: <strong>{created_by}</strong>",

View file

@ -1,5 +1,6 @@
import React, { Component } from "react";
import ReactRouterPropTypes from "react-router-prop-types";
import { Link } from "react-router-dom";
import styled from "styled-components";
import { Row, Col, Glyphicon, Well } from "react-bootstrap";
import { FormattedHTMLMessage, FormattedMessage } from "react-intl";
@ -7,7 +8,7 @@ import moment from "moment";
import prettysize from "prettysize";
import axios from "../../../../app/axios";
import { TEAM_DETAILS_PATH } from "../../../../app/routes";
import { TEAM_DETAILS_PATH, SETTINGS_TEAMS } from "../../../../app/routes";
import {
BORDER_LIGHT_COLOR,
COLOR_CONCRETE
@ -15,6 +16,7 @@ import {
import TeamsMembers from "./components/TeamsMembers";
import UpdateTeamDescriptionModal from "./components/UpdateTeamDescriptionModal";
import UpdateTeamNameModal from "./components/UpdateTeamNameModal";
const Wrapper = styled.div`
background: white;
@ -25,10 +27,7 @@ const Wrapper = styled.div`
padding: 16px 15px 50px 15px;
`;
const TabTitle = styled.div`
background-color: ${COLOR_CONCRETE};
padding: 15px;
`;
const TabTitle = styled.div`padding: 15px;`;
const BadgeWrapper = styled.div`
font-size: 1.4em;
@ -45,11 +44,21 @@ const StyledWell = styled(Well)`
}
`;
const StyledH3 = styled.h3`
&:hover {
text-decoration: underline;
cursor: pointer;
}
`;
const StyledOl = styled.ol`padding: 15px;`;
class SettingsTeamPageContainer extends Component {
constructor(props) {
super(props);
this.state = {
showModal: false,
showDescriptionModal: false,
showNameModal: false,
users: [],
team: {
id: 0,
@ -66,6 +75,8 @@ class SettingsTeamPageContainer extends Component {
);
this.updateTeamCallback = this.updateTeamCallback.bind(this);
this.updateUsersCallback = this.updateUsersCallback.bind(this);
this.showNameModal = this.showNameModal.bind(this);
this.hideNameModalCallback = this.hideNameModalCallback.bind(this);
}
componentDidMount() {
@ -78,11 +89,19 @@ class SettingsTeamPageContainer extends Component {
}
showDescriptionModal() {
this.setState({ showModal: true });
this.setState({ showDescriptionModal: true });
}
hideDescriptionModalCallback() {
this.setState({ showModal: false });
this.setState({ showDescriptionModal: false });
}
showNameModal() {
this.setState({ showNameModal: true });
}
hideNameModalCallback() {
this.setState({ showNameModal: false });
}
updateTeamCallback(team) {
@ -105,9 +124,20 @@ class SettingsTeamPageContainer extends Component {
render() {
return (
<Wrapper>
<StyledOl className="breadcrumb">
<li>
<Link to={SETTINGS_TEAMS}>
<FormattedMessage id="settings_page.all_teams" />
</Link>
</li>
<li className="active">
{this.state.team.name}
</li>
</StyledOl>
<TabTitle>
<FormattedMessage id="settings_page.all_teams" />
{` / ${this.state.team.name}`}
<StyledH3 onClick={this.showNameModal}>
{this.state.team.name}
</StyledH3>
</TabTitle>
<Row>
<Col xs={6} sm={3}>
@ -166,11 +196,17 @@ class SettingsTeamPageContainer extends Component {
team={this.state.team}
/>
<UpdateTeamDescriptionModal
showModal={this.state.showModal}
showModal={this.state.showDescriptionModal}
hideModal={this.hideDescriptionModalCallback}
team={this.state.team}
updateTeamCallback={this.updateTeamCallback}
/>
<UpdateTeamNameModal
showModal={this.state.showNameModal}
hideModal={this.hideNameModalCallback}
team={this.state.team}
updateTeamCallback={this.updateTeamCallback}
/>
</Wrapper>
);
}

View file

@ -66,7 +66,7 @@ class UpdateTeamDescriptionModal extends Component {
withCredentials: true,
data: {
team_id: this.props.team.id,
description: this.state.description
team: { description: this.state.description }
}
})
.then(response => {

View file

@ -0,0 +1,137 @@
import React, { Component } from "react";
import PropTypes, { bool, number, string, func } from "prop-types";
import {
Modal,
Button,
FormGroup,
ControlLabel,
FormControl,
HelpBlock
} from "react-bootstrap";
import { FormattedMessage } from "react-intl";
import _ from "lodash";
import styled from "styled-components";
import axios from "../../../../../app/axios";
import { NAME_MAX_LENGTH } from "../../../../../app/constants/numeric";
import { TEAM_UPDATE_PATH } from "../../../../../app/routes";
import { COLOR_APPLE_BLOSSOM } from "../../../../../app/constants/colors";
const StyledHelpBlock = styled(HelpBlock)`
color: ${COLOR_APPLE_BLOSSOM}
`;
class UpdateTeamNameModal extends Component {
constructor(props) {
super(props);
this.state = { errorMessage: "", name: "" };
this.onCloseModal = this.onCloseModal.bind(this);
this.updateName = this.updateName.bind(this);
this.handleName = this.handleName.bind(this);
this.getValidationState = this.getValidationState.bind(this);
}
componentDidMount() {
this.setState({ name: this.props.team.name });
}
onCloseModal() {
this.setState({ errorMessage: "", name: "" });
this.props.hideModal();
}
getValidationState() {
if (this.state.errorMessage.length > 0) {
return "error";
}
return null;
}
handleName(el) {
const { value } = el.target;
if (value.length > NAME_MAX_LENGTH) {
this.setState({
errorMessage: (
<FormattedMessage
id="error_messages.text_too_long"
values={{ max_length: NAME_MAX_LENGTH }}
/>
)
});
} else {
this.setState({ errorMessage: "", name: value });
}
}
updateName() {
axios({
method: "post",
url: TEAM_UPDATE_PATH,
withCredentials: true,
data: {
team_id: this.props.team.id,
team: { name: this.state.name }
}
})
.then(response => {
this.props.updateTeamCallback(response.data.team);
this.onCloseModal();
})
.catch(error => this.setState({ errorMessage: error.message }));
}
render() {
return (
<Modal show={this.props.showModal} onHide={this.onCloseModal}>
<Modal.Header closeButton>
<Modal.Title>
<FormattedMessage id="settings_page.update_team_name_modal.title" />
</Modal.Title>
</Modal.Header>
<Modal.Body>
<FormGroup
controlId="teamName"
validationState={this.getValidationState()}
>
<ControlLabel>
<FormattedMessage id="settings_page.update_team_name_modal.label" />
</ControlLabel>
<FormControl
type="text"
onChange={this.handleName}
value={this.state.name}
/>
<FormControl.Feedback />
<StyledHelpBlock>
{this.state.errorMessage}
</StyledHelpBlock>
</FormGroup>
</Modal.Body>
<Modal.Footer>
<Button onClick={this.onCloseModal}>
<FormattedMessage id="general.close" />
</Button>
<Button
bsStyle="success"
onClick={this.updateName}
disabled={!_.isEmpty(this.state.errorMessage)}
>
<FormattedMessage id="general.update" />
</Button>
</Modal.Footer>
</Modal>
);
}
}
UpdateTeamNameModal.propTypes = {
showModal: bool.isRequired,
hideModal: func.isRequired,
team: PropTypes.shape({
id: number.isRequired,
name: string
}).isRequired,
updateTeamCallback: func.isRequired
};
export default UpdateTeamNameModal;