diff --git a/scm-ui/public/locales/en/config.json b/scm-ui/public/locales/en/config.json index c6bd8c6db7..dd87bdcae2 100644 --- a/scm-ui/public/locales/en/config.json +++ b/scm-ui/public/locales/en/config.json @@ -1,7 +1,11 @@ { "config": { + "navigation-title": "Navigation" + }, + "global-config": { "title": "Configuration", - "navigation-title": "Navigation", - "globalConfig-label": "Global Configuration" + "navigation-label": "Global Configuration", + "error-title": "Error", + "error-subtitle": "Unknown Config Error" } } diff --git a/scm-ui/src/config/containers/Config.js b/scm-ui/src/config/containers/Config.js index a5266a6680..0a7d112192 100644 --- a/scm-ui/src/config/containers/Config.js +++ b/scm-ui/src/config/containers/Config.js @@ -40,7 +40,7 @@ class Config extends React.Component {
- +
diff --git a/scm-ui/src/config/containers/GlobalConfig.js b/scm-ui/src/config/containers/GlobalConfig.js index e0877e3a09..a3fcca70d5 100644 --- a/scm-ui/src/config/containers/GlobalConfig.js +++ b/scm-ui/src/config/containers/GlobalConfig.js @@ -1,18 +1,69 @@ import React from "react"; import { translate } from "react-i18next"; import Title from "../../components/layout/Title"; +import { + fetchConfig, + getFetchConfigFailure, + isFetchConfigPending +} from "../modules/config"; +import connect from "react-redux/es/connect/connect"; +import ErrorPage from "../../components/ErrorPage"; +import Loading from "../../components/Loading"; type Props = { + loading: boolean, + error: Error, + // context objects - t: string => string + t: string => string, + fetchConfig: void => void }; class GlobalConfig extends React.Component { - render() { - const { t } = this.props; + componentDidMount() { + this.props.fetchConfig(); + } - return ; + render() { + const { t, error, loading } = this.props; + + if (error) { + return ( + <ErrorPage + title={t("global-config.error-title")} + subtitle={t("global-config.error-subtitle")} + error={error} + /> + ); + } + + if (loading) { + return <Loading />; + } + + return <Title title={t("global-config.title")} />; } } -export default translate("config")(GlobalConfig); +const mapDispatchToProps = dispatch => { + return { + fetchConfig: () => { + dispatch(fetchConfig()); + } + }; +}; + +const mapStateToProps = state => { + const loading = isFetchConfigPending(state); + const error = getFetchConfigFailure(state); + + return { + loading, + error + }; +}; + +export default connect( + mapStateToProps, + mapDispatchToProps +)(translate("config")(GlobalConfig)); diff --git a/scm-ui/src/config/modules/config.js b/scm-ui/src/config/modules/config.js index b951d33ed3..062be6fc95 100644 --- a/scm-ui/src/config/modules/config.js +++ b/scm-ui/src/config/modules/config.js @@ -2,6 +2,8 @@ import { apiClient } from "../../apiclient"; import * as types from "../../modules/types"; import type { Action } from "../../types/Action"; +import { isPending } from "../../modules/pending"; +import { getFailure } from "../../modules/failure"; export const FETCH_CONFIG = "scm/groups/FETCH_CONFIG"; export const FETCH_CONFIG_PENDING = `${FETCH_CONFIG}_${types.PENDING_SUFFIX}`; @@ -69,3 +71,13 @@ function reducer(state: any = {}, action: any = {}) { } export default reducer; + +// selectors + +export function isFetchConfigPending(state: Object) { + return isPending(state, FETCH_CONFIG); +} + +export function getFetchConfigFailure(state: Object) { + return getFailure(state, FETCH_CONFIG); +} diff --git a/scm-ui/src/config/modules/config.test.js b/scm-ui/src/config/modules/config.test.js index f81df3d522..86b5db7cbf 100644 --- a/scm-ui/src/config/modules/config.test.js +++ b/scm-ui/src/config/modules/config.test.js @@ -4,11 +4,14 @@ import thunk from "redux-thunk"; import fetchMock from "fetch-mock"; import reducer, { + FETCH_CONFIG, FETCH_CONFIG_PENDING, FETCH_CONFIG_SUCCESS, FETCH_CONFIG_FAILURE, fetchConfig, - fetchConfigSuccess + fetchConfigSuccess, + getFetchConfigFailure, + isFetchConfigPending } from "./config"; const CONFIG_URL = "/scm/api/rest/v2/config"; @@ -114,3 +117,31 @@ describe("config reducer", () => { expect(newState.config.entries).toBe(config); }); }); + +describe("selector tests", () => { + it("should return true, when fetch config is pending", () => { + const state = { + pending: { + [FETCH_CONFIG]: true + } + }; + expect(isFetchConfigPending(state)).toEqual(true); + }); + + it("should return false, when fetch config is not pending", () => { + expect(isFetchConfigPending({})).toEqual(false); + }); + + it("should return error when fetch config did fail", () => { + const state = { + failure: { + [FETCH_CONFIG]: error + } + }; + expect(getFetchConfigFailure(state)).toEqual(error); + }); + + it("should return undefined when fetch config did not fail", () => { + expect(getFetchConfigFailure({})).toBe(undefined); + }); +});