diff --git a/app/javascript/src/components/PageTitle/index.jsx b/app/javascript/src/components/PageTitle/index.jsx
new file mode 100644
index 000000000..5700ef88a
--- /dev/null
+++ b/app/javascript/src/components/PageTitle/index.jsx
@@ -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 {props.children};
+};
+
+PageTitle.defaultProps = {
+ values: {}
+};
+
+export default injectIntl(PageTitle);
diff --git a/app/javascript/src/config/locales/messages.js b/app/javascript/src/config/locales/messages.js
index 26328ca30..d3ff9b457 100644
--- a/app/javascript/src/config/locales/messages.js
+++ b/app/javascript/src/config/locales/messages.js
@@ -8,6 +8,14 @@ export default {
loading: "Loading ...",
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: {
text_too_short: "is too short (minimum is {min_length} characters)",
text_too_long: "is too long (maximum is {max_length} characters)",
diff --git a/app/javascript/src/scenes/SettingsPage/index.jsx b/app/javascript/src/scenes/SettingsPage/index.jsx
index bf35a5008..8125b54ad 100644
--- a/app/javascript/src/scenes/SettingsPage/index.jsx
+++ b/app/javascript/src/scenes/SettingsPage/index.jsx
@@ -16,6 +16,7 @@ import {
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";
import SettingsPreferences from "./scenes/preferences";
@@ -61,7 +62,7 @@ export default class SettingsPage extends Component<*, State> {
render() {
return (
-
+
);
}
}
diff --git a/app/javascript/src/scenes/SettingsPage/scenes/preferences/index.jsx b/app/javascript/src/scenes/SettingsPage/scenes/preferences/index.jsx
index f0c7d9ad7..56a45458b 100644
--- a/app/javascript/src/scenes/SettingsPage/scenes/preferences/index.jsx
+++ b/app/javascript/src/scenes/SettingsPage/scenes/preferences/index.jsx
@@ -3,6 +3,7 @@ import React, { Component } from "react";
import { FormattedMessage } from "react-intl";
import { getUserPreferencesInfo } from "../../../../services/api/users_api";
+import PageTitle from "../../../../components/PageTitle";
import SettingsAccountWrapper from "../../components/SettingsAccountWrapper";
import InputTimezone from "./components/InputTimezone";
import NotificationsGroup from "./components/NotificationsGroup";
@@ -60,48 +61,46 @@ class SettingsPreferences extends Component {
render() {
return (
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
);
}
}
diff --git a/app/javascript/src/scenes/SettingsPage/scenes/profile/index.jsx b/app/javascript/src/scenes/SettingsPage/scenes/profile/index.jsx
index ed852af62..f162b87a1 100644
--- a/app/javascript/src/scenes/SettingsPage/scenes/profile/index.jsx
+++ b/app/javascript/src/scenes/SettingsPage/scenes/profile/index.jsx
@@ -1,29 +1,33 @@
// @flow
import React, { Component } from "react";
+
+import PageTitle from "../../../../components/PageTitle";
import SettingsAccountWrapper from "../../components/SettingsAccountWrapper";
import MyProfile from "./components/MyProfile";
import MyStatistics from "./components/MyStatistics";
type Props = {
tabState: Function
-}
+};
class SettingsProfile extends Component {
componentDidMount() {
- this.props.tabState("1")
+ this.props.tabState("1");
}
-
+
render() {
return (
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
);
}
}
diff --git a/app/javascript/src/scenes/SettingsPage/scenes/team/index.jsx b/app/javascript/src/scenes/SettingsPage/scenes/team/index.jsx
index 96186842a..258f7d1a9 100644
--- a/app/javascript/src/scenes/SettingsPage/scenes/team/index.jsx
+++ b/app/javascript/src/scenes/SettingsPage/scenes/team/index.jsx
@@ -15,6 +15,7 @@ import { getTeamDetails } from "../../../../services/api/teams_api";
import { SETTINGS_TEAMS_ROUTE } from "../../../../config/routes";
import { BORDER_LIGHT_COLOR } from "../../../../config/constants/colors";
+import PageTitle from "../../../../components/PageTitle";
import TeamsMembers from "./components/TeamsMembers";
import UpdateTeamDescriptionModal from "./components/UpdateTeamDescriptionModal";
import UpdateTeamNameModal from "./components/UpdateTeamNameModal";
@@ -108,7 +109,7 @@ class SettingsTeam extends Component {
// set team tab on active
(this: any).props.tabState("2");
const { id } = this.props.match.params;
- if(id) {
+ if (id) {
getTeamDetails(parseInt(id)).then(response => {
const { team, users } = response;
(this: any).setState({ users, team });
@@ -165,86 +166,91 @@ class SettingsTeam extends Component {
render() {
return (
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+ {this.state.team.name}
-
-
- {this.state.team.name}
-
-
-
-
- {this.state.team.name}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {this.renderDescription()}
-
-
-
-
-
- {this.renderEditNameModal()}
-
+
+
+
+ {this.state.team.name}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {this.renderDescription()}
+
+
+
+
+
+ {this.renderEditNameModal()}
+
+
);
}
}
diff --git a/app/javascript/src/scenes/SettingsPage/scenes/teams/index.jsx b/app/javascript/src/scenes/SettingsPage/scenes/teams/index.jsx
index 27facb24c..699eb14be 100644
--- a/app/javascript/src/scenes/SettingsPage/scenes/teams/index.jsx
+++ b/app/javascript/src/scenes/SettingsPage/scenes/teams/index.jsx
@@ -6,10 +6,11 @@ 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 type { MapStateToProps } from "react-redux";
import { BORDER_LIGHT_COLOR } from "../../../../config/constants/colors";
+import PageTitle from "../../../../components/PageTitle";
import TeamsPageDetails from "./components/TeamsPageDetails";
import TeamsDataTable from "./components/TeamsDataTable";
@@ -25,12 +26,12 @@ const Wrapper = styled.div`
type Props = {
tabState: Function,
teams: Array
-}
+};
class SettingsTeams extends Component {
static defaultProps = {
teams: [{ id: 0, name: "", current_team: "", role: "", members: 0 }]
- }
+ };
componentDidMount() {
// set team tab on active
@@ -40,15 +41,17 @@ class SettingsTeams extends Component {
render() {
const { teams } = this.props;
return (
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
);
}
}
diff --git a/app/javascript/src/scenes/SettingsPage/scenes/teams/new/index.jsx b/app/javascript/src/scenes/SettingsPage/scenes/teams/new/index.jsx
index 16691c216..ad1962d2b 100644
--- a/app/javascript/src/scenes/SettingsPage/scenes/teams/new/index.jsx
+++ b/app/javascript/src/scenes/SettingsPage/scenes/teams/new/index.jsx
@@ -32,6 +32,7 @@ import { getTeamsList } from "../../../../../components/actions/TeamsActions";
import { BORDER_LIGHT_COLOR } from "../../../../../config/constants/colors";
+import PageTitle from "../../../../../components/PageTitle";
import NameFormControl from "./components/NameFormControl";
const Wrapper = styled.div`
@@ -245,48 +246,50 @@ class SettingsNewTeam extends Component {
!_.isEmpty(this.state.formErrors.description);
return (
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
);
}
}
diff --git a/package.json b/package.json
index c304568ee..5f815adba 100644
--- a/package.json
+++ b/package.json
@@ -72,6 +72,7 @@
"react-bootstrap-table": "^4.0.0",
"react-bootstrap-timezone-picker": "^1.0.11",
"react-data-grid": "^2.0.2",
+ "react-document-title": "^2.0.3",
"react-dom": "15.6.1",
"react-intl": "^2.3.0",
"react-intl-redux": "^0.6.0",
diff --git a/yarn.lock b/yarn.lock
index 3cedba29a..a7d39944b 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2289,6 +2289,10 @@ exenv@1.2.0:
version "1.2.0"
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:
version "0.1.5"
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"
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:
version "1.0.1"
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:
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:
version "3.18.0"
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"
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:
version "1.2.0"
resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea"