removes modalContaine, move leaveTeamModal under teams

This commit is contained in:
zmagod 2017-10-23 15:02:04 +02:00
parent 7d6d95630d
commit 545cf50993
17 changed files with 173 additions and 167 deletions

View file

@ -1,7 +0,0 @@
import React from "react";
import LeaveTeamModal from "./modals/LeaveTeamModal";
export default () =>
<div>
<LeaveTeamModal />
</div>;

View file

@ -1,41 +1,37 @@
import axios from "../../config/axios";
import _ from "lodash";
import { TEAMS_PATH, CHANGE_TEAM_PATH } from "../../config/api_endpoints";
// @flow
import type {
Teams$Team,
Action$LeaveTeam,
Action$AddTeamData,
Actopm$SetCurrentTeam
} from "flow-typed";
import type { Dispatch } from "redux-thunk";
import { getTeams, changeCurrentTeam } from "../../services/api/teams_api";
import {
GET_LIST_OF_TEAMS,
SET_CURRENT_TEAM,
SHOW_LEAVE_TEAM_MODAL
SET_CURRENT_TEAM
} from "../../config/action_types";
export function leaveTeamModalShow(show = false, team = {}) {
return {
payload: { team, show },
type: SHOW_LEAVE_TEAM_MODAL
};
}
export function addTeamsData(data) {
export function addTeamsData(data: Array<Teams$Team>): Action$AddTeamData {
return {
type: GET_LIST_OF_TEAMS,
payload: data
};
}
export function setCurrentTeam(team) {
export function setCurrentTeam(team: Teams$Team): Actopm$SetCurrentTeam {
return {
team,
type: SET_CURRENT_TEAM
};
}
export function getTeamsList() {
export function getTeamsList(): Dispatch {
return dispatch => {
axios
.get(TEAMS_PATH, { withCredentials: true })
getTeams()
.then(response => {
const teams = response.data.teams.collection;
const { teams, currentTeam } = response;
dispatch(addTeamsData(teams));
const currentTeam = _.find(teams, team => team.current_team);
dispatch(setCurrentTeam(currentTeam));
})
.catch(error => {
@ -44,14 +40,12 @@ export function getTeamsList() {
};
}
export function changeTeam(team_id) {
export function changeTeam(teamID: number): Dispatch {
return dispatch => {
axios
.post(CHANGE_TEAM_PATH, { team_id }, { withCredentials: true })
changeCurrentTeam(teamID)
.then(response => {
const teams = response.data.teams.collection;
const { teams, currentTeam } = response;
dispatch(addTeamsData(teams));
const currentTeam = _.find(teams, team => team.current_team);
dispatch(setCurrentTeam(currentTeam));
})
.catch(error => {

View file

@ -1,7 +1,6 @@
import {
SET_CURRENT_TEAM,
GET_LIST_OF_TEAMS,
SHOW_LEAVE_TEAM_MODAL
GET_LIST_OF_TEAMS
} from "../../config/action_types";
export const setCurrentTeam = (
@ -23,13 +22,3 @@ export const getListOfTeams = (state = { collection: [] }, action) => {
}
return state;
};
export const showLeaveTeamModal = (
state = { show: false, team: { id: 0, name: "", user_team_id: 0 } },
action
) => {
if (action.type === SHOW_LEAVE_TEAM_MODAL) {
return { ...state, ...action.payload };
}
return state;
};

View file

@ -1,20 +1,18 @@
// @flow
// teams
export const SET_CURRENT_TEAM = "SET_CURRENT_TEAM";
export const GET_LIST_OF_TEAMS = "GET_LIST_OF_TEAMS";
export const SET_TEAM_DETAILS = "SET_TEAM_DETAILS";
export const SET_CURRENT_TEAM: string = "SET_CURRENT_TEAM";
export const GET_LIST_OF_TEAMS: string = "GET_LIST_OF_TEAMS";
export const SET_TEAM_DETAILS: string = "SET_TEAM_DETAILS";
// users
export const USER_LOGOUT = "USER_LOGOUT";
export const SET_CURRENT_USER = "SET_CURRENT_USER";
export const USER_LOGOUT: string = "USER_LOGOUT";
export const SET_CURRENT_USER: string = "SET_CURRENT_USER";
// user teams
export const LEAVE_TEAM = "LEAVE_TEAM";
// modals
export const SHOW_LEAVE_TEAM_MODAL = "SHOW_LEAVE_TEAM_MODAL";
export const UPDATE_TEAM_DESCRIPTION_MODAL = "UPDATE_TEAM_DESCRIPTION_MODAL";
export const LEAVE_TEAM: string = "LEAVE_TEAM";
// alerts
export const ADD_ALERT = "ADD_ALERT";
export const CLEAR_ALERT = "CLEAR_ALERT";
export const CLEAR_ALL_ALERTS = "CLEAR_ALL_ALERTS";
export const ADD_ALERT: string = "ADD_ALERT";
export const CLEAR_ALERT: string = "CLEAR_ALERT";
export const CLEAR_ALL_ALERTS: string = "CLEAR_ALL_ALERTS";

View file

@ -1,26 +0,0 @@
// settings
export const SETTINGS_PATH = "/settings";
export const SETTINGS_ACCOUNT_PATH = "/settings/account";
// teams
export const TEAMS_PATH = "/client_api/teams";
export const CHANGE_TEAM_PATH = "/client_api/teams/change_team";
export const TEAM_DETAILS_PATH = "/client_api/teams/:team_id/details";
// search
export const SEARCH_PATH = "/search";
// notifications
export const RECENT_NOTIFICATIONS_PATH = "/client_api/recent_notifications";
// info dropdown_title
export const CUSTOMER_SUPPORT_LINK = "http://scinote.net/support";
export const TUTORIALS_LINK = "http://scinote.net/product/tutorials/";
export const RELEASE_NOTES_LINK = "http://scinote.net/docs/release-notes/";
export const PREMIUM_LINK = "http://scinote.net/premium/";
export const CONTACT_US_LINK =
"http://scinote.net/story-of-scinote/#contact-scinote";
// user teams
export const LEAVE_TEAM_PATH = "/client_api/users/leave_team";
// settings
export const SETTINGS_TEAMS = "/settings/teams";

View file

@ -1,19 +0,0 @@
// @TODO remove this file ASAP the preferences/profile refactoring is merged
import axios from "axios";
import store from "./store";
import { SIGN_IN_PATH } from "./routes";
import { destroyState } from "../components/actions/UsersActions";
export default axios.create({
withCredentials: true,
headers: {
"X-CSRF-TOKEN": document.querySelector('meta[name="csrf-token"]').content
},
validateStatus(status) {
if (status === 401) {
store.dispatch(destroyState);
window.location = SIGN_IN_PATH;
}
return status >= 200 && status < 300;
}
});

View file

@ -2,8 +2,7 @@ import { combineReducers } from "redux";
import { USER_LOGOUT } from "./action_types";
import {
setCurrentTeam,
getListOfTeams,
showLeaveTeamModal
getListOfTeams
} from "../components/reducers/TeamReducers";
import { currentUser } from "../components/reducers/UsersReducer";
import { alerts } from "../components/reducers/AlertsReducers";
@ -12,7 +11,6 @@ const appReducer = combineReducers({
current_team: setCurrentTeam,
all_teams: getListOfTeams,
current_user: currentUser,
showLeaveTeamModal,
alerts
});

View file

@ -2,8 +2,21 @@ export const ROOT_PATH = "/";
export const SIGN_IN_PATH = "/users/sign_in";
// Settings page
export const SETTINGS_PATH = "/settings";
export const SETTINGS_TEAMS_ROUTE = "/settings/teams";
export const SETTINGS_TEAM_ROUTE = "/settings/teams/:id";
export const SETTINGS_NEW_TEAM_ROUTE = "/settings/teams/new";
export const SETTINGS_ACCOUNT_PROFILE = "/settings/account/profile";
export const SETTINGS_ACCOUNT_PREFERENCES = "/settings/account/preferences";
// search
export const SEARCH_PATH = "/search";
// info dropdown_title
export const CUSTOMER_SUPPORT_LINK = "http://scinote.net/support";
export const TUTORIALS_LINK = "http://scinote.net/product/tutorials/";
export const RELEASE_NOTES_LINK = "http://scinote.net/docs/release-notes/";
export const PREMIUM_LINK = "http://scinote.net/premium/";
export const CONTACT_US_LINK =
"http://scinote.net/story-of-scinote/#contact-scinote";

View file

@ -9,7 +9,6 @@ import messages from "./config/locales/messages";
import store from "./config/store";
import AlertsContainer from "./components/AlertsContainer";
import ModalsContainer from "./components/ModalsContainer";
import SettingsPage from "./scenes/SettingsPage";
import Navigation from "./components/Navigation";
@ -34,7 +33,6 @@ const ScinoteApp = () =>
</ContentWrapper>
</div>
</BrowserRouter>
<ModalsContainer />
</div>
</IntlProvider>
</Provider>;

View file

@ -7,6 +7,7 @@ import { FormattedMessage } from "react-intl";
import {
ROOT_PATH,
SETTINGS_PATH,
SETTINGS_TEAMS_ROUTE,
SETTINGS_TEAM_ROUTE,
SETTINGS_ACCOUNT_PROFILE,
@ -14,8 +15,6 @@ import {
SETTINGS_NEW_TEAM_ROUTE
} from "../../config/routes";
import { SETTINGS_PATH, SETTINGS_TEAMS } from "../../config/api_endpoints";
import PageTitle from "../../components/PageTitle";
import NotFound from "../../components/404/NotFound";
import SettingsProfile from "./scenes/profile";
@ -74,7 +73,7 @@ export default class SettingsPage extends Component<*, State> {
</NavItem>
</LinkContainer>
<LinkContainer
to={SETTINGS_TEAMS}
to={SETTINGS_TEAMS_ROUTE}
active={this.state.active === "2"}
>
<NavItem eventKey="2">

View file

@ -3,14 +3,12 @@ import PropTypes, { bool, number, string, func } from "prop-types";
import { Modal, Button, Alert, Glyphicon } from "react-bootstrap";
import { FormattedMessage, FormattedHTMLMessage } from "react-intl";
import { connect } from "react-redux";
import axios from "../../../config/axios";
import { leaveTeam } from "../../../../../services/api/teams_api";
import { LEAVE_TEAM_PATH } from "../../../config/api_endpoints";
import {
addTeamsData,
setCurrentTeam,
leaveTeamModalShow
} from "../../actions/TeamsActions";
setCurrentTeam
} from "../../../../../components/actions/TeamsActions";
class LeaveTeamModal extends Component {
constructor(props) {
@ -20,26 +18,22 @@ class LeaveTeamModal extends Component {
}
onCloseModal() {
this.props.leaveTeamModalShow(false);
this.props.hideLeaveTeamModel();
}
leaveTeam() {
const teamUrl = `${LEAVE_TEAM_PATH}?team=${this.props.team
.id}&user_team=${this.props.team.user_team_id}`;
axios
.delete(teamUrl, {
withCredentials: true
})
const { id, user_team_id } = this.props.team;
leaveTeam(id, user_team_id)
.then(response => {
const teams = response.data.teams.collection;
const { teams, currentTeam } = response;
this.props.updateTeamsState(teams);
this.props.addTeamsData(teams);
const currentTeam = _.find(teams, team => team.current_team);
this.props.setCurrentTeam(currentTeam);
})
.catch(error => {
console.log("error: ", error.response.data.message);
});
this.props.leaveTeamModalShow(false);
this.props.hideLeaveTeamModel();
}
render() {
@ -90,6 +84,7 @@ class LeaveTeamModal extends Component {
}
LeaveTeamModal.propTypes = {
updateTeamsState: func.isRequired,
showModal: bool.isRequired,
team: PropTypes.shape({
id: number.isRequired,
@ -97,17 +92,11 @@ LeaveTeamModal.propTypes = {
user_team_id: number.isRequired
}).isRequired,
addTeamsData: func.isRequired,
leaveTeamModalShow: func.isRequired,
hideLeaveTeamModel: func.isRequired,
setCurrentTeam: func.isRequired
};
const mapStateToProps = ({ showLeaveTeamModal }) => ({
showModal: showLeaveTeamModal.show,
team: showLeaveTeamModal.team
});
export default connect(mapStateToProps, {
leaveTeamModalShow,
export default connect(null, {
addTeamsData,
setCurrentTeam
})(LeaveTeamModal);

View file

@ -1,24 +1,40 @@
import React, { Component } from "react";
import PropTypes, { func, number, string, bool } from "prop-types";
import { connect } from "react-redux";
import { Button } from "react-bootstrap";
import { Link } from "react-router-dom";
import { FormattedMessage } from "react-intl";
import { leaveTeamModalShow } from "../../../../../components/actions/TeamsActions";
import DataTable from "../../../../../components/data_table";
import { SETTINGS_TEAMS_ROUTE } from "../../../../../config/routes";
import LeaveTeamModal from "./LeaveTeamModal";
const DefaultTeam = {
id: 0,
name: "",
current_team: false,
user_team_id: 0,
role: "",
members: 0,
can_be_leaved: false
};
class TeamsDataTable extends Component {
constructor(props) {
super(props);
this.state = {
leaveTeamModalShow: false,
team: DefaultTeam
};
this.leaveTeamModal = this.leaveTeamModal.bind(this);
this.leaveTeamButton = this.leaveTeamButton.bind(this);
this.linkToTeam = this.linkToTeam.bind(this);
this.hideLeaveTeamModel = this.hideLeaveTeamModel.bind(this);
}
leaveTeamModal(e, team) {
this.props.leaveTeamModalShow(true, team);
this.setState({ leaveTeamModalShow: true, team });
}
hideLeaveTeamModel() {
this.setState({ leaveTeamModalShow: false, team: DefaultTeam });
}
leaveTeamButton(id, team) {
@ -90,18 +106,26 @@ class TeamsDataTable extends Component {
}
];
return (
<DataTable
data={this.props.teams}
columns={columns}
pagination
options={options}
/>
<div>
<DataTable
data={this.props.teams}
columns={columns}
pagination
options={options}
/>
<LeaveTeamModal
updateTeamsState={this.props.updateTeamsState}
showModal={this.state.leaveTeamModalShow}
team={this.state.team}
hideLeaveTeamModel={this.hideLeaveTeamModel}
/>
</div>
);
}
}
TeamsDataTable.propTypes = {
leaveTeamModalShow: func.isRequired,
updateTeamsState: func.isRequired,
teams: PropTypes.arrayOf(
PropTypes.shape({
id: number.isRequired,
@ -114,4 +138,4 @@ TeamsDataTable.propTypes = {
)
};
export default connect(null, { leaveTeamModalShow })(TeamsDataTable);
export default TeamsDataTable;

View file

@ -3,11 +3,8 @@
import React, { Component } from "react";
import styled from "styled-components";
import { Breadcrumb } from "react-bootstrap";
import { connect } from "react-redux";
import { FormattedMessage } from "react-intl";
import type { State } from "flow-typed";
import type { MapStateToProps } from "react-redux";
import { getTeams } from "../../../../services/api/teams_api";
import { BORDER_LIGHT_COLOR } from "../../../../config/constants/colors";
import PageTitle from "../../../../components/PageTitle";
@ -24,22 +21,44 @@ const Wrapper = styled.div`
`;
type Props = {
tabState: Function,
tabState: Function
};
type State = {
teams: Array<Teams$Team>
};
class SettingsTeams extends Component<Props> {
static defaultProps = {
teams: [{ id: 0, name: "", current_team: "", role: "", members: 0 }]
};
class SettingsTeams extends Component<Props, State> {
constructor(props: Props) {
super(props);
this.state = {
teams: [
{
id: 0,
name: "",
current_team: true,
role: "",
members: 0,
can_be_leaved: false
}
]
};
(this: any).updateTeamsState = this.updateTeamsState.bind(this);
}
componentDidMount() {
getTeams().then(({ teams }) => {
this.updateTeamsState(teams);
});
// set team tab on active
this.props.tabState("2");
}
updateTeamsState(teams: Array<Teams$Team>): void {
this.setState({ teams });
}
render() {
const { teams } = this.props;
return (
<PageTitle localeID="page_title.all_teams_page">
<Wrapper>
@ -48,16 +67,15 @@ class SettingsTeams extends Component<Props> {
<FormattedMessage id="settings_page.all_teams" />
</Breadcrumb.Item>
</Breadcrumb>
<TeamsPageDetails teams={teams} />
<TeamsDataTable teams={teams} />
<TeamsPageDetails teams={this.state.teams} />
<TeamsDataTable
teams={this.state.teams}
updateTeamsState={this.updateTeamsState}
/>
</Wrapper>
</PageTitle>
);
}
}
const mapStateToProps: MapStateToProps<*, *, *> = (state: State) => ({
teams: state.all_teams.collection
});
export default connect(mapStateToProps)(SettingsTeams);
export default SettingsTeams;

View file

@ -8,7 +8,7 @@ export const ACTIVITIES_PATH = "/client_api/activities";
// settings
export const SETTINGS_PATH = "/settings";
export const SETTINGS_ACCOUNT_PATH = "/settings/account";
// teams
export const TEAMS_PATH = "/client_api/teams";
export const CHANGE_TEAM_PATH = "/client_api/teams/change_team";
@ -16,9 +16,6 @@ export const TEAM_DETAILS_PATH = "/client_api/teams/:team_id/details";
export const TEAM_UPDATE_PATH = "/client_api/teams/update";
export const CURRENT_USER_PATH = "/client_api/current_user_info"
// search
export const SEARCH_PATH = "/search";
// users
export const USER_PROFILE_INFO = "/client_api/users/profile_info";
export const UPDATE_USER_PATH = "/client_api/users/update";

View file

@ -1,7 +1,14 @@
// @flow
import type { Teams$NewTeam, Team$Update } from "flow-typed";
import _ from "lodash";
import { axiosInstance } from "./config";
import { TEAM_DETAILS_PATH, TEAMS_PATH, TEAM_UPDATE_PATH } from "./endpoints";
import {
TEAM_DETAILS_PATH,
TEAM_UPDATE_PATH,
TEAMS_PATH,
CHANGE_TEAM_PATH,
LEAVE_TEAM_PATH
} from "./endpoints";
export const getTeamDetails = (teamID: number): Promise<*> => {
const path = TEAM_DETAILS_PATH.replace(":team_id", teamID);
@ -15,3 +22,26 @@ export const updateTeam = (teamID: number, teamData: Team$Update): Promise<*> =>
axiosInstance
.post(TEAM_UPDATE_PATH, { team_id: teamID, team: teamData })
.then(({ data }) => data.team);
export const getTeams = (): Promise<*> =>
axiosInstance.get(TEAMS_PATH).then(({ data }) => {
const teams = data.teams.collection;
const currentTeam = _.find(teams, team => team.current_team);
return { teams, currentTeam };
});
export const changeCurrentTeam = (teamID: number): Promise<*> =>
axiosInstance.post(CHANGE_TEAM_PATH, { team_id: teamID }).then(({ data }) => {
const teams = data.teams.collection;
const currentTeam = _.find(teams, team => team.current_team);
return { teams, currentTeam };
});
export const leaveTeam = (teamID: number, userTeamID: number): Promise<*> => {
const teamUrl = `${LEAVE_TEAM_PATH}?team=${teamID}&user_team=${userTeamID}`;
return axiosInstance.delete(teamUrl).then(({ data }) => {
const teams = data.teams.collection;
const currentTeam = _.find(teams, team => team.current_team);
return { teams, currentTeam };
});
};

12
flow-typed/action_types.js vendored Normal file
View file

@ -0,0 +1,12 @@
// @flow
import type { Teams$Team } from "flow-typed";
export type Action$AddTeamData = {
payload: Array<Teams$Team>,
type: "GET_LIST_OF_TEAMS"
}
export type Actopm$SetCurrentTeam = {
team: Teams$Team,
action: "SET_CURRENT_TEAM"
}

View file

@ -21,7 +21,6 @@ export type Teams$NewTeam = {
description: string
};
export type Teams$Team = {
id: number,
name: string,