]> source.dussan.org Git - sonarqube.git/commitdiff
reorganize store directories
authorStas Vilchik <vilchiks@gmail.com>
Fri, 9 Dec 2016 14:44:24 +0000 (15:44 +0100)
committerStas Vilchik <vilchiks@gmail.com>
Fri, 9 Dec 2016 16:16:20 +0000 (17:16 +0100)
move store/ outside of app/
move components/store/* to store/

130 files changed:
server/sonar-web/src/main/js/app/components/AdminContainer.js
server/sonar-web/src/main/js/app/components/App.js
server/sonar-web/src/main/js/app/components/GlobalFooter.js
server/sonar-web/src/main/js/app/components/GlobalMessagesContainer.js
server/sonar-web/src/main/js/app/components/Landing.js
server/sonar-web/src/main/js/app/components/ProjectContainer.js
server/sonar-web/src/main/js/app/components/nav/component/ComponentNavFavorite.js
server/sonar-web/src/main/js/app/components/nav/global/GlobalNav.js
server/sonar-web/src/main/js/app/components/nav/global/GlobalNavBranding.js
server/sonar-web/src/main/js/app/components/nav/global/GlobalNavSearch.js
server/sonar-web/src/main/js/app/store/appState/duck.js [deleted file]
server/sonar-web/src/main/js/app/store/components/actions.js [deleted file]
server/sonar-web/src/main/js/app/store/components/reducer.js [deleted file]
server/sonar-web/src/main/js/app/store/favorites/duck.js [deleted file]
server/sonar-web/src/main/js/app/store/languages/actions.js [deleted file]
server/sonar-web/src/main/js/app/store/languages/reducer.js [deleted file]
server/sonar-web/src/main/js/app/store/measures/actions.js [deleted file]
server/sonar-web/src/main/js/app/store/measures/reducer.js [deleted file]
server/sonar-web/src/main/js/app/store/rootActions.js [deleted file]
server/sonar-web/src/main/js/app/store/rootReducer.js [deleted file]
server/sonar-web/src/main/js/app/store/users/actions.js [deleted file]
server/sonar-web/src/main/js/app/store/users/reducer.js [deleted file]
server/sonar-web/src/main/js/app/utils/getCurrentUserFromStore.js
server/sonar-web/src/main/js/app/utils/getStore.js
server/sonar-web/src/main/js/app/utils/handleRequiredAuthentication.js
server/sonar-web/src/main/js/app/utils/handleRequiredAuthorization.js
server/sonar-web/src/main/js/apps/about/components/AboutApp.js
server/sonar-web/src/main/js/apps/account/components/Account.js
server/sonar-web/src/main/js/apps/account/components/Security.js
server/sonar-web/src/main/js/apps/account/profile/Profile.js
server/sonar-web/src/main/js/apps/background-tasks/components/BackgroundTasksApp.js
server/sonar-web/src/main/js/apps/code/components/App.js
server/sonar-web/src/main/js/apps/component-issues/components/ComponentIssuesAppContainer.js
server/sonar-web/src/main/js/apps/component-measures/app/AppContainer.js
server/sonar-web/src/main/js/apps/component-measures/components/bubbleChart/MeasureBubbleChartContainer.js
server/sonar-web/src/main/js/apps/component-measures/details/MeasureDetailsContainer.js
server/sonar-web/src/main/js/apps/component-measures/details/actions.js
server/sonar-web/src/main/js/apps/component-measures/details/drilldown/ListViewContainer.js
server/sonar-web/src/main/js/apps/component-measures/details/drilldown/TreeViewContainer.js
server/sonar-web/src/main/js/apps/component-measures/details/history/MeasureHistoryContainer.js
server/sonar-web/src/main/js/apps/component-measures/details/treemap/MeasureTreemapContainer.js
server/sonar-web/src/main/js/apps/component-measures/home/AllMeasuresContainer.js
server/sonar-web/src/main/js/apps/component-measures/home/DomainMeasuresContainer.js
server/sonar-web/src/main/js/apps/component-measures/home/HomeContainer.js
server/sonar-web/src/main/js/apps/component-measures/home/actions.js
server/sonar-web/src/main/js/apps/component-measures/store/listViewActions.js
server/sonar-web/src/main/js/apps/component-measures/store/treeViewActions.js
server/sonar-web/src/main/js/apps/custom-measures/components/CustomMeasuresAppContainer.js
server/sonar-web/src/main/js/apps/issues/components/IssuesAppContainer.js
server/sonar-web/src/main/js/apps/overview/components/AppContainer.js
server/sonar-web/src/main/js/apps/overview/meta/MetaQualityProfiles.js
server/sonar-web/src/main/js/apps/permission-templates/components/AppContainer.js
server/sonar-web/src/main/js/apps/permission-templates/components/Template.js
server/sonar-web/src/main/js/apps/permissions/global/components/AllHoldersList.js
server/sonar-web/src/main/js/apps/permissions/global/components/PageHeader.js
server/sonar-web/src/main/js/apps/permissions/global/store/actions.js
server/sonar-web/src/main/js/apps/permissions/project/components/AllHoldersList.js
server/sonar-web/src/main/js/apps/permissions/project/components/App.js
server/sonar-web/src/main/js/apps/permissions/project/components/PageHeader.js
server/sonar-web/src/main/js/apps/permissions/project/store/actions.js
server/sonar-web/src/main/js/apps/permissions/shared/components/PageError.js
server/sonar-web/src/main/js/apps/project-admin/deletion/Deletion.js
server/sonar-web/src/main/js/apps/project-admin/key/BulkUpdate.js
server/sonar-web/src/main/js/apps/project-admin/key/Key.js
server/sonar-web/src/main/js/apps/project-admin/links/Links.js
server/sonar-web/src/main/js/apps/project-admin/quality-gate/QualityGate.js
server/sonar-web/src/main/js/apps/project-admin/quality-profiles/QualityProfiles.js
server/sonar-web/src/main/js/apps/project-admin/store/actions.js
server/sonar-web/src/main/js/apps/project-admin/store/rootReducer.js
server/sonar-web/src/main/js/apps/projects-admin/AppContainer.js
server/sonar-web/src/main/js/apps/projects/components/AllProjectsContainer.js
server/sonar-web/src/main/js/apps/projects/components/FavoriteFilterContainer.js
server/sonar-web/src/main/js/apps/projects/components/FavoriteProjectsContainer.js
server/sonar-web/src/main/js/apps/projects/components/PageHeaderContainer.js
server/sonar-web/src/main/js/apps/projects/components/ProjectCardContainer.js
server/sonar-web/src/main/js/apps/projects/components/ProjectCardLanguages.js
server/sonar-web/src/main/js/apps/projects/components/ProjectsListContainer.js
server/sonar-web/src/main/js/apps/projects/components/ProjectsListFooterContainer.js
server/sonar-web/src/main/js/apps/projects/filters/FilterContainer.js
server/sonar-web/src/main/js/apps/projects/store/actions.js
server/sonar-web/src/main/js/apps/projects/store/facetsDuck.js
server/sonar-web/src/main/js/apps/projects/store/stateDuck.js
server/sonar-web/src/main/js/apps/quality-gates/containers/DetailsContainer.js
server/sonar-web/src/main/js/apps/quality-gates/containers/QualityGatesAppContainer.js
server/sonar-web/src/main/js/apps/quality-profiles/components/AppContainer.js
server/sonar-web/src/main/js/apps/sessions/components/LoginFormContainer.js
server/sonar-web/src/main/js/apps/sessions/components/Logout.js
server/sonar-web/src/main/js/apps/settings/components/AllCategoriesList.js
server/sonar-web/src/main/js/apps/settings/components/App.js
server/sonar-web/src/main/js/apps/settings/components/AppContainer.js
server/sonar-web/src/main/js/apps/settings/components/CategoryDefinitionsList.js
server/sonar-web/src/main/js/apps/settings/components/Definition.js
server/sonar-web/src/main/js/apps/settings/components/EmailForm.js
server/sonar-web/src/main/js/apps/settings/encryption/EncryptionAppContainer.js
server/sonar-web/src/main/js/apps/settings/licenses/LicenseRowContainer.js
server/sonar-web/src/main/js/apps/settings/licenses/LicensesListContainer.js
server/sonar-web/src/main/js/apps/settings/serverId/ServerIdAppContainer.js
server/sonar-web/src/main/js/apps/settings/store/actions.js
server/sonar-web/src/main/js/apps/settings/store/encryptionPage/actions.js
server/sonar-web/src/main/js/apps/settings/store/licenses/actions.js
server/sonar-web/src/main/js/apps/settings/store/rootReducer.js
server/sonar-web/src/main/js/apps/settings/store/values/reducer.js
server/sonar-web/src/main/js/apps/update-center/components/UpdateCenterAppContainer.js
server/sonar-web/src/main/js/apps/users/components/UsersAppContainer.js
server/sonar-web/src/main/js/components/controls/FavoriteContainer.js
server/sonar-web/src/main/js/components/controls/GlobalMessages.js
server/sonar-web/src/main/js/components/store/configureStore.js [deleted file]
server/sonar-web/src/main/js/components/store/generalReducers.js [deleted file]
server/sonar-web/src/main/js/components/store/globalMessages.js [deleted file]
server/sonar-web/src/main/js/components/store/withStore.js [deleted file]
server/sonar-web/src/main/js/components/ui/Avatar.js
server/sonar-web/src/main/js/helpers/handlebars/avatarHelper.js
server/sonar-web/src/main/js/helpers/handlebars/ifShowAvatars.js
server/sonar-web/src/main/js/helpers/measures.js
server/sonar-web/src/main/js/store/appState/duck.js [new file with mode: 0644]
server/sonar-web/src/main/js/store/components/actions.js [new file with mode: 0644]
server/sonar-web/src/main/js/store/components/reducer.js [new file with mode: 0644]
server/sonar-web/src/main/js/store/favorites/duck.js [new file with mode: 0644]
server/sonar-web/src/main/js/store/globalMessages/duck.js [new file with mode: 0644]
server/sonar-web/src/main/js/store/languages/actions.js [new file with mode: 0644]
server/sonar-web/src/main/js/store/languages/reducer.js [new file with mode: 0644]
server/sonar-web/src/main/js/store/measures/actions.js [new file with mode: 0644]
server/sonar-web/src/main/js/store/measures/reducer.js [new file with mode: 0644]
server/sonar-web/src/main/js/store/rootActions.js [new file with mode: 0644]
server/sonar-web/src/main/js/store/rootReducer.js [new file with mode: 0644]
server/sonar-web/src/main/js/store/users/actions.js [new file with mode: 0644]
server/sonar-web/src/main/js/store/users/reducer.js [new file with mode: 0644]
server/sonar-web/src/main/js/store/utils/configureStore.js [new file with mode: 0644]
server/sonar-web/src/main/js/store/utils/generalReducers.js [new file with mode: 0644]
server/sonar-web/src/main/js/store/utils/withStore.js [new file with mode: 0644]

index 7ecbb77b2cddcf0043d72bcf8cc63dda3dac12fc..728118fac908c8fdb3122e21b94986026d68874e 100644 (file)
@@ -20,7 +20,7 @@
 import React from 'react';
 import { connect } from 'react-redux';
 import SettingsNav from './nav/settings/SettingsNav';
-import { getCurrentUser } from '../store/rootReducer';
+import { getCurrentUser } from '../../store/rootReducer';
 import { isUserAdmin } from '../../helpers/users';
 
 class AdminContainer extends React.Component {
index 4c13709deafc4b784f019f5d2ce0d1c818f27d77..6ddad08119e7b47c303383ab07c37b706ce75ca0 100644 (file)
@@ -21,8 +21,8 @@
 import React from 'react';
 import { connect } from 'react-redux';
 import GlobalLoading from './GlobalLoading';
-import { fetchCurrentUser } from '../store/users/actions';
-import { fetchLanguages, fetchAppState } from '../store/rootActions';
+import { fetchCurrentUser } from '../../store/users/actions';
+import { fetchLanguages, fetchAppState } from '../../store/rootActions';
 
 class App extends React.Component {
   mounted: bool;
index 8d0e5472014da1f01eba6433effc8992ee0ecfa2..8ca593eb458ac4001dc307d9ed09cafaff56907f 100644 (file)
@@ -21,7 +21,7 @@
 import React from 'react';
 import { Link } from 'react-router';
 import { connect } from 'react-redux';
-import { getAppState } from '../store/rootReducer';
+import { getAppState } from '../../store/rootReducer';
 
 class GlobalFooter extends React.Component {
   render () {
index 6faf954d495ad8c9a5616f24d0d74fead93659c1..64d2ef040e3ca43cde9db82e201917bd93aca990 100644 (file)
@@ -19,8 +19,8 @@
  */
 import { connect } from 'react-redux';
 import GlobalMessages from '../../components/controls/GlobalMessages';
