diff --git a/web/src/actions/projects.js b/web/src/actions/projects.js new file mode 100644 index 0000000000..18c91ea295 --- /dev/null +++ b/web/src/actions/projects.js @@ -0,0 +1,62 @@ +/* global Promise */ +// Copyright 2018 Red Hat, Inc +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. You may obtain +// a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations +// under the License. + +import * as API from '../api' + +export const PROJECTS_FETCH_REQUEST = 'PROJECTS_FETCH_REQUEST' +export const PROJECTS_FETCH_SUCCESS = 'PROJECTS_FETCH_SUCCESS' +export const PROJECTS_FETCH_FAIL = 'PROJECTS_FETCH_FAIL' + +export const requestProjects = () => ({ + type: PROJECTS_FETCH_REQUEST +}) + +export const receiveProjects = (tenant, json) => ({ + type: PROJECTS_FETCH_SUCCESS, + tenant: tenant, + projects: json, + receivedAt: Date.now() +}) + +const failedProjects = error => ({ + type: PROJECTS_FETCH_FAIL, + error +}) + +const fetchProjects = (tenant) => dispatch => { + dispatch(requestProjects()) + return API.fetchProjects(tenant.apiPrefix) + .then(response => dispatch(receiveProjects(tenant.name, response.data))) + .catch(error => dispatch(failedProjects(error))) +} + +const shouldFetchProjects = (tenant, state) => { + const projects = state.projects.projects[tenant.name] + if (!projects || projects.length === 0) { + return true + } + if (projects.isFetching) { + return false + } + return false +} + +export const fetchProjectsIfNeeded = (tenant, force) => ( + dispatch, getState) => { + if (force || shouldFetchProjects(tenant, getState())) { + return dispatch(fetchProjects(tenant)) + } + return Promise.resolve() +} diff --git a/web/src/pages/Projects.jsx b/web/src/pages/Projects.jsx index a8b9dec3f4..06c0960697 100644 --- a/web/src/pages/Projects.jsx +++ b/web/src/pages/Projects.jsx @@ -18,39 +18,30 @@ import { connect } from 'react-redux' import { Link } from 'react-router-dom' import { Table } from 'patternfly-react' -import { fetchProjects } from '../api' +import { fetchProjectsIfNeeded } from '../actions/projects' +import Refreshable from '../containers/Refreshable' -class ProjectsPage extends React.Component { +class ProjectsPage extends Refreshable { static propTypes = { - tenant: PropTypes.object + tenant: PropTypes.object, + remoteData: PropTypes.object, + dispatch: PropTypes.func } - state = { - projects: null - } - - updateData () { - fetchProjects(this.props.tenant.apiPrefix).then(response => { - this.setState({projects: response.data}) - }) + updateData (force) { + this.props.dispatch(fetchProjectsIfNeeded(this.props.tenant, force)) } componentDidMount () { document.title = 'Zuul Projects' - if (this.props.tenant.name) { - this.updateData() - } - } - - componentDidUpdate (prevProps) { - if (this.props.tenant.name !== prevProps.tenant.name) { - this.updateData() - } + super.componentDidMount() } render () { - const { projects } = this.state + const { remoteData } = this.props + const projects = remoteData.projects[this.props.tenant.name] + if (!projects) { return (
Loading...
) } @@ -91,19 +82,28 @@ class ProjectsPage extends React.Component { }) }) return ( -