aboutsummaryrefslogtreecommitdiffstats
path: root/server/sonar-web/src/main/js/apps/account
diff options
context:
space:
mode:
authorStas Vilchik <vilchiks@gmail.com>2016-06-06 11:45:34 +0200
committerStas Vilchik <vilchiks@gmail.com>2016-06-06 11:45:34 +0200
commit69e8f0ec49a910bbd80b81a566c18b2ec19032e4 (patch)
treeb64ef355d3d5ce49bdd8243dd1d064e3e7763620 /server/sonar-web/src/main/js/apps/account
parentfb218304c322c3e055d8450690f6ae3b2aad45cc (diff)
downloadsonarqube-69e8f0ec49a910bbd80b81a566c18b2ec19032e4.tar.gz
sonarqube-69e8f0ec49a910bbd80b81a566c18b2ec19032e4.zip
refactor account app to drop redux (#1019)
Diffstat (limited to 'server/sonar-web/src/main/js/apps/account')
-rw-r--r--server/sonar-web/src/main/js/apps/account/account.css (renamed from server/sonar-web/src/main/js/apps/account/styles/account.css)0
-rw-r--r--server/sonar-web/src/main/js/apps/account/app.js35
-rw-r--r--server/sonar-web/src/main/js/apps/account/components/AccountApp.js (renamed from server/sonar-web/src/main/js/apps/account/containers/AccountApp.js)66
-rw-r--r--server/sonar-web/src/main/js/apps/account/components/Issues.js (renamed from server/sonar-web/src/main/js/apps/account/containers/IssuesContainer.js)2
-rw-r--r--server/sonar-web/src/main/js/apps/account/components/Notifications.js6
-rw-r--r--server/sonar-web/src/main/js/apps/account/components/NotificationsContainer.js71
-rw-r--r--server/sonar-web/src/main/js/apps/account/components/Security.js6
-rw-r--r--server/sonar-web/src/main/js/apps/account/components/UserCard.js6
-rw-r--r--server/sonar-web/src/main/js/apps/account/containers/NotificationsContainer.js42
-rw-r--r--server/sonar-web/src/main/js/apps/account/containers/SecurityContainer.js28
-rw-r--r--server/sonar-web/src/main/js/apps/account/store/actions.js59
-rw-r--r--server/sonar-web/src/main/js/apps/account/store/configureStore.js36
-rw-r--r--server/sonar-web/src/main/js/apps/account/store/reducers.js71
13 files changed, 136 insertions, 292 deletions
diff --git a/server/sonar-web/src/main/js/apps/account/styles/account.css b/server/sonar-web/src/main/js/apps/account/account.css
index 28eb45f4a5e..28eb45f4a5e 100644
--- a/server/sonar-web/src/main/js/apps/account/styles/account.css
+++ b/server/sonar-web/src/main/js/apps/account/account.css
diff --git a/server/sonar-web/src/main/js/apps/account/app.js b/server/sonar-web/src/main/js/apps/account/app.js
index e4643b9349c..8bb8231f5db 100644
--- a/server/sonar-web/src/main/js/apps/account/app.js
+++ b/server/sonar-web/src/main/js/apps/account/app.js
@@ -21,16 +21,11 @@ import React from 'react';
import { render } from 'react-dom';
import { Router, Route, IndexRoute, Redirect, useRouterHistory } from 'react-router';
import { createHistory } from 'history';
-import { Provider } from 'react-redux';
-
-import configureStore from './store/configureStore';
-import AccountApp from './containers/AccountApp';
+import AccountApp from './components/AccountApp';
import Home from './components/Home';
-import NotificationsContainer from './containers/NotificationsContainer';
-import SecurityContainer from './containers/SecurityContainer';
-import IssuesContainer from './containers/IssuesContainer';
-
-import './styles/account.css';
+import NotificationsContainer from './components/NotificationsContainer';
+import Security from './components/Security';
+import Issues from './components/Issues';
window.sonarqube.appStarted.then(options => {
const el = document.querySelector(options.el);
@@ -39,20 +34,16 @@ window.sonarqube.appStarted.then(options => {
basename: window.baseUrl + '/account'
});
- const store = configureStore();
-
render((
- <Provider store={store}>
- <Router history={history}>
- <Route path="/" component={AccountApp}>
- <IndexRoute component={Home}/>
- <Route path="issues" component={IssuesContainer}/>
- <Route path="notifications" component={NotificationsContainer}/>
- <Route path="security" component={SecurityContainer}/>
+ <Router history={history}>
+ <Route path="/" component={AccountApp}>
+ <IndexRoute component={Home}/>
+ <Route path="issues" component={Issues}/>
+ <Route path="notifications" component={NotificationsContainer}/>
+ <Route path="security" component={Security}/>
- <Redirect from="/index" to="/"/>
- </Route>
- </Router>
- </Provider>
+ <Redirect from="/index" to="/"/>
+ </Route>
+ </Router>
), el);
});
diff --git a/server/sonar-web/src/main/js/apps/account/containers/AccountApp.js b/server/sonar-web/src/main/js/apps/account/components/AccountApp.js
index 2b3198b682b..84757dfd6fc 100644
--- a/server/sonar-web/src/main/js/apps/account/containers/AccountApp.js
+++ b/server/sonar-web/src/main/js/apps/account/components/AccountApp.js
@@ -18,37 +18,62 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import React, { Component, cloneElement } from 'react';
-import { connect } from 'react-redux';
-
-import Nav from '../components/Nav';
-import { fetchUser } from '../store/actions';
+import Nav from './Nav';
+import { getCurrentUser } from '../../../api/users';
import { getIssueFilters } from '../../../api/issues';
+import '../account.css';
-class AccountApp extends Component {
- state = {};
+export default class AccountApp extends Component {
+ state = {
+ loading: true
+ };
componentDidMount () {
- this.props.fetchUser();
- this.fetchFavoriteIssueFilters();
+ this.mounted = true;
+ Promise.all([
+ this.loadUser(),
+ this.loadFavoriteIssueFilters()
+ ]).then(() => this.finishLoading());
+ }
+
+ componentWillUnmount () {
+ this.mounted = false;
}
- fetchFavoriteIssueFilters () {
- getIssueFilters().then(issueFilters => {
+ loadUser () {
+ return getCurrentUser().then(user => {
+ if (this.mounted) {
+ this.setState({ user });
+ }
+ });
+ }
+
+ loadFavoriteIssueFilters () {
+ return getIssueFilters().then(issueFilters => {
const favoriteIssueFilters = issueFilters.filter(f => f.favorite);
this.setState({ issueFilters: favoriteIssueFilters });
});
}
+ finishLoading () {
+ if (this.mounted) {
+ this.setState({ loading: false });
+ }
+ }
+
render () {
- const { user } = this.props;
+ const { user, issueFilters, loading } = this.state;
- if (!user) {
- return null;
+ if (loading) {
+ return (
+ <div>
+ <i className="spinner spinner-margin"/>
+ </div>
+ );
}
const { favorites } = window.sonarqube.user;
const measureFilters = window.sonarqube.user.favoriteMeasureFilters;
- const { issueFilters } = this.state;
const children = cloneElement(this.props.children, {
measureFilters,
user,
@@ -64,16 +89,3 @@ class AccountApp extends Component {
);
}
}
-
-function mapStateToProps (state) {
- return { user: state.user };
-}
-
-function mapDispatchToProps (dispatch) {
- return { fetchUser: () => dispatch(fetchUser()) };
-}
-
-export default connect(
- mapStateToProps,
- mapDispatchToProps
-)(AccountApp);
diff --git a/server/sonar-web/src/main/js/apps/account/containers/IssuesContainer.js b/server/sonar-web/src/main/js/apps/account/components/Issues.js
index 67e927f3a4e..21c4b41c4c0 100644
--- a/server/sonar-web/src/main/js/apps/account/containers/IssuesContainer.js
+++ b/server/sonar-web/src/main/js/apps/account/components/Issues.js
@@ -21,7 +21,7 @@ import React, { Component } from 'react';
import IssuesApp from '../issues-app';
-export default class IssuesContainer extends Component {
+export default class Issues extends Component {
componentDidMount () {
this.issuesApp = IssuesApp;
this.issuesApp.start({
diff --git a/server/sonar-web/src/main/js/apps/account/components/Notifications.js b/server/sonar-web/src/main/js/apps/account/components/Notifications.js
index 8eb4e437afb..04e5fc7124f 100644
--- a/server/sonar-web/src/main/js/apps/account/components/Notifications.js
+++ b/server/sonar-web/src/main/js/apps/account/components/Notifications.js
@@ -23,7 +23,7 @@ import GlobalNotifications from './GlobalNotifications';
import ProjectNotifications from './ProjectNotifications';
import { translate } from '../../../helpers/l10n';
-export default function Notifications ({ globalNotifications, projectNotifications, onAddProject, onRemoveProject }) {
+const Notifications = ({ globalNotifications, projectNotifications, onAddProject, onRemoveProject }) => {
const channels = globalNotifications[0].channels.map(c => c.id);
return (
@@ -56,4 +56,6 @@ export default function Notifications ({ globalNotifications, projectNotificatio
</form>
</div>
);
-}
+};
+
+export default Notifications;
diff --git a/server/sonar-web/src/main/js/apps/account/components/NotificationsContainer.js b/server/sonar-web/src/main/js/apps/account/components/NotificationsContainer.js
new file mode 100644
index 00000000000..81a770a9e66
--- /dev/null
+++ b/server/sonar-web/src/main/js/apps/account/components/NotificationsContainer.js
@@ -0,0 +1,71 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+import React from 'react';
+import Notifications from './Notifications';
+
+export default class NotificationsContainer extends React.Component {
+ state = {
+ globalNotifications: window.sonarqube.notifications.global,
+ projectNotifications: window.sonarqube.notifications.project
+ };
+
+ componentWillMount () {
+ this.handleAddProject = this.handleAddProject.bind(this);
+ this.handleRemoveProject = this.handleRemoveProject.bind(this);
+ }
+
+ handleAddProject (project) {
+ const { projectNotifications } = this.state;
+ const found = projectNotifications
+ .find(notification => notification.project.internalId === project.internalId);
+
+ if (!found) {
+ const newProjectNotification = {
+ project,
+ notifications: window.sonarqube.notifications.projectDispatchers.map(dispatcher => {
+ const channels = window.sonarqube.notifications.channels.map(channel => {
+ return { id: channel, checked: false };
+ });
+ return { dispatcher, channels };
+ })
+ };
+
+ this.setState({
+ projectNotifications: [...projectNotifications, newProjectNotification]
+ });
+ }
+ }
+
+ handleRemoveProject (project) {
+ const projectNotifications = this.state.projectNotifications
+ .filter(notification => notification.project.internalId !== project.internalId);
+ this.setState({ projectNotifications });
+ }
+
+ render () {
+ return (
+ <Notifications
+ globalNotifications={this.state.globalNotifications}
+ projectNotifications={this.state.projectNotifications}
+ onAddProject={this.handleAddProject}
+ onRemoveProject={this.handleRemoveProject}/>
+ );
+ }
+}
diff --git a/server/sonar-web/src/main/js/apps/account/components/Security.js b/server/sonar-web/src/main/js/apps/account/components/Security.js
index ec220d082c5..a82ff5e748d 100644
--- a/server/sonar-web/src/main/js/apps/account/components/Security.js
+++ b/server/sonar-web/src/main/js/apps/account/components/Security.js
@@ -22,7 +22,7 @@ import React from 'react';
import Password from './Password';
import Tokens from './Tokens';
-export default function Security ({ user }) {
+const Security = ({ user }) => {
return (
<div className="page page-limited">
<div className="columns">
@@ -38,4 +38,6 @@ export default function Security ({ user }) {
</div>
</div>
);
-}
+};
+
+export default Security;
diff --git a/server/sonar-web/src/main/js/apps/account/components/UserCard.js b/server/sonar-web/src/main/js/apps/account/components/UserCard.js
index 82f9b939b28..4c90d7fe255 100644
--- a/server/sonar-web/src/main/js/apps/account/components/UserCard.js
+++ b/server/sonar-web/src/main/js/apps/account/components/UserCard.js
@@ -23,7 +23,7 @@ import { IndexLink } from 'react-router';
import UserExternalIdentity from './UserExternalIdentity';
import Avatar from '../../../components/shared/avatar';
-export default function UserCard ({ user }) {
+const UserCard = ({ user }) => {
return (
<section className="account-user clearfix">
<div id="avatar" className="account-nav-avatar">
@@ -45,4 +45,6 @@ export default function UserCard ({ user }) {
<div id="email" className="little-spacer-top">{user.email}</div>
</section>
);
-}
+};
+
+export default UserCard;
diff --git a/server/sonar-web/src/main/js/apps/account/containers/NotificationsContainer.js b/server/sonar-web/src/main/js/apps/account/containers/NotificationsContainer.js
deleted file mode 100644
index 0764dae9c46..00000000000
--- a/server/sonar-web/src/main/js/apps/account/containers/NotificationsContainer.js
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2016 SonarSource SA
- * mailto:contact AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { connect } from 'react-redux';
-
-import { addProjectNotifications, removeProjectNotifications } from '../store/actions';
-import Notifications from './../components/Notifications';
-
-function mapStateToProps (state) {
- return {
- globalNotifications: window.sonarqube.notifications.global,
- projectNotifications: state.projectNotifications
- };
-}
-
-function mapDispatchToProps (dispatch) {
- return {
- onAddProject: project => dispatch(addProjectNotifications(project)),
- onRemoveProject: project => dispatch(removeProjectNotifications(project))
- };
-}
-
-export default connect(
- mapStateToProps,
- mapDispatchToProps
-)(Notifications);
diff --git a/server/sonar-web/src/main/js/apps/account/containers/SecurityContainer.js b/server/sonar-web/src/main/js/apps/account/containers/SecurityContainer.js
deleted file mode 100644
index 8a800b71fb4..00000000000
--- a/server/sonar-web/src/main/js/apps/account/containers/SecurityContainer.js
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2016 SonarSource SA
- * mailto:contact AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { connect } from 'react-redux';
-
-import Security from './../components/Security';
-
-function mapStateToProps (state) {
- return { user: state.user };
-}
-
-export default connect(mapStateToProps)(Security);
diff --git a/server/sonar-web/src/main/js/apps/account/store/actions.js b/server/sonar-web/src/main/js/apps/account/store/actions.js
deleted file mode 100644
index f241d4c22c5..00000000000
--- a/server/sonar-web/src/main/js/apps/account/store/actions.js
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2016 SonarSource SA
- * mailto:contact AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { getCurrentUser } from '../../../api/users';
-
-export const REQUEST_USER = 'REQUEST_USER';
-export const RECEIVE_USER = 'RECEIVE_USER';
-export const ADD_PROJECT_NOTIFICATIONS = 'ADD_PROJECT_NOTIFICATIONS';
-export const REMOVE_PROJECT_NOTIFICATIONS = 'REMOVE_PROJECT_NOTIFICATIONS';
-
-export function requestUser () {
- return {
- type: REQUEST_USER
- };
-}
-
-export function receiveUser (user) {
- return {
- type: RECEIVE_USER,
- user
- };
-}
-
-export function addProjectNotifications (project) {
- return {
- type: ADD_PROJECT_NOTIFICATIONS,
- project
- };
-}
-
-export function removeProjectNotifications (project) {
- return {
- type: REMOVE_PROJECT_NOTIFICATIONS,
- project
- };
-}
-
-export function fetchUser () {
- return dispatch => {
- dispatch(requestUser());
- return getCurrentUser().then(user => dispatch(receiveUser(user)));
- };
-}
diff --git a/server/sonar-web/src/main/js/apps/account/store/configureStore.js b/server/sonar-web/src/main/js/apps/account/store/configureStore.js
deleted file mode 100644
index e412913dc76..00000000000
--- a/server/sonar-web/src/main/js/apps/account/store/configureStore.js
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2016 SonarSource SA
- * mailto:contact AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { createStore, applyMiddleware } from 'redux';
-import thunk from 'redux-thunk';
-import createLogger from 'redux-logger';
-import rootReducer from './reducers';
-
-const logger = createLogger({
- predicate: () => process.env.NODE_ENV !== 'production'
-});
-
-const createStoreWithMiddleware = applyMiddleware(
- thunk,
- logger
-)(createStore);
-
-export default function configureStore () {
- return createStoreWithMiddleware(rootReducer);
-}
diff --git a/server/sonar-web/src/main/js/apps/account/store/reducers.js b/server/sonar-web/src/main/js/apps/account/store/reducers.js
deleted file mode 100644
index e129a65f17f..00000000000
--- a/server/sonar-web/src/main/js/apps/account/store/reducers.js
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2016 SonarSource SA
- * mailto:contact AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { RECEIVE_USER, ADD_PROJECT_NOTIFICATIONS, REMOVE_PROJECT_NOTIFICATIONS } from './actions';
-
-function addProjectNotifications (state, project) {
- const found = state.find(notification => notification.project.internalId === project.internalId);
-
- if (found) {
- return state;
- }
-
- const newProjectNotification = {
- project,
- notifications: window.sonarqube.notifications.projectDispatchers.map(dispatcher => {
- const channels = window.sonarqube.notifications.channels.map(channel => {
- return { id: channel, checked: false };
- });
- return { dispatcher, channels };
- })
- };
-
- return [...state, newProjectNotification];
-}
-
-function removeProjectNotifications (state, project) {
- return state.filter(notification => notification.project.internalId !== project.internalId);
-}
-
-export const initialState = {
- user: null,
- projectNotifications: window.sonarqube.notifications.project
-};
-
-export default function (state = initialState, action = {}) {
- switch (action.type) {
- case RECEIVE_USER:
- return {
- ...state,
- user: action.user
- };
- case ADD_PROJECT_NOTIFICATIONS:
- return {
- ...state,
- projectNotifications: addProjectNotifications(state.projectNotifications, action.project)
- };
- case REMOVE_PROJECT_NOTIFICATIONS:
- return {
- ...state,
- projectNotifications: removeProjectNotifications(state.projectNotifications, action.project)
- };
- default:
- return state;
- }
-}