Skip to content

Commit

Permalink
Revert and cherry pick
Browse files Browse the repository at this point in the history
  • Loading branch information
kryswisnaskas committed Jun 25, 2021
1 parent b64ae0a commit abb0b2b
Show file tree
Hide file tree
Showing 13 changed files with 156 additions and 41 deletions.
2 changes: 1 addition & 1 deletion .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ parameters:
default: "main"
type: string
sandbox_git_branch: # change to feature branch to test deployment
default: "kw-overview-widget"
default: "kw-test"
type: string
prod_new_relic_app_id:
default: "877570491"
Expand Down
12 changes: 10 additions & 2 deletions frontend/src/pages/Landing/RegionalSelect.js
Original file line number Diff line number Diff line change
Expand Up @@ -115,11 +115,19 @@ function RegionalSelect(props) {
};

CustomOption.propTypes = {
data: PropTypes.object.isRequired,
innerRef: PropTypes.string.isRequired,
data: PropTypes.shape({
value: PropTypes.number,
label: PropTypes.string,
}),
innerRef: PropTypes.func,
innerProps: PropTypes.object.isRequired,
};

CustomOption.defaultProps = {
data: {},
innerRef: () => 0,
};

const options = [...getUserOptions(regions), { custom: true }];
return (
<Select
Expand Down
3 changes: 1 addition & 2 deletions frontend/src/pages/Landing/mocks.js
Original file line number Diff line number Diff line change
Expand Up @@ -302,10 +302,9 @@ export const generateXFakeReports = (count) => {
export const overviewRegionOne = {
numReports: '1',
numGrants: '2',
numNonGrantees: '2',
numTotalGrants: '4',
numParticipants: '3',
sumTrainingDuration: '5.0',
sumTaDuration: '1.0',
sumDuration: '0.5',
};

Expand Down
2 changes: 1 addition & 1 deletion frontend/src/setupTests.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,4 @@ import MutationObserver from '@sheerun/mutationobserver-shim';

window.MutationObserver = MutationObserver;

jest.setTimeout(10000);
jest.setTimeout(30000);
3 changes: 1 addition & 2 deletions frontend/src/widgets/Overview.css
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,7 @@
}

.smart-hub--overview-data {
margin-left: -20px;
margin-bottom: -20px;
margin-left: -36px !important;
}

.smart-hub--overview-nowrap {
Expand Down
26 changes: 14 additions & 12 deletions frontend/src/widgets/Overview.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,17 @@ function Field({
Field.propTypes = {
label: PropTypes.string.isRequired,
labelExt: PropTypes.string,
data: PropTypes.string.isRequired,
col: PropTypes.number,
data: PropTypes.string,
col: PropTypes.oneOfType([
PropTypes.string,
PropTypes.number,
]),
};

Field.defaultProps = {
labelExt: '',
col: 2,
data: '',
};

/*
Expand All @@ -49,15 +53,14 @@ function Overview({ data, region }) {
{' '}
TTA Overview
</h2>
<span className="smart-hub--overview-period"> 3/17/21 to Today</span>
<span className="smart-hub--overview-period"> 9/15/2020 to Today</span>
</Grid>
<Grid row className="smart-hub--overview-data">
<Field label="Grants served " labelExt={`(of ${data.numTotalGrants})`} data={data.numGrants} />
<Field label="Activity reports" data={data.numReports} />
<Field label="Participants" data={data.numParticipants} />
<Field label="Hours of Training" data={data.sumTrainingDuration} />
<Field label="Hours of TA" data={data.sumTaDuration} />
<Field label="Hours of TTA" data={data.sumDuration} />
<Grid row gap className="smart-hub--overview-data">
<Field col="fill" tablet={{ col: true }} label="Grants served " labelExt={`(of ${data.numTotalGrants})`} data={data.numGrants} />
<Field col="fill" label="Non-grantees served" data={data.numNonGrantees} />
<Field col="fill" label="Activity reports" data={data.numReports} />
<Field col="fill" label="Participants" data={data.numParticipants} />
<Field col={2} label="Hours of TTA" data={data.sumDuration} />
</Grid>
</Container>
);
Expand All @@ -67,10 +70,9 @@ Overview.propTypes = {
data: PropTypes.shape({
numReports: PropTypes.string,
numGrants: PropTypes.string,
numNonGrantees: PropTypes.string,
numTotalGrants: PropTypes.string,
numParticipants: PropTypes.string,
sumTrainingDuration: PropTypes.string,
sumTaDuration: PropTypes.string,
sumDuration: PropTypes.string,
}).isRequired,
region: PropTypes.number.isRequired,
Expand Down
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,9 @@
"import:hses:local": "./node_modules/.bin/babel-node ./src/tools/importGrantGranteesCLI.js --skipdownload",
"import:hses": "node ./build/server/tools/importGrantGranteesCLI.js",
"reconcile:legacy": "node ./build/server/tools/reconcileLegacyReports.js",
"reconcile:legacy:local": "./node_modules/.bin/babel-node ./src/tools/reconcileLegacyReports.js"
"reconcile:legacy:local": "./node_modules/.bin/babel-node ./src/tools/reconcileLegacyReports.js",
"populateLegacyNonGrantees": "node ./build/server/tools/populateLegacyNonGranteesCLI.js",
"populateLegacyNonGrantees:local": "./node_modules/.bin/babel-node ./src/tools/populateLegacyNonGranteesCLI.js"
},
"repository": {
"type": "git",
Expand Down
2 changes: 1 addition & 1 deletion src/routes/widgets/handlers.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ describe('Widget handlers', () => {
query: { 'region.in': ['1'] },
};
const response = {
numGrants: '0', numParticipants: '0', numReports: '0', numTotalGrants: '2', sumDuration: '0', sumTaDuration: '0', sumTrainingDuration: '0',
numGrants: '0', numNonGrantees: '0', numParticipants: '0', numReports: '0', numTotalGrants: '2', sumDuration: '0',
};

beforeEach(() => {
Expand Down
3 changes: 3 additions & 0 deletions src/services/users.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ export async function userById(userId) {
include: [
{ model: Permission, as: 'permissions', attributes: ['userId', 'scopeId', 'regionId'] },
],
order: [
[{ model: Permission, as: 'permissions' }, 'regionId', 'ASC'],
],
});
}

Expand Down
57 changes: 57 additions & 0 deletions src/tools/populateLegacyNonGrantees.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/* eslint-disable no-restricted-syntax */
/* eslint-disable no-loop-func */
import { Op } from 'sequelize';
import { auditLogger } from '../logger';
import { ActivityReport, ActivityRecipient, NonGrantee } from '../models';

const hubNonGrantees = {
HSCO: 'Head Start Collaboration Office',
'Local/State Education System': 'State Education System',
'State Early Learning System / Guidelines': 'State Early Learning Standards',
'State Advisory Council': 'QRIS System',
'Regional TTA Team / Specialists': 'Regional TTA/Other Specialists',
'State Early Learning Standards / Guidelines':
'State Early Learning Standards',
};

const populateLegacyNonGrantees = async () => {
const nonGranteeReports = await ActivityReport.findAll({
where: {
[Op.and]: [
{ legacyId: { [Op.ne]: null } },
{
imported: {
nonGranteeActivity: {
[Op.ne]: '',
},
},
},
],
},
});

for await (const nonGranteeReport of nonGranteeReports) {
const nonGranteeArray = nonGranteeReport.imported.nonGranteeActivity.split(
'\n',
);
for await (const nonGranteeName of nonGranteeArray) {
const translatedNonGranteeName = hubNonGrantees[nonGranteeName] || nonGranteeName;
const nonGrantee = await NonGrantee.findOne({
where: { name: translatedNonGranteeName },
});
if (nonGrantee) {
auditLogger.info(
`Processing non-grantee ${nonGrantee.id} for activity report ${nonGranteeReport.id}`,
);
await ActivityRecipient.findOrCreate({
where: {
activityReportId: nonGranteeReport.id,
nonGranteeId: nonGrantee.id,
},
});
}
}
}
};

export default populateLegacyNonGrantees;
7 changes: 7 additions & 0 deletions src/tools/populateLegacyNonGranteesCLI.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import populateLegacyNonGrantees from './populateLegacyNonGrantees';
import { auditLogger } from '../logger';

populateLegacyNonGrantees().catch((e) => {
auditLogger.error(e);
process.exit(1);
});
65 changes: 52 additions & 13 deletions src/widgets/overview.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Op } from 'sequelize';
import {
ActivityReport, ActivityRecipient, Grant, NonGrantee, sequelize,
} from '../models';
import { REPORT_STATUSES } from '../constants';
/*
Widgets on the backend should only have to worry about fetching data in the format required
by the widget. In this case we return a single object but other widgets my require an array
Expand All @@ -12,25 +13,63 @@ import {
If adding a new widget be sure to add the widget to ./index.js
*/
export default async function overview(scopes, region) {
const grantsWhere = `WHERE "status" = 'Active' AND "regionId" in (${region})`;
const trainingWhere = '"ttaType" = \'{"training"}\'';
const taWhere = '"ttaType" = \'{"technical-assistance"}\'';
const ttaWhere = '"ttaType" = \'{"training", "technical-assistance"}\'';
const baseWhere = `WHERE "regionId" IN (${region}) AND "legacyId" IS NULL AND "status" != 'deleted'`;
const grantsWhere = `WHERE "regionId" in (${region})`;
const baseWhere = `${grantsWhere} AND "status" = '${REPORT_STATUSES.APPROVED}'`;
// There could be a better way, but using sequelize.literal was the only way I could get correct
// numbers for SUM
// FIXME: see if there is a better way to get totals using SUM
const res = await ActivityReport.findAll({
attributes: [
[sequelize.fn('COUNT', sequelize.fn('DISTINCT', sequelize.col('"ActivityReport".id'))), 'numReports'],
[sequelize.fn('COUNT', sequelize.fn('DISTINCT', sequelize.col('"activityRecipients->grant"."id"'))), 'numGrants'],
[sequelize.literal(`(SELECT COUNT(*) from "Grants" ${grantsWhere})`), 'numTotalGrants'],
[sequelize.literal(`(SELECT COALESCE(SUM("numberOfParticipants"), 0) FROM "ActivityReports" ${baseWhere})`), 'numParticipants'],
[sequelize.literal(`(SELECT COALESCE(SUM(duration), 0) FROM "ActivityReports" ${baseWhere} AND ${trainingWhere})`), 'sumTrainingDuration'],
[sequelize.literal(`(SELECT COALESCE(SUM(duration), 0) FROM "ActivityReports" ${baseWhere} AND ${taWhere})`), 'sumTaDuration'],
[sequelize.literal(`(SELECT COALESCE(SUM(duration), 0) FROM "ActivityReports" ${baseWhere} AND ${ttaWhere})`), 'sumDuration'],
[
sequelize.fn(
'COUNT',
sequelize.fn('DISTINCT', sequelize.col('"ActivityReport".id')),
),
'numReports',
],
[
sequelize.fn(
'COUNT',
sequelize.fn(
'DISTINCT',
sequelize.col('"activityRecipients->grant"."id"'),
),
),
'numGrants',
],
[
sequelize.literal(`(SELECT COUNT(*) from "Grants" ${grantsWhere})`),
'numTotalGrants',
],
[
sequelize.fn(
'COUNT',
sequelize.fn(
'DISTINCT',
sequelize.col('"activityRecipients"."nonGranteeId"'),
),
),
'numNonGrantees',
],
[
sequelize.literal(
`(SELECT COALESCE(SUM("numberOfParticipants"), 0) FROM "ActivityReports" ${baseWhere})`,
),
'numParticipants',
],
[
sequelize.literal(
`(SELECT COALESCE(SUM(duration), 0) FROM "ActivityReports" ${baseWhere})`,
),
'sumDuration',
],
],
where: { [Op.and]: [scopes, { legacyId: null }] },
where: {
[Op.and]: [
scopes,
{ status: REPORT_STATUSES.APPROVED },
],
},
raw: true,
// without 'includeIgnoreAttributes' the attributes from the join table
// "activityReportObjectives" are included which causes postgres to error when
Expand Down
11 changes: 5 additions & 6 deletions src/widgets/overview.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -120,21 +120,20 @@ describe('Overview widget', () => {
await createOrUpdate({ ...regionTwoReport, duration: 1.5 }, reportOneR2);

const scopes = filtersToScopes({ 'region.in': ['17'] });
const data = await overview(scopes, 17);
const {
numReports,
numGrants,
numTotalGrants,
numNonGrantees,
numParticipants,
sumTrainingDuration,
sumTaDuration,
sumDuration,
} = await overview(scopes, 17);
} = data;
expect(numReports).toBe('4');
expect(numGrants).toBe('2');
expect(numTotalGrants).toBe('2');
expect(numNonGrantees).toBe('0');
expect(numParticipants).toBe('44');
expect(sumTrainingDuration).toBe('4.0');
expect(sumTaDuration).toBe('3.0');
expect(sumDuration).toBe('5.0');
expect(sumDuration).toBe('12.0');
});
});

0 comments on commit abb0b2b

Please sign in to comment.