-import { getGlobalMessages } from '../store/rootReducer';
-import { closeGlobalMessage } from '../../components/store/globalMessages';
+import { getGlobalMessages } from '../../store/rootReducer';
+import { closeGlobalMessage } from '../../store/globalMessages/duck';
 
 const mapStateToProps = state => ({
   messages: getGlobalMessages(state)
index 17074c24945a4080204851d33a6e29504152f030..40ea3a3c8e639424dec663859dd5e143002cc4c5 100644 (file)
@@ -21,7 +21,7 @@
 import React from 'react';
 import { withRouter } from 'react-router';
 import { connect } from 'react-redux';
-import { getCurrentUser } from '../store/rootReducer';
+import { getCurrentUser } from '../../store/rootReducer';
 
 class Landing extends React.Component {
   static propTypes = {
index 41eaec1e7dbb1a92e0337684cc8db64f2988b813..8a6cc890eb8478a4a8c09632798f3f6db472b57f 100644 (file)
@@ -20,8 +20,8 @@
 import React from 'react';
 import { connect } from 'react-redux';
 import ComponentNav from './nav/component/ComponentNav';
-import { fetchProject } from '../store/rootActions';
-import { getComponent } from '../store/rootReducer';
+import { fetchProject } from '../../store/rootActions';
+import { getComponent } from '../../store/rootReducer';
 
 class ProjectContainer extends React.Component {
   static propTypes = {
index e5ac6b7cbe6b3f66b2fb6f117286e6c5338bca96..468556939688eaea823b2b4c8ee273e4f20a81f0 100644 (file)
@@ -20,7 +20,7 @@
 import React from 'react';
 import { connect } from 'react-redux';
 import Favorite from '../../../../components/controls/Favorite';
-import { getCurrentUser } from '../../../store/rootReducer';
+import { getCurrentUser } from '../../../../store/rootReducer';
 
 class ComponentNavFavorite extends React.Component {
   static propTypes = {
index 01735c65a5a039b83fbd2044798718251d8c55db..7543197a7ae1a6a235f007521f1c895b375a72e7 100644 (file)
@@ -24,7 +24,7 @@ import GlobalNavMenu from './GlobalNavMenu';
 import GlobalNavUser from './GlobalNavUser';
 import GlobalNavSearch from './GlobalNavSearch';
 import ShortcutsHelpView from './ShortcutsHelpView';
-import { getCurrentUser } from '../../../store/rootReducer';
+import { getCurrentUser } from '../../../../store/rootReducer';
 
 class GlobalNav extends React.Component {
   componentDidMount () {
index b845eedfe58c7960a9a63b0057083746c89a58ee..9730f861f897ce6770335758b873f35bd3c6cff1 100644 (file)
@@ -20,7 +20,7 @@
 import React from 'react';
 import { Link } from 'react-router';
 import { connect } from 'react-redux';
-import { getSettingValue, getCurrentUser } from '../../../store/rootReducer';
+import { getSettingValue, getCurrentUser } from '../../../../store/rootReducer';
 import { translate } from '../../../../helpers/l10n';
 
 class GlobalNavBranding extends React.Component {
index c4d6f7c385c742babb0a271f7e627ce2943e4844..a0af8c4acd330b6032fa855960857323cf979019 100644 (file)
@@ -21,7 +21,7 @@ import Backbone from 'backbone';
 import React from 'react';
 import { connect } from 'react-redux';
 import SearchView from './SearchView';
-import { getCurrentUser } from '../../../store/rootReducer';
+import { getCurrentUser } from '../../../../store/rootReducer';
 
 function contains (root, node) {
   while (node) {
diff --git a/server/sonar-web/src/main/js/app/store/appState/duck.js b/server/sonar-web/src/main/js/app/store/appState/duck.js
deleted file mode 100644 (file)
index cd31387..0000000
+++ /dev/null
@@ -1,75 +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.
- */
-// @flow
-type AppState = {
-  authenticationError: boolean,
-  authorizationError: boolean,
-  qualifiers: ?Array<string>
-};
-
-export type Action = {
-  type: string,
-  appState: AppState
-}
-
-export const actions = {
-  SET_APP_STATE: 'SET_APP_STATE',
-  REQUIRE_AUTHENTICATION: 'REQUIRE_AUTHENTICATION',
-  REQUIRE_AUTHORIZATION: 'REQUIRE_AUTHORIZATION'
-};
-
-export const setAppState = (appState: AppState): Action => ({
-  type: actions.SET_APP_STATE,
-  appState
-});
-
-export const requireAuthentication = () => ({
-  type: actions.REQUIRE_AUTHENTICATION
-});
-
-export const requireAuthorization = () => ({
-  type: actions.REQUIRE_AUTHORIZATION
-});
-
-const defaultValue = {
-  authenticationError: false,
-  authorizationError: false,
-  qualifiers: null
-};
-
-export default (state: AppState = defaultValue, action: Action) => {
-  if (action.type === actions.SET_APP_STATE) {
-    return { ...state, ...action.appState };
-  }
-
-  if (action.type === actions.REQUIRE_AUTHENTICATION) {
-    return { ...state, authenticationError: true };
-  }
-
-  if (action.type === actions.REQUIRE_AUTHORIZATION) {
-    return { ...state, authorizationError: true };
-  }
-
-  return state;
-};
-
-export const getRootQualifiers = (state: AppState) => (
-    state.qualifiers
-);
diff --git a/server/sonar-web/src/main/js/app/store/components/actions.js b/server/sonar-web/src/main/js/app/store/components/actions.js
deleted file mode 100644 (file)
index 3ba34eb..0000000
+++ /dev/null
@@ -1,25 +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.
- */
-export const RECEIVE_COMPONENTS = 'RECEIVE_COMPONENTS';
-
-export const receiveComponents = components => ({
-  type: RECEIVE_COMPONENTS,
-  components
-});
diff --git a/server/sonar-web/src/main/js/app/store/components/reducer.js b/server/sonar-web/src/main/js/app/store/components/reducer.js
deleted file mode 100644 (file)
index c2d609a..0000000
+++ /dev/null
@@ -1,47 +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 { combineReducers } from 'redux';
-import keyBy from 'lodash/keyBy';
-import uniq from 'lodash/uniq';
-import { RECEIVE_COMPONENTS } from './actions';
-
-const byKey = (state = {}, action = {}) => {
-  if (action.type === RECEIVE_COMPONENTS) {
-    const changes = keyBy(action.components, 'key');
-    return { ...state, ...changes };
-  }
-
-  return state;
-};
-
-const keys = (state = [], action = {}) => {
-  if (action.type === RECEIVE_COMPONENTS) {
-    const changes = action.components.map(f => f.key);
-    return uniq([...state, ...changes]);
-  }
-
-  return state;
-};
-
-export default combineReducers({ byKey, keys });
-
-export const getComponent = (state, key) => (
-    state.byKey[key]
-);
diff --git a/server/sonar-web/src/main/js/app/store/favorites/duck.js b/server/sonar-web/src/main/js/app/store/favorites/duck.js
deleted file mode 100644 (file)
index 7c6d4b5..0000000
+++ /dev/null
@@ -1,63 +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 uniq from 'lodash/uniq';
-import without from 'lodash/without';
-
-export const actions = {
-  RECEIVE_FAVORITES: 'RECEIVE_FAVORITES',
-  ADD_FAVORITE: 'ADD_FAVORITE',
-  REMOVE_FAVORITE: 'REMOVE_FAVORITE'
-};
-
-export const receiveFavorites = favorites => ({
-  type: actions.RECEIVE_FAVORITES,
-  favorites
-});
-
-export const addFavorite = componentKey => ({
-  type: actions.ADD_FAVORITE,
-  componentKey
-});
-
-export const removeFavorite = componentKey => ({
-  type: actions.REMOVE_FAVORITE,
-  componentKey
-});
-
-export default (state = [], action = {}) => {
-  if (action.type === actions.RECEIVE_FAVORITES) {
-    return uniq([...state, ...action.favorites.map(f => f.key)]);
-  }
-
-  if (action.type === actions.ADD_FAVORITE) {
-    return uniq([...state, action.componentKey]);
-  }
-
-  if (action.type === actions.REMOVE_FAVORITE) {
-    return without(state, action.componentKey);
-  }
-
-  return state;
-};
-
-export const isFavorite = (state, componentKey) => (
-    state.includes(componentKey)
-);
-
diff --git a/server/sonar-web/src/main/js/app/store/languages/actions.js b/server/sonar-web/src/main/js/app/store/languages/actions.js
deleted file mode 100644 (file)
index 9d2d517..0000000
+++ /dev/null
@@ -1,25 +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.
- */
-export const RECEIVE_LANGUAGES = 'RECEIVE_LANGUAGES';
-
-export const receiveLanguages = languages => ({
-  type: RECEIVE_LANGUAGES,
-  languages
-});
diff --git a/server/sonar-web/src/main/js/app/store/languages/reducer.js b/server/sonar-web/src/main/js/app/store/languages/reducer.js
deleted file mode 100644 (file)
index 73eb9d5..0000000
+++ /dev/null
@@ -1,35 +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 keyBy from 'lodash/keyBy';
-import { RECEIVE_LANGUAGES } from './actions';
-
-const reducer = (state = {}, action = {}) => {
-  if (action.type === RECEIVE_LANGUAGES) {
-    return keyBy(action.languages, 'key');
-  }
-
-  return state;
-};
-
-export default reducer;
-
-export const getLanguages = state => (
-    state
-);
diff --git a/server/sonar-web/src/main/js/app/store/measures/actions.js b/server/sonar-web/src/main/js/app/store/measures/actions.js
deleted file mode 100644 (file)
index 2321163..0000000
+++ /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.
- */
-export const RECEIVE_COMPONENT_MEASURE = 'RECEIVE_COMPONENT_MEASURE';
-
-export const receiveComponentMeasure = (componentKey, metricKey, value) => ({
-  type: RECEIVE_COMPONENT_MEASURE,
-  componentKey,
-  metricKey,
-  value
-});
-
-export const RECEIVE_COMPONENT_MEASURES = 'RECEIVE_COMPONENT_MEASURES';
-
-export const receiveComponentMeasures = (componentKey, measures) => ({
-  type: RECEIVE_COMPONENT_MEASURES,
-  componentKey,
-  measures
-});
-
-export const RECEIVE_COMPONENTS_MEASURES = 'RECEIVE_COMPONENTS_MEASURES';
-
-export const receiveComponentsMeasures = componentsWithMeasures => ({
-  type: RECEIVE_COMPONENTS_MEASURES,
-  componentsWithMeasures
-});
diff --git a/server/sonar-web/src/main/js/app/store/measures/reducer.js b/server/sonar-web/src/main/js/app/store/measures/reducer.js
deleted file mode 100644 (file)
index 3d16666..0000000
+++ /dev/null
@@ -1,65 +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_COMPONENT_MEASURE, RECEIVE_COMPONENT_MEASURES, RECEIVE_COMPONENTS_MEASURES } from './actions';
-
-const byMetricKey = (state = {}, action = {}) => {
-  if (action.type === RECEIVE_COMPONENT_MEASURE) {
-    return { ...state, [action.metricKey]: action.value };
-  }
-
-  if (action.type === RECEIVE_COMPONENT_MEASURES) {
-    return { ...state, ...action.measures };
-  }
-
-  return state;
-};
-
-const reducer = (state = {}, action = {}) => {
-  if ([RECEIVE_COMPONENT_MEASURE, RECEIVE_COMPONENT_MEASURES].includes(action.type)) {
-    const component = state[action.componentKey];
-    return { ...state, [action.componentKey]: byMetricKey(component, action) };
-  }
-
-  if (action.type === RECEIVE_COMPONENTS_MEASURES) {
-    const newState = { ...state };
-    Object.keys(action.componentsWithMeasures).forEach(componentKey => {
-      Object.assign(newState, {
-        [componentKey]: byMetricKey(state[componentKey], {
-          type: RECEIVE_COMPONENT_MEASURES,
-          measures: action.componentsWithMeasures[componentKey]
-        })
-      });
-    });
-    return newState;
-  }
-
-  return state;
-};
-
-export default reducer;
-
-export const getComponentMeasure = (state, componentKey, metricKey) => {
-  const component = state[componentKey];
-  return component && component[metricKey];
-};
-
-export const getComponentMeasures = (state, componentKey) => (
-    state[componentKey]
-);
diff --git a/server/sonar-web/src/main/js/app/store/rootActions.js b/server/sonar-web/src/main/js/app/store/rootActions.js
deleted file mode 100644 (file)
index b2e9500..0000000
+++ /dev/null
@@ -1,77 +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 { getLanguages } from '../../api/languages';
-import { getGlobalNavigation, getComponentNavigation } from '../../api/nav';
-import * as auth from '../../api/auth';
-import { receiveLanguages } from './languages/actions';
-import { receiveComponents } from './components/actions';
-import { addGlobalErrorMessage } from '../../components/store/globalMessages';
-import { parseError } from '../../apps/code/utils';
-import { setAppState } from './appState/duck';
-
-const onFail = dispatch => error => (
-    parseError(error).then(message => dispatch(addGlobalErrorMessage(message)))
-);
-
-export const fetchAppState = () => dispatch => (
-    getGlobalNavigation().then(
-        appState => dispatch(setAppState(appState)),
-        onFail(dispatch)
-    )
-);
-
-export const fetchLanguages = () => dispatch => {
-  return getLanguages().then(
-      languages => dispatch(receiveLanguages(languages)),
-      onFail(dispatch)
-  );
-};
-
-const addQualifier = project => ({
-  ...project,
-  qualifier: project.breadcrumbs[project.breadcrumbs.length - 1].qualifier
-});
-
-export const fetchProject = key => dispatch => (
-    getComponentNavigation(key).then(
-        component => dispatch(receiveComponents([addQualifier(component)])),
-        onFail(dispatch)
-    )
-);
-
-export const doLogin = (login, password) => dispatch => (
-    auth.login(login, password).then(
-        () => { /* everything is fine */ },
-        () => {
-          dispatch(addGlobalErrorMessage('Authentication failed'));
-          return Promise.reject();
-        }
-    )
-);
-
-export const doLogout = () => dispatch => (
-    auth.logout().then(
-        () => { /* everything is fine */ },
-        () => {
-          dispatch(addGlobalErrorMessage('Logout failed'));
-          return Promise.reject();
-        }
-    )
-);
diff --git a/server/sonar-web/src/main/js/app/store/rootReducer.js b/server/sonar-web/src/main/js/app/store/rootReducer.js
deleted file mode 100644 (file)
index b5cba2f..0000000
+++ /dev/null
@@ -1,304 +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 { combineReducers } from 'redux';
-import appState from './appState/duck';
-import components, * as fromComponents from './components/reducer';
-import users, * as fromUsers from './users/reducer';
-import favorites, * as fromFavorites from './favorites/duck';
-import languages, * as fromLanguages from './languages/reducer';
-import measures, * as fromMeasures from './measures/reducer';
-import globalMessages, * as fromGlobalMessages from '../../components/store/globalMessages';
-
-import measuresApp, * as fromMeasuresApp from '../../apps/component-measures/store/rootReducer';
-import permissionsApp, * as fromPermissionsApp from '../../apps/permissions/shared/store/rootReducer';
-import projectAdminApp, * as fromProjectAdminApp from '../../apps/project-admin/store/rootReducer';
-import projectsApp, * as fromProjectsApp from '../../apps/projects/store/reducer';
-import qualityGatesApp from '../../apps/quality-gates/store/rootReducer';
-import settingsApp, * as fromSettingsApp from '../../apps/settings/store/rootReducer';
-
-export default combineReducers({
-  appState,
-  components,
-  globalMessages,
-  favorites,
-  languages,
-  measures,
-  users,
-
-  // apps
-  measuresApp,
-  permissionsApp,
-  projectAdminApp,
-  projectsApp,
-  qualityGatesApp,
-  settingsApp
-});
-
-export const getAppState = state => (
-    state.appState
-);
-
-export const getComponent = (state, key) => (
-    fromComponents.getComponent(state.components, key)
-);
-
-export const getGlobalMessages = state => (
-    fromGlobalMessages.getGlobalMessages(state.globalMessages)
-);
-
-export const getLanguages = (state, key) => (
-    fromLanguages.getLanguages(state.languages, key)
-);
-
-export const getCurrentUser = state => (
-    fromUsers.getCurrentUser(state.users)
-);
-
-export const isFavorite = (state, componentKey) => (
-    fromFavorites.isFavorite(state.favorites, componentKey)
-);
-
-export const getComponentMeasure = (state, componentKey, metricKey) => (
-    fromMeasures.getComponentMeasure(state.measures, componentKey, metricKey)
-);
-
-export const getComponentMeasures = (state, componentKey) => (
-    fromMeasures.getComponentMeasures(state.measures, componentKey)
-);
-
-export const getProjects = state => (
-    fromProjectsApp.getProjects(state.projectsApp)
-);
-
-export const getProjectsAppState = state => (
-    fromProjectsApp.getState(state.projectsApp)
-);
-
-export const getProjectsAppFacetByProperty = (state, property) => (
-    fromProjectsApp.getFacetByProperty(state.projectsApp, property)
-);
-
-export const getProjectsAppMaxFacetValue = state => (
-    fromProjectsApp.getMaxFacetValue(state.projectsApp)
-);
-
-export const getQualityGatesAppState = state => (
-    state.qualityGatesApp
-);
-
-export const getPermissionsAppUsers = state => (
-    fromPermissionsApp.getUsers(state.permissionsApp)
-);
-
-export const getPermissionsAppGroups = state => (
-    fromPermissionsApp.getGroups(state.permissionsApp)
-);
-
-export const isPermissionsAppLoading = state => (
-    fromPermissionsApp.isLoading(state.permissionsApp)
-);
-
-export const getPermissionsAppQuery = state => (
-    fromPermissionsApp.getQuery(state.permissionsApp)
-);
-
-export const getPermissionsAppFilter = state => (
-    fromPermissionsApp.getFilter(state.permissionsApp)
-);
-
-export const getPermissionsAppSelectedPermission = state => (
-    fromPermissionsApp.getSelectedPermission(state.permissionsApp)
-);
-
-export const getPermissionsAppError = state => (
-    fromPermissionsApp.getError(state.permissionsApp)
-);
-
-export const getSettingValue = (state, key) => (
-    fromSettingsApp.getValue(state.settingsApp, key)
-);
-
-export const getSettingsAppDefinition = (state, key) => (
-    fromSettingsApp.getDefinition(state.settingsApp, key)
-);
-
-export const getSettingsAppAllCategories = state => (
-    fromSettingsApp.getAllCategories(state.settingsApp)
-);
-
-export const getSettingsAppDefaultCategory = state => (
-    fromSettingsApp.getDefaultCategory(state.settingsApp)
-);
-
-export const getSettingsAppSettingsForCategory = (state, category) => (
-    fromSettingsApp.getSettingsForCategory(state.settingsApp, category)
-);
-
-export const getSettingsAppChangedValue = (state, key) => (
-    fromSettingsApp.getChangedValue(state.settingsApp, key)
-);
-
-export const isSettingsAppLoading = (state, key) => (
-    fromSettingsApp.isLoading(state.settingsApp, key)
-);
-
-export const getSettingsAppLicenseByKey = (state, key) => (
-    fromSettingsApp.getLicenseByKey(state.settingsApp, key)
-);
-
-export const getSettingsAppAllLicenseKeys = state => (
-    fromSettingsApp.getAllLicenseKeys(state.settingsApp)
-);
-
-export const getSettingsAppValidationMessage = (state, key) => (
-    fromSettingsApp.getValidationMessage(state.settingsApp, key)
-);
-
-export const getSettingsAppEncryptionState = state => (
-    fromSettingsApp.getEncryptionState(state.settingsApp)
-);
-
-export const getSettingsAppGlobalMessages = state => (
-    fromSettingsApp.getGlobalMessages(state.settingsApp)
-);
-
-export const getProjectAdminProfileByKey = (state, profileKey) => (
-    fromProjectAdminApp.getProfileByKey(state.projectAdminApp, profileKey)
-);
-
-export const getProjectAdminAllProfiles = state => (
-    fromProjectAdminApp.getAllProfiles(state.projectAdminApp)
-);
-
-export const getProjectAdminProjectProfiles = (state, projectKey) => (
-    fromProjectAdminApp.getProjectProfiles(state.projectAdminApp, projectKey)
-);
-
-export const getProjectAdminGateById = (state, gateId) => (
-    fromProjectAdminApp.getGateById(state.projectAdminApp, gateId)
-);
-
-export const getProjectAdminAllGates = state => (
-    fromProjectAdminApp.getAllGates(state.projectAdminApp)
-);
-
-export const getProjectAdminProjectGate = (state, projectKey) => (
-    fromProjectAdminApp.getProjectGate(state.projectAdminApp, projectKey)
-);
-
-export const getProjectAdminLinkById = (state, linkId) => (
-    fromProjectAdminApp.getLinkById(state.projectAdminApp, linkId)
-);
-
-export const getProjectAdminProjectLinks = (state, projectKey) => (
-    fromProjectAdminApp.getProjectLinks(state.projectAdminApp, projectKey)
-);
-
-export const getProjectAdminComponentByKey = (state, componentKey) => (
-    fromProjectAdminApp.getComponentByKey(state.projectAdminApp, componentKey)
-);
-
-export const getProjectAdminProjectModules = (state, projectKey) => (
-    fromProjectAdminApp.getProjectModules(state.projectAdminApp, projectKey)
-);
-
-export const getProjectAdminGlobalMessages = state => (
-    fromProjectAdminApp.getGlobalMessages(state.projectAdminApp)
-);
-
-export const getMeasuresAppComponent = state => (
-    fromMeasuresApp.getComponent(state.measuresApp)
-);
-
-export const getMeasuresAppAllMetrics = state => (
-    fromMeasuresApp.getAllMetrics(state.measuresApp)
-);
-
-export const getMeasuresAppDetailsMetric = state => (
-    fromMeasuresApp.getDetailsMetric(state.measuresApp)
-);
-
-export const getMeasuresAppDetailsMeasure = state => (
-    fromMeasuresApp.getDetailsMeasure(state.measuresApp)
-);
-
-export const getMeasuresAppDetailsSecondaryMeasure = state => (
-    fromMeasuresApp.getDetailsSecondaryMeasure(state.measuresApp)
-);
-
-export const getMeasuresAppDetailsPeriods = state => (
-    fromMeasuresApp.getDetailsPeriods(state.measuresApp)
-);
-
-export const isMeasuresAppFetching = state => (
-    fromMeasuresApp.isFetching(state.measuresApp)
-);
-
-export const getMeasuresAppList = state => (
-    fromMeasuresApp.getList(state.measuresApp)
-);
-
-export const getMeasuresAppListComponents = state => (
-    fromMeasuresApp.getListComponents(state.measuresApp)
-);
-
-export const getMeasuresAppListSelected = state => (
-    fromMeasuresApp.getListSelected(state.measuresApp)
-);
-
-export const getMeasuresAppListTotal = state => (
-    fromMeasuresApp.getListTotal(state.measuresApp)
-);
-
-export const getMeasuresAppListPageIndex = state => (
-    fromMeasuresApp.getListPageIndex(state.measuresApp)
-);
-
-export const getMeasuresAppTree = state => (
-    fromMeasuresApp.getTree(state.measuresApp)
-);
-
-export const getMeasuresAppTreeComponents = state => (
-    fromMeasuresApp.getTreeComponents(state.measuresApp)
-);
-
-export const getMeasuresAppTreeBreadcrumbs = state => (
-    fromMeasuresApp.getTreeBreadcrumbs(state.measuresApp)
-);
-
-export const getMeasuresAppTreeSelected = state => (
-    fromMeasuresApp.getTreeSelected(state.measuresApp)
-);
-
-export const getMeasuresAppTreeTotal = state => (
-    fromMeasuresApp.getTreeTotal(state.measuresApp)
-);
-
-export const getMeasuresAppTreePageIndex = state => (
-    fromMeasuresApp.getTreePageIndex(state.measuresApp)
-);
-
-export const getMeasuresAppHomeDomains = state => (
-    fromMeasuresApp.getHomeDomains(state.measuresApp)
-);
-
-export const getMeasuresAppHomePeriods = state => (
-    fromMeasuresApp.getHomePeriods(state.measuresApp)
-);
diff --git a/server/sonar-web/src/main/js/app/store/users/actions.js b/server/sonar-web/src/main/js/app/store/users/actions.js
deleted file mode 100644 (file)
index 71e055d..0000000
+++ /dev/null
@@ -1,31 +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 RECEIVE_CURRENT_USER = 'RECEIVE_CURRENT_USER';
-
-export const receiveCurrentUser = user => ({
-  type: RECEIVE_CURRENT_USER,
-  user
-});
-
-export const fetchCurrentUser = () => dispatch => (
-    getCurrentUser().then(user => dispatch(receiveCurrentUser(user)))
-);
diff --git a/server/sonar-web/src/main/js/app/store/users/reducer.js b/server/sonar-web/src/main/js/app/store/users/reducer.js
deleted file mode 100644 (file)
index 03dd5f9..0000000
+++ /dev/null
@@ -1,52 +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 { combineReducers } from 'redux';
-import uniq from 'lodash/uniq';
-import { RECEIVE_CURRENT_USER } from './actions';
-
-const usersByLogin = (state = {}, action = {}) => {
-  if (action.type === RECEIVE_CURRENT_USER) {
-    return { ...state, [action.user.login]: action.user };
-  }
-
-  return state;
-};
-
-const userLogins = (state = [], action = {}) => {
-  if (action.type === RECEIVE_CURRENT_USER) {
-    return uniq([...state, action.user.login]);
-  }
-
-  return state;
-};
-
-const currentUser = (state = null, action = {}) => {
-  if (action.type === RECEIVE_CURRENT_USER) {
-    return action.user;
-  }
-
-  return state;
-};
-
-export default combineReducers({ usersByLogin, userLogins, currentUser });
-
-export const getCurrentUser = state => (
-    state.currentUser
-);
index b16ba492a00e85b933b4acc028fab57ce390eb60..82791c3306c736038f18f870c6c0f30548d050e7 100644 (file)
@@ -18,7 +18,7 @@
  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  */
 // @flow
-import { getCurrentUser } from '../store/rootReducer';
+import { getCurrentUser } from '../../store/rootReducer';
 
 // TODO remove my usages
 const getCurrentUserFromStore = () => {
index 1fb1cad4e4f1b85099da374e75d8b96b9d24a117..010b0c581e99f0d7389a7b40eaa2dfabf0d7a708 100644 (file)
@@ -18,8 +18,8 @@
  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  */
 // @flow
-import configureStore from '../../components/store/configureStore';
-import rootReducer from '../store/rootReducer';
+import configureStore from '../../store/utils/configureStore';
+import rootReducer from '../../store/rootReducer';
 
 let store;
 
index 566434f196c8f6e005ca31bc9073ed2ce63aeafb..453c970a69d39736bada9a1de919bdb2e6a5b41f 100644 (file)
@@ -20,7 +20,7 @@
 // @flow
 import getStore from './getStore';
 import getHistory from './getHistory';
-import { requireAuthentication } from '../store/appState/duck';
+import { requireAuthentication } from '../../store/appState/duck';
 
 export default () => {
   const store = getStore();
index b8664b312df64ab5e2eef15c82182df674ac27e9..095d2f53f5af301010962d1f85b116b9f3d5ec75 100644 (file)
@@ -20,7 +20,7 @@
 // @flow
 import getStore from './getStore';
 import getHistory from './getHistory';
-import { requireAuthorization } from '../store/appState/duck';
+import { requireAuthorization } from '../../store/appState/duck';
 
 export default () => {
   const store = getStore();
index dae2e6c8158cfbeb54909da00cfb0a90c0baaab7..e95674f2c6b58bd60965c5e5fb7d0e46db5fbae6 100644 (file)
@@ -31,7 +31,7 @@ import AboutScanners from './AboutScanners';
 import { translate } from '../../../helpers/l10n';
 import { searchProjects } from '../../../api/components';
 import { getFacet } from '../../../api/issues';
-import { getSettingValue } from '../../../app/store/rootReducer';
+import { getSettingValue } from '../../../store/rootReducer';
 import * as settingsAPI from '../../../api/settings';
 import '../styles.css';
 
index 0606d1aef6147da34c3f1b1f966a0d35456253c4..633a6da22759e151c00b6f0957b7927ef2ccc195 100644 (file)
@@ -21,7 +21,7 @@ import React from 'react';
 import { connect } from 'react-redux';
 import Nav from './Nav';
 import UserCard from './UserCard';
-import { getCurrentUser } from '../../../app/store/rootReducer';
+import { getCurrentUser } from '../../../store/rootReducer';
 import '../account.css';
 
 class Account extends React.Component {
index 9accad023f5df9f10c5c3579d7e6d5c3ab0aadc8..f229aae99362175a78c67f0193bfeea828a27414 100644 (file)
@@ -23,7 +23,7 @@ import Helmet from 'react-helmet';
 import Password from './Password';
 import Tokens from './Tokens';
 import { translate } from '../../../helpers/l10n';
-import { getCurrentUser } from '../../../app/store/rootReducer';
+import { getCurrentUser } from '../../../store/rootReducer';
 
 class Security extends React.Component {
   render () {
index 776b328676e2c94aad61b0f9842b2c2e942e867f..3d3213b7ea22952b4561a7951868154e11375258 100644 (file)
@@ -22,7 +22,7 @@ import { connect } from 'react-redux';
 import UserExternalIdentity from './UserExternalIdentity';
 import UserGroups from './UserGroups';
 import UserScmAccounts from './UserScmAccounts';
-import { getCurrentUser } from '../../../app/store/rootReducer';
+import { getCurrentUser } from '../../../store/rootReducer';
 
 class Profile extends React.Component {
   render () {
index 94c5459e0fdd4609d7883c2fa4fd8da14e06eeed..d94951e32c7ec72c00c178965c778b5cab4bfdd5 100644 (file)
@@ -31,7 +31,7 @@ import Tasks from '../components/Tasks';
 import { getTypes, getActivity, getStatus, cancelAllTasks, cancelTask as cancelTaskAPI } from '../../../api/ce';
 import { updateTask, mapFiltersToParameters } from '../utils';
 import { Task } from '../types';
-import { getComponent } from '../../../app/store/rootReducer';
+import { getComponent } from '../../../store/rootReducer';
 import '../background-tasks.css';
 
 class BackgroundTasksApp extends React.Component {
index 4e27e90e01578d88a9187c4f22d722a0f4cbe3d7..7e265b23692da4f8cca9b7b7bf4c9f23a1bb56e3 100644 (file)
@@ -27,7 +27,7 @@ import Search from './Search';
 import ListFooter from '../../../components/controls/ListFooter';
 import { retrieveComponentChildren, retrieveComponent, loadMoreChildren, parseError } from '../utils';
 import { addComponent, addComponentBreadcrumbs, clearBucket } from '../bucket';
-import { getComponent } from '../../../app/store/rootReducer';
+import { getComponent } from '../../../store/rootReducer';
 import '../code.css';
 
 class App extends React.Component {
index 4ca3376c3b09d5bee652ba52b10b566113a5f6de..3c08036cb912120f8ee7253d90352207e39cc965 100644 (file)
@@ -20,7 +20,7 @@
 import React from 'react';
 import init from '../init';
 import { connect } from 'react-redux';
-import { getComponent, getCurrentUser } from '../../../app/store/rootReducer';
+import { getComponent, getCurrentUser } from '../../../store/rootReducer';
 
 class ComponentIssuesAppContainer extends React.Component {
   componentDidMount () {
index 5c1f09eaf63b3a856e89cf72b9982b056761dbd2..cd26bb8f63e873ee43f26f5bbb54f14015ec81c9 100644 (file)
@@ -20,7 +20,7 @@
 import { connect } from 'react-redux';
 import App from './App';
 import { fetchMetrics, setComponent } from './actions';
-import { getComponent, getMeasuresAppAllMetrics } from '../../../app/store/rootReducer';
+import { getComponent, getMeasuresAppAllMetrics } from '../../../store/rootReducer';
 
 const mapStateToProps = (state, ownProps) => ({
   component: getComponent(state, ownProps.location.query.id),
index 029cee95b55ed964ac666248e13c362f838daa0b..00534a6331c37f358ed074dc25898c38a163b80b 100644 (file)
@@ -19,7 +19,7 @@
  */
 import { connect } from 'react-redux';
 import MeasureBubbleChart from './BubbleChart';
-import { getMeasuresAppAllMetrics, getMeasuresAppComponent } from '../../../../app/store/rootReducer';
+import { getMeasuresAppAllMetrics, getMeasuresAppComponent } from '../../../../store/rootReducer';
 
 const mapStateToProps = state => {
   return {
index 055ce5225e3d6b9d75f4d3c56226aa3a77dd0a25..b569c01636b7dc3635f2da53d5673fa396f36cd6 100644 (file)
@@ -27,7 +27,7 @@ import {
   getMeasuresAppDetailsSecondaryMeasure,
   getMeasuresAppDetailsPeriods
   , getMeasuresAppComponent
-} from '../../../app/store/rootReducer';
+} from '../../../store/rootReducer';
 
 const mapStateToProps = state => {
   return {
index 608c7e2b97c1c93bc509e994538bddc71e3f8f5a..a7523787d22afc7b20276e38c349ee75a83a969a 100644 (file)
@@ -19,7 +19,7 @@
  */
 import { getMeasuresAndMeta } from '../../../api/measures';
 import { enhanceWithLeak } from '../utils';
-import { getMeasuresAppComponent, getMeasuresAppAllMetrics } from '../../../app/store/rootReducer';
+import { getMeasuresAppComponent, getMeasuresAppAllMetrics } from '../../../store/rootReducer';
 
 /*
  * Actions
index d982d7aef88ca833af4b4015089436aaff52a60e..57d20b41a4625c8f78891c5d7efe195668198754 100644 (file)
@@ -29,7 +29,7 @@ import {
   getMeasuresAppDetailsMetric,
   isMeasuresAppFetching
   , getMeasuresAppComponent
-} from '../../../../app/store/rootReducer';
+} from '../../../../store/rootReducer';
 
 const mapStateToProps = state => {
   return {
index 114b9ef08e21e45c6cdd45035873bc7ca6533b4c..cb5e2a0e76b402f1d1b0bb23ae95f94596a201b9 100644 (file)
@@ -38,7 +38,7 @@ import {
   getMeasuresAppDetailsMetric,
   isMeasuresAppFetching
   , getMeasuresAppComponent
-} from '../../../../app/store/rootReducer';
+} from '../../../../store/rootReducer';
 
 const mapStateToProps = state => {
   return {
index b70189eedb52681e5966f7ec40ec8a02da529dd9..d60569a17c299b407726197fe701e787a74749e3 100644 (file)
@@ -19,7 +19,7 @@
  */
 import { connect } from 'react-redux';
 import MeasureHistory from './MeasureHistory';
-import { getMeasuresAppDetailsMetric, getMeasuresAppComponent } from '../../../../app/store/rootReducer';
+import { getMeasuresAppDetailsMetric, getMeasuresAppComponent } from '../../../../store/rootReducer';
 
 const mapStateToProps = state => {
   return {
index e24858b82e33ed4c0fb1f57e199b6698c039bde5..2a040d7b0c2c63dda64a0cb3dd9ede784bca2ec7 100644 (file)
@@ -19,7 +19,7 @@
  */
 import { connect } from 'react-redux';
 import MeasureTreemap from './MeasureTreemap';
-import { getMeasuresAppDetailsMetric, getMeasuresAppComponent } from '../../../../app/store/rootReducer';
+import { getMeasuresAppDetailsMetric, getMeasuresAppComponent } from '../../../../store/rootReducer';
 
 const mapStateToProps = state => {
   return {
index d02d06bfcc3a1390f004f47b5dac54e9795a8851..b690cf7e21c267c2e85a5a0f207c3eda876b38e4 100644 (file)
@@ -23,7 +23,7 @@ import {
   getMeasuresAppHomeDomains,
   getMeasuresAppHomePeriods,
   getMeasuresAppComponent
-} from '../../../app/store/rootReducer';
+} from '../../../store/rootReducer';
 
 const mapStateToProps = state => {
   return {
index 53094eb9bc7cd2f9e1390d82c18366207f420781..858b09dbe1e4ac6d3b53810e307207d1485d3376 100644 (file)
@@ -23,7 +23,7 @@ import {
   getMeasuresAppHomeDomains,
   getMeasuresAppHomePeriods,
   getMeasuresAppComponent
-} from '../../../app/store/rootReducer';
+} from '../../../store/rootReducer';
 
 const mapStateToProps = state => {
   return {
index 58e3285c18198b89be63cc67237ac1b7c439f57c..9c16840b0c18ada30b78d3769eca35c7ace77a56 100644 (file)
@@ -25,7 +25,7 @@ import {
   getMeasuresAppHomeDomains,
   getMeasuresAppHomePeriods,
   getMeasuresAppComponent
-} from '../../../app/store/rootReducer';
+} from '../../../store/rootReducer';
 
 const mapStateToProps = state => {
   return {
index 006d4680523503d869ed5fe029a94bdece9ce13c..04a2f11da5c52a47441894dbfe333f2b372e61dd 100644 (file)
@@ -21,7 +21,7 @@ import { startFetching, stopFetching } from '../store/statusActions';
 import { getMeasuresAndMeta } from '../../../api/measures';
 import { getLeakPeriod } from '../../../helpers/periods';
 import { getLeakValue } from '../utils';
-import { getMeasuresAppComponent, getMeasuresAppAllMetrics } from '../../../app/store/rootReducer';
+import { getMeasuresAppComponent, getMeasuresAppAllMetrics } from '../../../store/rootReducer';
 
 export const RECEIVE_MEASURES = 'measuresApp/home/RECEIVE_MEASURES';
 
index 1f48656bfb8d46fe9536ce05e18b05e128e96b62..857c82b41c116bb5a1673f089b9ada2b12f87ac6 100644 (file)
@@ -21,7 +21,7 @@ import { getComponentTree } from '../../../api/components';
 import { enhanceWithMeasure } from '../utils';
 import { startFetching, stopFetching } from './statusActions';
 import complementary from '../config/complementary';
-import { getMeasuresAppList } from '../../../app/store/rootReducer';
+import { getMeasuresAppList } from '../../../store/rootReducer';
 
 export const UPDATE_STORE = 'measuresApp/drilldown/list/UPDATE_STORE';
 
index 81d2896c9d82c7a31c97c52ebba1f4175c9fa8fc..5697f7a2a79c2824d18c84bdf5ce5ad654b31c77 100644 (file)
@@ -23,7 +23,7 @@ import { getComponentTree } from '../../../api/components';
 import { enhanceWithMeasure } from '../utils';
 import { startFetching, stopFetching } from './statusActions';
 import complementary from '../config/complementary';
-import { getMeasuresAppTree } from '../../../app/store/rootReducer';
+import { getMeasuresAppTree } from '../../../store/rootReducer';
 
 /*
  * Actions
index ad4b91936c652e318bcee4dba42b3289e50ad6d6..3eb2a0b1db2f2550feff5ffaec4aca80cfffee7a 100644 (file)
@@ -20,7 +20,7 @@
 import React from 'react';
 import { connect } from 'react-redux';
 import init from '../init';
-import { getComponent } from '../../../app/store/rootReducer';
+import { getComponent } from '../../../store/rootReducer';
 
 class CustomMeasuresAppContainer extends React.Component {
   componentDidMount () {
index 4d5c56374eff68c44ecdb65751be0946324892ce..b33d4907d2ae640eb1c3451b98b3249273951199 100644 (file)
@@ -20,7 +20,7 @@
 import React from 'react';
 import { connect } from 'react-redux';
 import init from '../init';
-import { getCurrentUser } from '../../../app/store/rootReducer';
+import { getCurrentUser } from '../../../store/rootReducer';
 
 class IssuesAppContainer extends React.Component {
   static propTypes = {
index e697ff24c186fe8023cfca86eda7278b44229833..814390fbf3721bc9a16d0b34de86f3e350544dd1 100644 (file)
@@ -19,7 +19,7 @@
  */
 import { connect } from 'react-redux';
 import App from './App';
-import { getComponent } from '../../../app/store/rootReducer';
+import { getComponent } from '../../../store/rootReducer';
 
 const mapStateToProps = (state, ownProps) => ({
   component: getComponent(state, ownProps.location.query.id)
index 0530d58e218d61263ce61bae4728cbbf8104654a..8cdeb817cf19c9f7a54294ae52d0abbae22da49a 100644 (file)
@@ -24,7 +24,7 @@ import { TooltipsContainer } from '../../../components/mixins/tooltips-mixin';
 import { translate, translateWithParameters } from '../../../helpers/l10n';
 import { getQualityProfileUrl } from '../../../helpers/urls';
 import { searchRules } from '../../../api/rules';
-import { getLanguages } from '../../../app/store/rootReducer';
+import { getLanguages } from '../../../store/rootReducer';
 
 class MetaQualityProfiles extends React.Component {
   state = {
index 48ca02edbd8a1af476bde40b5641fea7906ffba4..e00ff5087b6ae4098dde7f2e7b30e5d632181f92 100644 (file)
@@ -19,8 +19,8 @@
  */
 import { connect } from 'react-redux';
 import App from './App';
-import { getAppState } from '../../../app/store/rootReducer';
-import { getRootQualifiers } from '../../../app/store/appState/duck';
+import { getAppState } from '../../../store/rootReducer';
+import { getRootQualifiers } from '../../../store/appState/duck';
 
 const mapStateToProps = state => ({
   topQualifiers: getRootQualifiers(getAppState(state))
index c22c27d9ec033c26dcfa40cfa7cb6dddaa7089b2..1639f5cb6c3206ae76309a9f25b91600bc4209df 100644 (file)
@@ -27,7 +27,7 @@ import SearchForm from '../../permissions/shared/components/SearchForm';
 import { PERMISSIONS_ORDER_FOR_PROJECT } from '../../permissions/project/constants';
 import * as api from '../../../api/permissions';
 import { translate } from '../../../helpers/l10n';
-import withStore from '../../../components/store/withStore';
+import withStore from '../../../store/utils/withStore';
 
 class Template extends React.Component {
   static propTypes = {
index 5634341502719b2370514920f6ff27adf229393e..dd781c3cd250110b782d1925c8987d8cee735c06 100644 (file)
@@ -38,7 +38,7 @@ import {
   getPermissionsAppQuery,
   getPermissionsAppFilter,
   getPermissionsAppSelectedPermission
-} from '../../../../app/store/rootReducer';
+} from '../../../../store/rootReducer';
 
 const PERMISSIONS_ORDER = [
   'admin',
index 299de992836634ffd41d47bcc3e21cf1d101a0c4..260c26c9ea0dc6440189eeed55013a386246b34a 100644 (file)
@@ -21,7 +21,7 @@ import React from 'react';
 import { connect } from 'react-redux';
 import { translate } from '../../../../helpers/l10n';
 import { loadHolders } from '../store/actions';
-import { isPermissionsAppLoading } from '../../../../app/store/rootReducer';
+import { isPermissionsAppLoading } from '../../../../store/rootReducer';
 
 class PageHeader extends React.Component {
   static propTypes = {
index 207a0cf7e0a1ea07ead0d75fefad9cc0bb4c26f0..eb2021a3b19294db9df277bd7db2407bdbbb3775 100644 (file)
@@ -35,7 +35,7 @@ import {
   getPermissionsAppQuery,
   getPermissionsAppFilter,
   getPermissionsAppSelectedPermission
-} from '../../../../app/store/rootReducer';
+} from '../../../../store/rootReducer';
 
 export const loadHolders = () => (dispatch, getState) => {
   const query = getPermissionsAppQuery(getState());
index 63b041b2fcfd6b0bd1884431d4622bfce38c2d41..dabcf13e5645a544dfd62d19dff90a73e2215ea4 100644 (file)
@@ -39,7 +39,7 @@ import {
   getPermissionsAppQuery,
   getPermissionsAppFilter,
   getPermissionsAppSelectedPermission
-} from '../../../../app/store/rootReducer';
+} from '../../../../store/rootReducer';
 
 class AllHoldersList extends React.Component {
   static propTypes = {
index c7657ddcc5131545a3cd2ccd221fc319762957d2..16e9f10db80614e3780745c1db5140e1c1d88851 100644 (file)
@@ -22,7 +22,7 @@ import { connect } from 'react-redux';
 import PageHeader from './PageHeader';
 import AllHoldersList from './AllHoldersList';
 import PageError from '../../shared/components/PageError';
-import { getComponent, getCurrentUser } from '../../../../app/store/rootReducer';
+import { getComponent, getCurrentUser } from '../../../../store/rootReducer';
 import '../../styles.css';
 
 // TODO helmet
index 456a16cf7a3127418f06944b48a960e8661cae4e..700b2b48ea326709c11672425c7b62fa97f6bf95 100644 (file)
@@ -22,7 +22,7 @@ import { connect } from 'react-redux';
 import { translate } from '../../../../helpers/l10n';
 import ApplyTemplateView from '../views/ApplyTemplateView';
 import { loadHolders } from '../store/actions';
-import { isPermissionsAppLoading } from '../../../../app/store/rootReducer';
+import { isPermissionsAppLoading } from '../../../../store/rootReducer';
 import { isUserAdmin } from '../../../../helpers/users';
 
 class PageHeader extends React.Component {
index b705876a6a263b54ba02227218e5bf3073763cb0..1982d34ea05bb2bee72b132c4fcd1359eec91931 100644 (file)
@@ -35,7 +35,7 @@ import {
   getPermissionsAppQuery,
   getPermissionsAppFilter,
   getPermissionsAppSelectedPermission
-} from '../../../../app/store/rootReducer';
+} from '../../../../store/rootReducer';
 
 export const loadHolders = projectKey => (dispatch, getState) => {
   const query = getPermissionsAppQuery(getState());
index 289a6c196a0b2c700cc4d197fdb7725ae1358525..e5fb83bfc382c1d1d99aa8c5493b0f4c51deafef 100644 (file)
@@ -19,7 +19,7 @@
  */
 import React from 'react';
 import { connect } from 'react-redux';
-import { getPermissionsAppError } from '../../../../app/store/rootReducer';
+import { getPermissionsAppError } from '../../../../store/rootReducer';
 
 class PageError extends React.Component {
   static propTypes = {
index 0fd141962aafd91bbb5368e031ea45f8ae5c547f..b609589522d62f9f876bced5dd82fc7888e059c3 100644 (file)
@@ -21,7 +21,7 @@ import React from 'react';
 import { connect } from 'react-redux';
 import Header from './Header';
 import Form from './Form';
-import { getComponent } from '../../../app/store/rootReducer';
+import { getComponent } from '../../../store/rootReducer';
 
 class Deletion extends React.Component {
   static propTypes = {
index 4bc8050a4643289c154c1717667fac164bf89746..a740ededa6c3dacb458732316630f72d9ce21300 100644 (file)
@@ -28,7 +28,7 @@ import {
     addGlobalErrorMessage,
     addGlobalSuccessMessage,
     closeAllGlobalMessages
-} from '../../../components/store/globalMessages';
+} from '../../../store/globalMessages/duck';
 import { reloadUpdateKeyPage } from './utils';
 import RecentHistory from '../../../app/components/nav/component/RecentHistory';
 
index 7b4c04846bbe27cc6d3ca515031400dce81d975d..c8256ced45564b740d92fcc33bdf2f5f7d9e6f9e 100644 (file)
@@ -30,11 +30,11 @@ import {
     addGlobalErrorMessage,
     closeAllGlobalMessages,
     addGlobalSuccessMessage
-} from '../../../components/store/globalMessages';
+} from '../../../store/globalMessages/duck';
 import { parseError } from '../../code/utils';
 import { reloadUpdateKeyPage } from './utils';
 import RecentHistory from '../../../app/components/nav/component/RecentHistory';
-import { getProjectAdminProjectModules, getComponent } from '../../../app/store/rootReducer';
+import { getProjectAdminProjectModules, getComponent } from '../../../store/rootReducer';
 
 class Key extends React.Component {
   static propTypes = {
index d1e611c87c4c0e8f30ecd3a6b3aad344d03d8259..f3d3c36991e9de1e8675a0814fcc4bdbae3e2ba6 100644 (file)
@@ -28,7 +28,7 @@ import {
     deleteProjectLink,
     createProjectLink
 } from '../store/actions';
-import { getProjectAdminProjectLinks, getComponent } from '../../../app/store/rootReducer';
+import { getProjectAdminProjectLinks, getComponent } from '../../../store/rootReducer';
 
 class Links extends React.Component {
   static propTypes = {
index 50eabdecb47cfcf7afae970828c96faec17784b5..7dcd84df4032888f94ebfc5ad0669d6bfd5c876d 100644 (file)
@@ -23,7 +23,7 @@ import shallowCompare from 'react-addons-shallow-compare';
 import Header from './Header';
 import Form from './Form';
 import { fetchProjectGate, setProjectGate } from '../store/actions';
-import { getProjectAdminAllGates, getProjectAdminProjectGate, getComponent } from '../../../app/store/rootReducer';
+import { getProjectAdminAllGates, getProjectAdminProjectGate, getComponent } from '../../../store/rootReducer';
 
 class QualityGate extends React.Component {
   static propTypes = {
index 5d4263cf6ebe37965aeee7aef632e52ed141da7b..591ede496bcb4eb3d8078e7b26361173ea4409e6 100644 (file)
@@ -27,7 +27,7 @@ import {
   getProjectAdminAllProfiles,
   getProjectAdminProjectProfiles,
   getComponent
-} from '../../../app/store/rootReducer';
+} from '../../../store/rootReducer';
 
 class QualityProfiles extends React.Component {
   static propTypes = {
index b5c3c1a5f21cb7c2713c207e8fba8aaf47a2cc07..eafbd8853ae68059c22f56c891c18b026919441e 100644 (file)
@@ -26,9 +26,9 @@ import {
 } from '../../../api/quality-gates';
 import { getProjectLinks, createLink } from '../../../api/projectLinks';
 import { getTree, changeKey as changeKeyApi } from '../../../api/components';
-import { addGlobalSuccessMessage } from '../../../components/store/globalMessages';
+import { addGlobalSuccessMessage } from '../../../store/globalMessages/duck';
 import { translate, translateWithParameters } from '../../../helpers/l10n';
-import { getProjectAdminProfileByKey } from '../../../app/store/rootReducer';
+import { getProjectAdminProfileByKey } from '../../../store/rootReducer';
 
 export const RECEIVE_PROFILES = 'projectAdmin/RECEIVE_PROFILES';
 export const receiveProfiles = profiles => ({
index a5c56087ce91c06bb09c04babf098333b4a78879..1a49d87e3e03658f687507d8148072a9b8191558 100644 (file)
@@ -35,7 +35,7 @@ import modulesByProject, {
 } from './modulesByProject';
 import globalMessages, {
     getGlobalMessages as nextGetGlobalMessages
-} from '../../../components/store/globalMessages';
+} from '../../../store/globalMessages/duck';
 
 const rootReducer = combineReducers({
   profiles,
index 11eb059ad02266556b096c0b9d134d74c68e7ec5..ebf5317536fab0a651cfa670627dc0cd884623ef 100644 (file)
@@ -20,8 +20,8 @@
 import React from 'react';
 import { connect } from 'react-redux';
 import Main from './main';
-import { getCurrentUser, getAppState } from '../../app/store/rootReducer';
-import { getRootQualifiers } from '../../app/store/appState/duck';
+import { getCurrentUser, getAppState } from '../../store/rootReducer';
+import { getRootQualifiers } from '../../store/appState/duck';
 
 class AppContainer extends React.Component {
   render () {
index d003248d72ca6f5bf885122faacf1aaf6ba5c59f..60dafe9a7e49dcc78a5b71f05612a8932236eea2 100644 (file)
@@ -20,7 +20,7 @@
 import { connect } from 'react-redux';
 import AllProjects from './AllProjects';
 import { fetchProjects } from '../store/actions';
-import { getCurrentUser } from '../../../app/store/rootReducer';
+import { getCurrentUser } from '../../../store/rootReducer';
 
 const mapStateToProps = state => ({
   user: getCurrentUser(state),
index c6437cf58f9462b6db6cf5414fd8717d98c65dad..01555a84f6f5c8ad3c6717e3ba27ed2cb01ba1f9 100644 (file)
@@ -19,7 +19,7 @@
  */
 import { connect } from 'react-redux';
 import FavoriteFilter from './FavoriteFilter';
-import { getCurrentUser } from '../../../app/store/rootReducer';
+import { getCurrentUser } from '../../../store/rootReducer';
 
 const mapStateToProps = state => ({
   user: getCurrentUser(state)
index 3e383549f3ef7180ab7fa15948dbf4e2ef847b49..567388b3af5a07b9298a44937022bc49bc13206e 100644 (file)
@@ -20,7 +20,7 @@
 import { connect } from 'react-redux';
 import AllProjects from './AllProjects';
 import { fetchProjects } from '../store/actions';
-import { getCurrentUser } from '../../../app/store/rootReducer';
+import { getCurrentUser } from '../../../store/rootReducer';
 
 const mapStateToProps = state => ({
   user: getCurrentUser(state),
index fe8c6fd6043e8b2a472df174e71dd01400b73ef6..c1400cd6cf937082b25b591825f5590571660db2 100644 (file)
@@ -19,7 +19,7 @@
  */
 import { connect } from 'react-redux';
 import PageHeader from './PageHeader';
-import { getProjectsAppState } from '../../../app/store/rootReducer';
+import { getProjectsAppState } from '../../../store/rootReducer';
 
 export default connect(
     state => getProjectsAppState(state)
index e260f56ca1556bfd7f6c8dc45f2dffbbfd504a72..87e4447ae547cc6d0350a5c8a6276f8e80ab29a5 100644 (file)
@@ -19,7 +19,7 @@
  */
 import { connect } from 'react-redux';
 import ProjectCard from './ProjectCard';
-import { getComponent, getComponentMeasures } from '../../../app/store/rootReducer';
+import { getComponent, getComponentMeasures } from '../../../store/rootReducer';
 
 export default connect(
     (state, ownProps) => ({
index f91571ab8c3c95e1fc15fb74354cf80e0a8dcdd3..53f2990244987acc60556ec87b49fe44b94b1dbe 100644 (file)
@@ -20,7 +20,7 @@
 import React from 'react';
 import sortBy from 'lodash/sortBy';
 import { connect } from 'react-redux';
-import { getLanguages } from '../../../app/store/rootReducer';
+import { getLanguages } from '../../../store/rootReducer';
 import { translate } from '../../../helpers/l10n';
 
 class ProjectCardLanguages extends React.Component {
index 3bbd31c328042542ab6330e665ccfe016488cb98..37f627b4da1d4bd3c39f10c68b88fa4c3f1afa3f 100644 (file)
@@ -19,7 +19,7 @@
  */
 import { connect } from 'react-redux';
 import ProjectsList from './ProjectsList';
-import { getProjects, getProjectsAppState } from '../../../app/store/rootReducer';
+import { getProjects, getProjectsAppState } from '../../../store/rootReducer';
 
 export default connect(
     state => ({
index 210b4312b9c325af0954f925a556f1eda27460c3..1e22e34a92d18560a148f44066c5dcb116899e8a 100644 (file)
@@ -18,7 +18,7 @@
  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  */
 import { connect } from 'react-redux';
-import { getProjects, getProjectsAppState } from '../../../app/store/rootReducer';
+import { getProjects, getProjectsAppState } from '../../../store/rootReducer';
 import { fetchMoreProjects } from '../store/actions';
 import ProjectsListFooter from './ProjectsListFooter';
 
index e943a6b2847b87cecf31ceb19eb68b1528982327..c753e163909ef67fd07209bb70bc87a383dcf62d 100644 (file)
@@ -22,7 +22,7 @@ import { connect } from 'react-redux';
 import { withRouter } from 'react-router';
 import omitBy from 'lodash/omitBy';
 import isNil from 'lodash/isNil';
-import { getProjectsAppFacetByProperty, getProjectsAppMaxFacetValue } from '../../../app/store/rootReducer';
+import { getProjectsAppFacetByProperty, getProjectsAppMaxFacetValue } from '../../../store/rootReducer';
 
 const mapStateToProps = (state, ownProps) => ({
   value: ownProps.query[ownProps.property],
index d14f38e08c83fd48f1ff3575cc825ce3d240cac3..5a6f5affdec93fcb960b82974fa5d4ebfe6d581e 100644 (file)
  */
 import groupBy from 'lodash/groupBy';
 import { searchProjects } from '../../../api/components';
-import { addGlobalErrorMessage } from '../../../components/store/globalMessages';
+import { addGlobalErrorMessage } from '../../../store/globalMessages/duck';
 import { parseError } from '../../code/utils';
-import { receiveComponents } from '../../../app/store/components/actions';
+import { receiveComponents } from '../../../store/components/actions';
 import { receiveProjects, receiveMoreProjects } from './projectsDuck';
 import { updateState } from './stateDuck';
-import { getProjectsAppState } from '../../../app/store/rootReducer';
+import { getProjectsAppState } from '../../../store/rootReducer';
 import { getMeasuresForProjects } from '../../../api/measures';
-import { receiveComponentsMeasures } from '../../../app/store/measures/actions';
+import { receiveComponentsMeasures } from '../../../store/measures/actions';
 import { convertToFilter } from './utils';
-import { receiveFavorites } from '../../../app/store/favorites/duck';
+import { receiveFavorites } from '../../../store/favorites/duck';
 
 const PAGE_SIZE = 50;
 
index 9a12aa620bf3fdf85a7f566fcc919007b6715864..0f7fbf95005465483fbbb240db0ef388241d9297 100644 (file)
@@ -19,7 +19,7 @@
  */
 import flatMap from 'lodash/flatMap';
 import sumBy from 'lodash/sumBy';
-import { createMap } from '../../../components/store/generalReducers';
+import { createMap } from '../../../store/utils/generalReducers';
 import { actions } from './projectsDuck';
 import { mapMetricToProperty } from './utils';
 
index d74a8f910ffb110386da718d637aacd13dd9de74..772a6467ffc5629d4a1fbb01e96a97866a02fa20 100644 (file)
@@ -17,7 +17,7 @@
  * along with this program; if not, write to the Free Software Foundation,
  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  */
-import { createValue } from '../../../components/store/generalReducers';
+import { createValue } from '../../../store/utils/generalReducers';
 
 export const actions = {
   UPDATE_STATE: 'projects/UPDATE_STATE'
index ae53d592b691207ad366baa93f44a1937a34c5df..a134c6975722e302b4249fb018a27543eee84562 100644 (file)
@@ -30,7 +30,7 @@ import {
   saveCondition
 } from '../store/actions';
 import Details from '../components/Details';
-import { getQualityGatesAppState } from '../../../app/store/rootReducer';
+import { getQualityGatesAppState } from '../../../store/rootReducer';
 
 const mapStateToProps = state => (
     getQualityGatesAppState(state)
index 4eaf763bb2b80420a74096ca905108de5773cfed..033660a7f386c0de7039a3854c0514e8a73975c7 100644 (file)
@@ -21,7 +21,7 @@ import { connect } from 'react-redux';
 
 import { setState, addQualityGate, deleteQualityGate } from '../store/actions';
 import QualityGateApp from '../components/QualityGatesApp';
-import { getQualityGatesAppState } from '../../../app/store/rootReducer';
+import { getQualityGatesAppState } from '../../../store/rootReducer';
 
 const mapStateToProps = state => (
     getQualityGatesAppState(state)
index 8d0749f0fc8429d949c34d78f3050ab6c05be63e..95197769f900bb990a2ee5a16357928e5c456cfd 100644 (file)
@@ -19,7 +19,7 @@
  */
 import { connect } from 'react-redux';
 import App from './App';
-import { getLanguages, getCurrentUser } from '../../../app/store/rootReducer';
+import { getLanguages, getCurrentUser } from '../../../store/rootReducer';
 
 export default connect(
     state => ({
index f3171181aed9ced27f193a5e4969516dc1371623..15f6822e766079d999875eb2c26e9bb952eeb78f 100644 (file)
@@ -21,8 +21,8 @@
 import React from 'react';
 import { connect } from 'react-redux';
 import LoginForm from './LoginForm';
-import { doLogin } from '../../../app/store/rootActions';
-import { getAppState } from '../../../app/store/rootReducer';
+import { doLogin } from '../../../store/rootActions';
+import { getAppState } from '../../../store/rootReducer';
 import { getIdentityProviders } from '../../../api/users';
 
 class LoginFormContainer extends React.Component {
index 409a099aa1804f300b1d6cfd69a61e1d95d3c979..e234f4a9a484d313b9881d32b0089e606cd830d5 100644 (file)
@@ -21,7 +21,7 @@
 import React from 'react';
 import { connect } from 'react-redux';
 import GlobalMessagesContainer from '../../../app/components/GlobalMessagesContainer';
-import { doLogout } from '../../../app/store/rootActions';
+import { doLogout } from '../../../store/rootActions';
 
 class Logout extends React.Component {
   componentDidMount () {
index 96fccd0abfe65165fafbcb1493878bee45e2fb26..4ef1a719f590488a77a80a6e01d766110f74c7a7 100644 (file)
@@ -21,7 +21,7 @@
 import React from 'react';
 import { connect } from 'react-redux';
 import CategoriesList from './CategoriesList';
-import { getSettingsAppAllCategories } from '../../../app/store/rootReducer';
+import { getSettingsAppAllCategories } from '../../../store/rootReducer';
 
 class AllCategoriesList extends React.Component {
   render () {
index 1ff0e46f97b4b6bccf6a8c64026d108c582f05d2..9a55ff3b0086ea2afc89f50582a6cf69a3bbc00d 100644 (file)
@@ -26,7 +26,7 @@ import CategoryDefinitionsList from './CategoryDefinitionsList';
 import AllCategoriesList from './AllCategoriesList';
 import WildcardsHelp from './WildcardsHelp';
 import { fetchSettings } from '../store/actions';
-import { getSettingsAppDefaultCategory } from '../../../app/store/rootReducer';
+import { getSettingsAppDefaultCategory } from '../../../store/rootReducer';
 import '../styles.css';
 
 type Props = {
index 288129ff5ec45c72c3bd56ca1cbd28a26532ff4a..3fdd465309b11582f1a04cc01205f29a5dc37f17 100644 (file)
@@ -19,7 +19,7 @@
  */
 import { connect } from 'react-redux';
 import App from './App';
-import { getComponent } from '../../../app/store/rootReducer';
+import { getComponent } from '../../../store/rootReducer';
 
 const mapStateToProps = (state, ownProps) => ({
   component: ownProps.location.query.id ? getComponent(state, ownProps.location.query.id) : undefined
index 510cffb443a302f8b43e3adf77fa3c09450ef7c2..49ebc13ded19738d6c65e5cc7fc613c0619e2873 100644 (file)
@@ -21,7 +21,7 @@
 import React from 'react';
 import { connect } from 'react-redux';
 import SubCategoryDefinitionsList from './SubCategoryDefinitionsList';
-import { getSettingsAppSettingsForCategory } from '../../../app/store/rootReducer';
+import { getSettingsAppSettingsForCategory } from '../../../store/rootReducer';
 
 
 class CategoryDefinitionsList extends React.Component {
index 0aa95078681bf18429dc38670609396dcab1ba25..7f607de7f788d24664204b3117ae0b3239b66970 100644 (file)
@@ -35,7 +35,7 @@ import {
   getSettingsAppChangedValue,
   isSettingsAppLoading,
   getSettingsAppValidationMessage
-} from '../../../app/store/rootReducer';
+} from '../../../store/rootReducer';
 
 class Definition extends React.Component {
   mounted: boolean;
index 3b236e0d52b5efb88d138857cf58e509912d23e2..1af5a0a8014fb5cae54b9f2c7296c2007e656831 100644 (file)
@@ -22,7 +22,7 @@ import { connect } from 'react-redux';
 import { translate, translateWithParameters } from '../../../helpers/l10n';
 import { sendTestEmail } from '../../../api/settings';
 import { parseError } from '../../code/utils';
-import { getCurrentUser } from '../../../app/store/rootReducer';
+import { getCurrentUser } from '../../../store/rootReducer';
 
 class EmailForm extends React.Component {
   constructor (props) {
index 0dd8e051b6779308993a3ffcf0b3fadaaadc8ee3..3883c8b9f4050483a705d1d361a6bd749444cd28 100644 (file)
@@ -20,7 +20,7 @@
 import { connect } from 'react-redux';
 import EncryptionApp from './EncryptionApp';
 import { checkSecretKey, generateSecretKey, encryptValue, startGeneration } from '../store/encryptionPage/actions';
-import { getSettingsAppEncryptionState } from '../../../app/store/rootReducer';
+import { getSettingsAppEncryptionState } from '../../../store/rootReducer';
 
 export default connect(
     state => getSettingsAppEncryptionState(state),
index 0b8fefd5c39e49c37cf72e6971f096380c9a8a7a..38eae34bea48d24a3e146261aef8ef176b2ee975 100644 (file)
@@ -20,7 +20,7 @@
 import { connect } from 'react-redux';
 import LicenseRow from './LicenseRow';
 import { setLicense } from '../store/licenses/actions';
-import { getSettingsAppLicenseByKey } from '../../../app/store/rootReducer';
+import { getSettingsAppLicenseByKey } from '../../../store/rootReducer';
 
 const mapStateToProps = (state, ownProps) => ({
   license: getSettingsAppLicenseByKey(state, ownProps.licenseKey)
index ca19e0a2b41bcfcc248291774a964fad92694186..0267a02ab17539250df352a31da8cc677734eda8 100644 (file)
@@ -20,7 +20,7 @@
 import { connect } from 'react-redux';
 import LicensesList from './LicensesList';
 import { fetchLicenses } from '../store/licenses/actions';
-import { getSettingsAppAllLicenseKeys } from '../../../app/store/rootReducer';
+import { getSettingsAppAllLicenseKeys } from '../../../store/rootReducer';
 
 const mapStateToProps = state => ({
   licenses: getSettingsAppAllLicenseKeys(state)
index efa8232767723d21ce253b3cee74d95751d45786..5ca187259d6ab33011193e05fbe1b9746266c3df 100644 (file)
@@ -19,7 +19,7 @@
  */
 import { connect } from 'react-redux';
 import ServerIdApp from './ServerIdApp';
-import { addGlobalErrorMessage, closeAllGlobalMessages } from '../../../components/store/globalMessages';
+import { addGlobalErrorMessage, closeAllGlobalMessages } from '../../../store/globalMessages/duck';
 
 export default connect(
     () => ({}),
index 79f4d15ed9cbad7d307dd2d23fea51db7439d9d1..169234c47a69806c4dd688d32739c32c9f4b3234 100644 (file)
@@ -22,12 +22,12 @@ import { receiveValues } from './values/actions';
 import { receiveDefinitions } from './definitions/actions';
 import { startLoading, stopLoading } from './settingsPage/loading/actions';
 import { parseError } from '../../code/utils';
-import { addGlobalErrorMessage, closeAllGlobalMessages } from '../../../components/store/globalMessages';
+import { addGlobalErrorMessage, closeAllGlobalMessages } from '../../../store/globalMessages/duck';
 import { passValidation, failValidation } from './settingsPage/validationMessages/actions';
 import { cancelChange } from './settingsPage/changedValues/actions';
 import { isEmptyValue } from '../utils';
 import { translate } from '../../../helpers/l10n';
-import { getSettingsAppDefinition, getSettingsAppChangedValue } from '../../../app/store/rootReducer';
+import { getSettingsAppDefinition, getSettingsAppChangedValue } from '../../../store/rootReducer';
 
 export const fetchSettings = componentKey => dispatch => {
   return getDefinitions(componentKey)
index 54bc6de0cec173ca5cb749e9582e1b439a1684c9..ab1a9155a877c029383530805ebc97de61fb8780 100644 (file)
@@ -19,7 +19,7 @@
  */
 import * as api from '../../../../api/settings';
 import { parseError } from '../../../code/utils';
-import { addGlobalErrorMessage, closeAllGlobalMessages } from '../../../../components/store/globalMessages';
+import { addGlobalErrorMessage, closeAllGlobalMessages } from '../../../../store/globalMessages/duck';
 
 export const UPDATE_ENCRYPTION = 'UPDATE_ENCRYPTION';
 
index 9071be540b5642ddffe95dd9df6f3a827d2d2f74..0b8ae6f073f289082754856ecd1fc102cea0637e 100644 (file)
@@ -19,7 +19,7 @@
  */
 import * as licenses from '../../../../api/licenses';
 import { parseError } from '../../../code/utils';
-import { addGlobalSuccessMessage, addGlobalErrorMessage } from '../../../../components/store/globalMessages';
+import { addGlobalSuccessMessage, addGlobalErrorMessage } from '../../../../store/globalMessages/duck';
 import { translate } from '../../../../helpers/l10n';
 import { isLicenseFromListInvalid, isLicenseInvalid } from '../../licenses/licenseUtils';
 
index 92b15323978141cddb0b3ac6457c5276a6bb635a..1d343e158731763caed5ef7bafbf6a02cbea718e 100644 (file)
@@ -23,8 +23,8 @@ import definitions, * as fromDefinitions from './definitions/reducer';
 import values, * as fromValues from './values/reducer';
 import settingsPage, * as fromSettingsPage from './settingsPage/reducer';
 import licenses, * as fromLicenses from './licenses/reducer';
-import globalMessages, * as fromGlobalMessages from '../../../components/store/globalMessages';
-import type { State as GlobalMessagesState } from '../../../components/store/globalMessages';
+import globalMessages, * as fromGlobalMessages from '../../../store/globalMessages/duck';
+import type { State as GlobalMessagesState } from '../../../store/globalMessages/duck';
 import encryptionPage from './encryptionPage/reducer';
 
 type State = {
index 196687f245ff9e3eb2771eaabdddb141995a0d46..c57ed067c36648607899d0cad91b4d080c8cc0fa 100644 (file)
@@ -20,7 +20,7 @@
 // @flow
 import keyBy from 'lodash/keyBy';
 import { RECEIVE_VALUES } from './actions';
-import { actions as appStateActions } from '../../../../app/store/appState/duck';
+import { actions as appStateActions } from '../../../../store/appState/duck';
 
 type State = { [key: string]: {} };
 
index 31a8392fb67f36526de82afe21d07d0889a8eb86..5386aadc2633dc1dd37dc969b58d502cee4e10f8 100644 (file)
@@ -20,7 +20,7 @@
 import React from 'react';
 import { connect } from 'react-redux';
 import init from '../init';
-import { getSettingValue } from '../../../app/store/rootReducer';
+import { getSettingValue } from '../../../store/rootReducer';
 
 class UpdateCenterAppContainer extends React.Component {
   componentDidMount () {
index 8abe6fce357237fd514ad44a42344cea3f97eeb7..6737d46a9d0cfa20e2f6e23db8175b8e50d72f9b 100644 (file)
@@ -20,7 +20,7 @@
 import React from 'react';
 import { connect } from 'react-redux';
 import init from '../init';
-import { getCurrentUser } from '../../../app/store/rootReducer';
+import { getCurrentUser } from '../../../store/rootReducer';
 
 class UsersAppContainer extends React.Component {
   static propTypes = {
index b2157ced05f09ab80d401edf3e758fac53eede54..f3c7c17f289b449d5bd5f16f9cf9f9e051758b44 100644 (file)
  */
 import { connect } from 'react-redux';
 import FavoriteBaseStateless from './FavoriteBaseStateless';
-import { isFavorite } from '../../app/store/rootReducer';
-import * as actionCreators from '../../app/store/favorites/duck';
+import { isFavorite } from '../../store/rootReducer';
+import * as actionCreators from '../../store/favorites/duck';
 import * as api from '../../api/favorites';
-import { addGlobalErrorMessage } from '../store/globalMessages';
+import { addGlobalErrorMessage } from '../../store/globalMessages/duck';
 import { parseError } from '../../apps/code/utils';
 
 const addFavorite = componentKey => dispatch => {
index 4d95243cfecec203c81c2ce6a8093abadbb799b9..e10af5d714a64182b1f1348ae23588c7b8b020d9 100644 (file)
@@ -19,7 +19,7 @@
  */
 import React from 'react';
 import classNames from 'classnames';
-import { ERROR, SUCCESS } from '../store/globalMessages';
+import { ERROR, SUCCESS } from '../../store/globalMessages/duck';
 
 export default class GlobalMessages extends React.Component {
   static propTypes = {
diff --git a/server/sonar-web/src/main/js/components/store/configureStore.js b/server/sonar-web/src/main/js/components/store/configureStore.js
deleted file mode 100644 (file)
index 97397d8..0000000
+++ /dev/null
@@ -1,40 +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, compose } from 'redux';
-import thunk from 'redux-thunk';
-
-const middlewares = [thunk];
-const composed = [];
-
-if (process.env.NODE_ENV !== 'production') {
-  const createLogger = require('redux-logger');
-  middlewares.push(createLogger());
-
-  composed.push(window.devToolsExtension ? window.devToolsExtension() : f => f);
-}
-
-const finalCreateStore = compose(
-    applyMiddleware(...middlewares),
-    ...composed
-)(createStore);
-
-export default function configureStore (rootReducer, initialState) {
-  return finalCreateStore(rootReducer, initialState);
-}
diff --git a/server/sonar-web/src/main/js/components/store/generalReducers.js b/server/sonar-web/src/main/js/components/store/generalReducers.js
deleted file mode 100644 (file)
index 8f88ff4..0000000
+++ /dev/null
@@ -1,95 +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.
- */
-// Author: Christoffer Niska <christofferniska@gmail.com>
-// https://gist.github.com/crisu83/42ecffccad9d04c74605fbc75c9dc9d1
-import uniq from 'lodash/uniq';
-
-/**
- * Creates a reducer that manages a single value.
- *
- * @param {function(state, action)} shouldUpdate
- * @param {function(state, action)} shouldReset
- * @param {function(state, action)} getValue
- * @param {*} defaultValue
- * @returns {function(state, action)}
- */
-export const createValue = (
-    shouldUpdate = () => true,
-    shouldReset = () => false,
-    getValue = (state, action) => action.payload,
-    defaultValue = null
-) => (state = defaultValue, action = {}) => {
-  if (shouldReset(state, action)) {
-    return defaultValue;
-  }
-  if (shouldUpdate(state, action)) {
-    return getValue(state, action);
-  }
-  return state;
-};
-
-/**
- * Creates a reducer that manages a map.
- *
- * @param {function(state, action)} shouldUpdate
- * @param {function(state, action)} shouldReset
- * @param {function(state, action)} getValues
- * @returns {function(state, action)}
- */
-export const createMap = (
-    shouldUpdate = () => true,
-    shouldReset = () => false,
-    getValues = (state, action) => action.payload
-) => createValue(shouldUpdate, shouldReset, (state, action) =>
-    ({ ...state, ...getValues(state, action) }), {});
-
-/**
- * Creates a reducer that manages a set.
- *
- * @param {function(state, action)} shouldUpdate
- * @param {function(state, action)} shouldReset
- * @param {function(state, action)} getValues
- * @returns {function(state, action)}
- */
-export const createSet = (
-    shouldUpdate = () => true,
-    shouldReset = () => false,
-    getValues = (state, action) => action.payload
-) => createValue(shouldUpdate, shouldReset, (state, action) =>
-    uniq([...state, ...getValues(state, action)]), []);
-
-/**
- * Creates a reducer that manages a flag.
- *
- * @param {function(state, action)} shouldTurnOn
- * @param {function(state, action)} shouldTurnOff
- * @param {bool} defaultValue
- * @returns {function(state, action)}
- */
-export const createFlag = (shouldTurnOn, shouldTurnOff, defaultValue = false) =>
-    (state = defaultValue, action = {}) => {
-      if (shouldTurnOn(state, action)) {
-        return true;
-      }
-      if (shouldTurnOff(state, action)) {
-        return false;
-      }
-      return state;
-    };
diff --git a/server/sonar-web/src/main/js/components/store/globalMessages.js b/server/sonar-web/src/main/js/components/store/globalMessages.js
deleted file mode 100644 (file)
index b5e11e1..0000000
+++ /dev/null
@@ -1,113 +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.
- */
-// @flow
-import uniqueId from 'lodash/uniqueId';
-import { actions } from '../../app/store/appState/duck';
-
-type Level = 'ERROR' | 'SUCCESS';
-
-type Message = {
-  id: string,
-  message: string,
-  level: Level
-};
-
-export type State = Array<Message>;
-
-type Action = Object;
-
-export const ERROR = 'ERROR';
-export const SUCCESS = 'SUCCESS';
-
-/* Actions */
-const ADD_GLOBAL_MESSAGE = 'ADD_GLOBAL_MESSAGE';
-const CLOSE_GLOBAL_MESSAGE = 'CLOSE_GLOBAL_MESSAGE';
-const CLOSE_ALL_GLOBAL_MESSAGES = 'CLOSE_ALL_GLOBAL_MESSAGES';
-
-const addGlobalMessageActionCreator = (id: string, message: string, level: Level) => ({
-  type: ADD_GLOBAL_MESSAGE,
-  message,
-  level,
-  id
-});
-
-export const closeGlobalMessage = (id: string) => ({
-  type: CLOSE_GLOBAL_MESSAGE,
-  id
-});
-
-export const closeAllGlobalMessages = (id: string) => ({
-  type: CLOSE_ALL_GLOBAL_MESSAGES,
-  id
-});
-
-const addGlobalMessage = (message: string, level: Level) => (dispatch: Function) => {
-  const id = uniqueId('global-message-');
-  dispatch(addGlobalMessageActionCreator(id, message, level));
-  setTimeout(() => dispatch(closeGlobalMessage(id)), 5000);
-};
-
-export const addGlobalErrorMessage = (message: string) =>
-    addGlobalMessage(message, ERROR);
-
-export const addGlobalSuccessMessage = (message: string) =>
-    addGlobalMessage(message, SUCCESS);
-
-/* Reducer */
-const globalMessages = (state: State = [], action: Action = {}) => {
-  switch (action.type) {
-    case ADD_GLOBAL_MESSAGE:
-      return [{
-        id: action.id,
-        message: action.message,
-        level: action.level
-      }];
-
-    case actions.REQUIRE_AUTHENTICATION:
-      // FIXME l10n
-      return [{
-        id: uniqueId('global-message-'),
-        message: 'Authentication required to see this page.',
-        level: ERROR
-      }];
-
-    case actions.REQUIRE_AUTHORIZATION:
-      // FIXME l10n
-      return [{
-        id: uniqueId('global-message-'),
-        message: 'You are not authorized to access this page. Please log in with more privileges and try again.',
-        level: ERROR
-      }];
-
-    case CLOSE_GLOBAL_MESSAGE:
-      return state.filter(message => message.id !== action.id);
-
-
-    case CLOSE_ALL_GLOBAL_MESSAGES:
-      return [];
-    default:
-      return state;
-  }
-};
-
-export default globalMessages;
-
-/* Selectors */
-export const getGlobalMessages = (state: State) => state;
diff --git a/server/sonar-web/src/main/js/components/store/withStore.js b/server/sonar-web/src/main/js/components/store/withStore.js
deleted file mode 100644 (file)
index 4518fc0..0000000
+++ /dev/null
@@ -1,54 +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 React from 'react';
-
-const withStore = (ComposedComponent, initial = {}) => {
-  let store = initial;
-
-  const updateStore = changes => {
-    store = { ...store, ...changes };
-  };
-
-  const getStore = () => ({ ...store });
-
-  return class extends React.Component {
-    static displayName = `withStore(${ComposedComponent.displayName})}`;
-
-    componentWillMount () {
-      this.handleUpdateStore = this.handleUpdateStore.bind(this);
-    }
-
-    handleUpdateStore (changes) {
-      updateStore(changes);
-      this.forceUpdate();
-    }
-
-    render () {
-      return (
-          <ComposedComponent
-              {...this.props}
-              getStore={getStore}
-              updateStore={this.handleUpdateStore}/>
-      );
-    }
-  };
-};
-
-export default withStore;
index 8e96bb380aec00e13ae1d32a50c3110813e63da8..8ec297fda8c844827bcc72e0ac8a640e8d9a235c 100644 (file)
@@ -21,7 +21,7 @@ import React from 'react';
 import { connect } from 'react-redux';
 import md5 from 'blueimp-md5';
 import classNames from 'classnames';
-import { getSettingValue } from '../../app/store/rootReducer';
+import { getSettingValue } from '../../store/rootReducer';
 
 class Avatar extends React.Component {
   static propTypes = {
index c790508b1c0d1deed79694e3b33f370fd8bc8bdb..cfd1b8041a13e9a348586f779d8675cf29af6391 100644 (file)
@@ -22,7 +22,7 @@ import Handlebars from 'handlebars/runtime';
 
 function gravatarServer () {
   const getStore = require('../../app/utils/getStore').default;
-  const { getSettingValue } = require('../../app/store/rootReducer');
+  const { getSettingValue } = require('../../store/rootReducer');
 
   const store = getStore();
   return (getSettingValue(store.getState(), 'sonar.lf.gravatarServerUrl') || {}).value;
index 87f038f1fa64dc73e43c3a4d3dddafaa3ada396b..c50d7467e8aab79ced83e14523b9215434688231 100644 (file)
@@ -19,7 +19,7 @@
  */
 function enableGravatar () {
   const getStore = require('../../app/utils/getStore').default;
-  const { getSettingValue } = require('../../app/store/rootReducer');
+  const { getSettingValue } = require('../../store/rootReducer');
 
   const store = getStore();
   return (getSettingValue(store.getState(), 'sonar.lf.enableGravatar') || {}).value === 'true';
index 6a7cd4a2d0e517bc3c352a8aab547b3db99f5459..0ec44e63753f5b1df7ff7da6838ce8282719d967 100644 (file)
@@ -305,7 +305,7 @@ function formatDurationShort (isNegative, days, hours, minutes) {
 function getHoursInDay () {
   // workaround cyclic dependencies
   const getStore = require('../app/utils/getStore').default;
-  const { getSettingValue } = require('../app/store/rootReducer');
+  const { getSettingValue } = require('../store/rootReducer');
 
   const store = getStore();
   const settingValue = getSettingValue(store.getState(), 'sonar.technicalDebt.hoursInDay');
@@ -360,7 +360,7 @@ function shortDurationVariationFormatter (value) {
 function getRatingGrid () {
   // workaround cyclic dependencies
   const getStore = require('../app/utils/getStore').default;
-  const { getSettingValue } = require('../app/store/rootReducer');
+  const { getSettingValue } = require('../store/rootReducer');
 
   const store = getStore();
   const settingValue = getSettingValue(store.getState(), 'sonar.technicalDebt.ratingGrid');
diff --git a/server/sonar-web/src/main/js/store/appState/duck.js b/server/sonar-web/src/main/js/store/appState/duck.js
new file mode 100644 (file)
index 0000000..cd31387
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ * 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.
+ */
+// @flow
+type AppState = {
+  authenticationError: boolean,
+  authorizationError: boolean,
+  qualifiers: ?Array<string>
+};
+
+export type Action = {
+  type: string,
+  appState: AppState
+}
+
+export const actions = {
+  SET_APP_STATE: 'SET_APP_STATE',
+  REQUIRE_AUTHENTICATION: 'REQUIRE_AUTHENTICATION',
+  REQUIRE_AUTHORIZATION: 'REQUIRE_AUTHORIZATION'
+};
+
+export const setAppState = (appState: AppState): Action => ({
+  type: actions.SET_APP_STATE,
+  appState
+});
+
+export const requireAuthentication = () => ({
+  type: actions.REQUIRE_AUTHENTICATION
+});
+
+export const requireAuthorization = () => ({
+  type: actions.REQUIRE_AUTHORIZATION
+});
+
+const defaultValue = {
+  authenticationError: false,
+  authorizationError: false,
+  qualifiers: null
+};
+
+export default (state: AppState = defaultValue, action: Action) => {
+  if (action.type === actions.SET_APP_STATE) {
+    return { ...state, ...action.appState };
+  }
+
+  if (action.type === actions.REQUIRE_AUTHENTICATION) {
+    return { ...state, authenticationError: true };
+  }
+
+  if (action.type === actions.REQUIRE_AUTHORIZATION) {
+    return { ...state, authorizationError: true };
+  }
+
+  return state;
+};
+
+export const getRootQualifiers = (state: AppState) => (
+    state.qualifiers
+);
diff --git a/server/sonar-web/src/main/js/store/components/actions.js b/server/sonar-web/src/main/js/store/components/actions.js
new file mode 100644 (file)
index 0000000..3ba34eb
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ * 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.
+ */
+export const RECEIVE_COMPONENTS = 'RECEIVE_COMPONENTS';
+
+export const receiveComponents = components => ({
+  type: RECEIVE_COMPONENTS,
+  components
+});
diff --git a/server/sonar-web/src/main/js/store/components/reducer.js b/server/sonar-web/src/main/js/store/components/reducer.js
new file mode 100644 (file)
index 0000000..c2d609a
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * 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 { combineReducers } from 'redux';
+import keyBy from 'lodash/keyBy';
+import uniq from 'lodash/uniq';
+import { RECEIVE_COMPONENTS } from './actions';
+
+const byKey = (state = {}, action = {}) => {
+  if (action.type === RECEIVE_COMPONENTS) {
+    const changes = keyBy(action.components, 'key');
+    return { ...state, ...changes };
+  }
+
+  return state;
+};
+
+const keys = (state = [], action = {}) => {
+  if (action.type === RECEIVE_COMPONENTS) {
+    const changes = action.components.map(f => f.key);
+    return uniq([...state, ...changes]);
+  }
+
+  return state;
+};
+
+export default combineReducers({ byKey, keys });
+
+export const getComponent = (state, key) => (
+    state.byKey[key]
+);
diff --git a/server/sonar-web/src/main/js/store/favorites/duck.js b/server/sonar-web/src/main/js/store/favorites/duck.js
new file mode 100644 (file)
index 0000000..7c6d4b5
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * 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 uniq from 'lodash/uniq';
+import without from 'lodash/without';
+
+export const actions = {
+  RECEIVE_FAVORITES: 'RECEIVE_FAVORITES',
+  ADD_FAVORITE: 'ADD_FAVORITE',
+  REMOVE_FAVORITE: 'REMOVE_FAVORITE'
+};
+
+export const receiveFavorites = favorites => ({
+  type: actions.RECEIVE_FAVORITES,
+  favorites
+});
+
+export const addFavorite = componentKey => ({
+  type: actions.ADD_FAVORITE,
+  componentKey
+});
+
+export const removeFavorite = componentKey => ({
+  type: actions.REMOVE_FAVORITE,
+  componentKey
+});
+
+export default (state = [], action = {}) => {
+  if (action.type === actions.RECEIVE_FAVORITES) {
+    return uniq([...state, ...action.favorites.map(f => f.key)]);
+  }
+
+  if (action.type === actions.ADD_FAVORITE) {
+    return uniq([...state, action.componentKey]);
+  }
+
+  if (action.type === actions.REMOVE_FAVORITE) {
+    return without(state, action.componentKey);
+  }
+
+  return state;
+};
+
+export const isFavorite = (state, componentKey) => (
+    state.includes(componentKey)
+);
+
diff --git a/server/sonar-web/src/main/js/store/globalMessages/duck.js b/server/sonar-web/src/main/js/store/globalMessages/duck.js
new file mode 100644 (file)
index 0000000..38e92ca
--- /dev/null
@@ -0,0 +1,113 @@
+/*
+ * 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.
+ */
+// @flow
+import uniqueId from 'lodash/uniqueId';
+import { actions } from '../appState/duck';
+
+type Level = 'ERROR' | 'SUCCESS';
+
+type Message = {
+  id: string,
+  message: string,
+  level: Level
+};
+
+export type State = Array<Message>;
+
+type Action = Object;
+
+export const ERROR = 'ERROR';
+export const SUCCESS = 'SUCCESS';
+
+/* Actions */
+const ADD_GLOBAL_MESSAGE = 'ADD_GLOBAL_MESSAGE';
+const CLOSE_GLOBAL_MESSAGE = 'CLOSE_GLOBAL_MESSAGE';
+const CLOSE_ALL_GLOBAL_MESSAGES = 'CLOSE_ALL_GLOBAL_MESSAGES';
+
+const addGlobalMessageActionCreator = (id: string, message: string, level: Level) => ({
+  type: ADD_GLOBAL_MESSAGE,
+  message,
+  level,
+  id
+});
+
+export const closeGlobalMessage = (id: string) => ({
+  type: CLOSE_GLOBAL_MESSAGE,
+  id
+});
+
+export const closeAllGlobalMessages = (id: string) => ({
+  type: CLOSE_ALL_GLOBAL_MESSAGES,
+  id
+});
+
+const addGlobalMessage = (message: string, level: Level) => (dispatch: Function) => {
+  const id = uniqueId('global-message-');
+  dispatch(addGlobalMessageActionCreator(id, message, level));
+  setTimeout(() => dispatch(closeGlobalMessage(id)), 5000);
+};
+
+export const addGlobalErrorMessage = (message: string) =>
+    addGlobalMessage(message, ERROR);
+
+export const addGlobalSuccessMessage = (message: string) =>
+    addGlobalMessage(message, SUCCESS);
+
+/* Reducer */
+const globalMessages = (state: State = [], action: Action = {}) => {
+  switch (action.type) {
+    case ADD_GLOBAL_MESSAGE:
+      return [{
+        id: action.id,
+        message: action.message,
+        level: action.level
+      }];
+
+    case actions.REQUIRE_AUTHENTICATION:
+      // FIXME l10n
+      return [{
+        id: uniqueId('global-message-'),
+        message: 'Authentication required to see this page.',
+        level: ERROR
+      }];
+
+    case actions.REQUIRE_AUTHORIZATION:
+      // FIXME l10n
+      return [{
+        id: uniqueId('global-message-'),
+        message: 'You are not authorized to access this page. Please log in with more privileges and try again.',
+        level: ERROR
+      }];
+
+    case CLOSE_GLOBAL_MESSAGE:
+      return state.filter(message => message.id !== action.id);
+
+
+    case CLOSE_ALL_GLOBAL_MESSAGES:
+      return [];
+    default:
+      return state;
+  }
+};
+
+export default globalMessages;
+
+/* Selectors */
+export const getGlobalMessages = (state: State) => state;
diff --git a/server/sonar-web/src/main/js/store/languages/actions.js b/server/sonar-web/src/main/js/store/languages/actions.js
new file mode 100644 (file)
index 0000000..9d2d517
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ * 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.
+ */
+export const RECEIVE_LANGUAGES = 'RECEIVE_LANGUAGES';
+
+export const receiveLanguages = languages => ({
+  type: RECEIVE_LANGUAGES,
+  languages
+});
diff --git a/server/sonar-web/src/main/js/store/languages/reducer.js b/server/sonar-web/src/main/js/store/languages/reducer.js
new file mode 100644 (file)
index 0000000..73eb9d5
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * 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 keyBy from 'lodash/keyBy';
+import { RECEIVE_LANGUAGES } from './actions';
+
+const reducer = (state = {}, action = {}) => {
+  if (action.type === RECEIVE_LANGUAGES) {
+    return keyBy(action.languages, 'key');
+  }
+
+  return state;
+};
+
+export default reducer;
+
+export const getLanguages = state => (
+    state
+);
diff --git a/server/sonar-web/src/main/js/store/measures/actions.js b/server/sonar-web/src/main/js/store/measures/actions.js
new file mode 100644 (file)
index 0000000..2321163
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * 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.
+ */
+export const RECEIVE_COMPONENT_MEASURE = 'RECEIVE_COMPONENT_MEASURE';
+
+export const receiveComponentMeasure = (componentKey, metricKey, value) => ({
+  type: RECEIVE_COMPONENT_MEASURE,
+  componentKey,
+  metricKey,
+  value
+});
+
+export const RECEIVE_COMPONENT_MEASURES = 'RECEIVE_COMPONENT_MEASURES';
+
+export const receiveComponentMeasures = (componentKey, measures) => ({
+  type: RECEIVE_COMPONENT_MEASURES,
+  componentKey,
+  measures
+});
+
+export const RECEIVE_COMPONENTS_MEASURES = 'RECEIVE_COMPONENTS_MEASURES';
+
+export const receiveComponentsMeasures = componentsWithMeasures => ({
+  type: RECEIVE_COMPONENTS_MEASURES,
+  componentsWithMeasures
+});
diff --git a/server/sonar-web/src/main/js/store/measures/reducer.js b/server/sonar-web/src/main/js/store/measures/reducer.js
new file mode 100644 (file)
index 0000000..3d16666
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * 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_COMPONENT_MEASURE, RECEIVE_COMPONENT_MEASURES, RECEIVE_COMPONENTS_MEASURES } from './actions';
+
+const byMetricKey = (state = {}, action = {}) => {
+  if (action.type === RECEIVE_COMPONENT_MEASURE) {
+    return { ...state, [action.metricKey]: action.value };
+  }
+
+  if (action.type === RECEIVE_COMPONENT_MEASURES) {
+    return { ...state, ...action.measures };
+  }
+
+  return state;
+};
+
+const reducer = (state = {}, action = {}) => {
+  if ([RECEIVE_COMPONENT_MEASURE, RECEIVE_COMPONENT_MEASURES].includes(action.type)) {
+    const component = state[action.componentKey];
+    return { ...state, [action.componentKey]: byMetricKey(component, action) };
+  }
+
+  if (action.type === RECEIVE_COMPONENTS_MEASURES) {
+    const newState = { ...state };
+    Object.keys(action.componentsWithMeasures).forEach(componentKey => {
+      Object.assign(newState, {
+        [componentKey]: byMetricKey(state[componentKey], {
+          type: RECEIVE_COMPONENT_MEASURES,
+          measures: action.componentsWithMeasures[componentKey]
+        })
+      });
+    });
+    return newState;
+  }
+
+  return state;
+};
+
+export default reducer;
+
+export const getComponentMeasure = (state, componentKey, metricKey) => {
+  const component = state[componentKey];
+  return component && component[metricKey];
+};
+
+export const getComponentMeasures = (state, componentKey) => (
+    state[componentKey]
+);
diff --git a/server/sonar-web/src/main/js/store/rootActions.js b/server/sonar-web/src/main/js/store/rootActions.js
new file mode 100644 (file)
index 0000000..005c115
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ * 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 { getLanguages } from '../api/languages';
+import { getGlobalNavigation, getComponentNavigation } from '../api/nav';
+import * as auth from '../api/auth';
+import { receiveLanguages } from './languages/actions';
+import { receiveComponents } from './components/actions';
+import { addGlobalErrorMessage } from './globalMessages/duck';
+import { parseError } from '../apps/code/utils';
+import { setAppState } from './appState/duck';
+
+const onFail = dispatch => error => (
+    parseError(error).then(message => dispatch(addGlobalErrorMessage(message)))
+);
+
+export const fetchAppState = () => dispatch => (
+    getGlobalNavigation().then(
+        appState => dispatch(setAppState(appState)),
+        onFail(dispatch)
+    )
+);
+
+export const fetchLanguages = () => dispatch => {
+  return getLanguages().then(
+      languages => dispatch(receiveLanguages(languages)),
+      onFail(dispatch)
+  );
+};
+
+const addQualifier = project => ({
+  ...project,
+  qualifier: project.breadcrumbs[project.breadcrumbs.length - 1].qualifier
+});
+
+export const fetchProject = key => dispatch => (
+    getComponentNavigation(key).then(
+        component => dispatch(receiveComponents([addQualifier(component)])),
+        onFail(dispatch)
+    )
+);
+
+export const doLogin = (login, password) => dispatch => (
+    auth.login(login, password).then(
+        () => { /* everything is fine */ },
+        () => {
+          dispatch(addGlobalErrorMessage('Authentication failed'));
+          return Promise.reject();
+        }
+    )
+);
+
+export const doLogout = () => dispatch => (
+    auth.logout().then(
+        () => { /* everything is fine */ },
+        () => {
+          dispatch(addGlobalErrorMessage('Logout failed'));
+          return Promise.reject();
+        }
+    )
+);
diff --git a/server/sonar-web/src/main/js/store/rootReducer.js b/server/sonar-web/src/main/js/store/rootReducer.js
new file mode 100644 (file)
index 0000000..1a9e879
--- /dev/null
@@ -0,0 +1,304 @@
+/*
+ * 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 { combineReducers } from 'redux';
+import appState from './appState/duck';
+import components, * as fromComponents from './components/reducer';
+import users, * as fromUsers from './users/reducer';
+import favorites, * as fromFavorites from './favorites/duck';
+import languages, * as fromLanguages from './languages/reducer';
+import measures, * as fromMeasures from './measures/reducer';
+import globalMessages, * as fromGlobalMessages from './globalMessages/duck';
+
+import measuresApp, * as fromMeasuresApp from '../apps/component-measures/store/rootReducer';
+import permissionsApp, * as fromPermissionsApp from '../apps/permissions/shared/store/rootReducer';
+import projectAdminApp, * as fromProjectAdminApp from '../apps/project-admin/store/rootReducer';
+import projectsApp, * as fromProjectsApp from '../apps/projects/store/reducer';
+import qualityGatesApp from '../apps/quality-gates/store/rootReducer';
+import settingsApp, * as fromSettingsApp from '../apps/settings/store/rootReducer';
+
+export default combineReducers({
+  appState,
+  components,
+  globalMessages,
+  favorites,
+  languages,
+  measures,
+  users,
+
+  // apps
+  measuresApp,
+  permissionsApp,
+  projectAdminApp,
+  projectsApp,
+  qualityGatesApp,
+  settingsApp
+});
+
+export const getAppState = state => (
+    state.appState
+);
+
+export const getComponent = (state, key) => (
+    fromComponents.getComponent(state.components, key)
+);
+
+export const getGlobalMessages = state => (
+    fromGlobalMessages.getGlobalMessages(state.globalMessages)
+);
+
+export const getLanguages = (state, key) => (
+    fromLanguages.getLanguages(state.languages, key)
+);
+
+export const getCurrentUser = state => (
+    fromUsers.getCurrentUser(state.users)
+);
+
+export const isFavorite = (state, componentKey) => (
+    fromFavorites.isFavorite(state.favorites, componentKey)
+);
+
+export const getComponentMeasure = (state, componentKey, metricKey) => (
+    fromMeasures.getComponentMeasure(state.measures, componentKey, metricKey)
+);
+
+export const getComponentMeasures = (state, componentKey) => (
+    fromMeasures.getComponentMeasures(state.measures, componentKey)
+);
+
+export const getProjects = state => (
+    fromProjectsApp.getProjects(state.projectsApp)
+);
+
+export const getProjectsAppState = state => (
+    fromProjectsApp.getState(state.projectsApp)
+);
+
+export const getProjectsAppFacetByProperty = (state, property) => (
+    fromProjectsApp.getFacetByProperty(state.projectsApp, property)
+);
+
+export const getProjectsAppMaxFacetValue = state => (
+    fromProjectsApp.getMaxFacetValue(state.projectsApp)
+);
+
+export const getQualityGatesAppState = state => (
+    state.qualityGatesApp
+);
+
+export const getPermissionsAppUsers = state => (
+    fromPermissionsApp.getUsers(state.permissionsApp)
+);
+
+export const getPermissionsAppGroups = state => (
+    fromPermissionsApp.getGroups(state.permissionsApp)
+);
+
+export const isPermissionsAppLoading = state => (
+    fromPermissionsApp.isLoading(state.permissionsApp)
+);
+
+export const getPermissionsAppQuery = state => (
+    fromPermissionsApp.getQuery(state.permissionsApp)
+);
+
+export const getPermissionsAppFilter = state => (
+    fromPermissionsApp.getFilter(state.permissionsApp)
+);
+
+export const getPermissionsAppSelectedPermission = state => (
+    fromPermissionsApp.getSelectedPermission(state.permissionsApp)
+);
+
+export const getPermissionsAppError = state => (
+    fromPermissionsApp.getError(state.permissionsApp)
+);
+
+export const getSettingValue = (state, key) => (
+    fromSettingsApp.getValue(state.settingsApp, key)
+);
+
+export const getSettingsAppDefinition = (state, key) => (
+    fromSettingsApp.getDefinition(state.settingsApp, key)
+);
+
+export const getSettingsAppAllCategories = state => (
+    fromSettingsApp.getAllCategories(state.settingsApp)
+);
+
+export const getSettingsAppDefaultCategory = state => (
+    fromSettingsApp.getDefaultCategory(state.settingsApp)
+);
+
+export const getSettingsAppSettingsForCategory = (state, category) => (
+    fromSettingsApp.getSettingsForCategory(state.settingsApp, category)
+);
+
+export const getSettingsAppChangedValue = (state, key) => (
+    fromSettingsApp.getChangedValue(state.settingsApp, key)
+);
+
+export const isSettingsAppLoading = (state, key) => (
+    fromSettingsApp.isLoading(state.settingsApp, key)
+);
+
+export const getSettingsAppLicenseByKey = (state, key) => (
+    fromSettingsApp.getLicenseByKey(state.settingsApp, key)
+);
+
+export const getSettingsAppAllLicenseKeys = state => (
+    fromSettingsApp.getAllLicenseKeys(state.settingsApp)
+);
+
+export const getSettingsAppValidationMessage = (state, key) => (
+    fromSettingsApp.getValidationMessage(state.settingsApp, key)
+);
+
+export const getSettingsAppEncryptionState = state => (
+    fromSettingsApp.getEncryptionState(state.settingsApp)
+);
+
+export const getSettingsAppGlobalMessages = state => (
+    fromSettingsApp.getGlobalMessages(state.settingsApp)
+);
+
+export const getProjectAdminProfileByKey = (state, profileKey) => (
+    fromProjectAdminApp.getProfileByKey(state.projectAdminApp, profileKey)
+);
+
+export const getProjectAdminAllProfiles = state => (
+    fromProjectAdminApp.getAllProfiles(state.projectAdminApp)
+);
+
+export const getProjectAdminProjectProfiles = (state, projectKey) => (
+    fromProjectAdminApp.getProjectProfiles(state.projectAdminApp, projectKey)
+);
+
+export const getProjectAdminGateById = (state, gateId) => (
+    fromProjectAdminApp.getGateById(state.projectAdminApp, gateId)
+);
+
+export const getProjectAdminAllGates = state => (
+    fromProjectAdminApp.getAllGates(state.projectAdminApp)
+);
+
+export const getProjectAdminProjectGate = (state, projectKey) => (
+    fromProjectAdminApp.getProjectGate(state.projectAdminApp, projectKey)
+);
+
+export const getProjectAdminLinkById = (state, linkId) => (
+    fromProjectAdminApp.getLinkById(state.projectAdminApp, linkId)
+);
+
+export const getProjectAdminProjectLinks = (state, projectKey) => (
+    fromProjectAdminApp.getProjectLinks(state.projectAdminApp, projectKey)
+);
+
+export const getProjectAdminComponentByKey = (state, componentKey) => (
+    fromProjectAdminApp.getComponentByKey(state.projectAdminApp, componentKey)
+);
+
+export const getProjectAdminProjectModules = (state, projectKey) => (
+    fromProjectAdminApp.getProjectModules(state.projectAdminApp, projectKey)
+);
+
+export const getProjectAdminGlobalMessages = state => (
+    fromProjectAdminApp.getGlobalMessages(state.projectAdminApp)
+);
+
+export const getMeasuresAppComponent = state => (
+    fromMeasuresApp.getComponent(state.measuresApp)
+);
+
+export const getMeasuresAppAllMetrics = state => (
+    fromMeasuresApp.getAllMetrics(state.measuresApp)
+);
+
+export const getMeasuresAppDetailsMetric = state => (
+    fromMeasuresApp.getDetailsMetric(state.measuresApp)
+);
+
+export const getMeasuresAppDetailsMeasure = state => (
+    fromMeasuresApp.getDetailsMeasure(state.measuresApp)
+);
+
+export const getMeasuresAppDetailsSecondaryMeasure = state => (
+    fromMeasuresApp.getDetailsSecondaryMeasure(state.measuresApp)
+);
+
+export const getMeasuresAppDetailsPeriods = state => (
+    fromMeasuresApp.getDetailsPeriods(state.measuresApp)
+);
+
+export const isMeasuresAppFetching = state => (
+    fromMeasuresApp.isFetching(state.measuresApp)
+);
+
+export const getMeasuresAppList = state => (
+    fromMeasuresApp.getList(state.measuresApp)
+);
+
+export const getMeasuresAppListComponents = state => (
+    fromMeasuresApp.getListComponents(state.measuresApp)
+);
+
+export const getMeasuresAppListSelected = state => (
+    fromMeasuresApp.getListSelected(state.measuresApp)
+);
+
+export const getMeasuresAppListTotal = state => (
+    fromMeasuresApp.getListTotal(state.measuresApp)
+);
+
+export const getMeasuresAppListPageIndex = state => (
+    fromMeasuresApp.getListPageIndex(state.measuresApp)
+);
+
+export const getMeasuresAppTree = state => (
+    fromMeasuresApp.getTree(state.measuresApp)
+);
+
+export const getMeasuresAppTreeComponents = state => (
+    fromMeasuresApp.getTreeComponents(state.measuresApp)
+);
+
+export const getMeasuresAppTreeBreadcrumbs = state => (
+    fromMeasuresApp.getTreeBreadcrumbs(state.measuresApp)
+);
+
+export const getMeasuresAppTreeSelected = state => (
+    fromMeasuresApp.getTreeSelected(state.measuresApp)
+);
+
+export const getMeasuresAppTreeTotal = state => (
+    fromMeasuresApp.getTreeTotal(state.measuresApp)
+);
+
+export const getMeasuresAppTreePageIndex = state => (
+    fromMeasuresApp.getTreePageIndex(state.measuresApp)
+);
+
+export const getMeasuresAppHomeDomains = state => (
+    fromMeasuresApp.getHomeDomains(state.measuresApp)
+);
+
+export const getMeasuresAppHomePeriods = state => (
+    fromMeasuresApp.getHomePeriods(state.measuresApp)
+);
diff --git a/server/sonar-web/src/main/js/store/users/actions.js b/server/sonar-web/src/main/js/store/users/actions.js
new file mode 100644 (file)
index 0000000..27efd8b
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * 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 RECEIVE_CURRENT_USER = 'RECEIVE_CURRENT_USER';
+
+export const receiveCurrentUser = user => ({
+  type: RECEIVE_CURRENT_USER,
+  user
+});
+
+export const fetchCurrentUser = () => dispatch => (
+    getCurrentUser().then(user => dispatch(receiveCurrentUser(user)))
+);
diff --git a/server/sonar-web/src/main/js/store/users/reducer.js b/server/sonar-web/src/main/js/store/users/reducer.js
new file mode 100644 (file)
index 0000000..03dd5f9
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * 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 { combineReducers } from 'redux';
+import uniq from 'lodash/uniq';
+import { RECEIVE_CURRENT_USER } from './actions';
+
+const usersByLogin = (state = {}, action = {}) => {
+  if (action.type === RECEIVE_CURRENT_USER) {
+    return { ...state, [action.user.login]: action.user };
+  }
+
+  return state;
+};
+
+const userLogins = (state = [], action = {}) => {
+  if (action.type === RECEIVE_CURRENT_USER) {
+    return uniq([...state, action.user.login]);
+  }
+
+  return state;
+};
+
+const currentUser = (state = null, action = {}) => {
+  if (action.type === RECEIVE_CURRENT_USER) {
+    return action.user;
+  }
+
+  return state;
+};
+
+export default combineReducers({ usersByLogin, userLogins, currentUser });
+
+export const getCurrentUser = state => (
+    state.currentUser
+);
diff --git a/server/sonar-web/src/main/js/store/utils/configureStore.js b/server/sonar-web/src/main/js/store/utils/configureStore.js
new file mode 100644 (file)
index 0000000..97397d8
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * 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, compose } from 'redux';
+import thunk from 'redux-thunk';
+
+const middlewares = [thunk];
+const composed = [];
+
+if (process.env.NODE_ENV !== 'production') {
+  const createLogger = require('redux-logger');
+  middlewares.push(createLogger());
+
+  composed.push(window.devToolsExtension ? window.devToolsExtension() : f => f);
+}
+
+const finalCreateStore = compose(
+    applyMiddleware(...middlewares),
+    ...composed
+)(createStore);
+
+export default function configureStore (rootReducer, initialState) {
+  return finalCreateStore(rootReducer, initialState);
+}
diff --git a/server/sonar-web/src/main/js/store/utils/generalReducers.js b/server/sonar-web/src/main/js/store/utils/generalReducers.js
new file mode 100644 (file)
index 0000000..8f88ff4
--- /dev/null
@@ -0,0 +1,95 @@
+/*
+ * 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.
+ */
+// Author: Christoffer Niska <christofferniska@gmail.com>
+// https://gist.github.com/crisu83/42ecffccad9d04c74605fbc75c9dc9d1
+import uniq from 'lodash/uniq';
+
+/**
+ * Creates a reducer that manages a single value.
+ *
+ * @param {function(state, action)} shouldUpdate
+ * @param {function(state, action)} shouldReset
+ * @param {function(state, action)} getValue
+ * @param {*} defaultValue
+ * @returns {function(state, action)}
+ */
+export const createValue = (
+    shouldUpdate = () => true,
+    shouldReset = () => false,
+    getValue = (state, action) => action.payload,
+    defaultValue = null
+) => (state = defaultValue, action = {}) => {
+  if (shouldReset(state, action)) {
+    return defaultValue;
+  }
+  if (shouldUpdate(state, action)) {
+    return getValue(state, action);
+  }
+  return state;
+};
+
+/**
+ * Creates a reducer that manages a map.
+ *
+ * @param {function(state, action)} shouldUpdate
+ * @param {function(state, action)} shouldReset
+ * @param {function(state, action)} getValues
+ * @returns {function(state, action)}
+ */
+export const createMap = (
+    shouldUpdate = () => true,
+    shouldReset = () => false,
+    getValues = (state, action) => action.payload
+) => createValue(shouldUpdate, shouldReset, (state, action) =>
+    ({ ...state, ...getValues(state, action) }), {});
+
+/**
+ * Creates a reducer that manages a set.
+ *
+ * @param {function(state, action)} shouldUpdate
+ * @param {function(state, action)} shouldReset
+ * @param {function(state, action)} getValues
+ * @returns {function(state, action)}
+ */
+export const createSet = (
+    shouldUpdate = () => true,
+    shouldReset = () => false,
+    getValues = (state, action) => action.payload
+) => createValue(shouldUpdate, shouldReset, (state, action) =>
+    uniq([...state, ...getValues(state, action)]), []);
+
+/**
+ * Creates a reducer that manages a flag.
+ *
+ * @param {function(state, action)} shouldTurnOn
+ * @param {function(state, action)} shouldTurnOff
+ * @param {bool} defaultValue
+ * @returns {function(state, action)}
+ */
+export const createFlag = (shouldTurnOn, shouldTurnOff, defaultValue = false) =>
+    (state = defaultValue, action = {}) => {
+      if (shouldTurnOn(state, action)) {
+        return true;
+      }
+      if (shouldTurnOff(state, action)) {
+        return false;
+      }
+      return state;
+    };
diff --git a/server/sonar-web/src/main/js/store/utils/withStore.js b/server/sonar-web/src/main/js/store/utils/withStore.js
new file mode 100644 (file)
index 0000000..4518fc0
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * 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';
+
+const withStore = (ComposedComponent, initial = {}) => {
+  let store = initial;
+
+  const updateStore = changes => {
+    store = { ...store, ...changes };
+  };
+
+  const getStore = () => ({ ...store });
+
+  return class extends React.Component {
+    static displayName = `withStore(${ComposedComponent.displayName})}`;
+
+    componentWillMount () {
+      this.handleUpdateStore = this.handleUpdateStore.bind(this);
+    }
+
+    handleUpdateStore (changes) {
+      updateStore(changes);
+      this.forceUpdate();
+    }
+
+    render () {
+      return (
+          <ComposedComponent
+              {...this.props}
+              getStore={getStore}
+              updateStore={this.handleUpdateStore}/>
+      );
+    }
+  };
+};
+
+export default withStore;