diff --git a/app/controllers/client_api/users/user_teams_controller.rb b/app/controllers/client_api/users/user_teams_controller.rb new file mode 100644 index 000000000..40f486f51 --- /dev/null +++ b/app/controllers/client_api/users/user_teams_controller.rb @@ -0,0 +1,17 @@ +module ClientApi + module Users + class UserTeamsController < ApplicationController + + def leave_team + byebug + respond_to do |format| + format.json do + render template: '/client_api/users/show', + status: :ok, + locals: { user: current_user } + end + end + end + end + end +end diff --git a/app/javascript/packs/app/action_types.js b/app/javascript/packs/app/action_types.js index 059d8c6a6..373dd0de5 100644 --- a/app/javascript/packs/app/action_types.js +++ b/app/javascript/packs/app/action_types.js @@ -22,3 +22,7 @@ export const CHANGE_RECENT_NOTIFICATION_EMAIL = "CHANGE_RECENT_NOTIFICATION_EMAIL"; export const CHANGE_SYSTEM_MESSAGE_NOTIFICATION_EMAIL = "CHANGE_SYSTEM_MESSAGE_NOTIFICATION_EMAIL"; + +// user teams +export const LEAVE_TEAM = "LEAVE_TEAM" +export const SHOW_LEAVE_TEAM_MODAL = "SHOW_LEAVE_TEAM_MODAL" diff --git a/app/javascript/packs/app/constants/colors.js b/app/javascript/packs/app/constants/colors.js index 4150eaa14..686dbb53f 100644 --- a/app/javascript/packs/app/constants/colors.js +++ b/app/javascript/packs/app/constants/colors.js @@ -11,6 +11,7 @@ export const NOTIFICATION_YES = "#5a8921"; export const NOTIFICATION_YES_BORDER = "#4d751c"; export const SIDEBAR_HOVER_GRAY_COLOR = "#D2D2D2"; +export const COLOR_CONCRETE = "#f2f2f2"; export const COLOR_ALTO = "#dddddd"; export const COLOR_GRAY = "#909088"; export const COLOR_ALABASTER = "#fcfcfc"; diff --git a/app/javascript/packs/app/reducers.js b/app/javascript/packs/app/reducers.js index d83169529..0cfd67fc9 100644 --- a/app/javascript/packs/app/reducers.js +++ b/app/javascript/packs/app/reducers.js @@ -5,10 +5,12 @@ import { } from "../shared/reducers/TeamReducers"; import { globalActivities } from "../shared/reducers/ActivitiesReducers"; import { currentUser } from "../shared/reducers/UsersReducer"; +import { showLeaveTeamModal } from "../shared/reducers/LeaveTeamReducer"; export default combineReducers({ current_team: setCurrentTeam, all_teams: getListOfTeams, global_activities: globalActivities, - current_user: currentUser + current_user: currentUser, + showLeaveTeamModal }); diff --git a/app/javascript/packs/app/routes.js b/app/javascript/packs/app/routes.js index 373db2b32..4f926c2d5 100644 --- a/app/javascript/packs/app/routes.js +++ b/app/javascript/packs/app/routes.js @@ -22,6 +22,9 @@ 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_ACCOUNT_PROFILE = "/settings/account/profile"; export const SETTINGS_ACCOUNT_PREFERENCES = "/settings/account/preferences"; diff --git a/app/javascript/packs/locales/messages.js b/app/javascript/packs/locales/messages.js index a47793a62..a09f1c488 100644 --- a/app/javascript/packs/locales/messages.js +++ b/app/javascript/packs/locales/messages.js @@ -11,6 +11,9 @@ export default { page_title: "sciNote" }, settings_page: { + all_teams: "All teams", + in_team: "You are member of {num} team", + in_teams: "You are member of {num} team", account: "Account", team: "Team", avatar: "Avatar", diff --git a/app/javascript/packs/shared/actions/LeaveTeamActions.js b/app/javascript/packs/shared/actions/LeaveTeamActions.js new file mode 100644 index 000000000..1274795de --- /dev/null +++ b/app/javascript/packs/shared/actions/LeaveTeamActions.js @@ -0,0 +1,8 @@ +import { SHOW_LEAVE_TEAM_MODAL } from "../../app/action_types"; + +export function leaveTeamModalShow(show, id) { + return({ + payload: { show, id }, + type: SHOW_LEAVE_TEAM_MODAL + }); +} diff --git a/app/javascript/packs/shared/actions/TeamsActions.js b/app/javascript/packs/shared/actions/TeamsActions.js index a1410c1fa..b16fa5eab 100644 --- a/app/javascript/packs/shared/actions/TeamsActions.js +++ b/app/javascript/packs/shared/actions/TeamsActions.js @@ -22,10 +22,10 @@ export function getTeamsList() { axios .get(TEAMS_PATH, { withCredentials: true }) .then(response => { - let teams = _.values(response.data); + const teams = response.data.teams.collection; dispatch(addTeamsData(teams)); - let current_team = _.find(teams, team => team.current_team); - dispatch(setCurrentUser(current_team)); + const currentTeam = _.find(teams, team => team.current_team); + dispatch(setCurrentUser(currentTeam)); }) .catch(error => { console.log("get Teams Error: ", error); diff --git a/app/javascript/packs/shared/modals_container/index.jsx b/app/javascript/packs/shared/modals_container/index.jsx new file mode 100644 index 000000000..7cf9aff55 --- /dev/null +++ b/app/javascript/packs/shared/modals_container/index.jsx @@ -0,0 +1,7 @@ +import React from "react"; +import LeaveTeamModal from "./modals/LeaveTeamModal"; + +export default () => +
+ +
; diff --git a/app/javascript/packs/shared/modals_container/modals/LeaveTeamModal.jsx b/app/javascript/packs/shared/modals_container/modals/LeaveTeamModal.jsx new file mode 100644 index 000000000..8e7e00860 --- /dev/null +++ b/app/javascript/packs/shared/modals_container/modals/LeaveTeamModal.jsx @@ -0,0 +1,31 @@ +import React, { Component } from "react"; +import { Modal, Button } from "react-bootstrap"; +import { FormattedMessage } from "react-intl"; +import { connect } from "react-redux"; + +class LeaveTeamModal extends Component { + render() { + return ( + + + + + + + BANANAN + + + + + ); + } +} + +const mapStateToProps = ({ showLeaveTeamModal }) => ({ + showModal: showLeaveTeamModal.show, + teamId: showLeaveTeamModal.id +}); + +export default connect(mapStateToProps)(LeaveTeamModal); diff --git a/app/javascript/packs/shared/navigation/components/TeamSwitch.jsx b/app/javascript/packs/shared/navigation/components/TeamSwitch.jsx index bbb1a5ec2..d04a46561 100644 --- a/app/javascript/packs/shared/navigation/components/TeamSwitch.jsx +++ b/app/javascript/packs/shared/navigation/components/TeamSwitch.jsx @@ -89,7 +89,7 @@ TeamSwitch.propTypes = { // Map the states from store to component const mapStateToProps = ({ all_teams, current_team }) => ({ current_team, - all_teams: _.values(all_teams) + all_teams: all_teams.collection }); // Map the fetch activity action to component diff --git a/app/javascript/packs/shared/reducers/LeaveTeamReducer.js b/app/javascript/packs/shared/reducers/LeaveTeamReducer.js new file mode 100644 index 000000000..c09b097aa --- /dev/null +++ b/app/javascript/packs/shared/reducers/LeaveTeamReducer.js @@ -0,0 +1,8 @@ +import { SHOW_LEAVE_TEAM_MODAL } from '../../app/action_types' + +export function showLeaveTeamModal(state = {show: false, id: 0}, action) { + if(action.type ===SHOW_LEAVE_TEAM_MODAL) { + return {...state, ...action.payload} + } + return state +} diff --git a/app/javascript/packs/shared/reducers/TeamReducers.js b/app/javascript/packs/shared/reducers/TeamReducers.js index 707752c93..faccc52cd 100644 --- a/app/javascript/packs/shared/reducers/TeamReducers.js +++ b/app/javascript/packs/shared/reducers/TeamReducers.js @@ -8,9 +8,12 @@ export const setCurrentTeam = (state = initialState, action) => { return state; }; -export const getListOfTeams = (state = [], action) => { +export const getListOfTeams = (state = { collection: [] }, action) => { if (action.type === GET_LIST_OF_TEAMS) { - return Object.assign({}, state, action.payload); + return { + ...state, + collection: action.payload + }; } return state; }; diff --git a/app/javascript/packs/src/settings/app.jsx b/app/javascript/packs/src/settings/app.jsx index 3269663ed..76b992326 100644 --- a/app/javascript/packs/src/settings/app.jsx +++ b/app/javascript/packs/src/settings/app.jsx @@ -10,6 +10,7 @@ import store from "../../app/store"; import messages from "../../locales/messages"; import MainNav from "./components/MainNav"; +import ModalsContainer from "../../shared/modals_container"; addLocaleData([...enLocaleData]); const locale = "en-US"; @@ -17,6 +18,7 @@ const locale = "en-US"; const SettingsPage = () =>
+
; document.addEventListener("DOMContentLoaded", () => { diff --git a/app/javascript/packs/src/settings/components/team/SettingsTeams.jsx b/app/javascript/packs/src/settings/components/team/SettingsTeams.jsx index b6114583b..1aa6793e2 100644 --- a/app/javascript/packs/src/settings/components/team/SettingsTeams.jsx +++ b/app/javascript/packs/src/settings/components/team/SettingsTeams.jsx @@ -1,7 +1,16 @@ import React from "react"; +import PropTypes from "prop-types"; import styled from "styled-components"; +import { connect } from "react-redux"; +import { FormattedMessage } from "react-intl"; -import { BORDER_LIGHT_COLOR } from "../../../../app/constants/colors"; +import { + BORDER_LIGHT_COLOR, + COLOR_CONCRETE +} from "../../../../app/constants/colors"; + +import TeamsPageDetails from "./components/TeamsPageDetails"; +import TeamsDataTable from "./components/TeamsDataTable"; const Wrapper = styled.div` background: white; @@ -9,12 +18,39 @@ const Wrapper = styled.div` border: 1px solid ${BORDER_LIGHT_COLOR}; border-top: none; margin: 0; - padding: 16px 0 50px 0; + padding: 16px 15px 50px 15px; `; -const SettingsTeams = () => +const TabTitle = styled.div` + background-color: ${COLOR_CONCRETE}; + padding: 15px; +`; + +const SettingsTeams = ({ teams }) => -

Settings Teams

+ + + + +
; -export default SettingsTeams; +SettingsTeams.propTypes = { + teams: PropTypes.arrayOf( + PropTypes.shape({ + id: PropTypes.number.isRequired, + name: PropTypes.string.isRequired, + current_team: PropTypes.bool.isRequired + }).isRequired + ) +}; + +SettingsTeams.defaultProps = { + teams: [{id: 0, name: "", current_team: "", role: "", members: 0}] +}; + +const mapStateToProps = ({ all_teams }) => ({ + teams: all_teams.collection +}); + +export default connect(mapStateToProps)(SettingsTeams); diff --git a/app/javascript/packs/src/settings/components/team/actions/UserTeamsActions.js b/app/javascript/packs/src/settings/components/team/actions/UserTeamsActions.js new file mode 100644 index 000000000..33f07eb5a --- /dev/null +++ b/app/javascript/packs/src/settings/components/team/actions/UserTeamsActions.js @@ -0,0 +1,2 @@ + +import { LEAVE_TEAM_PATH } from '../../../../../app/routes' diff --git a/app/javascript/packs/src/settings/components/team/components/TeamsDataTable.jsx b/app/javascript/packs/src/settings/components/team/components/TeamsDataTable.jsx new file mode 100644 index 000000000..0d528ceca --- /dev/null +++ b/app/javascript/packs/src/settings/components/team/components/TeamsDataTable.jsx @@ -0,0 +1,45 @@ +import React, { Component } from "react"; +import { TableHeaderColumn } from "react-bootstrap-table"; +import { connect } from "react-redux"; +import { Button } from "react-bootstrap"; +import { leaveTeamModalShow } from "../../../../../shared/actions/LeaveTeamActions"; +import DataTable from "../../../../../shared/data_table"; + +class TeamsDataTable extends Component { + constructor(props) { + super(props); + this.leaveTeamModal = this.leaveTeamModal.bind(this); + } + + leaveTeamModal(e, id) { + e.peventDefault(); + this.props.leaveTeamModalShow(true, id); + } + + leaveTeamButton(id) { + return ( + + ); + } + + render() { + return ( + + + Name + + Role + Memebers + + + ); + } +} + +const mapDispatchToProps = dispatch => ({ + leaveTeamModalShow(show, id) { + dispatch(leaveTeamModalShow(show, id)); + } +}); + +export default connect(null, mapDispatchToProps)(TeamsDataTable); diff --git a/app/javascript/packs/src/settings/components/team/components/TeamsPageDetails.jsx b/app/javascript/packs/src/settings/components/team/components/TeamsPageDetails.jsx new file mode 100644 index 000000000..4e3cc2d40 --- /dev/null +++ b/app/javascript/packs/src/settings/components/team/components/TeamsPageDetails.jsx @@ -0,0 +1,52 @@ +import React from "react"; +import PropTypes from "prop-types"; +import styled from "styled-components" +import { FormattedMessage, FormattedPlural } from "react-intl"; +import { Button } from "react-bootstrap"; + +const Wrapper = styled.div` + margin: 15px 0; +` +const TeamsPageDetails = ({ teams }) => { + const teamsNumber = teams.length; + return ( + + + } + other={ + + } + /> + + + ); +}; + +TeamsPageDetails.propTypes = { + teams: PropTypes.arrayOf( + PropTypes.shape({ + id: PropTypes.number.isRequired, + name: PropTypes.string.isRequired, + current_team: PropTypes.bool.isRequired + }) + ) +}; + +TeamsPageDetails.defaultProps = { + teams: [] +}; + +export default TeamsPageDetails; diff --git a/app/views/client_api/teams/index.json.jbuilder b/app/views/client_api/teams/index.json.jbuilder index fb48d4e90..31ffa78e3 100644 --- a/app/views/client_api/teams/index.json.jbuilder +++ b/app/views/client_api/teams/index.json.jbuilder @@ -1,5 +1,7 @@ -json.array! teams do |team| - json.id team.id - json.name team.name - json.current_team team == current_user.current_team +json.teams do + json.collection teams do |team| + json.id team.id + json.name team.name + json.current_team team == current_user.current_team + end end diff --git a/config/routes.rb b/config/routes.rb index a557b7a66..a19e10477 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -23,6 +23,10 @@ Rails.application.routes.draw do get '/recent_notifications', to: 'notifications#recent_notifications' # users get '/current_user_info', to: 'users#current_user_info' + + namespace :users do + delete '/leave_team', to: 'user_teams#leave_team' + end end # Save sample table state