Skip to content

Commit

Permalink
Refactor IRS monitor page container as #806
Browse files Browse the repository at this point in the history
  • Loading branch information
peterMuriuki committed Apr 24, 2020
1 parent 695ddc5 commit 871af57
Show file tree
Hide file tree
Showing 4 changed files with 130 additions and 34 deletions.
53 changes: 53 additions & 0 deletions src/containers/pages/IRS/plans/hooks.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import { SupersetFormData } from '@onaio/superset-connector/dist/types';
import React, { useEffect, useState } from 'react';
import { ActionCreator } from 'redux';
import { SUPERSET_IRS_REPORTING_PLANS_SLICE } from '../../../../configs/env';
import { displayError } from '../../../../helpers/errors';
import supersetFetch from '../../../../services/superset';

interface AsyncSupersetPlans<TData, TAction> {
superset: typeof supersetFetch;
data: TData[];
fetchPlans: ActionCreator<TAction>;
supersetSlice: string;
supersetOptions: SupersetFormData | null;
}

export const useAsyncSupersetPlans = <TData, TAction>({
superset = supersetFetch,
data = [],
fetchPlans,
supersetSlice = SUPERSET_IRS_REPORTING_PLANS_SLICE,
supersetOptions = null,
}: AsyncSupersetPlans<TData, TAction>) => {
const [loading, setLoading] = useState<boolean>(false);
const mounted = React.useRef<boolean>(false);

/** async function to load the data */
async function loadData() {
try {
setLoading(data.length === 0); // only set loading when there are no plans
const asyncOperation = supersetOptions
? superset(supersetSlice, supersetOptions)
: superset(supersetSlice);

await asyncOperation.then((result: TData[]) => fetchPlans(result));
} catch (e) {
throw e;
} finally {
if (mounted) {
setLoading(false);
}
}
}

useEffect(() => {
mounted.current = true;
loadData().catch(error => displayError(error));
return () => {
mounted.current = false;
};
}, []);

return loading;
};
51 changes: 22 additions & 29 deletions src/containers/pages/IRS/plans/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import ListView from '@onaio/list-view';
import reducerRegistry from '@onaio/redux-reducer-registry';
import React, { useEffect, useState } from 'react';
import React from 'react';
import { Helmet } from 'react-helmet';
import { connect } from 'react-redux';
import { Link } from 'react-router-dom';
Expand All @@ -14,20 +14,21 @@ import {
END_DATE,
HOME,
IRS_PLANS,
NO_PLANS_LOADED_MESSAGE,
START_DATE,
STATUS_HEADER,
TITLE,
} from '../../../../configs/lang';
import { planStatusDisplay } from '../../../../configs/settings';
import { HOME_URL, REPORT_IRS_PLAN_URL } from '../../../../constants';
import { displayError } from '../../../../helpers/errors';
import supersetFetch from '../../../../services/superset';
import IRSPlansReducer, {
fetchIRSPlans,
getIRSPlansArray,
IRSPlan,
reducerName as IRSPlansReducerName,
} from '../../../../store/ducks/generic/plans';
import { useAsyncSupersetPlans } from './hooks';

