Better handle loading states

Now if BuildBot does not have build data, it will be indicated
with question mark.
Moved pagination to a separate component, got rid of pageReducer
This commit is contained in:
Victor Perevertkin 2020-03-16 05:36:21 +03:00
parent 9d00ab2f3f
commit 55258739d2
No known key found for this signature in database
GPG Key ID: C750B7222E9C7830
15 changed files with 232 additions and 225 deletions

View File

@ -6,18 +6,29 @@ import {
Route, Route,
Redirect Redirect
} from "react-router-dom"; } from "react-router-dom";
import { connect } from 'react-redux'
import Header from './components/Header'; import Header from './components/Header';
import Commits from './components/Commits'; import Commits from './components/Commits';
import Pulls from './components/Pulls'; import Pulls from './components/Pulls';
import Loading from './components/Loading'
import configureStore from './redux/store'; import configureStore from './redux/store';
import { loadBuilders } from './redux/actions'
import { LOAD_STATE } from './redux/constants'
const store = configureStore(); const store = configureStore();
export default function App() { class App extends React.PureComponent {
return ( // things which are needed regardles the current view
<Provider store={store}> componentDidMount() {
<Router> this.props.dispatch(loadBuilders())
<div> }
<Header/>
render() {
return (
<React.Fragment>
<Header/>
{this.props.canRender ?
<Switch> <Switch>
<Route path="/pulls/:pull_state"><Pulls/></Route> <Route path="/pulls/:pull_state"><Pulls/></Route>
<Route path="/commits/:branch"><Commits/></Route> <Route path="/commits/:branch"><Commits/></Route>
@ -26,7 +37,22 @@ export default function App() {
<Route path="/commits"><Redirect to="/commits/master"/></Route> <Route path="/commits"><Redirect to="/commits/master"/></Route>
<Route path="/"><Redirect to="/commits/master"/></Route> <Route path="/"><Redirect to="/commits/master"/></Route>
</Switch> </Switch>
</div> : <Loading text="Loading basic data..." />}
</React.Fragment>)
}
}
function mapStateToProps(state) {
return ({canRender: state.isLoading.buildersDataState === LOAD_STATE.LOADED})
}
const WrappedApp = connect(mapStateToProps)(App)
export default function outerApp() {
return (
<Provider store={store}>
<Router>
<WrappedApp />
</Router> </Router>
</Provider> </Provider>
); );

View File

@ -7,11 +7,7 @@ import {
DropdownMenu, DropdownMenu,
DropdownItem DropdownItem
} from 'reactstrap'; } from 'reactstrap';
import { import { loadBranches, loadCommits } from '../redux/actions';
loadBranches,
loadCommits,
loadBuilders
} from '../redux/actions';
class Branches extends React.Component { class Branches extends React.Component {
constructor(props) { constructor(props) {
@ -21,7 +17,6 @@ class Branches extends React.Component {
}; };
} }
componentDidMount() { componentDidMount() {
this.props.loadBuilders();
this.props.loadBranches(); this.props.loadBranches();
} }
@ -76,8 +71,7 @@ const mapStateToProps = ({ branches }) => ({
const mapDispatchToProps = dispatch => ({ const mapDispatchToProps = dispatch => ({
loadCommits: (branch, next) => dispatch(loadCommits(branch, next)), loadCommits: (branch, next) => dispatch(loadCommits(branch, next)),
loadBranches: () => dispatch(loadBranches()), loadBranches: () => dispatch(loadBranches())
loadBuilders: () => dispatch(loadBuilders())
}); });
export default connect( export default connect(

View File

@ -6,17 +6,15 @@ import Branches from './Branches';
import './styles/Commit.css'; import './styles/Commit.css';
import CommitsCard from './CommitsCard'; import CommitsCard from './CommitsCard';
import Loading from './Loading'; import Loading from './Loading';
import Pagination from './Pagination'
import { LOAD_STATE } from '../redux/constants'
class Commits extends React.PureComponent { class Commits extends React.PureComponent {
componentDidMount() { componentDidMount() {
this.props.loadCommits(this.props.branch); if (this.props.firstLoad) {
this.props.loadBuilds(); this.props.loadCommits(this.props.branch, 1); // TODO: remove the hack
} this.props.loadBuilds();
componentDidUpdate(prevProps) {
if (this.props.branch !== prevProps.branch) {
this.props.loadCommits(this.props.branch)
this.props.loadBuilds()
} }
} }
@ -35,7 +33,7 @@ class Commits extends React.PureComponent {
}; };
render() { render() {
const {branch, page} = this.props; const { branch, currentPage } = this.props
return ( return (
<div className='container mt-2'> <div className='container mt-2'>
@ -46,7 +44,7 @@ class Commits extends React.PureComponent {
</div> </div>
</div> </div>
{this.props.isLoading.load ? ( {this.props.isLoading ? (
<Loading <Loading
text={`Fetching latest Commits of ${branch} for you...`} text={`Fetching latest Commits of ${branch} for you...`}
/> />
@ -60,38 +58,10 @@ class Commits extends React.PureComponent {
Err:{this.props.error} Err:{this.props.error}
</div> </div>
) : ( ) : (
<div> <Pagination
<button currentPage={currentPage}
type='button' nextPage={() => this.props.loadCommits(branch, currentPage + 1)}
onClick={() => { prevPage={() => this.props.loadCommits(branch, currentPage - 1)} />
this.props.loadCommits(branch, page.prev);
}}
className='btn btn-primary '
disabled={
page.prev === null || this.props.error !== null
}
>
<i className='fa fa-caret-left' aria-hidden='true' />
Previous Page{' '}
</button>{' '}
<button
type='button'
onClick={() => {
this.props.loadCommits(branch, page.next);
}}
className='btn btn-primary'
disabled={
page.next === null || this.props.error !== null
}
>
Next Page{' '}
<i className='fa fa-caret-right' aria-hidden='true' />
</button>
<footer className='blockquote-footer'>
Page {page.next - 1}
</footer>
<div className='footer-blockquote' />
</div>
)} )}
</div> </div>
)} )}
@ -110,15 +80,15 @@ const mapStateToProps = ({
commits, commits,
builders, builders,
error, error,
page,
builds, builds,
tests tests
}) => ({ }) => ({
isLoading, isLoading: isLoading.commitsLoadInfo.lastState !== LOAD_STATE.LOADED,
firstLoad: !isLoading.commitsLoadInfo.loadedPages.includes(1), //if we need to load first page
currentPage: isLoading.commitsLoadInfo.currentPage,
commits, commits,
builders, builders,
error, error,
page,
builds, builds,
tests tests
}); });

View File

@ -1,8 +1,9 @@
import React from 'react'; import React from 'react';
import { connect } from 'react-redux'
import { UncontrolledCollapse, CardBody, Card, CardHeader } from 'reactstrap'; import { UncontrolledCollapse, CardBody, Card, CardHeader } from 'reactstrap';
import BuildDetails from './BuildDetails'; import BuildDetails from './BuildDetails';
import TestDetails from './TestDetails'; import TestDetails from './TestDetails';
import { JOB_STATUS } from '../redux/constants' import { JOB_STATUS, LOAD_STATE } from '../redux/constants'
import { statusElement } from './utils' import { statusElement } from './utils'
function firstLineTrimmed(str) { function firstLineTrimmed(str) {
@ -16,7 +17,7 @@ function firstLineTrimmed(str) {
} }
function getTotalStatus(jobs) { function getTotalStatus(jobs) {
if (!jobs.length) return null if (!jobs || !jobs.length) return JOB_STATUS.NO_DATA
let ret = JOB_STATUS.SUCCESS let ret = JOB_STATUS.SUCCESS
@ -30,31 +31,31 @@ function getTotalStatus(jobs) {
return ret return ret
} }
function CommitsCard({sha, ...props}) { function CommitsCard({sha, author, commit, loadStatus, ...props}) {
let tog = 'toggler' + sha; let tog = 'toggler' + sha;
let committerDate = new Date(props.commit.committer.date); let committerDate = new Date(commit.committer.date);
let authorDate = new Date(props.commit.author.date); let authorDate = new Date(commit.author.date);
let author = encodeURIComponent(props.commit.author.name); const author_login = author ? author.login : commit.author.name
let committer = encodeURIComponent(props.commit.committer.name); const builds = props.builds ? props.builds : []
const tests = props.tests ? props.tests : []
return ( return (
<Card className="mb-1"> <Card className="mb-1">
<CardHeader className='new' type='button' id={tog}> <CardHeader className='new' type='button' id={tog}>
<div className='row'> <div className='row'>
<div className='col-sm-9'> <div className='col-sm-9'>
<a className="text-monospace" href={`https://github.com/reactos/reactos/commit/${sha}`}>{sha.substring(0, 7)}</a> <a className="text-monospace" href={`https://github.com/reactos/reactos/commit/${sha}`}>{sha.substring(0, 7)}</a>
{" "}{firstLineTrimmed(props.commit.message)} {" "}{firstLineTrimmed(commit.message)}
</div> </div>
<div className='col-sm-2'>{props.author.login}</div> <div className='col-sm-2'>{author_login}</div>
<div className="col-sm-1"> <div className="col-sm-1">
{props.builds && {loadStatus.buildBot === LOAD_STATE.LOADING
props.builds.length > 0 ? <span title="Loading results"><i className="fa fa-refresh fa-spin" /></span>
? statusElement(getTotalStatus(props.builds), "Build status") : statusElement(getTotalStatus(props.builds), "Build status") }
: <span title="Loading results"><i className="fa fa-refresh fa-spin" /></span> }
{" "} {" "}
{props.tests && {loadStatus.buildBot === LOAD_STATE.LOADING
props.tests.length > 0 ? <span title="Loading results"><i className="fa fa-refresh fa-spin" /></span>
? statusElement(getTotalStatus(props.tests), "Test status") : statusElement(getTotalStatus(props.tests), "Test status") }
: <span title="Loading results"><i className="fa fa-refresh fa-spin" /></span> }
</div> </div>
</div> </div>
</CardHeader> </CardHeader>
@ -66,13 +67,13 @@ function CommitsCard({sha, ...props}) {
<a <a
target='_blank' target='_blank'
rel='noreferrer noopener' rel='noreferrer noopener'
href={props.commit.html_url} href={commit.html_url}
> >
{sha} {sha}
</a> </a>
</p> </p>
<p> <p>
<strong>Commit Msg:</strong> {props.commit.message} <strong>Commit Msg:</strong> {commit.message}
</p> </p>
</div> </div>
<div className='row'> <div className='row'>
@ -81,11 +82,11 @@ function CommitsCard({sha, ...props}) {
<a <a
target='_blank' target='_blank'
rel='noreferrer noopener' rel='noreferrer noopener'
href={`https://git.reactos.org/?p=reactos.git;a=search;s=${author};st=author`} href={`https://git.reactos.org/?p=reactos.git;a=search;s=${encodeURIComponent(commit.author.name)};st=author`}
> >
{props.commit.author.name} {commit.author.name}
</a> </a>
{` <${props.commit.author.email}>`} {` <${commit.author.email}>`}
</div> </div>
<div className='col-sm'> <div className='col-sm'>
<strong>Author Date: </strong> <strong>Author Date: </strong>
@ -98,11 +99,11 @@ function CommitsCard({sha, ...props}) {
<a <a
target='_blank' target='_blank'
rel='noreferrer noopener' rel='noreferrer noopener'
href={`https://git.reactos.org/?p=reactos.git;a=search;s=${committer};st=committer`} href={`https://git.reactos.org/?p=reactos.git;a=search;s=${encodeURIComponent(commit.committer.name)};st=committer`}
> >
{props.commit.committer.name} {commit.committer.name}
</a> </a>
{` <${props.commit.committer.email}>`} {` <${commit.committer.email}>`}
</div> </div>
<div className='col-sm'> <div className='col-sm'>
<strong>Committer Date: </strong> <strong>Committer Date: </strong>
@ -113,23 +114,15 @@ function CommitsCard({sha, ...props}) {
<div className="row"> <div className="row">
<div className="col-md-5"> <div className="col-md-5">
<h5>Build Details:</h5> <h5>Build Details:</h5>
{props.builds ? ( {loadStatus.buildBot === LOAD_STATE.LOADING
<BuildDetails builds={props.builds} /> ? <strong>Loading builds data...</strong>
) : ( : <BuildDetails builds={builds} /> }
<div>
<strong>Loading Builds...</strong>
</div>
)}
</div> </div>
<div className="col-md-7"> <div className="col-md-7">
<h5>Test Details:</h5> <h5>Test Details:</h5>
{props.tests ? ( {loadStatus.buildBot === LOAD_STATE.LOADING
<TestDetails tests={props.tests} previousTests={props.previousTests} /> ? <strong>Loading tests data...</strong>
) : ( : <TestDetails tests={tests} previousTests={props.previousTests} /> }
<div>
<strong>No data Exists</strong>
</div>
)}
</div> </div>
</div> </div>
</CardBody> </CardBody>
@ -137,4 +130,9 @@ function CommitsCard({sha, ...props}) {
</Card> </Card>
); );
} }
export default CommitsCard;
function mapStateToProps(state, ownProps) {
return {...ownProps, loadStatus: state.isLoading.byCommit[ownProps.sha]}
}
export default connect(mapStateToProps)(CommitsCard);

View File

@ -0,0 +1,30 @@
import React from 'react'
export default function Pagination({currentPage, nextPage, prevPage}) {
return (
<div>
<button
type='button'
onClick={prevPage}
className='btn btn-primary '
disabled={currentPage === 1}
>
<i className='fa fa-caret-left' aria-hidden='true' />
Previous Page{' '}
</button>{' '}
<button
type='button'
onClick={nextPage}
className='btn btn-primary'
>
Next Page{' '}
<i className='fa fa-caret-right' aria-hidden='true' />
</button>
<footer className='blockquote-footer'>
Page {currentPage}
</footer>
<div className='footer-blockquote' />
</div>
)
}

View File

@ -4,16 +4,14 @@ import { NavLink, useParams } from 'react-router-dom';
import { loadPulls } from '../redux/actions'; import { loadPulls } from '../redux/actions';
import './styles/Pulls.css'; import './styles/Pulls.css';
import Loading from './Loading'; import Loading from './Loading';
import Pagination from './Pagination'
import PullsCard from './PullsCard'; import PullsCard from './PullsCard';
import { LOAD_STATE } from '../redux/constants'
class Pulls extends React.PureComponent { class Pulls extends React.PureComponent {
componentDidMount() { componentDidMount() {
this.props.loadPulls(this.props.pullState); if (this.props.firstLoad) {
} this.props.loadPulls(this.props.pullState, 1)
componentDidUpdate(prevProps) {
if (this.props.pullState !== prevProps.pullState) {
this.props.loadPulls(this.props.pullState)
} }
} }
@ -30,7 +28,7 @@ class Pulls extends React.PureComponent {
); );
}; };
render() { render() {
const {pullState, page} = this.props; const { pullState, currentPage } = this.props;
return ( return (
<div className='container mt-2'> <div className='container mt-2'>
@ -51,7 +49,7 @@ class Pulls extends React.PureComponent {
</div> </div>
</div> </div>
{this.props.isLoading.load ? ( {this.props.isLoading ? (
<Loading text='Fetching latest PRs for you...' /> <Loading text='Fetching latest PRs for you...' />
) : ( ) : (
<div> <div>
@ -63,38 +61,10 @@ class Pulls extends React.PureComponent {
Err:{this.props.error} Err:{this.props.error}
</div> </div>
) : ( ) : (
<div> <Pagination
<button currentPage={currentPage}
type='button' nextPage={() => this.props.loadPulls(pullState, currentPage + 1)}
onClick={() => { prevPage={() => this.props.loadPulls(pullState, currentPage - 1)} />
this.props.loadPulls(pullState, page.prev);
}}
className='btn btn-primary '
disabled={
page.prev === null || this.props.error !== null
}
>
<i className='fa fa-caret-left' aria-hidden='true' />
Previous Page{' '}
</button>{' '}
<button
type='button'
onClick={() => {
this.props.loadPulls(pullState, page.next);
}}
className='btn btn-primary'
disabled={
page.next === null || this.props.error !== null
}
>
Next Page{' '}
<i className='fa fa-caret-right' aria-hidden='true' />
</button>
<footer className='blockquote-footer'>
Page {page.next - 1}
</footer>
<div className='footer-blockquote' />
</div>
)} )}
</div> </div>
)} )}
@ -111,16 +81,16 @@ function PullsWrapper(props) {
const mapStateToProps = ({ const mapStateToProps = ({
pulls, pulls,
builders, builders,
page,
isLoading, isLoading,
error, error,
builds, builds,
tests tests
}) => ({ }) => ({
isLoading: isLoading.pullsLoadInfo.lastState !== LOAD_STATE.LOADED,
firstLoad: !isLoading.pullsLoadInfo.loadedPages.includes(1), //if we need to load first page
currentPage: isLoading.pullsLoadInfo.currentPage,
pulls, pulls,
builders, builders,
page,
isLoading,
error, error,
builds, builds,
tests tests

View File

@ -10,6 +10,8 @@ export function statusElement(status, statusText) {
return <span className="text-warning" title={statusText}><i className="fa fa-hourglass" /></span> return <span className="text-warning" title={statusText}><i className="fa fa-hourglass" /></span>
case JOB_STATUS.FAILURE: case JOB_STATUS.FAILURE:
return <span className="text-danger" title={statusText}><i className="fa fa-times" /></span> return <span className="text-danger" title={statusText}><i className="fa fa-times" /></span>
case JOB_STATUS.NO_DATA:
return <span title={statusText}><i className="fa fa-question" /></span>
default: default:
return null return null
} }

View File

@ -71,11 +71,8 @@ export const setTestmanError = error => ({
error error
}); });
export const setPages = (next, prev) => ({ // branches
type: 'PAGE_LOAD_SUCCESS',
next,
prev
});
export const loadBranches = () => ({ export const loadBranches = () => ({
type: BRANCHES.LOAD type: BRANCHES.LOAD
}); });

View File

@ -7,7 +7,15 @@ export const PULL_STATE = {
export const JOB_STATUS = { export const JOB_STATUS = {
SUCCESS: 0, SUCCESS: 0,
FAILURE: 1, FAILURE: 1,
ONGOING: 2 ONGOING: 2,
NO_DATA: 3
}
export const LOAD_STATE = {
NOT_LOADED: 0,
LOADING: 1,
LOADED: 2,
ERROR: 3
} }
export const BUILDER_TYPE = { export const BUILDER_TYPE = {

View File

@ -6,7 +6,6 @@ import errorReducer from './errorReducer';
import branchReducer from './branchReducer'; import branchReducer from './branchReducer';
import builderReducer from './builderReducer'; import builderReducer from './builderReducer';
import pullsReducer from './pullsReducer'; import pullsReducer from './pullsReducer';
import pageReducer from './pageReducer';
import builds from './builds'; import builds from './builds';
import tests from './tests' import tests from './tests'
@ -17,7 +16,6 @@ const rootReducer = combineReducers({
branches: branchReducer, branches: branchReducer,
builders: builderReducer, builders: builderReducer,
pulls: pullsReducer, pulls: pullsReducer,
page: pageReducer,
builds, builds,
tests tests
}); });

View File

@ -1,45 +1,89 @@
import { COMMITS, BRANCHES, PULLS, BUILD_DATA, BUILDERS } from '../constants'; import { COMMITS, BRANCHES, PULLS, BUILD_DATA, TEST_DATA, BUILDERS, LOAD_STATE } from '../constants';
const loadingReducer = (state = { newPage: 1, load: false }, action) => { const defaultState = {
byCommit: {},
buildersDataState: LOAD_STATE.NOT_LOADED,
commitsLoadInfo: {lastState: LOAD_STATE.NOT_LOADED, currentPage: 1, loadedPages: []},
pullsLoadInfo: {lastState: LOAD_STATE.NOT_LOADED, currentPage: 1, loadedPages: []},
buildBotLoadInfo: {lastState: LOAD_STATE.NOT_LOADED},
testManLoadInfo: {lastState: LOAD_STATE.NOT_LOADED}
}
function loadingReducer(state = defaultState, action) {
switch (action.type) { switch (action.type) {
case COMMITS.LOAD:
return { newPage: action.newPage, load: true };
case BUILDERS.LOAD: case BUILDERS.LOAD:
return { ...state, load: true }; return { ...state, buildersDataState: LOAD_STATE.LOADING }
case PULLS.LOAD:
return { newPage: action.newPage, load: true };
case BRANCHES.LOAD:
return { newPage: action.newPage, load: true };
case BUILD_DATA.LOAD:
return { newPage: action.newPage, load: true };
case COMMITS.LOAD_SUCCESS:
return { ...state, load: false };
case BUILDERS.LOAD_SUCCESS: case BUILDERS.LOAD_SUCCESS:
return { ...state, load: true }; return { ...state, buildersDataState: LOAD_STATE.LOADED }
case PULLS.LOAD_SUCCESS: case COMMITS.LOAD: {
return { ...state, load: false }; const commitsLoadInfo = {
...state.commitsLoadInfo,
lastState: LOAD_STATE.LOADING,
lastPage: action.newPage
}
case BRANCHES.LOAD_SUCCESS: return { ...state, commitsLoadInfo}
return { newPage: action.newPage, load: true }; }
case COMMITS.LOAD_SUCCESS: {
const byCommit = {...state.byCommit}
case BUILD_DATA.LOAD_SUCCESS: const commitsLoadInfo = {
return { load: false }; ...state.commitsLoadInfo,
lastState: LOAD_STATE.LOADED,
currentPage: state.commitsLoadInfo.lastPage,
loadedPages: state.commitsLoadInfo.loadedPages.concat([state.commitsLoadInfo.lastPage])
}
case COMMITS.LOAD_FAIL: for(let commit of Object.values(action.commits))
return { ...state, load: false }; {
byCommit[commit.sha] = {buildBot: LOAD_STATE.LOADING, tests: LOAD_STATE.LOADING}
}
case PULLS.LOAD_FAIL: return { ...state, byCommit, commitsLoadInfo}
return { ...state, load: false }; }
case BUILD_DATA.LOAD: {
const byCommit = {...state.byCommit}
for(let sha of Object.keys(byCommit))
{
byCommit[sha] = {buildBot: LOAD_STATE.LOADING, tests: byCommit[sha].tests}
}
return {...state, byCommit };
}
case PULLS.LOAD: {
const pullsLoadInfo = {
...state.pullsLoadInfo,
lastState: LOAD_STATE.LOADING,
lastPage: action.newPage
}
return { ...state, pullsLoadInfo}
}
case PULLS.LOAD_SUCCESS: {
const pullsLoadInfo = {
...state.pullsLoadInfo,
lastState: LOAD_STATE.LOADED,
currentPage: state.pullsLoadInfo.lastPage,
loadedPages: state.pullsLoadInfo.loadedPages.concat([state.pullsLoadInfo.lastPage])
}
return { ...state, pullsLoadInfo }
}
case BUILD_DATA.LOAD_SUCCESS: {
const byCommit = {...state.byCommit}
for(let [sha, build] of Object.entries(action.builds))
{
if (byCommit[sha]) {
byCommit[sha] = {buildBot: LOAD_STATE.LOADED, tests: byCommit[sha].tests}
}
}
return { ...state, byCommit };
}
default: default:
return { ...state, load: false }; return state
} }
}; };

View File

@ -1,19 +0,0 @@
import { BRANCHES } from '../constants';
const pageReducer = (state = { next: 1, prev: 0 }, action) => {
switch (action.type) {
case BRANCHES.CURRENT:
return {
next: 1,
prev: 0
};
case 'PAGE_LOAD_SUCCESS':
return {
next: action.next,
prev: action.prev
};
default:
return state;
}
};
export default pageReducer;

View File

@ -1,21 +1,13 @@
import { throttle, call, put, select } from 'redux-saga/effects'; import { throttle, call, put, select } from 'redux-saga/effects';
import { COMMITS } from '../constants'; import { COMMITS } from '../constants';
import { fetchCommits } from '../api'; import { fetchCommits } from '../api';
import { setCommits, setCommitsError, setPages } from '../actions'; import { setCommits, setCommitsError } from '../actions';
export const getNewPage = state => parseInt(state.isLoading.newPage, 10);
function* handleCommitsLoad(action) { function* handleCommitsLoad(action) {
try { try {
const newPage = yield select(getNewPage); let commits = yield call(fetchCommits, action.branch, action.newPage)
let commits = yield call(fetchCommits, action.branch, newPage);
yield put(setCommits(commits.commits.body)); yield put(setCommits(commits.commits.body));
yield put(
setPages(
commits.page.next !== undefined ? commits.page.next.page : null,
commits.page.prev !== undefined ? commits.page.prev.page : null
)
);
} catch (error) { } catch (error) {
//dispatch error //dispatch error
yield put(setCommitsError(error.toString())); yield put(setCommitsError(error.toString()));

View File

@ -1,23 +1,16 @@
import { takeEvery, call, put, select } from 'redux-saga/effects'; import { takeEvery, call, put, select } from 'redux-saga/effects';
import { PULLS } from '../constants'; import { PULLS } from '../constants';
import { fetchPulls } from '../api'; import { fetchPulls } from '../api';
import { setPulls, setPullsError, setPages } from '../actions'; import { setPulls, setPullsError } from '../actions';
const getNewPage = state => parseInt(state.isLoading.newPage, 10);
function* handlePullsLoad(action) { function* handlePullsLoad(action) {
try { try {
const newPage = yield select(getNewPage); let pulls = yield call(fetchPulls, action.state, action.newPage);
let pulls = yield call(fetchPulls, action.state, newPage); yield put(setPulls(pulls.pulls.body));
yield put(setPulls(pulls.pulls.body)); } catch (error) {
yield put( yield put(setPullsError(error.toString()));
setPages( }
pulls.page.next !== undefined ? pulls.page.next.page : null,
pulls.page.prev !== undefined ? pulls.page.prev.page : null
)
);
} catch (error) {
yield put(setPullsError(error.toString()));
}
} }
export default function* watchPullsLoad() { export default function* watchPullsLoad() {

View File

@ -9,7 +9,11 @@ function* handleTestmanLoad() {
const shas = pulls.map(pull => pull.merge_commit_sha); const shas = pulls.map(pull => pull.merge_commit_sha);
const testResults = yield call(fetchTests, shas[9], shas[0], 1); const testResults = yield call(fetchTests, shas[9], shas[0], 1);
const testByPulls = {}; const testByPulls = {};
console.log(shas)
for (let sha of shas) { for (let sha of shas) {
// some pulls don't have merge_commit_sha
if (!sha) continue
testByPulls[sha] = testResults.filter(test => testByPulls[sha] = testResults.filter(test =>
sha.startsWith(test.revision._text) sha.startsWith(test.revision._text)
); );