mirror of
https://github.com/scinote-eln/scinote-web.git
synced 2025-09-18 02:54:39 +08:00
adds user account dropdown
This commit is contained in:
parent
226458a3f0
commit
bd352869a3
13 changed files with 216 additions and 13 deletions
14
app/controllers/client_api/users_controller.rb
Normal file
14
app/controllers/client_api/users_controller.rb
Normal file
|
@ -0,0 +1,14 @@
|
|||
module ClientApi
|
||||
class UsersController < ApplicationController
|
||||
|
||||
def current_user_info
|
||||
respond_to do |format|
|
||||
format.json do
|
||||
render template: '/client_api/users/show',
|
||||
status: :ok,
|
||||
locals: { user: current_user }
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -4,9 +4,11 @@ import {
|
|||
getListOfTeams
|
||||
} from "../shared/reducers/TeamReducers";
|
||||
import { globalActivities } from "../shared/reducers/ActivitiesReducers";
|
||||
import { currentUser } from "../shared/reducers/UsersReducer";
|
||||
|
||||
export default combineReducers({
|
||||
current_team: setCurrentTeam,
|
||||
all_teams: getListOfTeams,
|
||||
global_activities: globalActivities
|
||||
global_activities: globalActivities,
|
||||
current_user: currentUser
|
||||
});
|
||||
|
|
|
@ -10,3 +10,14 @@ export const SEARCH_PATH = "/search";
|
|||
|
||||
// notifications
|
||||
export const RECENT_NOTIFICATIONS_PATH = "/client_api/recent_notifications";
|
||||
|
||||
// users
|
||||
export const CURRENT_USER_PATH = "/client_api/current_user_info";
|
||||
|
||||
// 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";
|
||||
|
|
|
@ -18,6 +18,18 @@ export default {
|
|||
dropdown_title: "Notifications",
|
||||
dropdown_settings_link: "Settings",
|
||||
dropdown_show_all: "Show all notifications"
|
||||
},
|
||||
info_dropdown: {
|
||||
customer_support: "Customer support",
|
||||
tutorials: "Tutorials",
|
||||
release_notes: "Release notes",
|
||||
premium: "Premium",
|
||||
contact_us: "Contact us"
|
||||
},
|
||||
user_account_dropdown: {
|
||||
greeting: "Hi, {name}",
|
||||
settings: "Settings",
|
||||
log_out: "Log out"
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
23
app/javascript/packs/shared/actions/UsersActions.js
Normal file
23
app/javascript/packs/shared/actions/UsersActions.js
Normal file
|
@ -0,0 +1,23 @@
|
|||
import axios from "axios";
|
||||
import { CURRENT_USER_PATH } from "../../app/routes";
|
||||
import { SET_CURRENT_USER } from "./types";
|
||||
|
||||
function addCurrentUser(data) {
|
||||
return {
|
||||
type: SET_CURRENT_USER,
|
||||
payload: data
|
||||
};
|
||||
}
|
||||
|
||||
export function getCurrentUser() {
|
||||
return dispatch => {
|
||||
axios
|
||||
.get(CURRENT_USER_PATH, { withCredentials: true })
|
||||
.then(({ data }) => {
|
||||
dispatch(addCurrentUser(data.user));
|
||||
})
|
||||
.catch(error => {
|
||||
console.log("get Current User Error: ", error);
|
||||
});
|
||||
};
|
||||
}
|
|
@ -4,3 +4,6 @@ export const GET_LIST_OF_TEAMS = "GET_LIST_OF_TEAMS";
|
|||
|
||||
// activities
|
||||
export const GLOBAL_ACTIVITIES_DATA = "GLOBAL_ACTIVITIES_DATA";
|
||||
|
||||
// users
|
||||
export const SET_CURRENT_USER = "SET_CURRENT_USER";
|
||||
|
|
|
@ -1 +1,3 @@
|
|||
export const MAIN_COLOR_BLUE = '#37a0d9';
|
||||
export const WHITE_COLOR = '#fff';
|
||||
export const BORDER_GRAY_COLOR = '#d2d2d2';
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
import React from "react";
|
||||
import { FormattedMessage } from "react-intl";
|
||||
import { NavDropdown, MenuItem } from "react-bootstrap";
|
||||
import {
|
||||
CUSTOMER_SUPPORT_LINK,
|
||||
TUTORIALS_LINK,
|
||||
RELEASE_NOTES_LINK,
|
||||
PREMIUM_LINK,
|
||||
CONTACT_US_LINK
|
||||
} from "../../../app/routes";
|
||||
|
||||
const InfoDropdown = () =>
|
||||
<NavDropdown
|
||||
noCaret
|
||||
title={<span className="glyphicon glyphicon-info-sign" />}
|
||||
id="nav-info-dropdown"
|
||||
>
|
||||
<MenuItem href={CUSTOMER_SUPPORT_LINK} target="_blank">
|
||||
<FormattedMessage id="info_dropdown.customer_support" />
|
||||
</MenuItem>
|
||||
<MenuItem href={TUTORIALS_LINK} target="_blank">
|
||||
<FormattedMessage id="info_dropdown.tutorials" />
|
||||
</MenuItem>
|
||||
<MenuItem href={RELEASE_NOTES_LINK} target="_blank">
|
||||
<FormattedMessage id="info_dropdown.release_notes" />
|
||||
</MenuItem>
|
||||
<MenuItem href={PREMIUM_LINK} target="_blank">
|
||||
<FormattedMessage id="info_dropdown.premium" />
|
||||
</MenuItem>
|
||||
<MenuItem href={CONTACT_US_LINK} target="_blank">
|
||||
<FormattedMessage id="info_dropdown.contact_us" />
|
||||
</MenuItem>
|
||||
</NavDropdown>;
|
||||
|
||||
export default InfoDropdown;
|
|
@ -0,0 +1,75 @@
|
|||
import React, { Component } from "react";
|
||||
import { connect } from "react-redux";
|
||||
import PropTypes from "prop-types";
|
||||
import { NavDropdown, MenuItem } from "react-bootstrap";
|
||||
import styled from "styled-components";
|
||||
import { FormattedMessage } from "react-intl";
|
||||
|
||||
import { getCurrentUser } from "../../actions/UsersActions";
|
||||
|
||||
const StyledNavDropdown = styled(NavDropdown)`
|
||||
& #user-account-dropdown {
|
||||
padding-top: 10px;
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
`;
|
||||
|
||||
class UserAccountDropdown extends Component {
|
||||
componentDidMount() {
|
||||
this.props.getCurrentUser();
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<StyledNavDropdown
|
||||
id="user-account-dropdown"
|
||||
className="dropdown"
|
||||
noCaret
|
||||
title={
|
||||
<span>
|
||||
<FormattedMessage
|
||||
id="user_account_dropdown.greeting"
|
||||
values={{ name: this.props.current_user.fullName }}
|
||||
/>
|
||||
<img
|
||||
src={this.props.current_user.avatarPath}
|
||||
alt={this.props.current_user.fullName}
|
||||
className="img-circle"
|
||||
/>
|
||||
</span>
|
||||
}
|
||||
>
|
||||
<MenuItem href="/settings">
|
||||
<FormattedMessage id="user_account_dropdown.settings" />
|
||||
</MenuItem>
|
||||
<MenuItem divider />
|
||||
<MenuItem href="/users/sign_out">
|
||||
<FormattedMessage id="user_account_dropdown.log_out" />
|
||||
</MenuItem>
|
||||
</StyledNavDropdown>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
UserAccountDropdown.propTypes = {
|
||||
getCurrentUser: PropTypes.func.isRequired,
|
||||
current_user: PropTypes.shape({
|
||||
id: PropTypes.number.isRequired,
|
||||
fullName: PropTypes.string.isRequired,
|
||||
avatarPath: PropTypes.string.isRequired
|
||||
}).isRequired
|
||||
};
|
||||
|
||||
// Map the states from store to component
|
||||
const mapStateToProps = ({ current_user }) => ({ current_user });
|
||||
|
||||
// Map the fetch activity action to component
|
||||
const mapDispatchToProps = dispatch => ({
|
||||
getCurrentUser() {
|
||||
dispatch(getCurrentUser());
|
||||
}
|
||||
});
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(
|
||||
UserAccountDropdown
|
||||
);
|
|
@ -3,13 +3,24 @@ import PropTypes from "prop-types";
|
|||
import { connect } from "react-redux";
|
||||
import { Navbar, Nav, NavItem } from "react-bootstrap";
|
||||
import styled from "styled-components";
|
||||
import { MAIN_COLOR_BLUE } from "../constants/colors";
|
||||
import {
|
||||
MAIN_COLOR_BLUE,
|
||||
WHITE_COLOR,
|
||||
BORDER_GRAY_COLOR
|
||||
} from "../constants/colors";
|
||||
import { getActivities } from "../actions/ActivitiesActions";
|
||||
import { getTeamsList } from "../actions/TeamsActions";
|
||||
import TeamSwitch from "./components/TeamSwitch";
|
||||
import GlobalActivitiesModal from "./components/GlobalActivitiesModal";
|
||||
import SearchDropdown from "./components/SearchDropdown";
|
||||
import NotificationsDropdown from "./components/NotificationsDropdown"
|
||||
import NotificationsDropdown from "./components/NotificationsDropdown";
|
||||
import InfoDropdown from "./components/InfoDropdown";
|
||||
import UserAccountDropdown from "./components/UserAccountDropdown";
|
||||
|
||||
const StyledNavbar = styled(Navbar)`
|
||||
background-color: ${WHITE_COLOR};
|
||||
border-color: ${BORDER_GRAY_COLOR};
|
||||
`;
|
||||
|
||||
const StyledBrand = styled.a`
|
||||
background-color: ${MAIN_COLOR_BLUE};
|
||||
|
@ -21,7 +32,9 @@ const StyledBrand = styled.a`
|
|||
}
|
||||
|
||||
& > img {
|
||||
height: 20px;
|
||||
margin-top: -4px;
|
||||
max-width: 132px;
|
||||
max-height: 26px;
|
||||
}
|
||||
`;
|
||||
|
||||
|
@ -38,7 +51,6 @@ class Navigation extends Component {
|
|||
}
|
||||
|
||||
componentDidMount() {
|
||||
console.log("runned");
|
||||
this.props.getTeamsList();
|
||||
}
|
||||
|
||||
|
@ -58,7 +70,7 @@ class Navigation extends Component {
|
|||
render() {
|
||||
return (
|
||||
<div>
|
||||
<Navbar onSelect={this.selectItemCallback}>
|
||||
<StyledNavbar onSelect={this.selectItemCallback}>
|
||||
<Navbar.Header>
|
||||
<Navbar.Brand>
|
||||
<StyledBrand href="/" title="sciNote">
|
||||
|
@ -97,11 +109,10 @@ class Navigation extends Component {
|
|||
<TeamSwitch eventKey={5} />
|
||||
<SearchDropdown />
|
||||
<NotificationsDropdown />
|
||||
<NavItem eventKey={7} href="#">
|
||||
Link Right
|
||||
</NavItem>
|
||||
<InfoDropdown />
|
||||
<UserAccountDropdown />
|
||||
</Nav>
|
||||
</Navbar>
|
||||
</StyledNavbar>
|
||||
<GlobalActivitiesModal
|
||||
showModal={this.state.showActivitesModal}
|
||||
onCloseModal={this.closeModalCallback}
|
||||
|
|
11
app/javascript/packs/shared/reducers/UsersReducer.js
Normal file
11
app/javascript/packs/shared/reducers/UsersReducer.js
Normal file
|
@ -0,0 +1,11 @@
|
|||
import { SET_CURRENT_USER } from "../actions/types";
|
||||
|
||||
export function currentUser(
|
||||
state = { id: 0, fullName: "", avatarPath: "" },
|
||||
action
|
||||
) {
|
||||
if (action.type === SET_CURRENT_USER) {
|
||||
return Object.assign({}, state, action.payload);
|
||||
}
|
||||
return state;
|
||||
}
|
5
app/views/client_api/users/show.json.jbuilder
Normal file
5
app/views/client_api/users/show.json.jbuilder
Normal file
|
@ -0,0 +1,5 @@
|
|||
json.user do
|
||||
json.id user.id
|
||||
json.fullName user.full_name
|
||||
json.avatarPath avatar_path(user, :icon_small)
|
||||
end
|
|
@ -15,14 +15,13 @@ Rails.application.routes.draw do
|
|||
namespace :client_api, defaults: { format: 'json' } do
|
||||
# activities
|
||||
get '/activities', to: 'activities#index'
|
||||
|
||||
# teams
|
||||
get '/teams', to: 'teams#index'
|
||||
post '/change_team', to: 'teams#change_team'
|
||||
|
||||
# notifications
|
||||
get '/recent_notifications', to: 'notifications#recent_notifications'
|
||||
|
||||
# users
|
||||
get '/current_user_info', to: 'users#current_user_info'
|
||||
end
|
||||
|
||||
# Save sample table state
|
||||
|
|
Loading…
Add table
Reference in a new issue