mirror of
https://github.com/scinote-eln/scinote-web.git
synced 2025-10-08 21:06:24 +08:00
Merge branch 'decoupling-settings-page' of https://github.com/biosistemika/scinote-web into zd_SCI_1688
This commit is contained in:
commit
e3e3f4c75d
10 changed files with 261 additions and 187 deletions
27
app/javascript/src/components/PageTitle/index.jsx
Normal file
27
app/javascript/src/components/PageTitle/index.jsx
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
// @flow
|
||||||
|
import React from "react";
|
||||||
|
import type { Node } from "react";
|
||||||
|
import type { MessageDescriptor } from "flow-typed";
|
||||||
|
import DocumentTitle from "react-document-title";
|
||||||
|
import { formatMessage, defineMessages, injectIntl } from "react-intl";
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
intl: any,
|
||||||
|
localeID: string,
|
||||||
|
values?: any,
|
||||||
|
children: Node
|
||||||
|
};
|
||||||
|
|
||||||
|
const PageTitle = (props: Props): Node => {
|
||||||
|
const message = defineMessages({
|
||||||
|
placeholder: { id: props.localeID }
|
||||||
|
});
|
||||||
|
const title = props.intl.formatMessage(message.placeholder, props.values);
|
||||||
|
return <DocumentTitle title={title}>{props.children}</DocumentTitle>;
|
||||||
|
};
|
||||||
|
|
||||||
|
PageTitle.defaultProps = {
|
||||||
|
values: {}
|
||||||
|
};
|
||||||
|
|
||||||
|
export default injectIntl(PageTitle);
|
|
@ -8,6 +8,14 @@ export default {
|
||||||
loading: "Loading ...",
|
loading: "Loading ...",
|
||||||
upload: "Upload"
|
upload: "Upload"
|
||||||
},
|
},
|
||||||
|
page_title: {
|
||||||
|
root: "SciNote",
|
||||||
|
settings_preference_page: "SciNote | Settings | Preferences",
|
||||||
|
settings_profile_page: "SciNote | Settings | Profile",
|
||||||
|
team_page: "SciNote | Settings | Teams | {name}",
|
||||||
|
all_teams_page: "SciNote | Settings | Teams",
|
||||||
|
new_team_page: "SciNote | Settings | Teams | New"
|
||||||
|
},
|
||||||
error_messages: {
|
error_messages: {
|
||||||
text_too_short: "is too short (minimum is {min_length} characters)",
|
text_too_short: "is too short (minimum is {min_length} characters)",
|
||||||
text_too_long: "is too long (maximum is {max_length} characters)",
|
text_too_long: "is too long (maximum is {max_length} characters)",
|
||||||
|
|
|
@ -16,6 +16,7 @@ import {
|
||||||
|
|
||||||
import { SETTINGS_PATH, SETTINGS_TEAMS } from "../../config/api_endpoints";
|
import { SETTINGS_PATH, SETTINGS_TEAMS } from "../../config/api_endpoints";
|
||||||
|
|
||||||
|
import PageTitle from "../../components/PageTitle";
|
||||||
import NotFound from "../../components/404/NotFound";
|
import NotFound from "../../components/404/NotFound";
|
||||||
import SettingsProfile from "./scenes/profile";
|
import SettingsProfile from "./scenes/profile";
|
||||||
import SettingsPreferences from "./scenes/preferences";
|
import SettingsPreferences from "./scenes/preferences";
|
||||||
|
@ -61,7 +62,7 @@ export default class SettingsPage extends Component<*, State> {
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<div>
|
<PageTitle localeID="page_title.root">
|
||||||
<div className="container">
|
<div className="container">
|
||||||
<Nav bsStyle="tabs" activeKey="1" onSelect={this.handleSelect}>
|
<Nav bsStyle="tabs" activeKey="1" onSelect={this.handleSelect}>
|
||||||
<LinkContainer
|
<LinkContainer
|
||||||
|
@ -126,7 +127,7 @@ export default class SettingsPage extends Component<*, State> {
|
||||||
<Route component={NotFound} />
|
<Route component={NotFound} />
|
||||||
</Switch>
|
</Switch>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</PageTitle>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@ import React, { Component } from "react";
|
||||||
import { FormattedMessage } from "react-intl";
|
import { FormattedMessage } from "react-intl";
|
||||||
|
|
||||||
import { getUserPreferencesInfo } from "../../../../services/api/users_api";
|
import { getUserPreferencesInfo } from "../../../../services/api/users_api";
|
||||||
|
import PageTitle from "../../../../components/PageTitle";
|
||||||
import SettingsAccountWrapper from "../../components/SettingsAccountWrapper";
|
import SettingsAccountWrapper from "../../components/SettingsAccountWrapper";
|
||||||
import InputTimezone from "./components/InputTimezone";
|
import InputTimezone from "./components/InputTimezone";
|
||||||
import NotificationsGroup from "./components/NotificationsGroup";
|
import NotificationsGroup from "./components/NotificationsGroup";
|
||||||
|
@ -60,6 +61,7 @@ class SettingsPreferences extends Component<Props, State> {
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
|
<PageTitle localeID="page_title.settings_preference_page">
|
||||||
<SettingsAccountWrapper>
|
<SettingsAccountWrapper>
|
||||||
<div className="col-xs-12 col-sm-9">
|
<div className="col-xs-12 col-sm-9">
|
||||||
<InputTimezone
|
<InputTimezone
|
||||||
|
@ -75,9 +77,7 @@ class SettingsPreferences extends Component<Props, State> {
|
||||||
subtitle="settings_page.assignement_msg"
|
subtitle="settings_page.assignement_msg"
|
||||||
iconClasses="fa fa-newspaper-o"
|
iconClasses="fa fa-newspaper-o"
|
||||||
inAppNotification={this.state.assignments_notification}
|
inAppNotification={this.state.assignments_notification}
|
||||||
emailNotification={
|
emailNotification={this.state.assignments_email_notification}
|
||||||
this.state.assignments_email_notification
|
|
||||||
}
|
|
||||||
iconBackground={MAIN_COLOR_BLUE}
|
iconBackground={MAIN_COLOR_BLUE}
|
||||||
reloadInfo={this.getPreferencesInfo}
|
reloadInfo={this.getPreferencesInfo}
|
||||||
/>
|
/>
|
||||||
|
@ -93,15 +93,14 @@ class SettingsPreferences extends Component<Props, State> {
|
||||||
type={SYSTEM_NOTIFICATION}
|
type={SYSTEM_NOTIFICATION}
|
||||||
title="settings_page.system_message"
|
title="settings_page.system_message"
|
||||||
subtitle="settings_page.system_message_msg"
|
subtitle="settings_page.system_message_msg"
|
||||||
emailNotification={
|
emailNotification={this.state.system_message_email_notification}
|
||||||
this.state.system_message_email_notification
|
|
||||||
}
|
|
||||||
iconClasses="glyphicon glyphicon-tower"
|
iconClasses="glyphicon glyphicon-tower"
|
||||||
iconBackground={ICON_GREEN_COLOR}
|
iconBackground={ICON_GREEN_COLOR}
|
||||||
reloadInfo={this.getPreferencesInfo}
|
reloadInfo={this.getPreferencesInfo}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</SettingsAccountWrapper>
|
</SettingsAccountWrapper>
|
||||||
|
</PageTitle>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,21 +1,24 @@
|
||||||
// @flow
|
// @flow
|
||||||
|
|
||||||
import React, { Component } from "react";
|
import React, { Component } from "react";
|
||||||
|
|
||||||
|
import PageTitle from "../../../../components/PageTitle";
|
||||||
import SettingsAccountWrapper from "../../components/SettingsAccountWrapper";
|
import SettingsAccountWrapper from "../../components/SettingsAccountWrapper";
|
||||||
import MyProfile from "./components/MyProfile";
|
import MyProfile from "./components/MyProfile";
|
||||||
import MyStatistics from "./components/MyStatistics";
|
import MyStatistics from "./components/MyStatistics";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
tabState: Function
|
tabState: Function
|
||||||
}
|
};
|
||||||
|
|
||||||
class SettingsProfile extends Component<Props> {
|
class SettingsProfile extends Component<Props> {
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
this.props.tabState("1")
|
this.props.tabState("1");
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
|
<PageTitle localeID="page_title.settings_profile_page">
|
||||||
<SettingsAccountWrapper>
|
<SettingsAccountWrapper>
|
||||||
<div className="col-xs-12 col-sm-4">
|
<div className="col-xs-12 col-sm-4">
|
||||||
<MyProfile />
|
<MyProfile />
|
||||||
|
@ -24,6 +27,7 @@ class SettingsProfile extends Component<Props> {
|
||||||
<MyStatistics />
|
<MyStatistics />
|
||||||
</div>
|
</div>
|
||||||
</SettingsAccountWrapper>
|
</SettingsAccountWrapper>
|
||||||
|
</PageTitle>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,7 @@ import { getTeamDetails } from "../../../../services/api/teams_api";
|
||||||
import { SETTINGS_TEAMS_ROUTE } from "../../../../config/routes";
|
import { SETTINGS_TEAMS_ROUTE } from "../../../../config/routes";
|
||||||
import { BORDER_LIGHT_COLOR } from "../../../../config/constants/colors";
|
import { BORDER_LIGHT_COLOR } from "../../../../config/constants/colors";
|
||||||
|
|
||||||
|
import PageTitle from "../../../../components/PageTitle";
|
||||||
import TeamsMembers from "./components/TeamsMembers";
|
import TeamsMembers from "./components/TeamsMembers";
|
||||||
import UpdateTeamDescriptionModal from "./components/UpdateTeamDescriptionModal";
|
import UpdateTeamDescriptionModal from "./components/UpdateTeamDescriptionModal";
|
||||||
import UpdateTeamNameModal from "./components/UpdateTeamNameModal";
|
import UpdateTeamNameModal from "./components/UpdateTeamNameModal";
|
||||||
|
@ -108,7 +109,7 @@ class SettingsTeam extends Component<Props, State> {
|
||||||
// set team tab on active
|
// set team tab on active
|
||||||
(this: any).props.tabState("2");
|
(this: any).props.tabState("2");
|
||||||
const { id } = this.props.match.params;
|
const { id } = this.props.match.params;
|
||||||
if(id) {
|
if (id) {
|
||||||
getTeamDetails(parseInt(id)).then(response => {
|
getTeamDetails(parseInt(id)).then(response => {
|
||||||
const { team, users } = response;
|
const { team, users } = response;
|
||||||
(this: any).setState({ users, team });
|
(this: any).setState({ users, team });
|
||||||
|
@ -165,6 +166,10 @@ class SettingsTeam extends Component<Props, State> {
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
|
<PageTitle
|
||||||
|
localeID="page_title.team_page"
|
||||||
|
values={{ name: this.state.team.name }}
|
||||||
|
>
|
||||||
<Wrapper>
|
<Wrapper>
|
||||||
<Breadcrumb>
|
<Breadcrumb>
|
||||||
<LinkContainer to={SETTINGS_TEAMS_ROUTE}>
|
<LinkContainer to={SETTINGS_TEAMS_ROUTE}>
|
||||||
|
@ -245,6 +250,7 @@ class SettingsTeam extends Component<Props, State> {
|
||||||
/>
|
/>
|
||||||
{this.renderEditNameModal()}
|
{this.renderEditNameModal()}
|
||||||
</Wrapper>
|
</Wrapper>
|
||||||
|
</PageTitle>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,10 +6,11 @@ import { Breadcrumb } from "react-bootstrap";
|
||||||
import { connect } from "react-redux";
|
import { connect } from "react-redux";
|
||||||
import { FormattedMessage } from "react-intl";
|
import { FormattedMessage } from "react-intl";
|
||||||
import type { State } from "flow-typed";
|
import type { State } from "flow-typed";
|
||||||
import type { MapStateToProps } from "react-redux"
|
import type { MapStateToProps } from "react-redux";
|
||||||
|
|
||||||
import { BORDER_LIGHT_COLOR } from "../../../../config/constants/colors";
|
import { BORDER_LIGHT_COLOR } from "../../../../config/constants/colors";
|
||||||
|
|
||||||
|
import PageTitle from "../../../../components/PageTitle";
|
||||||
import TeamsPageDetails from "./components/TeamsPageDetails";
|
import TeamsPageDetails from "./components/TeamsPageDetails";
|
||||||
import TeamsDataTable from "./components/TeamsDataTable";
|
import TeamsDataTable from "./components/TeamsDataTable";
|
||||||
|
|
||||||
|
@ -25,12 +26,12 @@ const Wrapper = styled.div`
|
||||||
type Props = {
|
type Props = {
|
||||||
tabState: Function,
|
tabState: Function,
|
||||||
teams: Array<Teams$Team>
|
teams: Array<Teams$Team>
|
||||||
}
|
};
|
||||||
|
|
||||||
class SettingsTeams extends Component<Props> {
|
class SettingsTeams extends Component<Props> {
|
||||||
static defaultProps = {
|
static defaultProps = {
|
||||||
teams: [{ id: 0, name: "", current_team: "", role: "", members: 0 }]
|
teams: [{ id: 0, name: "", current_team: "", role: "", members: 0 }]
|
||||||
}
|
};
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
// set team tab on active
|
// set team tab on active
|
||||||
|
@ -40,6 +41,7 @@ class SettingsTeams extends Component<Props> {
|
||||||
render() {
|
render() {
|
||||||
const { teams } = this.props;
|
const { teams } = this.props;
|
||||||
return (
|
return (
|
||||||
|
<PageTitle localeID="page_title.all_teams_page">
|
||||||
<Wrapper>
|
<Wrapper>
|
||||||
<Breadcrumb>
|
<Breadcrumb>
|
||||||
<Breadcrumb.Item active>
|
<Breadcrumb.Item active>
|
||||||
|
@ -49,6 +51,7 @@ class SettingsTeams extends Component<Props> {
|
||||||
<TeamsPageDetails teams={teams} />
|
<TeamsPageDetails teams={teams} />
|
||||||
<TeamsDataTable teams={teams} />
|
<TeamsDataTable teams={teams} />
|
||||||
</Wrapper>
|
</Wrapper>
|
||||||
|
</PageTitle>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,6 +32,7 @@ import { getTeamsList } from "../../../../../components/actions/TeamsActions";
|
||||||
|
|
||||||
import { BORDER_LIGHT_COLOR } from "../../../../../config/constants/colors";
|
import { BORDER_LIGHT_COLOR } from "../../../../../config/constants/colors";
|
||||||
|
|
||||||
|
import PageTitle from "../../../../../components/PageTitle";
|
||||||
import NameFormControl from "./components/NameFormControl";
|
import NameFormControl from "./components/NameFormControl";
|
||||||
|
|
||||||
const Wrapper = styled.div`
|
const Wrapper = styled.div`
|
||||||
|
@ -245,6 +246,7 @@ class SettingsNewTeam extends Component<Props, State> {
|
||||||
!_.isEmpty(this.state.formErrors.description);
|
!_.isEmpty(this.state.formErrors.description);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
<PageTitle localeID="page_title.new_team_page">
|
||||||
<Wrapper>
|
<Wrapper>
|
||||||
<Breadcrumb>
|
<Breadcrumb>
|
||||||
<LinkContainer to={SETTINGS_TEAMS_ROUTE}>
|
<LinkContainer to={SETTINGS_TEAMS_ROUTE}>
|
||||||
|
@ -287,6 +289,7 @@ class SettingsNewTeam extends Component<Props, State> {
|
||||||
</ButtonToolbar>
|
</ButtonToolbar>
|
||||||
</form>
|
</form>
|
||||||
</Wrapper>
|
</Wrapper>
|
||||||
|
</PageTitle>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -72,6 +72,7 @@
|
||||||
"react-bootstrap-table": "^4.0.0",
|
"react-bootstrap-table": "^4.0.0",
|
||||||
"react-bootstrap-timezone-picker": "^1.0.11",
|
"react-bootstrap-timezone-picker": "^1.0.11",
|
||||||
"react-data-grid": "^2.0.2",
|
"react-data-grid": "^2.0.2",
|
||||||
|
"react-document-title": "^2.0.3",
|
||||||
"react-dom": "15.6.1",
|
"react-dom": "15.6.1",
|
||||||
"react-intl": "^2.3.0",
|
"react-intl": "^2.3.0",
|
||||||
"react-intl-redux": "^0.6.0",
|
"react-intl-redux": "^0.6.0",
|
||||||
|
|
22
yarn.lock
22
yarn.lock
|
@ -2289,6 +2289,10 @@ exenv@1.2.0:
|
||||||
version "1.2.0"
|
version "1.2.0"
|
||||||
resolved "https://registry.yarnpkg.com/exenv/-/exenv-1.2.0.tgz#3835f127abf075bfe082d0aed4484057c78e3c89"
|
resolved "https://registry.yarnpkg.com/exenv/-/exenv-1.2.0.tgz#3835f127abf075bfe082d0aed4484057c78e3c89"
|
||||||
|
|
||||||
|
exenv@^1.2.1:
|
||||||
|
version "1.2.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/exenv/-/exenv-1.2.2.tgz#2ae78e85d9894158670b03d47bec1f03bd91bb9d"
|
||||||
|
|
||||||
expand-brackets@^0.1.4:
|
expand-brackets@^0.1.4:
|
||||||
version "0.1.5"
|
version "0.1.5"
|
||||||
resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-0.1.5.tgz#df07284e342a807cd733ac5af72411e581d1177b"
|
resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-0.1.5.tgz#df07284e342a807cd733ac5af72411e581d1177b"
|
||||||
|
@ -5018,6 +5022,13 @@ react-data-grid@^2.0.2:
|
||||||
version "2.0.60"
|
version "2.0.60"
|
||||||
resolved "https://registry.yarnpkg.com/react-data-grid/-/react-data-grid-2.0.60.tgz#4a1549d4dad032677439f25dbcf1036ab966032f"
|
resolved "https://registry.yarnpkg.com/react-data-grid/-/react-data-grid-2.0.60.tgz#4a1549d4dad032677439f25dbcf1036ab966032f"
|
||||||
|
|
||||||
|
react-document-title@^2.0.3:
|
||||||
|
version "2.0.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/react-document-title/-/react-document-title-2.0.3.tgz#bbf922a0d71412fc948245e4283b2412df70f2b9"
|
||||||
|
dependencies:
|
||||||
|
prop-types "^15.5.6"
|
||||||
|
react-side-effect "^1.0.2"
|
||||||
|
|
||||||
react-dom-factories@^1.0.0:
|
react-dom-factories@^1.0.0:
|
||||||
version "1.0.1"
|
version "1.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/react-dom-factories/-/react-dom-factories-1.0.1.tgz#c50692ac5ff1adb39d86dfe6dbe3485dacf58455"
|
resolved "https://registry.yarnpkg.com/react-dom-factories/-/react-dom-factories-1.0.1.tgz#c50692ac5ff1adb39d86dfe6dbe3485dacf58455"
|
||||||
|
@ -5124,6 +5135,13 @@ react-s-alert@^1.3.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
babel-runtime "^6.23.0"
|
babel-runtime "^6.23.0"
|
||||||
|
|
||||||
|
react-side-effect@^1.0.2:
|
||||||
|
version "1.1.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/react-side-effect/-/react-side-effect-1.1.3.tgz#512c25abe0dec172834c4001ec5c51e04d41bc5c"
|
||||||
|
dependencies:
|
||||||
|
exenv "^1.2.1"
|
||||||
|
shallowequal "^1.0.1"
|
||||||
|
|
||||||
react-tagsinput@^3.17.0:
|
react-tagsinput@^3.17.0:
|
||||||
version "3.18.0"
|
version "3.18.0"
|
||||||
resolved "https://registry.yarnpkg.com/react-tagsinput/-/react-tagsinput-3.18.0.tgz#40e036fc0f4c3d6b4689858189ab02926717a818"
|
resolved "https://registry.yarnpkg.com/react-tagsinput/-/react-tagsinput-3.18.0.tgz#40e036fc0f4c3d6b4689858189ab02926717a818"
|
||||||
|
@ -5601,6 +5619,10 @@ shallow-clone@^0.1.2:
|
||||||
lazy-cache "^0.2.3"
|
lazy-cache "^0.2.3"
|
||||||
mixin-object "^2.0.1"
|
mixin-object "^2.0.1"
|
||||||
|
|
||||||
|
shallowequal@^1.0.1:
|
||||||
|
version "1.0.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/shallowequal/-/shallowequal-1.0.2.tgz#1561dbdefb8c01408100319085764da3fcf83f8f"
|
||||||
|
|
||||||
shebang-command@^1.2.0:
|
shebang-command@^1.2.0:
|
||||||
version "1.2.0"
|
version "1.2.0"
|
||||||
resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea"
|
resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea"
|
||||||
|
|
Loading…
Add table
Reference in a new issue