Update side panel to 3-state design (#1276)

* Update field name to follow constant standard

* Add table to ETL commands to README

* Update Generate Map Tiles run time

* Add a comma to copy

* Add 3 state UI experience

- PR will only show workforce dev
- IA will only show workforce dev w/o linguistic iso
- update tests to tests 3 states
- change state to territory for Island Areas

* Modify PR and IA threshold counts

* Update tile_data_expected.pkl file
This commit is contained in:
Vim 2022-02-16 17:24:35 -05:00 committed by GitHub
commit f90125d1b4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 634 additions and 48 deletions

View file

@ -48,13 +48,101 @@ const AreaDetail = ({properties}:IAreaDetailProps) => {
const population = properties[constants.TOTAL_POPULATION] ? properties[constants.TOTAL_POPULATION] : "N/A";
const countyName = properties[constants.COUNTY_NAME] ? properties[constants.COUNTY_NAME] : "N/A";
const stateName = properties[constants.STATE_NAME] ? properties[constants.STATE_NAME] : "N/A";
const sidePanelState = properties[constants.SIDE_PANEL_STATE];
const isCommunityFocus = score >= constants.SCORE_BOUNDARY_THRESHOLD;
const feedbackEmailSubject = `Census tract ID ${blockGroup}, ${countyName}, ${stateName}`;
const feedbackEmailBody = intl.formatMessage(EXPLORE_COPY.SEND_FEEDBACK.EMAIL_BODY);
/**
* The workforce development category has some indicators who's source will vary depending on which
* territory is selected. This function allows us to change the source of workforce development indicators
* depending on which territory was selected
*/
const getWorkForceIndicatorValue = (indicatorName:string) => {
if (sidePanelState === constants.SIDE_PANEL_STATE_VALUES.ISLAND_AREAS) {
if (indicatorName === 'lowMedInc') {
return properties[constants.ISLAND_AREAS_LOW_MEDIAN_INCOME_LOW_HS_EDU_PERCENTILE_FIELD] ?
properties[constants.ISLAND_AREAS_LOW_MEDIAN_INCOME_LOW_HS_EDU_PERCENTILE_FIELD] : null;
}
if (indicatorName === 'unemploy') {
return properties[constants.ISLAND_AREAS_UNEMPLOYMENT_LOW_HS_EDU_PERCENTILE_FIELD] ?
properties[constants.ISLAND_AREAS_UNEMPLOYMENT_LOW_HS_EDU_PERCENTILE_FIELD] : null;
}
if (indicatorName === 'poverty') {
return properties[constants.ISLAND_AREAS_POVERTY_LOW_HS_EDU_PERCENTILE_FIELD] ?
properties[constants.ISLAND_AREAS_POVERTY_LOW_HS_EDU_PERCENTILE_FIELD] : null;
}
if (indicatorName === 'highSchool') {
return properties[constants.ISLAND_AREAS_HS_EDU_PERCENTAGE_FIELD] ?
properties[constants.ISLAND_AREAS_HS_EDU_PERCENTAGE_FIELD] : null;
}
}
if (indicatorName === 'lowMedInc') {
return properties[constants.LOW_MEDIAN_INCOME_PERCENTILE] ?
properties[constants.LOW_MEDIAN_INCOME_PERCENTILE] : null;
}
if (indicatorName === 'unemploy') {
return properties[constants.UNEMPLOYMENT_PROPERTY_PERCENTILE] ?
properties[constants.UNEMPLOYMENT_PROPERTY_PERCENTILE] : null;
}
if (indicatorName === 'poverty') {
return properties[constants.POVERTY_PROPERTY_PERCENTILE] ?
properties[constants.POVERTY_PROPERTY_PERCENTILE] : null;
}
if (indicatorName === 'highSchool') {
return properties[constants.HIGH_SCHOOL_PROPERTY_PERCENTILE] ?
properties[constants.HIGH_SCHOOL_PROPERTY_PERCENTILE] : null;
}
};
/**
* The workforce development category has some indicators who's disadvantaged boolean
* will vary depending on which territory is selected. This function allows us to change
* the boolean of workforce development indicators depending on which territory was selected
*/
const getWorkForceIndicatorIsDisadv = (indicatorName:string) => {
if (sidePanelState === constants.SIDE_PANEL_STATE_VALUES.ISLAND_AREAS) {
if (indicatorName === 'lowMedInc') {
return properties[constants.IS_GTE_90_ISLAND_AREA_LOW_MEDIAN_INCOME_AND_IS_LOW_HS_EDU_2009] ?
properties[constants.IS_GTE_90_ISLAND_AREA_LOW_MEDIAN_INCOME_AND_IS_LOW_HS_EDU_2009] : null;
}
if (indicatorName === 'unemploy') {
return properties[constants.IS_GTE_90_ISLAND_AREA_UNEMPLOYMENT_AND_IS_LOW_HS_EDU_2009] ?
properties[constants.IS_GTE_90_ISLAND_AREA_UNEMPLOYMENT_AND_IS_LOW_HS_EDU_2009] : null;
}
if (indicatorName === 'poverty') {
return properties[constants.IS_GTE_90_ISLAND_AREA_BELOW_100_POVERTY_AND_IS_LOW_HS_EDU_2009] ?
properties[constants.IS_GTE_90_ISLAND_AREA_BELOW_100_POVERTY_AND_IS_LOW_HS_EDU_2009] : null;
}
if (indicatorName === 'highSchool') {
return properties[constants.ISLAND_AREA_LOW_HS_EDU] ?
properties[constants.ISLAND_AREA_LOW_HS_EDU] : null;
}
}
if (indicatorName === 'lowMedInc') {
return properties[constants.IS_GTE_90_LOW_MEDIAN_INCOME_AND_LOW_HIGH_SCHOOL_EDU] ?
properties[constants.IS_GTE_90_LOW_MEDIAN_INCOME_AND_LOW_HIGH_SCHOOL_EDU] : null;
}
if (indicatorName === 'unemploy') {
return properties[constants.IS_GTE_90_UNEMPLOYMENT_AND_LOW_HIGH_SCHOOL_EDU] ?
properties[constants.IS_GTE_90_UNEMPLOYMENT_AND_LOW_HIGH_SCHOOL_EDU] : null;
}
if (indicatorName === 'poverty') {
return properties[constants.IS_GTE_90_BELOW_100_POVERTY_AND_LOW_HIGH_SCHOOL_EDU] ?
properties[constants.IS_GTE_90_BELOW_100_POVERTY_AND_LOW_HIGH_SCHOOL_EDU] : null;
}
if (indicatorName === 'highSchool') {
return properties[constants.IS_LOW_HS_EDUCATION_LOW_HIGHER_ED_PRIORITIZED] &&
properties[constants.IS_LOW_HS_EDUCATION_LOW_HIGHER_ED_PRIORITIZED] == 1 ?
true : false;
}
};
// Define each indicator in the side panel with constants from copy file (for intl)
// Indicators are grouped by category
const expAgLoss:indicatorInfo = {
@ -218,10 +306,8 @@ const AreaDetail = ({properties}:IAreaDetailProps) => {
const lowMedInc:indicatorInfo = {
label: intl.formatMessage(EXPLORE_COPY.SIDE_PANEL_INDICATORS.LOW_MED_INC),
description: intl.formatMessage(EXPLORE_COPY.SIDE_PANEL_INDICATOR_DESCRIPTION.LOW_MED_INCOME),
value: properties[constants.LOW_MEDIAN_INCOME_PERCENTILE] ?
properties[constants.LOW_MEDIAN_INCOME_PERCENTILE] : null,
isDisadvagtaged: properties[constants.IS_GTE_90_LOW_MEDIAN_INCOME_AND_LOW_HIGH_SCHOOL_EDU] ?
properties[constants.IS_GTE_90_LOW_MEDIAN_INCOME_AND_LOW_HIGH_SCHOOL_EDU] : null,
value: getWorkForceIndicatorValue('lowMedInc'),
isDisadvagtaged: getWorkForceIndicatorIsDisadv('lowMedInc'),
};
const lingIso:indicatorInfo = {
label: intl.formatMessage(EXPLORE_COPY.SIDE_PANEL_INDICATORS.LING_ISO),
@ -234,32 +320,25 @@ const AreaDetail = ({properties}:IAreaDetailProps) => {
const unemploy:indicatorInfo = {
label: intl.formatMessage(EXPLORE_COPY.SIDE_PANEL_INDICATORS.UNEMPLOY),
description: intl.formatMessage(EXPLORE_COPY.SIDE_PANEL_INDICATOR_DESCRIPTION.UNEMPLOY),
value: properties[constants.UNEMPLOYMENT_PROPERTY_PERCENTILE] ?
properties[constants.UNEMPLOYMENT_PROPERTY_PERCENTILE] : null,
isDisadvagtaged: properties[constants.IS_GTE_90_UNEMPLOYMENT_AND_LOW_HIGH_SCHOOL_EDU] ?
properties[constants.IS_GTE_90_UNEMPLOYMENT_AND_LOW_HIGH_SCHOOL_EDU] : null,
value: getWorkForceIndicatorValue('unemploy'),
isDisadvagtaged: getWorkForceIndicatorIsDisadv('unemploy'),
};
const poverty:indicatorInfo = {
label: intl.formatMessage(EXPLORE_COPY.SIDE_PANEL_INDICATORS.POVERTY),
description: intl.formatMessage(EXPLORE_COPY.SIDE_PANEL_INDICATOR_DESCRIPTION.POVERTY),
value: properties[constants.POVERTY_PROPERTY_PERCENTILE] ?
properties[constants.POVERTY_PROPERTY_PERCENTILE] : null,
isDisadvagtaged: properties[constants.IS_GTE_90_BELOW_100_POVERTY_AND_LOW_HIGH_SCHOOL_EDU] ?
properties[constants.IS_GTE_90_BELOW_100_POVERTY_AND_LOW_HIGH_SCHOOL_EDU] : null,
value: getWorkForceIndicatorValue('poverty'),
isDisadvagtaged: getWorkForceIndicatorIsDisadv('poverty'),
};
const highSchool:indicatorInfo = {
label: intl.formatMessage(EXPLORE_COPY.SIDE_PANEL_INDICATORS.HIGH_SCL),
description: intl.formatMessage(EXPLORE_COPY.SIDE_PANEL_INDICATOR_DESCRIPTION.HIGH_SKL),
value: properties[constants.HIGH_SCHOOL_PROPERTY_PERCENTILE] ?
properties[constants.HIGH_SCHOOL_PROPERTY_PERCENTILE] : null,
isDisadvagtaged: properties[constants.IS_LOW_HS_EDUCATION_LOW_HIGHER_ED_PRIORITIZED] &&
properties[constants.IS_LOW_HS_EDUCATION_LOW_HIGHER_ED_PRIORITIZED] == 1 ?
true : false,
value: getWorkForceIndicatorValue('highSchool'),
isDisadvagtaged: getWorkForceIndicatorIsDisadv('highSchool'),
isPercent: true,
};
// Aggregate indicators based on categories
const categories = [
let categories = [
{
id: 'climate-change',
titleText: intl.formatMessage(EXPLORE_COPY.SIDE_PANEL_CATEGORY.CLIMATE),
@ -318,6 +397,24 @@ const AreaDetail = ({properties}:IAreaDetailProps) => {
},
];
/**
* Modify the category array depending on the sidePanelState field. This field comes from the backend
* and is called UI_EXP.
*
* This sidePanelState has 3 values; namely, Nation, Puerto Rico and Island Areas.
*/
if (sidePanelState === constants.SIDE_PANEL_STATE_VALUES.PUERTO_RICO) {
// For Puerto Rico - only show the workforce development category
categories = categories.filter((category) => category.id === 'work-dev');
};
if (sidePanelState === constants.SIDE_PANEL_STATE_VALUES.ISLAND_AREAS) {
// For Island Areas - only show workforce dev category
categories = categories.filter((category) => category.id === 'work-dev');
// For Island Areas - remove the linguistic Isolation
categories[0].indicators = [lowMedInc, unemploy, poverty, highSchool];
}
// Create the AccoridionItems by mapping over the categories array. In this array we define the
// various indicators for a specific category. This is an array which then maps over the <Indicator />
// component to render the actual Indicator
@ -365,7 +462,10 @@ const AreaDetail = ({properties}:IAreaDetailProps) => {
</li>
<li>
<span className={styles.censusLabel}>
{intl.formatMessage(EXPLORE_COPY.SIDE_PANEL_CBG_INFO.STATE)}
{properties[constants.SIDE_PANEL_STATE] !== constants.SIDE_PANEL_STATE_VALUES.NATION ?
intl.formatMessage(EXPLORE_COPY.SIDE_PANEL_CBG_INFO.TERRITORY) :
intl.formatMessage(EXPLORE_COPY.SIDE_PANEL_CBG_INFO.STATE)
}
</span>
<span className={styles.censusText}>{` ${stateName}`}</span>
</li>
@ -407,7 +507,7 @@ const AreaDetail = ({properties}:IAreaDetailProps) => {
defaultMessage={'{disadvCount} of {totalCount} thresholds exceeded'}
values={{
disadvCount: properties[constants.TOTAL_NUMBER_OF_DISADVANTAGE_INDICATORS],
totalCount: constants.TOTAL_NUMBER_OF_INDICATORS,
totalCount: properties[constants.TOTAL_NUMBER_OF_INDICATORS],
}}/>
</div>

View file

@ -1,6 +1,207 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`rendering of the AreaDetail checks if various text fields are visible 1`] = `
exports[`rendering of the AreaDetail checks if indicators for ISLAND AREAS are present 1`] = `
<DocumentFragment>
<aside
data-cy="aside"
>
<div>
Methodology version 0.1
</div>
<ul>
<li>
<span>
Census tract:
</span>
<span>
98729374234
</span>
</li>
<li>
<span>
County:
</span>
<span>
N/A
</span>
</li>
<li>
<span>
Territory:
</span>
<span>
N/A
</span>
</li>
<li>
<span>
Population:
</span>
<span>
3,435,435
</span>
</li>
</ul>
<div>
<div>
Identified as disadvantaged?
</div>
<div>
<h3>
YES
</h3>
<div />
</div>
<div>
of thresholds exceeded
</div>
<a
href="
mailto:Screeningtool-Support@omb.eop.gov?subject=Census tract ID 98729374234, N/A, N/A&body=Please provide feedback about this census tract, including about the datasets, the data categories provided for this tract, the communities who live in this tract, and anything else relevant that we should know.
"
>
<button
class="usa-button"
data-testid="button"
type="button"
>
<div>
Send feedback
</div>
</button>
</a>
</div>
<div
aria-multiselectable="true"
class="usa-accordion"
data-testid="accordion"
>
<h2
class="usa-accordion__heading"
>
<button
aria-controls="work-dev"
aria-expanded="false"
class="usa-accordion__button"
data-testid="accordionButton_work-dev"
type="button"
>
<div>
<div>
Workforce development
</div>
<div
class=""
/>
</div>
</button>
</h2>
<div
class="usa-accordion__content usa-prose"
data-testid="accordionItem_work-dev"
hidden=""
id="work-dev"
>
<div>
<div>
Indicator
</div>
<div>
Percentile (0-100)
</div>
</div>
<li
data-cy="indicatorBox"
>
<div>
<div>
Low median income
<div>
Median income calculated as a percent of the areas median income
</div>
</div>
<div>
60
<sup>
<span>
th
</span>
</sup>
</div>
</div>
</li>
<li
data-cy="indicatorBox"
>
<div>
<div>
Unemployment
<div>
Number of unemployed people as a percentage of the labor force
</div>
</div>
<div>
90
<sup>
<span>
th
</span>
</sup>
</div>
</div>
</li>
<li
data-cy="indicatorBox"
>
<div>
<div>
Poverty
<div>
Percent of a tract's population in households where the household income is at or below
100% of the federal poverty level
</div>
</div>
<div>
80
<sup>
<span>
th
</span>
</sup>
</div>
</div>
</li>
<li
data-cy="indicatorBox"
>
<div>
<div>
High school degree achievement rate
<div>
Percent of people ages 25 years or older whose education level is less than a high school diploma
when higher ed enrollment rate is less than 20% in order to exclude areas with college and graduate students
</div>
</div>
<div>
N/A
<span>
%
</span>
</div>
</div>
</li>
</div>
</div>
</aside>
</DocumentFragment>
`;
exports[`rendering of the AreaDetail checks if indicators for NATION is present 1`] = `
<DocumentFragment>
<aside
data-cy="aside"
@ -53,7 +254,7 @@ exports[`rendering of the AreaDetail checks if various text fields are visible 1
<div />
</div>
<div>
of 21 thresholds exceeded
of thresholds exceeded
</div>
<a
href="
@ -181,7 +382,7 @@ exports[`rendering of the AreaDetail checks if various text fields are visible 1
</div>
</div>
<div>
12
19
<sup>
<span>
th
@ -275,7 +476,7 @@ exports[`rendering of the AreaDetail checks if various text fields are visible 1
</div>
</div>
<div>
12
19
<sup>
<span>
th
@ -369,7 +570,7 @@ exports[`rendering of the AreaDetail checks if various text fields are visible 1
</div>
</div>
<div>
12
19
<sup>
<span>
th
@ -468,7 +669,7 @@ exports[`rendering of the AreaDetail checks if various text fields are visible 1
</div>
</div>
<div>
12
19
<sup>
<span>
th
@ -580,7 +781,7 @@ exports[`rendering of the AreaDetail checks if various text fields are visible 1
</div>
</div>
<div>
12
19
<sup>
<span>
th
@ -656,7 +857,7 @@ exports[`rendering of the AreaDetail checks if various text fields are visible 1
</div>
</div>
<div>
12
19
<sup>
<span>
th
@ -791,7 +992,7 @@ exports[`rendering of the AreaDetail checks if various text fields are visible 1
</div>
</div>
<div>
12
19
<sup>
<span>
th
@ -909,7 +1110,7 @@ exports[`rendering of the AreaDetail checks if various text fields are visible 1
</div>
</div>
<div>
12
19
<sup>
<span>
th
@ -932,7 +1133,228 @@ exports[`rendering of the AreaDetail checks if various text fields are visible 1
</div>
</div>
<div>
N/A
98
<span>
%
</span>
</div>
</div>
</li>
</div>
</div>
</aside>
</DocumentFragment>
`;
exports[`rendering of the AreaDetail checks if indicators for PUERTO RICO are present 1`] = `
<DocumentFragment>
<aside
data-cy="aside"
>
<div>
Methodology version 0.1
</div>
<ul>
<li>
<span>
Census tract:
</span>
<span>
98729374234
</span>
</li>
<li>
<span>
County:
</span>
<span>
N/A
</span>
</li>
<li>
<span>
Territory:
</span>
<span>
N/A
</span>
</li>
<li>
<span>
Population:
</span>
<span>
3,435,435
</span>
</li>
</ul>
<div>
<div>
Identified as disadvantaged?
</div>
<div>
<h3>
YES
</h3>
<div />
</div>
<div>
of thresholds exceeded
</div>
<a
href="
mailto:Screeningtool-Support@omb.eop.gov?subject=Census tract ID 98729374234, N/A, N/A&body=Please provide feedback about this census tract, including about the datasets, the data categories provided for this tract, the communities who live in this tract, and anything else relevant that we should know.
"
>
<button
class="usa-button"
data-testid="button"
type="button"
>
<div>
Send feedback
</div>
</button>
</a>
</div>
<div
aria-multiselectable="true"
class="usa-accordion"
data-testid="accordion"
>
<h2
class="usa-accordion__heading"
>
<button
aria-controls="work-dev"
aria-expanded="false"
class="usa-accordion__button"
data-testid="accordionButton_work-dev"
type="button"
>
<div>
<div>
Workforce development
</div>
<div
class=""
/>
</div>
</button>
</h2>
<div
class="usa-accordion__content usa-prose"
data-testid="accordionItem_work-dev"
hidden=""
id="work-dev"
>
<div>
<div>
Indicator
</div>
<div>
Percentile (0-100)
</div>
</div>
<li
data-cy="indicatorBox"
>
<div>
<div>
Low median income
<div>
Median income calculated as a percent of the areas median income
</div>
</div>
<div>
N/A
<sup>
<span />
</sup>
</div>
</div>
</li>
<li
data-cy="indicatorBox"
>
<div>
<div>
Linguistic isolation
<div>
Percent of households where no one over the age 14 speaks English well
</div>
</div>
<div>
97
<sup>
<span>
th
</span>
</sup>
</div>
</div>
</li>
<li
data-cy="indicatorBox"
>
<div>
<div>
Unemployment
<div>
Number of unemployed people as a percentage of the labor force
</div>
</div>
<div>
96
<sup>
<span>
th
</span>
</sup>
</div>
</div>
</li>
<li
data-cy="indicatorBox"
>
<div>
<div>
Poverty
<div>
Percent of a tract's population in households where the household income is at or below
100% of the federal poverty level
</div>
</div>
<div>
19
<sup>
<span>
th
</span>
</sup>
</div>
</div>
</li>
<li
data-cy="indicatorBox"
>
<div>
<div>
High school degree achievement rate
<div>
Percent of people ages 25 years or older whose education level is less than a high school diploma
when higher ed enrollment rate is less than 20% in order to exclude areas with college and graduate students
</div>
</div>
<div>
98
<span>
%
</span>

View file

@ -8,23 +8,56 @@ import * as constants from '../../../data/constants';
describe('rendering of the AreaDetail', () => {
const properties = {
[constants.POVERTY_PROPERTY_PERCENTILE]: .12,
[constants.EDUCATION_PROPERTY_PERCENTILE]: .98,
[constants.HIGH_SCHOOL_PROPERTY_PERCENTILE]: .98,
[constants.LINGUISTIC_ISOLATION_PROPERTY_PERCENTILE]: .97,
[constants.UNEMPLOYMENT_PROPERTY_PERCENTILE]: .96,
[constants.HOUSING_BURDEN_PROPERTY_PERCENTILE]: .95,
[constants.SCORE_PROPERTY_HIGH]: .95,
[constants.GEOID_PROPERTY]: 98729374234,
[constants.TOTAL_POPULATION]: 3435435,
[constants.AREA_MEDIAN_INCOME_PERCENTILE]: .19,
[constants.POVERTY_PROPERTY_PERCENTILE]: .19,
[constants.SIDE_PANEL_STATE]: constants.SIDE_PANEL_STATE_VALUES.NATION,
};
const {asFragment} = render(
<LocalizedComponent>
<AreaDetail properties={properties}/>
</LocalizedComponent>,
);
it('checks if various text fields are visible', () => {
it('checks if indicators for NATION is present', () => {
const {asFragment} = render(
<LocalizedComponent>
<AreaDetail properties={properties}/>
</LocalizedComponent>,
);
expect(asFragment()).toMatchSnapshot();
});
it('checks if indicators for PUERTO RICO are present', () => {
const propertiesPR = {
...properties,
[constants.SIDE_PANEL_STATE]: constants.SIDE_PANEL_STATE_VALUES.PUERTO_RICO,
};
const {asFragment} = render(
<LocalizedComponent>
<AreaDetail properties={propertiesPR}/>
</LocalizedComponent>,
);
expect(asFragment()).toMatchSnapshot();
});
it('checks if indicators for ISLAND AREAS are present', () => {
const propertiesIA = {
...properties,
[constants.ISLAND_AREAS_UNEMPLOYMENT_LOW_HS_EDU_PERCENTILE_FIELD]: .9,
[constants.ISLAND_AREAS_POVERTY_LOW_HS_EDU_PERCENTILE_FIELD]: .8,
[constants.ISLAND_AREAS_LOW_MEDIAN_INCOME_LOW_HS_EDU_PERCENTILE_FIELD]: .6,
[constants.ISLAND_AREAS_LOW_HS_EDU_PERCENTILE_FIELD]: .5,
[constants.SIDE_PANEL_STATE]: constants.SIDE_PANEL_STATE_VALUES.ISLAND_AREAS,
};
const {asFragment} = render(
<LocalizedComponent>
<AreaDetail properties={propertiesIA}/>
</LocalizedComponent>,
);
expect(asFragment()).toMatchSnapshot();
});
});

View file

@ -658,7 +658,7 @@ exports[`rendering of the DatasetContainer checks if various text fields are vis
rel="noreferrer"
target="_blank"
>
Treatment Storage, and Disposal Facilities (TSDF) data
Treatment, Storage, and Disposal Facilities (TSDF) data
</a>
from 2020 calculated from EPA RCRA database as compiled
by EPA's EJSCREEN