web: refactor info and tenant reducers action
This change adds info fetch state action type and simplifies the main App by using the new info attributes. Change-Id: I2cfd3f6ae605051e11f58272e62925d8f97e4ac9
This commit is contained in:
parent
76867ca14a
commit
17144c2a46
|
@ -86,8 +86,12 @@ class App extends React.Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
renderContent = () => {
|
renderContent = () => {
|
||||||
const { tenant } = this.props
|
const { info, tenant } = this.props
|
||||||
const allRoutes = []
|
const allRoutes = []
|
||||||
|
|
||||||
|
if (info.isFetching) {
|
||||||
|
return (<h2>Fetching info...</h2>)
|
||||||
|
}
|
||||||
this.menu
|
this.menu
|
||||||
// Do not include '/tenants' route in white-label setup
|
// Do not include '/tenants' route in white-label setup
|
||||||
.filter(item =>
|
.filter(item =>
|
||||||
|
@ -102,10 +106,13 @@ class App extends React.Component {
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
if (tenant.defaultRoute)
|
||||||
|
allRoutes.push(
|
||||||
|
<Redirect from='*' to={tenant.defaultRoute} key='default-route' />
|
||||||
|
)
|
||||||
return (
|
return (
|
||||||
<Switch>
|
<Switch>
|
||||||
{allRoutes}
|
{allRoutes}
|
||||||
<Redirect from='*' to={tenant.defaultRoute} key='default-route' />
|
|
||||||
</Switch>
|
</Switch>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -113,7 +120,7 @@ class App extends React.Component {
|
||||||
componentDidUpdate() {
|
componentDidUpdate() {
|
||||||
// This method is called when info property is updated
|
// This method is called when info property is updated
|
||||||
const { tenant, info } = this.props
|
const { tenant, info } = this.props
|
||||||
if (info.capabilities) {
|
if (info.ready) {
|
||||||
let tenantName, whiteLabel
|
let tenantName, whiteLabel
|
||||||
|
|
||||||
if (info.tenant) {
|
if (info.tenant) {
|
||||||
|
@ -129,12 +136,10 @@ class App extends React.Component {
|
||||||
|
|
||||||
if (match) {
|
if (match) {
|
||||||
tenantName = match.params.tenant
|
tenantName = match.params.tenant
|
||||||
} else {
|
|
||||||
tenantName = ''
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Set tenant only if it changed to prevent DidUpdate loop
|
// Set tenant only if it changed to prevent DidUpdate loop
|
||||||
if (typeof tenant.name === 'undefined' || tenant.name !== tenantName) {
|
if (tenant.name !== tenantName) {
|
||||||
const tenantAction = setTenantAction(tenantName, whiteLabel)
|
const tenantAction = setTenantAction(tenantName, whiteLabel)
|
||||||
this.props.dispatch(tenantAction)
|
this.props.dispatch(tenantAction)
|
||||||
if (tenantName) {
|
if (tenantName) {
|
||||||
|
@ -204,10 +209,6 @@ class App extends React.Component {
|
||||||
const { menuCollapsed, showErrors } = this.state
|
const { menuCollapsed, showErrors } = this.state
|
||||||
const { tenant, configErrors } = this.props
|
const { tenant, configErrors } = this.props
|
||||||
|
|
||||||
if (typeof tenant.name === 'undefined') {
|
|
||||||
return (<h2>Loading...</h2>)
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<React.Fragment>
|
<React.Fragment>
|
||||||
<Masthead
|
<Masthead
|
||||||
|
|
|
@ -19,7 +19,7 @@ import ReactDOM from 'react-dom'
|
||||||
import { Link, BrowserRouter as Router } from 'react-router-dom'
|
import { Link, BrowserRouter as Router } from 'react-router-dom'
|
||||||
import { Provider } from 'react-redux'
|
import { Provider } from 'react-redux'
|
||||||
|
|
||||||
import { fetchInfoAction } from './actions/info'
|
import { fetchInfoIfNeeded } from './actions/info'
|
||||||
import createZuulStore from './store'
|
import createZuulStore from './store'
|
||||||
import App from './App'
|
import App from './App'
|
||||||
import TenantsPage from './pages/Tenants'
|
import TenantsPage from './pages/Tenants'
|
||||||
|
@ -54,7 +54,7 @@ it('renders multi tenant', () => {
|
||||||
const application = ReactTestUtils.renderIntoDocument(
|
const application = ReactTestUtils.renderIntoDocument(
|
||||||
<Provider store={store}><Router><App /></Router></Provider>
|
<Provider store={store}><Router><App /></Router></Provider>
|
||||||
)
|
)
|
||||||
store.dispatch(fetchInfoAction()).then(() => {
|
store.dispatch(fetchInfoIfNeeded()).then(() => {
|
||||||
// Link should be tenant scoped
|
// Link should be tenant scoped
|
||||||
const topMenuLinks = ReactTestUtils.scryRenderedComponentsWithType(
|
const topMenuLinks = ReactTestUtils.scryRenderedComponentsWithType(
|
||||||
application, Link)
|
application, Link)
|
||||||
|
@ -86,7 +86,7 @@ it('renders single tenant', () => {
|
||||||
<Provider store={store}><Router><App /></Router></Provider>
|
<Provider store={store}><Router><App /></Router></Provider>
|
||||||
)
|
)
|
||||||
|
|
||||||
store.dispatch(fetchInfoAction()).then(() => {
|
store.dispatch(fetchInfoIfNeeded()).then(() => {
|
||||||
// Link should be white-label scoped
|
// Link should be white-label scoped
|
||||||
const topMenuLinks = ReactTestUtils.scryRenderedComponentsWithType(
|
const topMenuLinks = ReactTestUtils.scryRenderedComponentsWithType(
|
||||||
application, Link)
|
application, Link)
|
||||||
|
|
|
@ -12,16 +12,46 @@
|
||||||
// License for the specific language governing permissions and limitations
|
// License for the specific language governing permissions and limitations
|
||||||
// under the License.
|
// under the License.
|
||||||
|
|
||||||
import { fetchInfo } from '../api'
|
import * as API from '../api'
|
||||||
|
|
||||||
export function fetchInfoAction () {
|
export const INFO_FETCH_REQUEST = 'INFO_FETCH_REQUEST'
|
||||||
return (dispatch) => {
|
export const INFO_FETCH_SUCCESS = 'INFO_FETCH_SUCCESS'
|
||||||
return fetchInfo()
|
export const INFO_FETCH_FAIL = 'INFO_FETCH_FAIL'
|
||||||
.then(response => {
|
|
||||||
dispatch({type: 'FETCH_INFO_SUCCESS', info: response.data.info})
|
export const fetchInfoRequest = () => ({
|
||||||
})
|
type: INFO_FETCH_REQUEST
|
||||||
.catch(error => {
|
})
|
||||||
throw (error)
|
|
||||||
})
|
export const fetchInfoSuccess = json => ({
|
||||||
|
type: INFO_FETCH_SUCCESS,
|
||||||
|
tenant: json.info.tenant,
|
||||||
|
})
|
||||||
|
|
||||||
|
const fetchInfoFail = error => ({
|
||||||
|
type: INFO_FETCH_FAIL,
|
||||||
|
error
|
||||||
|
})
|
||||||
|
|
||||||
|
const fetchInfo = () => dispatch => {
|
||||||
|
dispatch(fetchInfoRequest())
|
||||||
|
return API.fetchInfo()
|
||||||
|
.then(response => dispatch(fetchInfoSuccess(response.data)))
|
||||||
|
.catch(error => dispatch(fetchInfoFail(error)))
|
||||||
|
}
|
||||||
|
|
||||||
|
const shouldFetchInfo = state => {
|
||||||
|
const info = state.info
|
||||||
|
if (!info) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if (info.isFetching) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
export const fetchInfoIfNeeded = () => (dispatch, getState) => {
|
||||||
|
if (shouldFetchInfo(getState())) {
|
||||||
|
return dispatch(fetchInfo())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,8 @@
|
||||||
// License for the specific language governing permissions and limitations
|
// License for the specific language governing permissions and limitations
|
||||||
// under the License.
|
// under the License.
|
||||||
|
|
||||||
|
export const TENANT_SET = 'TENANT_SET'
|
||||||
|
|
||||||
export function setTenantAction (name, whiteLabel) {
|
export function setTenantAction (name, whiteLabel) {
|
||||||
let apiPrefix = ''
|
let apiPrefix = ''
|
||||||
let linkPrefix = ''
|
let linkPrefix = ''
|
||||||
|
@ -24,7 +26,7 @@ export function setTenantAction (name, whiteLabel) {
|
||||||
defaultRoute = '/tenants'
|
defaultRoute = '/tenants'
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
type: 'SET_TENANT',
|
type: TENANT_SET,
|
||||||
tenant: {
|
tenant: {
|
||||||
name: name,
|
name: name,
|
||||||
whiteLabel: whiteLabel,
|
whiteLabel: whiteLabel,
|
||||||
|
|
|
@ -25,14 +25,14 @@ import './index.css'
|
||||||
|
|
||||||
import { getHomepageUrl } from './api'
|
import { getHomepageUrl } from './api'
|
||||||
import registerServiceWorker from './registerServiceWorker'
|
import registerServiceWorker from './registerServiceWorker'
|
||||||
import { fetchInfoAction } from './actions/info'
|
import { fetchInfoIfNeeded } from './actions/info'
|
||||||
import createZuulStore from './store'
|
import createZuulStore from './store'
|
||||||
import App from './App'
|
import App from './App'
|
||||||
|
|
||||||
const store = createZuulStore()
|
const store = createZuulStore()
|
||||||
|
|
||||||
// Load info endpoint
|
// Load info endpoint
|
||||||
store.dispatch(fetchInfoAction())
|
store.dispatch(fetchInfoIfNeeded())
|
||||||
|
|
||||||
ReactDOM.render(
|
ReactDOM.render(
|
||||||
<Provider store={store}>
|
<Provider store={store}>
|
||||||
|
|
|
@ -12,10 +12,29 @@
|
||||||
// License for the specific language governing permissions and limitations
|
// License for the specific language governing permissions and limitations
|
||||||
// under the License.
|
// under the License.
|
||||||
|
|
||||||
export default (state = {}, action) => {
|
import {
|
||||||
|
INFO_FETCH_REQUEST,
|
||||||
|
INFO_FETCH_SUCCESS,
|
||||||
|
INFO_FETCH_FAIL,
|
||||||
|
} from '../actions/info'
|
||||||
|
|
||||||
|
export default (state = {
|
||||||
|
isFetching: false,
|
||||||
|
tenant: null,
|
||||||
|
}, action) => {
|
||||||
switch (action.type) {
|
switch (action.type) {
|
||||||
case 'FETCH_INFO_SUCCESS':
|
case INFO_FETCH_REQUEST:
|
||||||
return action.info
|
case INFO_FETCH_FAIL:
|
||||||
|
return {
|
||||||
|
isFetching: true,
|
||||||
|
tenant: null,
|
||||||
|
}
|
||||||
|
case INFO_FETCH_SUCCESS:
|
||||||
|
return {
|
||||||
|
isFetching: false,
|
||||||
|
tenant: action.tenant,
|
||||||
|
ready: true
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
return state
|
return state
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,9 +12,11 @@
|
||||||
// License for the specific language governing permissions and limitations
|
// License for the specific language governing permissions and limitations
|
||||||
// under the License.
|
// under the License.
|
||||||
|
|
||||||
export default (state = {}, action) => {
|
import { TENANT_SET } from '../actions/tenant'
|
||||||
|
|
||||||
|
export default (state = {name: null}, action) => {
|
||||||
switch (action.type) {
|
switch (action.type) {
|
||||||
case 'SET_TENANT':
|
case TENANT_SET:
|
||||||
return action.tenant
|
return action.tenant
|
||||||
default:
|
default:
|
||||||
return state
|
return state
|
||||||
|
|
Loading…
Reference in New Issue