From 33be8c3500e678c3d56202a8f204aabe1f1e84bd Mon Sep 17 00:00:00 2001 From: Stas Vilchik Date: Fri, 4 Nov 2016 09:59:58 +0100 Subject: extend the main js app (#1345) --- .../config/webpack/webpack.config.base.js | 2 - server/sonar-web/src/main/js/app/index.js | 8 +- .../sonar-web/src/main/js/app/store/rootReducer.js | 8 +- .../src/main/js/apps/quality-gates/app.js | 61 -------------- .../js/apps/quality-gates/components/Details.js | 4 +- .../main/js/apps/quality-gates/components/List.js | 2 +- .../quality-gates/components/QualityGatesApp.js | 2 +- .../quality-gates/containers/DetailsContainer.js | 50 ++++++------ .../containers/QualityGatesAppContainer.js | 19 +++-- .../src/main/js/apps/quality-gates/routes.js | 33 ++++++++ .../main/js/apps/quality-gates/store/actions.js | 28 +++---- .../main/js/apps/quality-gates/store/reducers.js | 93 ---------------------- .../js/apps/quality-gates/store/rootReducer.js | 93 ++++++++++++++++++++++ .../src/main/js/apps/quality-profiles/app.js | 59 -------------- .../changelog/ChangelogContainer.js | 6 +- .../compare/ComparisonContainer.js | 2 +- .../js/apps/quality-profiles/components/App.js | 17 ++-- .../quality-profiles/components/AppContainer.js | 28 +++++++ .../quality-profiles/components/ProfileActions.js | 4 +- .../quality-profiles/components/ProfileLink.js | 2 +- .../quality-profiles/components/ProfileNotFound.js | 2 +- .../apps/quality-profiles/details/ProfileHeader.js | 6 +- .../js/apps/quality-profiles/home/PageHeader.js | 2 +- .../js/apps/quality-profiles/home/ProfilesList.js | 3 +- .../quality-profiles/home/ProfilesListHeader.js | 4 +- .../src/main/js/apps/quality-profiles/routes.js | 41 ++++++++++ .../WEB-INF/app/views/profiles/index.html.erb | 5 +- .../WEB-INF/app/views/quality_gates/index.html.erb | 5 +- 28 files changed, 283 insertions(+), 306 deletions(-) delete mode 100644 server/sonar-web/src/main/js/apps/quality-gates/app.js create mode 100644 server/sonar-web/src/main/js/apps/quality-gates/routes.js delete mode 100644 server/sonar-web/src/main/js/apps/quality-gates/store/reducers.js create mode 100644 server/sonar-web/src/main/js/apps/quality-gates/store/rootReducer.js delete mode 100644 server/sonar-web/src/main/js/apps/quality-profiles/app.js create mode 100644 server/sonar-web/src/main/js/apps/quality-profiles/components/AppContainer.js create mode 100644 server/sonar-web/src/main/js/apps/quality-profiles/routes.js diff --git a/server/sonar-web/config/webpack/webpack.config.base.js b/server/sonar-web/config/webpack/webpack.config.base.js index 336f414ec60..bb4c81e63fc 100644 --- a/server/sonar-web/config/webpack/webpack.config.base.js +++ b/server/sonar-web/config/webpack/webpack.config.base.js @@ -46,8 +46,6 @@ module.exports = { 'project-admin': './src/main/js/apps/project-admin/app.js', 'project-permissions': './src/main/js/apps/permissions/project/app.js', 'projects-admin': './src/main/js/apps/projects-admin/app.js', - 'quality-gates': './src/main/js/apps/quality-gates/app.js', - 'quality-profiles': './src/main/js/apps/quality-profiles/app.js', 'settings': './src/main/js/apps/settings/app.js', 'source-viewer': './src/main/js/apps/source-viewer/app.js', 'system': './src/main/js/apps/system/app.js', diff --git a/server/sonar-web/src/main/js/app/index.js b/server/sonar-web/src/main/js/app/index.js index addf577ee07..107dc2ae53c 100644 --- a/server/sonar-web/src/main/js/app/index.js +++ b/server/sonar-web/src/main/js/app/index.js @@ -24,7 +24,9 @@ import { createHistory } from 'history'; import { Provider } from 'react-redux'; import App from './components/App'; import accountRoutes from '../apps/account/routes'; -import projectsRouters from '../apps/projects/routes'; +import projectsRoutes from '../apps/projects/routes'; +import qualityGatesRoutes from '../apps/quality-gates/routes'; +import qualityProfilesRoutes from '../apps/quality-profiles/routes'; import configureStore from '../components/store/configureStore'; import rootReducer from './store/rootReducer'; import './styles/index'; @@ -43,7 +45,9 @@ window.sonarqube.appStarted.then(options => { {accountRoutes} - {projectsRouters} + {projectsRoutes} + {qualityGatesRoutes} + {qualityProfilesRoutes} diff --git a/server/sonar-web/src/main/js/app/store/rootReducer.js b/server/sonar-web/src/main/js/app/store/rootReducer.js index a46042491fa..a317c982af6 100644 --- a/server/sonar-web/src/main/js/app/store/rootReducer.js +++ b/server/sonar-web/src/main/js/app/store/rootReducer.js @@ -27,6 +27,7 @@ import globalMessages, * as fromGlobalMessages from '../../components/store/glob import issuesActivity, * as fromIssuesActivity from '../../apps/account/home/store/reducer'; import projectsApp, * as fromProjectsApp from '../../apps/projects/store/reducer'; +import qualityGatesApp from '../../apps/quality-gates/store/rootReducer'; export default combineReducers({ components, @@ -38,7 +39,8 @@ export default combineReducers({ // apps issuesActivity, - projectsApp + projectsApp, + qualityGatesApp }); export const getComponent = (state, key) => ( @@ -88,3 +90,7 @@ export const getProjectsAppFacetByProperty = (state, property) => ( export const getProjectsAppMaxFacetValue = state => ( fromProjectsApp.getMaxFacetValue(state.projectsApp) ); + +export const getQualityGatesAppState = state => ( + state.qualityGatesApp +); diff --git a/server/sonar-web/src/main/js/apps/quality-gates/app.js b/server/sonar-web/src/main/js/apps/quality-gates/app.js deleted file mode 100644 index ded4a821315..00000000000 --- a/server/sonar-web/src/main/js/apps/quality-gates/app.js +++ /dev/null @@ -1,61 +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'; -import { render } from 'react-dom'; -import { Router, Route, IndexRoute, Redirect, useRouterHistory } from 'react-router'; -import { createHistory } from 'history'; -import { combineReducers } from 'redux'; -import { Provider } from 'react-redux'; -import { syncHistoryWithStore, routerReducer } from 'react-router-redux'; - -import QualityGatesAppContainer from './containers/QualityGatesAppContainer'; -import Intro from './components/Intro'; -import DetailsContainer from './containers/DetailsContainer'; -import rootReducer from './store/reducers'; -import configureStore from '../../components/store/configureStore'; - -window.sonarqube.appStarted.then(options => { - const el = document.querySelector(options.el); - - const history = useRouterHistory(createHistory)({ - basename: window.baseUrl + '/quality_gates' - }); - - const finalReducer = combineReducers({ - rootReducer, - routing: routerReducer - }); - - const store = configureStore(finalReducer); - - const finalHistory = syncHistoryWithStore(history, store); - - render(( - - - - - - - - - - ), el); -}); diff --git a/server/sonar-web/src/main/js/apps/quality-gates/components/Details.js b/server/sonar-web/src/main/js/apps/quality-gates/components/Details.js index 0b0b2766c23..d02601bfe6e 100644 --- a/server/sonar-web/src/main/js/apps/quality-gates/components/Details.js +++ b/server/sonar-web/src/main/js/apps/quality-gates/components/Details.js @@ -65,7 +65,7 @@ export default class Details extends Component { qualityGate, onCopy: (newQualityGate) => { onCopy(newQualityGate); - router.push(`/show/${newQualityGate.id}`); + router.push(`/quality_gates/show/${newQualityGate.id}`); } }).render(); } @@ -90,7 +90,7 @@ export default class Details extends Component { qualityGate, onDelete: (qualityGate) => { onDelete(qualityGate); - router.replace('/'); + router.replace('/quality_gates'); } }).render(); } diff --git a/server/sonar-web/src/main/js/apps/quality-gates/components/List.js b/server/sonar-web/src/main/js/apps/quality-gates/components/List.js index 88a9a16f107..66b8ec046ef 100644 --- a/server/sonar-web/src/main/js/apps/quality-gates/components/List.js +++ b/server/sonar-web/src/main/js/apps/quality-gates/components/List.js @@ -28,7 +28,7 @@ export default function List ({ qualityGates }) { {qualityGates.map(qualityGate => ( diff --git a/server/sonar-web/src/main/js/apps/quality-gates/components/QualityGatesApp.js b/server/sonar-web/src/main/js/apps/quality-gates/components/QualityGatesApp.js index 8d3d4838a6c..9395bac2b25 100644 --- a/server/sonar-web/src/main/js/apps/quality-gates/components/QualityGatesApp.js +++ b/server/sonar-web/src/main/js/apps/quality-gates/components/QualityGatesApp.js @@ -51,7 +51,7 @@ export default class QualityGatesApp extends Component { const { router } = this.context; addQualityGate(qualityGate); - router.push(`/show/${qualityGate.id}`); + router.push(`/quality_gates/show/${qualityGate.id}`); } render () { diff --git a/server/sonar-web/src/main/js/apps/quality-gates/containers/DetailsContainer.js b/server/sonar-web/src/main/js/apps/quality-gates/containers/DetailsContainer.js index 3f2c835edf5..ae53d592b69 100644 --- a/server/sonar-web/src/main/js/apps/quality-gates/containers/DetailsContainer.js +++ b/server/sonar-web/src/main/js/apps/quality-gates/containers/DetailsContainer.js @@ -18,37 +18,35 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import { connect } from 'react-redux'; - import { - deleteQualityGate, - showQualityGate, - renameQualityGate, - copyQualityGate, - setQualityGateAsDefault, - unsetQualityGateAsDefault, - addCondition, - deleteCondition, - saveCondition + deleteQualityGate, + showQualityGate, + renameQualityGate, + copyQualityGate, + setQualityGateAsDefault, + unsetQualityGateAsDefault, + addCondition, + deleteCondition, + saveCondition } from '../store/actions'; import Details from '../components/Details'; +import { getQualityGatesAppState } from '../../../app/store/rootReducer'; -function mapStateToProps (state) { - return state.rootReducer; -} +const mapStateToProps = state => ( + getQualityGatesAppState(state) +); -function mapDispatchToProps (dispatch) { - return { - onShow: qualityGate => dispatch(showQualityGate(qualityGate)), - onDelete: qualityGate => dispatch(deleteQualityGate(qualityGate)), - onRename: (qualityGate, newName) => dispatch(renameQualityGate(qualityGate, newName)), - onCopy: qualityGate => dispatch(copyQualityGate(qualityGate)), - onSetAsDefault: qualityGate => dispatch(setQualityGateAsDefault(qualityGate)), - onUnsetAsDefault: qualityGate => dispatch(unsetQualityGateAsDefault(qualityGate)), - onAddCondition: metric => dispatch(addCondition(metric)), - onSaveCondition: (oldCondition, newCondition) => dispatch(saveCondition(oldCondition, newCondition)), - onDeleteCondition: condition => dispatch(deleteCondition(condition)) - }; -} +const mapDispatchToProps = dispatch => ({ + onShow: qualityGate => dispatch(showQualityGate(qualityGate)), + onDelete: qualityGate => dispatch(deleteQualityGate(qualityGate)), + onRename: (qualityGate, newName) => dispatch(renameQualityGate(qualityGate, newName)), + onCopy: qualityGate => dispatch(copyQualityGate(qualityGate)), + onSetAsDefault: qualityGate => dispatch(setQualityGateAsDefault(qualityGate)), + onUnsetAsDefault: qualityGate => dispatch(unsetQualityGateAsDefault(qualityGate)), + onAddCondition: metric => dispatch(addCondition(metric)), + onSaveCondition: (oldCondition, newCondition) => dispatch(saveCondition(oldCondition, newCondition)), + onDeleteCondition: condition => dispatch(deleteCondition(condition)) +}); export default connect( mapStateToProps, diff --git a/server/sonar-web/src/main/js/apps/quality-gates/containers/QualityGatesAppContainer.js b/server/sonar-web/src/main/js/apps/quality-gates/containers/QualityGatesAppContainer.js index 2145fd817ea..4eaf763bb2b 100644 --- a/server/sonar-web/src/main/js/apps/quality-gates/containers/QualityGatesAppContainer.js +++ b/server/sonar-web/src/main/js/apps/quality-gates/containers/QualityGatesAppContainer.js @@ -21,18 +21,17 @@ import { connect } from 'react-redux'; import { setState, addQualityGate, deleteQualityGate } from '../store/actions'; import QualityGateApp from '../components/QualityGatesApp'; +import { getQualityGatesAppState } from '../../../app/store/rootReducer'; -function mapStateToProps (state) { - return state.rootReducer; -} +const mapStateToProps = state => ( + getQualityGatesAppState(state) +); -function mapDispatchToProps (dispatch) { - return { - updateStore: nextState => dispatch(setState(nextState)), - addQualityGate: qualityGate => dispatch(addQualityGate(qualityGate)), - deleteQualityGate: qualityGate => dispatch(deleteQualityGate(qualityGate)) - }; -} +const mapDispatchToProps = dispatch => ({ + updateStore: nextState => dispatch(setState(nextState)), + addQualityGate: qualityGate => dispatch(addQualityGate(qualityGate)), + deleteQualityGate: qualityGate => dispatch(deleteQualityGate(qualityGate)) +}); export default connect( mapStateToProps, diff --git a/server/sonar-web/src/main/js/apps/quality-gates/routes.js b/server/sonar-web/src/main/js/apps/quality-gates/routes.js new file mode 100644 index 00000000000..8f471c3930b --- /dev/null +++ b/server/sonar-web/src/main/js/apps/quality-gates/routes.js @@ -0,0 +1,33 @@ +/* + * SonarQube + * Copyright (C) 2009-2016 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +import React from 'react'; +import { Route, IndexRoute, Redirect } from 'react-router'; +import QualityGatesAppContainer from './containers/QualityGatesAppContainer'; +import Intro from './components/Intro'; +import DetailsContainer from './containers/DetailsContainer'; + +export default ( + + + + + + +); diff --git a/server/sonar-web/src/main/js/apps/quality-gates/store/actions.js b/server/sonar-web/src/main/js/apps/quality-gates/store/actions.js index 201fb4c4e6b..280d81aebdf 100644 --- a/server/sonar-web/src/main/js/apps/quality-gates/store/actions.js +++ b/server/sonar-web/src/main/js/apps/quality-gates/store/actions.js @@ -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. */ -export const SET_STATE = 'SET_STATE'; +export const SET_STATE = 'qualityGates/SET_STATE'; export function setState (nextState) { return { type: SET_STATE, @@ -25,40 +25,40 @@ export function setState (nextState) { }; } -export const ADD = 'ADD'; +export const ADD = 'qualityGates/ADD'; export function addQualityGate (qualityGate) { return { - type: 'ADD', + type: ADD, qualityGate }; } -export const DELETE = 'DELETE'; +export const DELETE = 'qualityGates/DELETE'; export function deleteQualityGate (qualityGate) { return { - type: 'DELETE', + type: DELETE, qualityGate }; } -export const SHOW = 'SHOW'; +export const SHOW = 'qualityGates/SHOW'; export function showQualityGate (qualityGate) { return { - type: 'SHOW', + type: SHOW, qualityGate }; } -export const RENAME = 'RENAME'; +export const RENAME = 'qualityGates/RENAME'; export function renameQualityGate (qualityGate, newName) { return { - type: 'RENAME', + type: RENAME, qualityGate, newName }; } -export const COPY = 'COPY'; +export const COPY = 'qualityGates/COPY'; export function copyQualityGate (qualityGate) { return { type: COPY, @@ -74,7 +74,7 @@ export function setQualityGateAsDefault (qualityGate) { }; } -export const UNSET_AS_DEFAULT = 'UNSET_AS_DEFAULT'; +export const UNSET_AS_DEFAULT = 'qualityGates/UNSET_AS_DEFAULT'; export function unsetQualityGateAsDefault (qualityGate) { return { type: UNSET_AS_DEFAULT, @@ -82,7 +82,7 @@ export function unsetQualityGateAsDefault (qualityGate) { }; } -export const ADD_CONDITION = 'ADD_CONDITION'; +export const ADD_CONDITION = 'qualityGates/ADD_CONDITION'; export function addCondition (metric) { return { type: ADD_CONDITION, @@ -90,7 +90,7 @@ export function addCondition (metric) { }; } -export const SAVE_CONDITION = 'SAVE_CONDITION'; +export const SAVE_CONDITION = 'qualityGates/SAVE_CONDITION'; export function saveCondition (oldCondition, newCondition) { return { type: SAVE_CONDITION, @@ -99,7 +99,7 @@ export function saveCondition (oldCondition, newCondition) { }; } -export const DELETE_CONDITION = 'DELETE_CONDITION'; +export const DELETE_CONDITION = 'qualityGates/DELETE_CONDITION'; export function deleteCondition (condition) { return { type: DELETE_CONDITION, diff --git a/server/sonar-web/src/main/js/apps/quality-gates/store/reducers.js b/server/sonar-web/src/main/js/apps/quality-gates/store/reducers.js deleted file mode 100644 index 0b8e06d0656..00000000000 --- a/server/sonar-web/src/main/js/apps/quality-gates/store/reducers.js +++ /dev/null @@ -1,93 +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 { - SET_STATE, - ADD, - DELETE, - SHOW, - RENAME, - COPY, - SET_AS_DEFAULT, - UNSET_AS_DEFAULT, - ADD_CONDITION, - DELETE_CONDITION, - SAVE_CONDITION -} from './actions'; -import { checkIfDefault, addCondition, deleteCondition, replaceCondition } from './utils'; - -const initialState = {}; - -export default function rootReducer (state = initialState, action = {}) { - switch (action.type) { - case SET_STATE: - return { ...state, ...action.nextState }; - case ADD: - case COPY: - return { ...state, qualityGates: [...state.qualityGates, action.qualityGate] }; - case DELETE: - return { ...state, qualityGates: state.qualityGates.filter(candidate => candidate.id !== action.qualityGate.id) }; - case SHOW: - return { - ...state, - qualityGate: { ...action.qualityGate, isDefault: checkIfDefault(action.qualityGate, state.qualityGates) } - }; - case RENAME: - return { - ...state, - qualityGates: state.qualityGates.map(candidate => { - return candidate.id === action.qualityGate.id ? { ...candidate, name: action.newName } : candidate; - }), - qualityGate: { ...state.qualityGate, name: action.newName } - }; - case SET_AS_DEFAULT: - return { - ...state, - qualityGates: state.qualityGates.map(candidate => { - return { ...candidate, isDefault: candidate.id === action.qualityGate.id }; - }), - qualityGate: { ...state.qualityGate, isDefault: state.qualityGate.id === action.qualityGate.id } - }; - case UNSET_AS_DEFAULT: - return { - ...state, - qualityGates: state.qualityGates.map(candidate => { - return candidate.id === action.qualityGate.id ? { ...candidate, isDefault: false } : candidate; - }), - qualityGate: { ...state.qualityGate, isDefault: false } - }; - case ADD_CONDITION: - return { - ...state, - qualityGate: addCondition(state.qualityGate, action.metric) - }; - case DELETE_CONDITION: - return { - ...state, - qualityGate: deleteCondition(state.qualityGate, action.condition) - }; - case SAVE_CONDITION: - return { - ...state, - qualityGate: replaceCondition(state.qualityGate, action.oldCondition, action.newCondition) - }; - default: - return state; - } -} diff --git a/server/sonar-web/src/main/js/apps/quality-gates/store/rootReducer.js b/server/sonar-web/src/main/js/apps/quality-gates/store/rootReducer.js new file mode 100644 index 00000000000..0b8e06d0656 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/quality-gates/store/rootReducer.js @@ -0,0 +1,93 @@ +/* + * 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 { + SET_STATE, + ADD, + DELETE, + SHOW, + RENAME, + COPY, + SET_AS_DEFAULT, + UNSET_AS_DEFAULT, + ADD_CONDITION, + DELETE_CONDITION, + SAVE_CONDITION +} from './actions'; +import { checkIfDefault, addCondition, deleteCondition, replaceCondition } from './utils'; + +const initialState = {}; + +export default function rootReducer (state = initialState, action = {}) { + switch (action.type) { + case SET_STATE: + return { ...state, ...action.nextState }; + case ADD: + case COPY: + return { ...state, qualityGates: [...state.qualityGates, action.qualityGate] }; + case DELETE: + return { ...state, qualityGates: state.qualityGates.filter(candidate => candidate.id !== action.qualityGate.id) }; + case SHOW: + return { + ...state, + qualityGate: { ...action.qualityGate, isDefault: checkIfDefault(action.qualityGate, state.qualityGates) } + }; + case RENAME: + return { + ...state, + qualityGates: state.qualityGates.map(candidate => { + return candidate.id === action.qualityGate.id ? { ...candidate, name: action.newName } : candidate; + }), + qualityGate: { ...state.qualityGate, name: action.newName } + }; + case SET_AS_DEFAULT: + return { + ...state, + qualityGates: state.qualityGates.map(candidate => { + return { ...candidate, isDefault: candidate.id === action.qualityGate.id }; + }), + qualityGate: { ...state.qualityGate, isDefault: state.qualityGate.id === action.qualityGate.id } + }; + case UNSET_AS_DEFAULT: + return { + ...state, + qualityGates: state.qualityGates.map(candidate => { + return candidate.id === action.qualityGate.id ? { ...candidate, isDefault: false } : candidate; + }), + qualityGate: { ...state.qualityGate, isDefault: false } + }; + case ADD_CONDITION: + return { + ...state, + qualityGate: addCondition(state.qualityGate, action.metric) + }; + case DELETE_CONDITION: + return { + ...state, + qualityGate: deleteCondition(state.qualityGate, action.condition) + }; + case SAVE_CONDITION: + return { + ...state, + qualityGate: replaceCondition(state.qualityGate, action.oldCondition, action.newCondition) + }; + default: + return state; + } +} diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/app.js b/server/sonar-web/src/main/js/apps/quality-profiles/app.js deleted file mode 100644 index cb998c8edfc..00000000000 --- a/server/sonar-web/src/main/js/apps/quality-profiles/app.js +++ /dev/null @@ -1,59 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2016 SonarSource SA - * mailto:contact AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -import React from 'react'; -import { render } from 'react-dom'; -import { - Router, - Route, - IndexRoute, - Redirect, - useRouterHistory -} from 'react-router'; -import { createHistory } from 'history'; -import App from './components/App'; -import ProfileContainer from './components/ProfileContainer'; -import HomeContainer from './home/HomeContainer'; -import ProfileDetails from './details/ProfileDetails'; -import ChangelogContainer from './changelog/ChangelogContainer'; -import ComparisonContainer from './compare/ComparisonContainer'; - -window.sonarqube.appStarted.then(options => { - const el = document.querySelector(options.el); - - const history = useRouterHistory(createHistory)({ - basename: window.baseUrl + '/profiles' - }); - - render(( - - - - - - - - - - - - - - ), el); -}); diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/changelog/ChangelogContainer.js b/server/sonar-web/src/main/js/apps/quality-profiles/changelog/ChangelogContainer.js index 2c0bdd1c882..59adf9809dd 100644 --- a/server/sonar-web/src/main/js/apps/quality-profiles/changelog/ChangelogContainer.js +++ b/server/sonar-web/src/main/js/apps/quality-profiles/changelog/ChangelogContainer.js @@ -114,17 +114,17 @@ export default class ChangelogContainer extends React.Component { handleFromDateChange (fromDate) { const query = { ...this.props.location.query, since: fromDate }; - this.context.router.push({ pathname: '/changelog', query }); + this.context.router.push({ pathname: '/profiles/changelog', query }); } handleToDateChange (toDate) { const query = { ...this.props.location.query, to: toDate }; - this.context.router.push({ pathname: '/changelog', query }); + this.context.router.push({ pathname: '/profiles/changelog', query }); } handleReset () { const query = { key: this.props.profile.key }; - this.context.router.push({ pathname: '/changelog', query }); + this.context.router.push({ pathname: '/profiles/changelog', query }); } render () { diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/compare/ComparisonContainer.js b/server/sonar-web/src/main/js/apps/quality-profiles/compare/ComparisonContainer.js index 03d5d145212..24bc4b33668 100644 --- a/server/sonar-web/src/main/js/apps/quality-profiles/compare/ComparisonContainer.js +++ b/server/sonar-web/src/main/js/apps/quality-profiles/compare/ComparisonContainer.js @@ -81,7 +81,7 @@ export default class ComparisonContainer extends React.Component { handleCompare (withKey) { this.context.router.push({ - pathname: '/compare', + pathname: '/profiles/compare', query: { key: this.props.profile.key, withKey diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/components/App.js b/server/sonar-web/src/main/js/apps/quality-profiles/components/App.js index 2c2eff071c9..75c7354fd06 100644 --- a/server/sonar-web/src/main/js/apps/quality-profiles/components/App.js +++ b/server/sonar-web/src/main/js/apps/quality-profiles/components/App.js @@ -18,11 +18,7 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import React from 'react'; -import { getLanguages } from '../../../api/languages'; -import { - getQualityProfiles, - getExporters -} from '../../../api/quality-profiles'; +import { getQualityProfiles, getExporters } from '../../../api/quality-profiles'; import { getCurrentUser } from '../../../api/users'; import '../styles.css'; import { sortProfiles } from '../utils'; @@ -49,15 +45,13 @@ export default class App extends React.Component { this.setState({ loading: true }); Promise.all([ getCurrentUser(), - getLanguages(), getExporters(), getQualityProfiles() ]).then(responses => { if (this.mounted) { - const [user, languages, exporters, profiles] = responses; + const [user, exporters, profiles] = responses; const canAdmin = user.permissions.global.includes('profileadmin'); this.setState({ - languages, exporters, canAdmin, profiles: sortProfiles(profiles), @@ -76,13 +70,16 @@ export default class App extends React.Component { } renderChild () { - if (this.state.loading) { + const areLanguagesLoading = Object.keys(this.props.languages).length === 0; + if (this.state.loading || areLanguagesLoading) { return ; } + const finalLanguages = Object.values(this.props.languages); + return React.cloneElement(this.props.children, { profiles: this.state.profiles, - languages: this.state.languages, + languages: finalLanguages, exporters: this.state.exporters, canAdmin: this.state.canAdmin, updateProfiles: this.updateProfiles diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/components/AppContainer.js b/server/sonar-web/src/main/js/apps/quality-profiles/components/AppContainer.js new file mode 100644 index 00000000000..3f164b4c0c2 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/quality-profiles/components/AppContainer.js @@ -0,0 +1,28 @@ +/* + * SonarQube + * Copyright (C) 2009-2016 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +import { connect } from 'react-redux'; +import App from './App'; +import { getLanguages } from '../../../app/store/rootReducer'; + +export default connect( + state => ({ + languages: getLanguages(state) + }) +)(App); diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/components/ProfileActions.js b/server/sonar-web/src/main/js/apps/quality-profiles/components/ProfileActions.js index f0a834c0555..b79902486e3 100644 --- a/server/sonar-web/src/main/js/apps/quality-profiles/components/ProfileActions.js +++ b/server/sonar-web/src/main/js/apps/quality-profiles/components/ProfileActions.js @@ -54,7 +54,7 @@ export default class ProfileActions extends React.Component { }).on('done', profile => { this.props.updateProfiles().then(() => { this.context.router.push({ - pathname: '/show', + pathname: '/profiles/show', query: { key: profile.key } }); }); @@ -72,7 +72,7 @@ export default class ProfileActions extends React.Component { new DeleteProfileView({ profile: this.props.profile }).on('done', () => { - this.context.router.replace('/'); + this.context.router.replace('/profiles'); this.props.updateProfiles(); }).render(); } diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/components/ProfileLink.js b/server/sonar-web/src/main/js/apps/quality-profiles/components/ProfileLink.js index 1e0d0cfd1dd..6e15a51668e 100644 --- a/server/sonar-web/src/main/js/apps/quality-profiles/components/ProfileLink.js +++ b/server/sonar-web/src/main/js/apps/quality-profiles/components/ProfileLink.js @@ -30,7 +30,7 @@ export default class ProfileLink extends React.Component { const query = { key: profileKey }; return ( {children} diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/components/ProfileNotFound.js b/server/sonar-web/src/main/js/apps/quality-profiles/components/ProfileNotFound.js index 9c37677df44..c04bb9c10d7 100644 --- a/server/sonar-web/src/main/js/apps/quality-profiles/components/ProfileNotFound.js +++ b/server/sonar-web/src/main/js/apps/quality-profiles/components/ProfileNotFound.js @@ -26,7 +26,7 @@ export default class ProfileNotFound extends React.Component { return (
- + {translate('quality_profiles.page')}
diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileHeader.js b/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileHeader.js index 439be30205c..44182e47a2d 100644 --- a/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileHeader.js +++ b/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileHeader.js @@ -86,12 +86,12 @@ export default class ProfileHeader extends React.Component { return (
- + {translate('quality_profiles.page')} {' / '} {profile.languageName} @@ -111,7 +111,7 @@ export default class ProfileHeader extends React.Component { {this.renderUsageDate()}
  • {translate('changelog')} diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/home/PageHeader.js b/server/sonar-web/src/main/js/apps/quality-profiles/home/PageHeader.js index 9d9ed85759f..1ae3bef24c8 100644 --- a/server/sonar-web/src/main/js/apps/quality-profiles/home/PageHeader.js +++ b/server/sonar-web/src/main/js/apps/quality-profiles/home/PageHeader.js @@ -64,7 +64,7 @@ export default class PageHeader extends React.Component { }).on('done', profile => { this.props.updateProfiles().then(() => { this.context.router.push({ - pathname: '/show', + pathname: '/profiles/show', query: { key: profile.key } }); }); diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/home/ProfilesList.js b/server/sonar-web/src/main/js/apps/quality-profiles/home/ProfilesList.js index ba333be7e12..3e3e1765133 100644 --- a/server/sonar-web/src/main/js/apps/quality-profiles/home/ProfilesList.js +++ b/server/sonar-web/src/main/js/apps/quality-profiles/home/ProfilesList.js @@ -18,7 +18,6 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import React from 'react'; -import { PropTypes as RouterPropTypes } from 'react-router'; import groupBy from 'lodash/groupBy'; import pick from 'lodash/pick'; import sortBy from 'lodash/sortBy'; @@ -32,7 +31,7 @@ export default class ProfilesList extends React.Component { static propTypes = { profiles: ProfilesListType, languages: LanguagesListType, - location: RouterPropTypes.location, + location: React.PropTypes.object, canAdmin: React.PropTypes.bool.isRequired, updateProfiles: React.PropTypes.func.isRequired }; diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/home/ProfilesListHeader.js b/server/sonar-web/src/main/js/apps/quality-profiles/home/ProfilesListHeader.js index 010321937ce..8a71385bf4a 100644 --- a/server/sonar-web/src/main/js/apps/quality-profiles/home/ProfilesListHeader.js +++ b/server/sonar-web/src/main/js/apps/quality-profiles/home/ProfilesListHeader.js @@ -52,14 +52,14 @@ export default class ProfilesListHeader extends React.Component { return (
    • - + {translate('quality_profiles.all_profiles')}
    • {this.props.languages.map(language => (
    • {language.name} diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/routes.js b/server/sonar-web/src/main/js/apps/quality-profiles/routes.js new file mode 100644 index 00000000000..b5729b5643b --- /dev/null +++ b/server/sonar-web/src/main/js/apps/quality-profiles/routes.js @@ -0,0 +1,41 @@ +/* + * SonarQube + * Copyright (C) 2009-2016 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +import React from 'react'; +import { Route, IndexRoute, Redirect } from 'react-router'; +import AppContainer from './components/AppContainer'; +import ProfileContainer from './components/ProfileContainer'; +import HomeContainer from './home/HomeContainer'; +import ProfileDetails from './details/ProfileDetails'; +import ChangelogContainer from './changelog/ChangelogContainer'; +import ComparisonContainer from './compare/ComparisonContainer'; + +export default ( + + + + + + + + + + + +); diff --git a/server/sonar-web/src/main/webapp/WEB-INF/app/views/profiles/index.html.erb b/server/sonar-web/src/main/webapp/WEB-INF/app/views/profiles/index.html.erb index b41bb0bbcd5..513b41c5692 100644 --- a/server/sonar-web/src/main/webapp/WEB-INF/app/views/profiles/index.html.erb +++ b/server/sonar-web/src/main/webapp/WEB-INF/app/views/profiles/index.html.erb @@ -1,6 +1,3 @@ <% content_for :extra_script do %> - - + <% end %> diff --git a/server/sonar-web/src/main/webapp/WEB-INF/app/views/quality_gates/index.html.erb b/server/sonar-web/src/main/webapp/WEB-INF/app/views/quality_gates/index.html.erb index 5cc9585f4dd..513b41c5692 100644 --- a/server/sonar-web/src/main/webapp/WEB-INF/app/views/quality_gates/index.html.erb +++ b/server/sonar-web/src/main/webapp/WEB-INF/app/views/quality_gates/index.html.erb @@ -1,6 +1,3 @@ <% content_for :extra_script do %> - - + <% end %> -- cgit v1.2.3