/** register the plan definitions reducer */
reducerRegistry.register(IRSPlansReducerName, IRSPlansReducer);
Expand All @@ -42,7 +43,7 @@ interface PlanListProps {
/** Simple component that loads the new plan form and allows you to create a new plan */
const IRSPlansList = (props: PlanListProps) => {
const { fetchPlans, plans, service } = props;
const [loading, setLoading] = useState<boolean>(true);
// const [loading, setLoading] = useState<boolean>(true);

const pageTitle: string = IRS_PLANS;

Expand All @@ -59,27 +60,15 @@ const IRSPlansList = (props: PlanListProps) => {
],
};

/** async function to load the data */
async function loadData() {
try {
setLoading(plans.length < 1); // only set loading when there are no plans
await service(SUPERSET_IRS_REPORTING_PLANS_SLICE).then((result: IRSPlan[]) =>
fetchPlans(result)
);
} catch (e) {
// do something with the error?
} finally {
setLoading(false);
}
}

useEffect(() => {
loadData().catch(error => displayError(error));
}, []);

if (loading === true) {
return <Loading />;
}
const asyncSupersetOptions = {
data: plans,
fetchPlans,
superset: service,
supersetOptions: null,
supersetSlice: SUPERSET_IRS_REPORTING_PLANS_SLICE,
};

const loading = useAsyncSupersetPlans(asyncSupersetOptions);

const listViewProps = {
data: plans.map(planObj => {
Expand Down Expand Up @@ -108,11 +97,15 @@ const IRSPlansList = (props: PlanListProps) => {
<h3 className="mt-3 mb-3 page-title">{pageTitle}</h3>
</Col>
</Row>
<Row>
<Col>
<ListView {...listViewProps} />
</Col>
</Row>
{loading ? (
<Loading />
) : (
<Row>
<Col>
{plans.length > 0 ? <ListView {...listViewProps} /> : <p>{NO_PLANS_LOADED_MESSAGE}</p>}
</Col>
</Row>
)}
</div>
);
};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`components/IRS Reports/IRSPlansList Does not show loader when store has data: First table rows 1`] = `"IRS 2019-09-05 TEST"`;

exports[`components/IRS Reports/IRSPlansList Works with store: First table row 1`] = `"IRS 2019-09-05 TEST"`;

exports[`components/IRS Reports/IRSPlansList renders plan definition list correctly: breadcrumbs 1`] = `
Array [
<li
Expand Down
56 changes: 51 additions & 5 deletions src/containers/pages/IRS/plans/tests/index.test.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@
import reducerRegistry from '@onaio/redux-reducer-registry';
import { mount, shallow } from 'enzyme';
import toJson from 'enzyme-to-json';
import { createBrowserHistory } from 'history';
import React from 'react';
import { Provider } from 'react-redux';
import { Router } from 'react-router';
import { IRSPlansList } from '../';
import { IRSPlan } from '../../../../../store/ducks/generic/plans';
import ConnectedIRSPlansList, { IRSPlansList } from '../';
import store from '../../../../../store';
import { fetchIRSPlans, IRSPlan } from '../../../../../store/ducks/generic/plans';
import IRSPlansReducer, {
reducerName as IRSPlansReducerName,
} from '../../../../../store/ducks/generic/plans';
import * as fixtures from '../../../../../store/ducks/generic/tests/fixtures';

/* tslint:disable-next-line no-var-requires */
const fetch = require('jest-fetch-mock');
reducerRegistry.register(IRSPlansReducerName, IRSPlansReducer);

const history = createBrowserHistory();

Expand All @@ -29,7 +34,6 @@ describe('components/IRS Reports/IRSPlansList', () => {
});

it('renders plan definition list correctly', () => {
fetch.mockResponseOnce(JSON.stringify({}));
const props = {
plans: fixtures.plans as IRSPlan[],
};
Expand All @@ -44,4 +48,46 @@ describe('components/IRS Reports/IRSPlansList', () => {
expect(toJson(wrapper.find('tbody tr td'))).toMatchSnapshot('table rows');
wrapper.unmount();
});

it('Works with store', async () => {
const supersetMock: any = jest.fn(async () => fixtures.plans);
const wrapper = mount(
<Provider store={store}>
<Router history={history}>
<ConnectedIRSPlansList service={supersetMock} />
</Router>
</Provider>
);
expect(wrapper.find('Ripple').length).toEqual(1);

await new Promise(resolve => setImmediate(resolve));
wrapper.update();
expect(
wrapper
.find('tbody tr td')
.at(0)
.text()
).toMatchSnapshot('First table row');
wrapper.unmount();
});

it('Does not show loader when store has data', async () => {
store.dispatch(fetchIRSPlans(fixtures.plans as IRSPlan[]));
const supersetMock: any = jest.fn(async () => fixtures.plans);
const wrapper = mount(
<Provider store={store}>
<Router history={history}>
<ConnectedIRSPlansList service={supersetMock} />
</Router>
</Provider>
);
expect(wrapper.find('Ripple').length).toEqual(0);
expect(
wrapper
.find('tbody tr td')
.at(0)
.text()
).toMatchSnapshot('First table rows');
wrapper.unmount();
});
});

0 comments on commit 871af57

Please sign in to comment.