This report indicates whether keys in the 'en' localization file are present in
- your chosen localization. It will also list any keys in your chosen localization
+ your chosen localization. It will also list any keys in your chosen localization
which should be removed.
indicates a check passed.
+ name = { `check square` }
+ size = { `large` }
+ color = { `green` } />indicates a check passed.
indicates a check failed and action is needed.
+ name = { `window close` }
+ size = { `large` }
+ color = { `red` } />indicates a check failed and action is needed.
@@ -252,7 +270,7 @@ class LocalizationReport extends Component {
@@ -261,4 +279,8 @@ class LocalizationReport extends Component {
}
};
-export { LocalizationReport };
+export {
+ LocalizationReport,
+ ReportItem,
+ ReportList,
+};
diff --git a/src/containers/VisitPage.js b/src/containers/VisitPage.js
index 016ca1fd..a29ae3bb 100644
--- a/src/containers/VisitPage.js
+++ b/src/containers/VisitPage.js
@@ -9,6 +9,7 @@ import { Redirect } from 'react-router-dom';
import { setNestedProperty } from '../utils/setNestedProperty';
import { cloneDeep } from 'lodash';
import { convertForUpdate } from '../utils/convertForUpdate';
+import { addClientGetterProperty } from '../dev/command-line-utils';
// Data
// import { clientList } from '../config/dummyClients';
@@ -23,7 +24,7 @@ import { FeedbackPrompt } from '../components/prompts/FeedbackPrompt';
import { FeedbackForm } from '../components/prompts/FeedbackForm';
import { FeedbackAnytime } from '../components/prompts/FeedbackAnytime';
import { PredictionsWarning } from '../components/prompts/PredictionsWarning';
-import StepBar from '../components/StepBar';
+import { StepBar } from '../components/StepBar';
import { BigButton } from '../forms/inputs';
import { ButtonReset } from '../forms/ButtonReset';
import { STEP_VALS } from '../forms/STEP_VALS';
@@ -56,6 +57,15 @@ class VisitPage extends Component {
componentDidMount() {
this.didMount = true;
+
+ // Webpack should remove this whole conditional when not built for development environment
+ if (process.env.NODE_ENV === 'development') {
+ // Override property set in App.js, because that property
+ // doesn't get changed by updateClientValue()
+ addClientGetterProperty(() => {
+ return this.state.client;
+ });
+ }
}
resetClientIfOk = (shouldReset) => {
diff --git a/src/data/federal/2017/SNAPData.js b/src/data/federal/2017/SNAPData.js
index 4afbafee..14fc21e1 100644
--- a/src/data/federal/2017/SNAPData.js
+++ b/src/data/federal/2017/SNAPData.js
@@ -1,10 +1,19 @@
-/*
- * RESOURCES
- * Derived from https://www.masslegalservices.org/content/online-snap-calculator
- * http://www.mass.gov/eohhs/consumer/basic-needs/financial/program-eligibility-charts-and-tables.html
- * http://www.mass.gov/eohhs/gov/departments/dta/program-eligibility-charts-and-tables.html
+/** Data tables for MA SNAP calculations.
+ *
+ * RESOURCES:
+ * Derived from {@link https://www.masslegalservices.org/content/online-snap-calculator}
+ * {@link http://www.mass.gov/eohhs/consumer/basic-needs/financial/program-eligibility-charts-and-tables.html}
+ * {@link http://www.mass.gov/eohhs/gov/departments/dta/program-eligibility-charts-and-tables.html}
+ * Standard deductions: {@link http://www.mass.gov/eohhs/docs/dta/eligibility-charts/c-snap-364-400.pdf}
+ * Utility allowance categories: {@link http://www.mass.gov/eohhs/docs/dta/eligibility-charts/c-snap-364-945.pdf}
+ * Net income limits: {@link http://www.mass.gov/eohhs/docs/dta/eligibility-charts/c-snap-364-970.pdf}
+ * SNAP allowance maximums: {@link http://www.mass.gov/eohhs/docs/dta/eligibility-charts/c-snap-364-980-hh-1-10.pdf}
+ *
+ * @namespace
*/
const SNAPData = {
+ // Code-style note: Properties have to use quotes
+
// in monthly values, because that is what 106 CMR 364.400 leads to: http://www.mass.gov/eohhs/docs/dta/eligibility-charts/c-snap-364-400.pdf
STANDARD_DEDUCTIONS: { 0: 0, 1: 160, 2: 160, 3: 160, 4: 170, 5: 199, 6: 228, 'eachAdditional': 0 },
PERCENT_GROSS_MONTHLY_EARNED: 0.20,
@@ -25,5 +34,7 @@ const SNAPData = {
SMALL_HOUSEHOLD_SIZE: 2,
SMALL_HOUSEHOLD_MIN_GRANT: 15,
};
+// @todo: Make class for 'money amount by number of items'-type object
+
export { SNAPData };
diff --git a/src/data/federal/federalPovertyGuidelines.js b/src/data/federal/federalPovertyGuidelines.js
index 22ac39cf..05db39f0 100644
--- a/src/data/federal/federalPovertyGuidelines.js
+++ b/src/data/federal/federalPovertyGuidelines.js
@@ -1,6 +1,12 @@
+/** Data tables for Federal poverty guildelines/income limits.
+ *
+ * RESOURCES:
+ * {@link https://aspe.hhs.gov/poverty-guidelines}
+ * {@link http://www.mass.gov/eohhs/docs/masshealth/deskguides/fpl-deskguide.pdf}
+ *
+ * @namespace
+ */
const federalPovertyGuidelines = { 0: 0, 1: 12060, 2: 16240, 3: 20420, 4: 24600, 5: 28780, 6: 32960, 7: 37140, 8: 41320, 'eachAdditional': 4180 };
-export { federalPovertyGuidelines };
-//http://www.mass.gov/eohhs/docs/masshealth/deskguides/fpl-deskguide.pdf
-//https://aspe.hhs.gov/poverty-guidelines
+export { federalPovertyGuidelines };
diff --git a/src/data/massachusetts/name-cores.js b/src/data/massachusetts/name-cores.js
index 1ecd8014..d27674b1 100644
--- a/src/data/massachusetts/name-cores.js
+++ b/src/data/massachusetts/name-cores.js
@@ -1,36 +1,44 @@
-/** Arrays of names which can act as a base off of which
-* to build client property keys
+/** Collections of names that fall under common MA categories.
+* Right now they're meant to be used to make sums of
+* client property values. This has been useful when
+* property names have changed.
+* @module
*
-* @example var gross = client[ timeframe + base + 'Monthly' ];
+* @example
+* import { sumProps } from './someUtilityFolder';
+* let client = { disabledMedical: 1, otherMedical: 10, disabledAssistance: 100 };
+* var allMedicalExpenses = sumProps(ALL_MEDICAL_EXPENSES);
+* console.log(allMedicalExpenses);
+* // 111
*/
const UNEARNED_INCOME_SOURCES = [
- 'TAFDC',
- 'SSI',
- 'SSDI',
- 'childSupportIn',
- 'unemployment',
- 'workersComp',
- 'pension',
- 'socialSecurity',
- 'alimony',
- 'otherIncome',
+ `TAFDC`,
+ `SSI`,
+ `SSDI`,
+ `childSupportIn`,
+ `unemployment`,
+ `workersComp`,
+ `pension`,
+ `socialSecurity`,
+ `alimony`,
+ `otherIncome`,
];
const UNDER13_CARE_EXPENSES = [
- 'childDirectCare',
- 'childBeforeAndAfterSchoolCare',
- 'childTransportation',
- 'childOtherCare',
+ `childDirectCare`,
+ `childBeforeAndAfterSchoolCare`,
+ `childTransportation`,
+ `childOtherCare`,
];
const OVER12_CARE_EXPENSES = [
- 'adultDirectCare',
- 'adultTransportation',
- 'adultOtherCare',
+ `adultDirectCare`,
+ `adultTransportation`,
+ `adultOtherCare`,
];
-/** @todo Convert all to this later, but will have
+/* @todo Convert all to this later, but will have
* to generate new SNAP test cases because the
* strings they check against have the array
* elements in a different order.
@@ -40,14 +48,14 @@ const UNDER13_NON_TRANSPORT_CARE = [
`childBeforeAndAfterSchoolCare`,
`childOtherCare`,
];
-const UNDER13_TRANSPORT = [ `childTransportation` ];
+const UNDER13_TRANSPORT = [ `childTransportation` ];
// const UNDER13_CARE_EXPENSES = UNDER13_NON_TRANSPORT_CARE.concat(UNDER13_TRANSPORT);
const OVER12_NON_TRANSPORT_CARE = [
`adultDirectCare`,
`adultOtherCare`,
];
-const OVER12_TRANSPORT = [ `adultTransportation` ];
+const OVER12_TRANSPORT = [ `adultTransportation` ];
// const OVER12_CARE_EXPENSES = OVER12_NON_TRANSPORT_CARE.concat(OVER12_TRANSPORT);
const NON_TRANSPORT_DEPENDENT_COSTS = UNDER13_NON_TRANSPORT_CARE.concat(OVER12_NON_TRANSPORT_CARE);
diff --git a/src/dev/command-line-utils.js b/src/dev/command-line-utils.js
new file mode 100644
index 00000000..a5f4565c
--- /dev/null
+++ b/src/dev/command-line-utils.js
@@ -0,0 +1,43 @@
+import cloneDeep from 'lodash/cloneDeep';
+
+export const printSummaryToConsole = () => {
+ console.log(
+ `
+%c========================= Cliff Effects Dev Utilities =========================
+
+- enableDev() - Enable the Dev HUD (without needing to go to /dev)
+
+- clientClone - A deep clone of the current value of the loaded client
+
+===============================================================================`,
+ 'color: blue',
+ );
+};
+
+export const addEnableDevProperty = (devSetter) => {
+ Object.defineProperties(
+ window,
+ {
+ enableDev: {
+ enumerable: true,
+ configurable: true,
+ value: devSetter,
+ },
+ }
+ );
+};
+
+export const addClientGetterProperty = (clientGetter) => {
+ Object.defineProperties(
+ window,
+ {
+ clientClone: {
+ enumerable: true,
+ configurable: true,
+ get: () => {
+ return cloneDeep(clientGetter());
+ },
+ },
+ }
+ );
+};
diff --git a/src/forms/output/BenefitsLineGraph.js b/src/forms/output/BenefitsLineGraph.js
deleted file mode 100644
index daa0bb33..00000000
--- a/src/forms/output/BenefitsLineGraph.js
+++ /dev/null
@@ -1,124 +0,0 @@
-import React, { Component } from 'react';
-import _ from 'lodash';
-import { Line } from 'react-chartjs-2';
-import { Message } from 'semantic-ui-react';
-
-// CUSTOM ELEMENTS
-import { VerticalLine } from './VerticalLine';
-
-// LOGIC
-import { timescaleMultipliers } from '../../utils/convert-by-timescale';
-import {
- formatAxis,
- formatLabel,
- formatBenefitLinesTitle,
-} from '../../utils/charts/chartFormatting';
-import { getChartData } from '../../utils/charts/getChartData';
-
-// DATA
-// In future, graphs will control their own aspect ratio,
-// zoom levels, etc., so for now they'll have access to
-// the limit values.
-import { PROGRAM_CHART_VALUES } from '../../utils/charts/PROGRAM_CHART_VALUES';
-
-
-// Graphs get things in monthly values, so we'll convert from there
-let multipliers = timescaleMultipliers.fromMonthly,
- // Each graph controls its own scaling
- limits = PROGRAM_CHART_VALUES.limits;
-
-
-class BenefitsLineGraph extends Component {
-
- constructor (props) {
- super(props);
- this.state = { verticalLine: new VerticalLine() };
- }
-
- render () {
- const { client, timescale, activePrograms, className } = this.props;
- const multiplier = multipliers[ timescale ];
-
- if (activePrograms.length === 0) {
- return No public benefit programs have been selected;
- }
-
- // Adjust to time-interval, round to hundreds
- let max = Math.ceil((limits.max * multiplier) / 100) * 100,
- interval = Math.ceil((max / 100) / 10) * 10;
-
- let extraProps = {};
-
- for (let benefitIndex = 0; benefitIndex < activePrograms.length; benefitIndex++) {
- extraProps[ activePrograms[ benefitIndex ] ] = { fill: false };
- }
-
- const xRange = _.range(limits.min, max, interval), // x-axis/earned income numbers
- datasets = getChartData(xRange, multiplier, client, activePrograms, extraProps);
-
- // If there's no data to show, don't show the table
- if (datasets.length === 0) {
- return null;
- }
-
- // react-chartjs-2 keeps references to plugins, so we
- // have to mutate that reference
- const earned = client.future.earned * multiplier,
- hack = this.state.verticalLine;
- hack.xRange = xRange;
- hack.earned = earned;
-
- let lineProps = {
- data: {
- labels: xRange,
- datasets: datasets,
- }, // end `data`
- options: {
- title: {
- display: true,
- text: 'Individual Benefit Amounts for Household as Pay Changes',
- },
- showLines: true,
- scales: {
- yAxes: [
- {
- scaleLabel: {
- display: true,
- labelString: 'Benefit Value ($)',
- },
- ticks: {
- beginAtZero: true,
- /* chart.js v2.7 requires a callback function */
- callback: formatAxis,
- },
- },
- ], // end `yAxes`
- xAxes: [
- {
- scaleLabel: {
- display: true,
- labelString: timescale + ' Pay ($)',
- },
- ticks: { callback: formatAxis },
- },
- ], // end `xAxes`
- }, // end `scales`
- tooltips: {
- callbacks: {
- title: formatBenefitLinesTitle,
- label: formatLabel,
- },
- }, // end `tooltips`
- }, // end `options`
- plugins: [ this.state.verticalLine ],
- }; // end lineProps
-
- return (
-
- );
- }
-
-}; // End
-
-
-export { BenefitsLineGraph };
diff --git a/src/forms/output/BenefitsLines.js b/src/forms/output/BenefitsLines.js
index 68f654d4..3333348d 100644
--- a/src/forms/output/BenefitsLines.js
+++ b/src/forms/output/BenefitsLines.js
@@ -81,21 +81,21 @@ class BenefitsLinesComp extends Component {
classes += ` ` + className;
}
- const multiplier = multipliers[ timescale ],
- resources = activePrograms,
- currentEarned = client.current.earned * multiplier,
- getText = textFromTranslatedElement;
+ let multiplier = multipliers[ timescale ],
+ resources = activePrograms,
+ currentEarned = client.current.earned * multiplier,
+ getText = textFromTranslatedElement;
// Adjust to time-interval. Highcharts will round
// for displayed ticks.
- const max = (limits.max * multiplier),
- interval = ((max / 100) / 10);
+ let max = (limits.max * multiplier),
+ interval = ((max / 100) / 10);
- const xRange = range(limits.min, max, interval), // x-axis/earned income numbers
- datasets = getChartData(xRange, multiplier, client, resources, {});
+ let xRange = range(limits.min, max, interval), // x-axis/earned income numbers
+ datasets = getChartData(xRange, multiplier, client, resources, {});
// Individual benefit lines
- const lines = [];
+ let lines = [];
for (let dataset of datasets) {
let line = (
${getText(translations.i_beforeMoney)}`,
- labelHeaderFormatEnd = `{point.key:,.2f}${getText(translations.i_afterMoney)} `,
- labelHeaderFormat = labelHeaderFormatStart + labelHeaderFormatEnd;
+ let labelHeaderFormatStart = `${getText(translations.i_beforeMoney)}`,
+ labelHeaderFormatEnd = `{point.key:,.2f}${getText(translations.i_afterMoney)} `,
+ labelHeaderFormat = labelHeaderFormatStart + labelHeaderFormatEnd;
- const plotOptions = { line: { pointInterval: interval }};
+ let plotOptions = { line: { pointInterval: interval }};
return (