Merge branch 'main' into esfoobar-usds/1327-marshmallow-yaml

This commit is contained in:
Jorge Escobar 2022-03-30 11:50:03 -04:00
commit 6e78d42a57
104 changed files with 5868 additions and 3298 deletions

View file

@ -16,7 +16,9 @@ on:
branches: [ main ]
pull_request:
# The branches below must be a subset of the branches above
branches: [ main ]
branches:
- main
- '**/release/**'
schedule:
- cron: '42 4 * * 1'

View file

@ -53,8 +53,9 @@ jobs:
uses: cypress-io/github-action@v2
with:
working-directory: ${{env.WORKING_DIRECTORY}}
browser: chrome
start: npm start
wait-on: "http://localhost:8000"
wait-on: "http://localhost:8000/en"
- name: Upload Artifact
uses: actions/upload-artifact@v2
with:

View file

@ -1,15 +1,15 @@
Feature: The About page will open from all other pages
Scenario: About page open when navigating from Explore the Tool page
Given I am on the "Explore the tool" page
When I click on the "About" page in the navigation
Then I see "About" in the title
Scenario: About page open when navigating from Methodology page
Given I am on the "Methodology" page
When I click on the "About" page in the navigation
Then I see "About" in the title
Scenario: About page open when navigating from Explore the Tool page
Given I am on the "Explore the tool" page
When I click on the "About" page in the navigation
Then I see "About" in the title
Scenario: About page open when navigating from Contact page
Given I am on the "Contact" page
When I click on the "About" page in the navigation

View file

@ -1,32 +1,14 @@
Feature: All links on Public Eng page are functional
Scenario: Anyone should be able to register on Mar 9th
Given I am on the "Public" page
When I look for the "Mar 9 Reg Link" CTA
And I click on the "Mar 9 Reg Link" event
Then the link should respond successfully
# Scenario: Anyone should be able to register on Mar 22th
# Given I am on the "Public" page
# When I look for the "Mar 22 Reg Link" CTA
# And I click on the "Mar 22 Reg Link" event
# Then the link should respond successfully
Scenario: Anyone should be able to register on Mar 10th
Given I am on the "Public" page
When I look for the "Mar 10 Reg Link" CTA
And I click on the "Mar 10 Reg Link" event
Then the link should respond successfully
Scenario: Anyone should be able to register on Mar 16th
Given I am on the "Public" page
When I look for the "Mar 16 Reg Link" CTA
And I click on the "Mar 16 Reg Link" event
Then the link should respond successfully
Scenario: Anyone should be able to register on Mar 22th
Given I am on the "Public" page
When I look for the "Mar 22 Reg Link" CTA
And I click on the "Mar 22 Reg Link" event
Then the link should respond successfully
Scenario: Anyone should be able to register on Apr 15th
Given I am on the "Public" page
When I look for the "Apr 15 Reg Link" CTA
And I click on the "Apr 15 Reg Link" event
Then the link should respond successfully
# Scenario: Anyone should be able to register on Apr 15th
# Given I am on the "Public" page
# When I look for the "Apr 15 Reg Link" CTA
# And I click on the "Apr 15 Reg Link" event
# Then the link should respond successfully

124
client/package-lock.json generated
View file

@ -48,9 +48,9 @@
"axe-core": "^4.4.1",
"babel-jest": "^27.5.1",
"babel-preset-gatsby": "^1.14.0",
"cypress": "^9.5.2",
"cypress": "^8.3.0",
"cypress-axe": "^0.14.0",
"cypress-cucumber-preprocessor": "^4.3.1",
"cypress-cucumber-preprocessor": "^4.2.0",
"eslint": "^7.32.0",
"eslint-config-google": "^0.14.0",
"eslint-plugin-cypress": "^2.12.1",
@ -4129,9 +4129,9 @@
"integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew=="
},
"node_modules/@types/sinonjs__fake-timers": {
"version": "8.1.1",
"resolved": "https://registry.npmjs.org/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-8.1.1.tgz",
"integrity": "sha512-0kSuKjAS0TrGLJ0M/+8MaFkGsQhZpB6pxOmvS3K8FYI72K//YmdfoW9X2qPsAKh1mkwxGD5zib9s1FIFed6E8g==",
"version": "6.0.4",
"resolved": "https://registry.npmjs.org/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-6.0.4.tgz",
"integrity": "sha512-IFQTJARgMUBF+xVd2b+hIgXWrZEjND3vJtRCvIelcFB5SIXfjV4bOHbHJ0eXKh+0COrBRc8MqteKAz/j88rE0A==",
"dev": true
},
"node_modules/@types/sizzle": {
@ -7925,26 +7925,25 @@
}
},
"node_modules/cypress": {
"version": "9.5.2",
"resolved": "https://registry.npmjs.org/cypress/-/cypress-9.5.2.tgz",
"integrity": "sha512-gYiQYvJozMzDOriUV1rCt6CeRM/pRK4nhwGJj3nJQyX2BoUdTCVwp30xDMKc771HiNVhBtgj5o5/iBdVDVXQUg==",
"version": "8.3.0",
"resolved": "https://registry.npmjs.org/cypress/-/cypress-8.3.0.tgz",
"integrity": "sha512-zA5Rcq8AZIfRfPXU0CCcauofF+YpaU9HYbfqkunFTmFV0Kdlo14tNjH2E3++MkjXKFnv3/pXq+HgxWtw8CSe8Q==",
"dev": true,
"hasInstallScript": true,
"dependencies": {
"@cypress/request": "^2.88.10",
"@cypress/request": "^2.88.5",
"@cypress/xvfb": "^1.2.4",
"@types/node": "^14.14.31",
"@types/sinonjs__fake-timers": "8.1.1",
"@types/sinonjs__fake-timers": "^6.0.2",
"@types/sizzle": "^2.3.2",
"arch": "^2.2.0",
"blob-util": "^2.0.2",
"bluebird": "^3.7.2",
"buffer": "^5.6.0",
"cachedir": "^2.3.0",
"chalk": "^4.1.0",
"check-more-types": "^2.24.0",
"cli-cursor": "^3.1.0",
"cli-table3": "~0.6.1",
"cli-table3": "~0.6.0",
"commander": "^5.1.0",
"common-tags": "^1.8.0",
"dayjs": "^1.10.4",
@ -7966,12 +7965,12 @@
"minimist": "^1.2.5",
"ospath": "^1.2.2",
"pretty-bytes": "^5.6.0",
"proxy-from-env": "1.0.0",
"ramda": "~0.27.1",
"request-progress": "^3.0.0",
"semver": "^7.3.2",
"supports-color": "^8.1.1",
"tmp": "~0.2.1",
"untildify": "^4.0.0",
"url": "^0.11.0",
"yauzl": "^2.10.0"
},
"bin": {
@ -7995,12 +7994,12 @@
}
},
"node_modules/cypress-cucumber-preprocessor": {
"version": "4.3.1",
"resolved": "https://registry.npmjs.org/cypress-cucumber-preprocessor/-/cypress-cucumber-preprocessor-4.3.1.tgz",
"integrity": "sha512-BKUYXqoTeKzkPXohEczDtpAwRCY0ZPtIpfRwJut16yNLqdXQMV+aItwanxe3cbJTFlwg562NAjL4LMdiOhkAjg==",
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/cypress-cucumber-preprocessor/-/cypress-cucumber-preprocessor-4.2.0.tgz",
"integrity": "sha512-iVm+gUROvg8lDIFStP4/B+0xHAwj6c6HCoUtkZqq8Ee/tcqe2Vlhz1eAq2Q5+tzmCk2/CIh06suvqB+RQpjWBw==",
"dev": true,
"dependencies": {
"@cypress/browserify-preprocessor": "^3.0.2",
"@cypress/browserify-preprocessor": "^3.0.1",
"chai": "^4.2.0",
"chokidar": "3.5.2",
"cosmiconfig": "^4.0.0",
@ -8062,30 +8061,6 @@
"integrity": "sha512-q4jlIR71hUpWTnGhXWcakgkZeHa3CCjcQcnuzU8M891BAWA2jHiziiWEPEkdS5pFsz7H9HJiy8BrK7tBRNrY7A==",
"dev": true
},
"node_modules/cypress/node_modules/buffer": {
"version": "5.7.1",
"resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
"integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
"dev": true,
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/feross"
},
{
"type": "patreon",
"url": "https://www.patreon.com/feross"
},
{
"type": "consulting",
"url": "https://feross.org/support"
}
],
"dependencies": {
"base64-js": "^1.3.1",
"ieee754": "^1.1.13"
}
},
"node_modules/cypress/node_modules/commander": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz",
@ -8110,12 +8085,6 @@
"node": ">=10"
}
},
"node_modules/cypress/node_modules/proxy-from-env": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.0.0.tgz",
"integrity": "sha1-M8UDmPcOp+uW0h97gXYwpVeRx+4=",
"dev": true
},
"node_modules/cypress/node_modules/supports-color": {
"version": "8.1.1",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
@ -20444,6 +20413,12 @@
"resolved": "https://registry.npmjs.org/quickselect/-/quickselect-2.0.0.tgz",
"integrity": "sha512-RKJ22hX8mHe3Y6wH/N3wCM6BWtjaxIyyUIkpHOvfFnxdI4yD4tBXEBKSbriGujF6jnSVkJrffuo6vxACiSSxIw=="
},
"node_modules/ramda": {
"version": "0.27.2",
"resolved": "https://registry.npmjs.org/ramda/-/ramda-0.27.2.tgz",
"integrity": "sha512-SbiLPU40JuJniHexQSAgad32hfwd+DRUdwF2PlVuI5RZD0/vahUco7R8vD86J/tcEKKF9vZrUVwgtmGCqlCKyA==",
"dev": true
},
"node_modules/randombytes": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
@ -29834,9 +29809,9 @@
"integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew=="
},
"@types/sinonjs__fake-timers": {
"version": "8.1.1",
"resolved": "https://registry.npmjs.org/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-8.1.1.tgz",
"integrity": "sha512-0kSuKjAS0TrGLJ0M/+8MaFkGsQhZpB6pxOmvS3K8FYI72K//YmdfoW9X2qPsAKh1mkwxGD5zib9s1FIFed6E8g==",
"version": "6.0.4",
"resolved": "https://registry.npmjs.org/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-6.0.4.tgz",
"integrity": "sha512-IFQTJARgMUBF+xVd2b+hIgXWrZEjND3vJtRCvIelcFB5SIXfjV4bOHbHJ0eXKh+0COrBRc8MqteKAz/j88rE0A==",
"dev": true
},
"@types/sizzle": {
@ -32819,25 +32794,24 @@
}
},
"cypress": {
"version": "9.5.2",
"resolved": "https://registry.npmjs.org/cypress/-/cypress-9.5.2.tgz",
"integrity": "sha512-gYiQYvJozMzDOriUV1rCt6CeRM/pRK4nhwGJj3nJQyX2BoUdTCVwp30xDMKc771HiNVhBtgj5o5/iBdVDVXQUg==",
"version": "8.3.0",
"resolved": "https://registry.npmjs.org/cypress/-/cypress-8.3.0.tgz",
"integrity": "sha512-zA5Rcq8AZIfRfPXU0CCcauofF+YpaU9HYbfqkunFTmFV0Kdlo14tNjH2E3++MkjXKFnv3/pXq+HgxWtw8CSe8Q==",
"dev": true,
"requires": {
"@cypress/request": "^2.88.10",
"@cypress/request": "^2.88.5",
"@cypress/xvfb": "^1.2.4",
"@types/node": "^14.14.31",
"@types/sinonjs__fake-timers": "8.1.1",
"@types/sinonjs__fake-timers": "^6.0.2",
"@types/sizzle": "^2.3.2",
"arch": "^2.2.0",
"blob-util": "^2.0.2",
"bluebird": "^3.7.2",
"buffer": "^5.6.0",
"cachedir": "^2.3.0",
"chalk": "^4.1.0",
"check-more-types": "^2.24.0",
"cli-cursor": "^3.1.0",
"cli-table3": "~0.6.1",
"cli-table3": "~0.6.0",
"commander": "^5.1.0",
"common-tags": "^1.8.0",
"dayjs": "^1.10.4",
@ -32859,12 +32833,12 @@
"minimist": "^1.2.5",
"ospath": "^1.2.2",
"pretty-bytes": "^5.6.0",
"proxy-from-env": "1.0.0",
"ramda": "~0.27.1",
"request-progress": "^3.0.0",
"semver": "^7.3.2",
"supports-color": "^8.1.1",
"tmp": "~0.2.1",
"untildify": "^4.0.0",
"url": "^0.11.0",
"yauzl": "^2.10.0"
},
"dependencies": {
@ -32874,16 +32848,6 @@
"integrity": "sha512-q4jlIR71hUpWTnGhXWcakgkZeHa3CCjcQcnuzU8M891BAWA2jHiziiWEPEkdS5pFsz7H9HJiy8BrK7tBRNrY7A==",
"dev": true
},
"buffer": {
"version": "5.7.1",
"resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
"integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
"dev": true,
"requires": {
"base64-js": "^1.3.1",
"ieee754": "^1.1.13"
}
},
"commander": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz",
@ -32902,12 +32866,6 @@
"universalify": "^2.0.0"
}
},
"proxy-from-env": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.0.0.tgz",
"integrity": "sha1-M8UDmPcOp+uW0h97gXYwpVeRx+4=",
"dev": true
},
"supports-color": {
"version": "8.1.1",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
@ -32927,12 +32885,12 @@
"requires": {}
},
"cypress-cucumber-preprocessor": {
"version": "4.3.1",
"resolved": "https://registry.npmjs.org/cypress-cucumber-preprocessor/-/cypress-cucumber-preprocessor-4.3.1.tgz",
"integrity": "sha512-BKUYXqoTeKzkPXohEczDtpAwRCY0ZPtIpfRwJut16yNLqdXQMV+aItwanxe3cbJTFlwg562NAjL4LMdiOhkAjg==",
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/cypress-cucumber-preprocessor/-/cypress-cucumber-preprocessor-4.2.0.tgz",
"integrity": "sha512-iVm+gUROvg8lDIFStP4/B+0xHAwj6c6HCoUtkZqq8Ee/tcqe2Vlhz1eAq2Q5+tzmCk2/CIh06suvqB+RQpjWBw==",
"dev": true,
"requires": {
"@cypress/browserify-preprocessor": "^3.0.2",
"@cypress/browserify-preprocessor": "^3.0.1",
"chai": "^4.2.0",
"chokidar": "3.5.2",
"cosmiconfig": "^4.0.0",
@ -42194,6 +42152,12 @@
"resolved": "https://registry.npmjs.org/quickselect/-/quickselect-2.0.0.tgz",
"integrity": "sha512-RKJ22hX8mHe3Y6wH/N3wCM6BWtjaxIyyUIkpHOvfFnxdI4yD4tBXEBKSbriGujF6jnSVkJrffuo6vxACiSSxIw=="
},
"ramda": {
"version": "0.27.2",
"resolved": "https://registry.npmjs.org/ramda/-/ramda-0.27.2.tgz",
"integrity": "sha512-SbiLPU40JuJniHexQSAgad32hfwd+DRUdwF2PlVuI5RZD0/vahUco7R8vD86J/tcEKKF9vZrUVwgtmGCqlCKyA==",
"dev": true
},
"randombytes": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",

View file

@ -47,9 +47,9 @@
"axe-core": "^4.4.1",
"babel-jest": "^27.5.1",
"babel-preset-gatsby": "^1.14.0",
"cypress": "^9.5.2",
"cypress": "^8.3.0",
"cypress-axe": "^0.14.0",
"cypress-cucumber-preprocessor": "^4.3.1",
"cypress-cucumber-preprocessor": "^4.2.0",
"eslint": "^7.32.0",
"eslint-config-google": "^0.14.0",
"eslint-plugin-cypress": "^2.12.1",

View file

@ -1,21 +1,23 @@
/* eslint-disable quotes */
// External Libs:
import React from 'react';
import {useIntl, FormattedMessage} from 'gatsby-plugin-intl';
import {useIntl} from 'gatsby-plugin-intl';
import {Accordion, Button} from '@trussworks/react-uswds';
// Components:
import Category from '../Category';
import DisadvantageDot from '../DisadvantageDot';
import ExceedBurden from '../ExceedBurden';
import Indicator from '../Indicator';
// Styles and constants
import * as styles from './areaDetail.module.scss';
import * as constants from '../../data/constants';
import * as EXPLORE_COPY from '../../data/copy/explore';
import * as CONTACT_COPY from '../../data/copy/contact';
import * as COMMON_COPY from '../../data/copy/common';
// @ts-ignore
// import mailIcon from '/node_modules/uswds/dist/img/usa-icons/mail.svg';
import mailIcon from '/node_modules/uswds/dist/img/usa-icons/mail_outline.svg';
interface IAreaDetailProps {
properties: constants.J40Properties,
@ -35,6 +37,7 @@ export interface indicatorInfo {
value: number,
isDisadvagtaged: boolean,
isPercent?: boolean,
threshold?: number,
}
const AreaDetail = ({properties}:IAreaDetailProps) => {
@ -97,8 +100,8 @@ const AreaDetail = ({properties}:IAreaDetailProps) => {
}
if (indicatorName === 'poverty') {
return properties.hasOwnProperty(constants
.POVERTY_PROPERTY_PERCENTILE) ?
properties[constants.POVERTY_PROPERTY_PERCENTILE] : null;
.POVERTY_BELOW_100_PERCENTILE) ?
properties[constants.POVERTY_BELOW_100_PERCENTILE] : null;
}
if (indicatorName === 'highSchool') {
return properties.hasOwnProperty(constants
@ -117,18 +120,18 @@ const AreaDetail = ({properties}:IAreaDetailProps) => {
if (sidePanelState === constants.SIDE_PANEL_STATE_VALUES.ISLAND_AREAS) {
if (indicatorName === 'lowMedInc') {
return properties.hasOwnProperty(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;
.IS_EXCEEDS_THRESH_FOR_ISLAND_AREA_LOW_MEDIAN_INCOME) ?
properties[constants.IS_EXCEEDS_THRESH_FOR_ISLAND_AREA_LOW_MEDIAN_INCOME] : null;
}
if (indicatorName === 'unemploy') {
return properties.hasOwnProperty(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;
.IS_EXCEEDS_THRESH_FOR_ISLAND_AREA_UNEMPLOYMENT) ?
properties[constants.IS_EXCEEDS_THRESH_FOR_ISLAND_AREA_UNEMPLOYMENT] : null;
}
if (indicatorName === 'poverty') {
return properties.hasOwnProperty(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;
.IS_EXCEEDS_THRESH_FOR_ISLAND_AREA_BELOW_100_POVERTY) ?
properties[constants.IS_EXCEEDS_THRESH_FOR_ISLAND_AREA_BELOW_100_POVERTY] : null;
}
if (indicatorName === 'highSchool') {
return properties.hasOwnProperty(constants
@ -139,18 +142,18 @@ const AreaDetail = ({properties}:IAreaDetailProps) => {
if (indicatorName === 'lowMedInc') {
return properties.hasOwnProperty(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;
.IS_EXCEEDS_THRESH_FOR_LOW_MEDIAN_INCOME) ?
properties[constants.IS_EXCEEDS_THRESH_FOR_LOW_MEDIAN_INCOME] : null;
}
if (indicatorName === 'unemploy') {
return properties.hasOwnProperty(constants
.IS_GTE_90_UNEMPLOYMENT_AND_LOW_HIGH_SCHOOL_EDU) ?
properties[constants.IS_GTE_90_UNEMPLOYMENT_AND_LOW_HIGH_SCHOOL_EDU] : null;
.IS_EXCEEDS_THRESH_FOR_UNEMPLOYMENT) ?
properties[constants.IS_EXCEEDS_THRESH_FOR_UNEMPLOYMENT] : null;
}
if (indicatorName === 'poverty') {
return properties.hasOwnProperty(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;
.IS_EXCEEDS_THRESH_FOR_BELOW_100_POVERTY) ?
properties[constants.IS_EXCEEDS_THRESH_FOR_BELOW_100_POVERTY] : null;
}
if (indicatorName === 'highSchool') {
return properties.hasOwnProperty(constants
@ -166,24 +169,24 @@ const AreaDetail = ({properties}:IAreaDetailProps) => {
description: intl.formatMessage(EXPLORE_COPY.SIDE_PANEL_INDICATOR_DESCRIPTION.EXP_AG_LOSS),
value: properties.hasOwnProperty(constants.EXP_AGRICULTURE_LOSS_PERCENTILE) ?
properties[constants.EXP_AGRICULTURE_LOSS_PERCENTILE] : null,
isDisadvagtaged: properties[constants.IS_GTE_90_EXP_AGR_LOSS_AND_IS_LOW_INCOME] ?
properties[constants.IS_GTE_90_EXP_AGR_LOSS_AND_IS_LOW_INCOME] : null,
isDisadvagtaged: properties[constants.IS_EXCEEDS_THRESH_FOR_EXP_AGR_LOSS] ?
properties[constants.IS_EXCEEDS_THRESH_FOR_EXP_AGR_LOSS] : null,
};
const expBldLoss:indicatorInfo = {
label: intl.formatMessage(EXPLORE_COPY.SIDE_PANEL_INDICATORS.EXP_BLD_LOSS),
description: intl.formatMessage(EXPLORE_COPY.SIDE_PANEL_INDICATOR_DESCRIPTION.EXP_BLD_LOSS),
value: properties.hasOwnProperty(constants.EXP_BUILDING_LOSS_PERCENTILE) ?
properties[constants.EXP_BUILDING_LOSS_PERCENTILE] : null,
isDisadvagtaged: properties[constants.IS_GTE_90_EXP_BLD_LOSS_AND_IS_LOW_INCOME] ?
properties[constants.IS_GTE_90_EXP_BLD_LOSS_AND_IS_LOW_INCOME] : null,
isDisadvagtaged: properties[constants.IS_EXCEEDS_THRESH_FOR_EXP_BLD_LOSS] ?
properties[constants.IS_EXCEEDS_THRESH_FOR_EXP_BLD_LOSS] : null,
};
const expPopLoss:indicatorInfo = {
label: intl.formatMessage(EXPLORE_COPY.SIDE_PANEL_INDICATORS.EXP_POP_LOSS),
description: intl.formatMessage(EXPLORE_COPY.SIDE_PANEL_INDICATOR_DESCRIPTION.EXP_POP_LOSS),
value: properties.hasOwnProperty(constants.EXP_POPULATION_LOSS_PERCENTILE) ?
properties[constants.EXP_POPULATION_LOSS_PERCENTILE] : null,
isDisadvagtaged: properties[constants.IS_GTE_90_EXP_POP_LOSS_AND_IS_LOW_INCOME] ?
properties[constants.IS_GTE_90_EXP_POP_LOSS_AND_IS_LOW_INCOME] : null,
isDisadvagtaged: properties[constants.IS_EXCEEDS_THRESH_FOR_EXP_POP_LOSS] ?
properties[constants.IS_EXCEEDS_THRESH_FOR_EXP_POP_LOSS] : null,
};
const lowInc:indicatorInfo = {
label: intl.formatMessage(EXPLORE_COPY.SIDE_PANEL_INDICATORS.LOW_INCOME),
@ -192,15 +195,17 @@ const AreaDetail = ({properties}:IAreaDetailProps) => {
properties[constants.POVERTY_BELOW_200_PERCENTILE] : null,
isDisadvagtaged: properties[constants.IS_FEDERAL_POVERTY_LEVEL_200] ?
properties[constants.IS_FEDERAL_POVERTY_LEVEL_200] : null,
threshold: 65,
};
const higherEd:indicatorInfo = {
label: intl.formatMessage(EXPLORE_COPY.SIDE_PANEL_INDICATORS.HIGH_ED),
description: intl.formatMessage(EXPLORE_COPY.SIDE_PANEL_INDICATOR_DESCRIPTION.HIGH_ED),
value: properties.hasOwnProperty(constants.HIGHER_ED_PERCENTILE) ?
properties[constants.HIGHER_ED_PERCENTILE] : null,
value: properties.hasOwnProperty(constants.NON_HIGHER_ED_PERCENTILE) ?
properties[constants.NON_HIGHER_ED_PERCENTILE] : null,
isDisadvagtaged: properties[constants.IS_HIGHER_ED_PERCENTILE] ?
properties[constants.IS_HIGHER_ED_PERCENTILE] : null,
isPercent: true,
threshold: 80,
};
const energyBurden:indicatorInfo = {
@ -208,16 +213,16 @@ const AreaDetail = ({properties}:IAreaDetailProps) => {
description: intl.formatMessage(EXPLORE_COPY.SIDE_PANEL_INDICATOR_DESCRIPTION.ENERGY_BURDEN),
value: properties.hasOwnProperty(constants.ENERGY_PERCENTILE) ?
properties[constants.ENERGY_PERCENTILE] : null,
isDisadvagtaged: properties[constants.IS_GTE_90_ENERGY_BURDEN_AND_IS_LOW_INCOME] ?
properties[constants.IS_GTE_90_ENERGY_BURDEN_AND_IS_LOW_INCOME] : null,
isDisadvagtaged: properties[constants.IS_EXCEEDS_THRESH_FOR_ENERGY_BURDEN] ?
properties[constants.IS_EXCEEDS_THRESH_FOR_ENERGY_BURDEN] : null,
};
const pm25:indicatorInfo = {
label: intl.formatMessage(EXPLORE_COPY.SIDE_PANEL_INDICATORS.PM_2_5),
description: intl.formatMessage(EXPLORE_COPY.SIDE_PANEL_INDICATOR_DESCRIPTION.PM_2_5),
value: properties.hasOwnProperty(constants.PM25_PERCENTILE) ?
properties[constants.PM25_PERCENTILE] : null,
isDisadvagtaged: properties[constants.IS_GTE_90_PM25_AND_IS_LOW_INCOME] ?
properties[constants.IS_GTE_90_PM25_AND_IS_LOW_INCOME] : null,
isDisadvagtaged: properties[constants.IS_EXCEEDS_THRESH_FOR_PM25] ?
properties[constants.IS_EXCEEDS_THRESH_FOR_PM25] : null,
};
const dieselPartMatter:indicatorInfo = {
@ -225,16 +230,16 @@ const AreaDetail = ({properties}:IAreaDetailProps) => {
description: intl.formatMessage(EXPLORE_COPY.SIDE_PANEL_INDICATOR_DESCRIPTION.DIESEL_PARTICULATE_MATTER),
value: properties.hasOwnProperty(constants.DIESEL_MATTER_PERCENTILE) ?
properties[constants.DIESEL_MATTER_PERCENTILE] : null,
isDisadvagtaged: properties[constants.IS_GTE_90_DIESEL_PM_AND_IS_LOW_INCOME] ?
properties[constants.IS_GTE_90_DIESEL_PM_AND_IS_LOW_INCOME] : null,
isDisadvagtaged: properties[constants.IS_EXCEEDS_THRESH_FOR_DIESEL_PM] ?
properties[constants.IS_EXCEEDS_THRESH_FOR_DIESEL_PM] : null,
};
const trafficVolume:indicatorInfo = {
label: intl.formatMessage(EXPLORE_COPY.SIDE_PANEL_INDICATORS.TRAFFIC_VOLUME),
description: intl.formatMessage(EXPLORE_COPY.SIDE_PANEL_INDICATOR_DESCRIPTION.TRAFFIC_VOLUME),
value: properties.hasOwnProperty(constants.TRAFFIC_PERCENTILE) ?
properties[constants.TRAFFIC_PERCENTILE] : null,
isDisadvagtaged: properties[constants.IS_GTE_90_TRAFFIC_PROX_AND_IS_LOW_INCOME] ?
properties[constants.IS_GTE_90_TRAFFIC_PROX_AND_IS_LOW_INCOME] : null,
isDisadvagtaged: properties[constants.IS_EXCEEDS_THRESH_FOR_TRAFFIC_PROX] ?
properties[constants.IS_EXCEEDS_THRESH_FOR_TRAFFIC_PROX] : null,
};
const houseBurden:indicatorInfo = {
@ -242,16 +247,16 @@ const AreaDetail = ({properties}:IAreaDetailProps) => {
description: intl.formatMessage(EXPLORE_COPY.SIDE_PANEL_INDICATOR_DESCRIPTION.HOUSE_BURDEN),
value: properties.hasOwnProperty(constants.HOUSING_BURDEN_PROPERTY_PERCENTILE) ?
properties[constants.HOUSING_BURDEN_PROPERTY_PERCENTILE] : null,
isDisadvagtaged: properties[constants.IS_GTE_90_HOUSE_BURDEN_AND_IS_LOW_INCOME] ?
properties[constants.IS_GTE_90_HOUSE_BURDEN_AND_IS_LOW_INCOME] : null,
isDisadvagtaged: properties[constants.IS_EXCEEDS_THRESH_FOR_HOUSE_BURDEN] ?
properties[constants.IS_EXCEEDS_THRESH_FOR_HOUSE_BURDEN] : null,
};
const leadPaint:indicatorInfo = {
label: intl.formatMessage(EXPLORE_COPY.SIDE_PANEL_INDICATORS.LEAD_PAINT),
description: intl.formatMessage(EXPLORE_COPY.SIDE_PANEL_INDICATOR_DESCRIPTION.LEAD_PAINT),
value: properties.hasOwnProperty(constants.LEAD_PAINT_PERCENTILE) ?
properties[constants.LEAD_PAINT_PERCENTILE] : null,
isDisadvagtaged: properties[constants.IS_GTE_90_LEAD_PAINT_AND_MEDIAN_HOME_VAL_AND_IS_LOW_INCOME] ?
properties[constants.IS_GTE_90_LEAD_PAINT_AND_MEDIAN_HOME_VAL_AND_IS_LOW_INCOME] : null,
isDisadvagtaged: properties[constants.IS_EXCEEDS_THRESH_FOR_LEAD_PAINT_AND_MEDIAN_HOME_VAL] ?
properties[constants.IS_EXCEEDS_THRESH_FOR_LEAD_PAINT_AND_MEDIAN_HOME_VAL] : null,
};
// const medHomeVal:indicatorInfo = {
// label: intl.formatMessage(EXPLORE_COPY.SIDE_PANEL_INDICATORS.MED_HOME_VAL),
@ -266,24 +271,24 @@ const AreaDetail = ({properties}:IAreaDetailProps) => {
description: intl.formatMessage(EXPLORE_COPY.SIDE_PANEL_INDICATOR_DESCRIPTION.PROX_HAZ),
value: properties.hasOwnProperty(constants.PROXIMITY_TSDF_SITES_PERCENTILE) ?
properties[constants.PROXIMITY_TSDF_SITES_PERCENTILE] : null,
isDisadvagtaged: properties[constants.IS_GTE_90_HAZARD_WASTE_AND_IS_LOW_INCOME] ?
properties[constants.IS_GTE_90_HAZARD_WASTE_AND_IS_LOW_INCOME] : null,
isDisadvagtaged: properties[constants.IS_EXCEEDS_THRESH_FOR_HAZARD_WASTE] ?
properties[constants.IS_EXCEEDS_THRESH_FOR_HAZARD_WASTE] : null,
};
const proxNPL:indicatorInfo = {
label: intl.formatMessage(EXPLORE_COPY.SIDE_PANEL_INDICATORS.PROX_NPL),
description: intl.formatMessage(EXPLORE_COPY.SIDE_PANEL_INDICATOR_DESCRIPTION.PROX_NPL),
value: properties.hasOwnProperty(constants.PROXIMITY_NPL_SITES_PERCENTILE) ?
properties[constants.PROXIMITY_NPL_SITES_PERCENTILE] : null,
isDisadvagtaged: properties[constants.IS_GTE_90_SUPERFUND_AND_IS_LOW_INCOME] ?
properties[constants.IS_GTE_90_SUPERFUND_AND_IS_LOW_INCOME] : null,
isDisadvagtaged: properties[constants.IS_EXCEEDS_THRESH_FOR_SUPERFUND] ?
properties[constants.IS_EXCEEDS_THRESH_FOR_SUPERFUND] : null,
};
const proxRMP:indicatorInfo = {
label: intl.formatMessage(EXPLORE_COPY.SIDE_PANEL_INDICATORS.PROX_RMP),
description: intl.formatMessage(EXPLORE_COPY.SIDE_PANEL_INDICATOR_DESCRIPTION.PROX_RMP),
value: properties.hasOwnProperty(constants.PROXIMITY_RMP_SITES_PERCENTILE) ?
properties[constants.PROXIMITY_RMP_SITES_PERCENTILE] : null,
isDisadvagtaged: properties[constants.IS_GTE_90_RMP_AND_IS_LOW_INCOME] ?
properties[constants.IS_GTE_90_RMP_AND_IS_LOW_INCOME] : null,
isDisadvagtaged: properties[constants.IS_EXCEEDS_THRESH_FOR_RMP] ?
properties[constants.IS_EXCEEDS_THRESH_FOR_RMP] : null,
};
const wasteWater:indicatorInfo = {
@ -291,8 +296,8 @@ const AreaDetail = ({properties}:IAreaDetailProps) => {
description: intl.formatMessage(EXPLORE_COPY.SIDE_PANEL_INDICATOR_DESCRIPTION.WASTE_WATER),
value: properties.hasOwnProperty(constants.WASTEWATER_PERCENTILE) ?
properties[constants.WASTEWATER_PERCENTILE] : null,
isDisadvagtaged: properties[constants.IS_GTE_90_WASTEWATER_AND_IS_LOW_INCOME] ?
properties[constants.IS_GTE_90_WASTEWATER_AND_IS_LOW_INCOME] : null,
isDisadvagtaged: properties[constants.IS_EXCEEDS_THRESH_FOR_WASTEWATER] ?
properties[constants.IS_EXCEEDS_THRESH_FOR_WASTEWATER] : null,
};
const asthma:indicatorInfo = {
@ -300,32 +305,32 @@ const AreaDetail = ({properties}:IAreaDetailProps) => {
description: intl.formatMessage(EXPLORE_COPY.SIDE_PANEL_INDICATOR_DESCRIPTION.ASTHMA),
value: properties.hasOwnProperty(constants.ASTHMA_PERCENTILE) ?
properties[constants.ASTHMA_PERCENTILE] : null,
isDisadvagtaged: properties[constants.IS_GTE_90_ASTHMA_AND_IS_LOW_INCOME] ?
properties[constants.IS_GTE_90_ASTHMA_AND_IS_LOW_INCOME] : null,
isDisadvagtaged: properties[constants.IS_EXCEEDS_THRESH_FOR_ASTHMA] ?
properties[constants.IS_EXCEEDS_THRESH_FOR_ASTHMA] : null,
};
const diabetes:indicatorInfo = {
label: intl.formatMessage(EXPLORE_COPY.SIDE_PANEL_INDICATORS.DIABETES),
description: intl.formatMessage(EXPLORE_COPY.SIDE_PANEL_INDICATOR_DESCRIPTION.DIABETES),
value: properties.hasOwnProperty(constants.DIABETES_PERCENTILE) ?
properties[constants.DIABETES_PERCENTILE] : null,
isDisadvagtaged: properties[constants.IS_GTE_90_DIABETES_AND_IS_LOW_INCOME] ?
properties[constants.IS_GTE_90_DIABETES_AND_IS_LOW_INCOME] : null,
isDisadvagtaged: properties[constants.IS_EXCEEDS_THRESH_FOR_DIABETES] ?
properties[constants.IS_EXCEEDS_THRESH_FOR_DIABETES] : null,
};
const heartDisease:indicatorInfo = {
label: intl.formatMessage(EXPLORE_COPY.SIDE_PANEL_INDICATORS.HEART_DISEASE),
description: intl.formatMessage(EXPLORE_COPY.SIDE_PANEL_INDICATOR_DESCRIPTION.HEART_DISEASE),
value: properties.hasOwnProperty(constants.HEART_PERCENTILE) ?
properties[constants.HEART_PERCENTILE] : null,
isDisadvagtaged: properties[constants.IS_GTE_90_HEART_DISEASE_AND_IS_LOW_INCOME] ?
properties[constants.IS_GTE_90_HEART_DISEASE_AND_IS_LOW_INCOME] : null,
isDisadvagtaged: properties[constants.IS_EXCEEDS_THRESH_FOR_HEART_DISEASE] ?
properties[constants.IS_EXCEEDS_THRESH_FOR_HEART_DISEASE] : null,
};
const lifeExpect:indicatorInfo = {
label: intl.formatMessage(EXPLORE_COPY.SIDE_PANEL_INDICATORS.LIFE_EXPECT),
description: intl.formatMessage(EXPLORE_COPY.SIDE_PANEL_INDICATOR_DESCRIPTION.LOW_LIFE_EXPECT),
value: properties.hasOwnProperty(constants.LIFE_PERCENTILE) ?
properties[constants.LIFE_PERCENTILE] : null,
isDisadvagtaged: properties[constants.IS_GTE_90_LOW_LIFE_EXP_AND_IS_LOW_INCOME] ?
properties[constants.IS_GTE_90_LOW_LIFE_EXP_AND_IS_LOW_INCOME] : null,
isDisadvagtaged: properties[constants.IS_EXCEEDS_THRESH_FOR_LOW_LIFE_EXP] ?
properties[constants.IS_EXCEEDS_THRESH_FOR_LOW_LIFE_EXP] : null,
};
const lingIso:indicatorInfo = {
@ -333,8 +338,8 @@ const AreaDetail = ({properties}:IAreaDetailProps) => {
description: intl.formatMessage(EXPLORE_COPY.SIDE_PANEL_INDICATOR_DESCRIPTION.LING_ISO),
value: properties.hasOwnProperty(constants.LINGUISTIC_ISOLATION_PROPERTY_PERCENTILE) ?
properties[constants.LINGUISTIC_ISOLATION_PROPERTY_PERCENTILE] : null,
isDisadvagtaged: properties[constants.IS_GTE_90_LINGUISITIC_ISO_AND_IS_LOW_INCOME] ?
properties[constants.IS_GTE_90_LINGUISITIC_ISO_AND_IS_LOW_INCOME] : null,
isDisadvagtaged: properties[constants.IS_EXCEEDS_THRESH_FOR_LINGUISITIC_ISO] ?
properties[constants.IS_EXCEEDS_THRESH_FOR_LINGUISITIC_ISO] : null,
};
const lowMedInc:indicatorInfo = {
label: intl.formatMessage(EXPLORE_COPY.SIDE_PANEL_INDICATORS.LOW_MED_INC),
@ -360,65 +365,111 @@ const AreaDetail = ({properties}:IAreaDetailProps) => {
value: getWorkForceIndicatorValue('highSchool'),
isDisadvagtaged: getWorkForceIndicatorIsDisadv('highSchool'),
isPercent: true,
threshold: 10,
};
// Aggregate indicators based on categories
/**
* Aggregate indicators based on categories
*
* The indicators property must be an array with last two elements being the
* socioeconomic burdens.
*/
let categories = [
{
id: 'climate-change',
titleText: intl.formatMessage(EXPLORE_COPY.SIDE_PANEL_CATEGORY.CLIMATE),
indicators: [expAgLoss, expBldLoss, expPopLoss, lowInc, higherEd],
indicators: [expAgLoss, expBldLoss, expPopLoss],
socioEcIndicators: [lowInc, higherEd],
isDisadvagtaged: properties[constants.IS_CLIMATE_FACTOR_DISADVANTAGED_M] ?
properties[constants.IS_CLIMATE_FACTOR_DISADVANTAGED_M] : null,
isExceed1MoreBurden: properties[constants.IS_CLIMATE_EXCEED_ONE_OR_MORE_INDICATORS_M] ?
properties[constants.IS_CLIMATE_EXCEED_ONE_OR_MORE_INDICATORS_M] : null,
isExceedBothSocioBurdens: properties[constants.IS_EXCEED_BOTH_SOCIO_INDICATORS_M] ?
properties[constants.IS_EXCEED_BOTH_SOCIO_INDICATORS_M] : null,
},
{
id: 'clean-energy',
titleText: intl.formatMessage(EXPLORE_COPY.SIDE_PANEL_CATEGORY.CLEAN_ENERGY),
indicators: [energyBurden, pm25, lowInc, higherEd],
indicators: [energyBurden, pm25],
socioEcIndicators: [lowInc, higherEd],
isDisadvagtaged: properties[constants.IS_ENERGY_FACTOR_DISADVANTAGED_M] ?
properties[constants.IS_ENERGY_FACTOR_DISADVANTAGED_M] : null,
isExceed1MoreBurden: properties[constants.IS_ENERGY_EXCEED_ONE_OR_MORE_INDICATORS_M] ?
properties[constants.IS_ENERGY_EXCEED_ONE_OR_MORE_INDICATORS_M] : null,
isExceedBothSocioBurdens: properties[constants.IS_EXCEED_BOTH_SOCIO_INDICATORS_M] ?
properties[constants.IS_EXCEED_BOTH_SOCIO_INDICATORS_M] : null,
},
{
id: 'clean-transport',
titleText: intl.formatMessage(EXPLORE_COPY.SIDE_PANEL_CATEGORY.CLEAN_TRANSPORT),
indicators: [dieselPartMatter, trafficVolume, lowInc, higherEd],
indicators: [dieselPartMatter, trafficVolume],
socioEcIndicators: [lowInc, higherEd],
isDisadvagtaged: properties[constants.IS_TRANSPORT_FACTOR_DISADVANTAGED_M] ?
properties[constants.IS_TRANSPORT_FACTOR_DISADVANTAGED_M] : null,
isExceed1MoreBurden: properties[constants.IS_TRANSPORT_EXCEED_ONE_OR_MORE_INDICATORS_M] ?
properties[constants.IS_TRANSPORT_EXCEED_ONE_OR_MORE_INDICATORS_M] : null,
isExceedBothSocioBurdens: properties[constants.IS_EXCEED_BOTH_SOCIO_INDICATORS_M] ?
properties[constants.IS_EXCEED_BOTH_SOCIO_INDICATORS_M] : null,
},
{
id: 'sustain-house',
titleText: intl.formatMessage(EXPLORE_COPY.SIDE_PANEL_CATEGORY.SUSTAIN_HOUSE),
indicators: [houseBurden, leadPaint, lowInc, higherEd],
indicators: [houseBurden, leadPaint],
socioEcIndicators: [lowInc, higherEd],
isDisadvagtaged: properties[constants.IS_HOUSING_FACTOR_DISADVANTAGED_M] ?
properties[constants.IS_HOUSING_FACTOR_DISADVANTAGED_M] : null,
isExceed1MoreBurden: properties[constants.IS_HOUSING_EXCEED_ONE_OR_MORE_INDICATORS_M] ?
properties[constants.IS_HOUSING_EXCEED_ONE_OR_MORE_INDICATORS_M] : null,
isExceedBothSocioBurdens: properties[constants.IS_EXCEED_BOTH_SOCIO_INDICATORS_M] ?
properties[constants.IS_EXCEED_BOTH_SOCIO_INDICATORS_M] : null,
},
{
id: 'leg-pollute',
titleText: intl.formatMessage(EXPLORE_COPY.SIDE_PANEL_CATEGORY.LEG_POLLUTE),
indicators: [proxHaz, proxNPL, proxRMP, lowInc, higherEd],
indicators: [proxHaz, proxNPL, proxRMP],
socioEcIndicators: [lowInc, higherEd],
isDisadvagtaged: properties[constants.IS_POLLUTION_FACTOR_DISADVANTAGED_M] ?
properties[constants.IS_POLLUTION_FACTOR_DISADVANTAGED_M] : null,
isExceed1MoreBurden: properties[constants.IS_POLLUTION_EXCEED_ONE_OR_MORE_INDICATORS_M] ?
properties[constants.IS_POLLUTION_EXCEED_ONE_OR_MORE_INDICATORS_M] : null,
isExceedBothSocioBurdens: properties[constants.IS_EXCEED_BOTH_SOCIO_INDICATORS_M] ?
properties[constants.IS_EXCEED_BOTH_SOCIO_INDICATORS_M] : null,
},
{
id: 'clean-water',
titleText: intl.formatMessage(EXPLORE_COPY.SIDE_PANEL_CATEGORY.CLEAN_WATER),
indicators: [wasteWater, lowInc, higherEd],
indicators: [wasteWater],
socioEcIndicators: [lowInc, higherEd],
isDisadvagtaged: properties[constants.IS_WATER_FACTOR_DISADVANTAGED_M] ?
properties[constants.IS_WATER_FACTOR_DISADVANTAGED_M] : null,
isExceed1MoreBurden: properties[constants.IS_WATER_EXCEED_ONE_OR_MORE_INDICATORS_M] ?
properties[constants.IS_WATER_EXCEED_ONE_OR_MORE_INDICATORS_M] : null,
isExceedBothSocioBurdens: properties[constants.IS_EXCEED_BOTH_SOCIO_INDICATORS_M] ?
properties[constants.IS_EXCEED_BOTH_SOCIO_INDICATORS_M] : null,
},
{
id: 'health-burdens',
titleText: intl.formatMessage(EXPLORE_COPY.SIDE_PANEL_CATEGORY.HEALTH_BURDEN),
indicators: [asthma, diabetes, heartDisease, lifeExpect, lowInc, higherEd],
indicators: [asthma, diabetes, heartDisease, lifeExpect],
socioEcIndicators: [lowInc, higherEd],
isDisadvagtaged: properties[constants.IS_HEALTH_FACTOR_DISADVANTAGED_M] ?
properties[constants.IS_HEALTH_FACTOR_DISADVANTAGED_M] : null,
isExceed1MoreBurden: properties[constants.IS_HEALTH_EXCEED_ONE_OR_MORE_INDICATORS_M] ?
properties[constants.IS_HEALTH_EXCEED_ONE_OR_MORE_INDICATORS_M] : null,
isExceedBothSocioBurdens: properties[constants.IS_EXCEED_BOTH_SOCIO_INDICATORS_M] ?
properties[constants.IS_EXCEED_BOTH_SOCIO_INDICATORS_M] : null,
},
{
id: 'work-dev',
titleText: intl.formatMessage(EXPLORE_COPY.SIDE_PANEL_CATEGORY.WORK_DEV),
indicators: [lingIso, lowMedInc, , unemploy, poverty, highSchool, higherEd],
indicators: [lingIso, lowMedInc, , unemploy, poverty],
socioEcIndicators: [highSchool, higherEd],
isDisadvagtaged: properties[constants.IS_WORKFORCE_FACTOR_DISADVANTAGED_M] ?
properties[constants.IS_WORKFORCE_FACTOR_DISADVANTAGED_M] : null,
isExceed1MoreBurden: properties[constants.IS_WORKFORCE_EXCEED_ONE_OR_MORE_INDICATORS_M] ?
properties[constants.IS_WORKFORCE_EXCEED_ONE_OR_MORE_INDICATORS_M] : null,
isExceedBothSocioBurdens: properties[constants.IS_WORKFORCE_EXCEED_BOTH_SOCIO_INDICATORS_M] ?
properties[constants.IS_WORKFORCE_EXCEED_BOTH_SOCIO_INDICATORS_M] : null,
},
];
@ -448,16 +499,31 @@ const AreaDetail = ({properties}:IAreaDetailProps) => {
title: <Category name={category.titleText} isDisadvantaged={category.isDisadvagtaged}/>,
content: (
<>
{/* Category Header */}
<div className={styles.categoryHeader}>
<div>{intl.formatMessage(EXPLORE_COPY.SIDE_PANEL_CATEGORY.INDICATOR)}</div>
<div>{intl.formatMessage(EXPLORE_COPY.SIDE_PANEL_CATEGORY.PERCENTILE)}</div>
</div>
{/* Exceeds one or more burdens */}
<ExceedBurden
text={EXPLORE_COPY.SIDE_PANEL_SPACERS.EXCEED_ONE_OR_MORE}
isBurdened={category.isExceed1MoreBurden}
/>
{/* Category Indicators */}
{/* indicators */}
{category.indicators.map((indicator:any, index:number) => {
return <Indicator key={`ind${index}`} indicator={indicator}/>;
})}
{/* AND */}
<div className={styles.categorySpacer}>AND</div>
{/* Exceeds both socioeconomic burdens */}
<ExceedBurden
text={EXPLORE_COPY.SIDE_PANEL_SPACERS.EXCEED_BOTH_SOCIO}
isBurdened={category.isExceedBothSocioBurdens}
/>
{/* socio-economic indicators */}
{category.socioEcIndicators.map((indicator:any, index:number) => {
return <Indicator key={`ind${index}`} indicator={indicator}/>;
})}
</>
),
expanded: false,
@ -521,35 +587,38 @@ const AreaDetail = ({properties}:IAreaDetailProps) => {
}
</div>
{/* Number of thresholds exceeded */}
<div className={
properties[constants.TOTAL_NUMBER_OF_DISADVANTAGE_INDICATORS] > 0 ?
styles.showThresholdExceed : styles.hideThresholdExceed
}>
<FormattedMessage
id={'explore.page.threshold.count.exceed'}
description={"threshold exceeded count"}
defaultMessage={'{disadvCount} of {totalCount} thresholds exceeded'}
values={{
disadvCount: properties[constants.TOTAL_NUMBER_OF_DISADVANTAGE_INDICATORS],
totalCount: properties[constants.TOTAL_NUMBER_OF_INDICATORS],
}}/>
{/* Number of categories exceeded */}
<div className={styles.showCategoriesExceed}>
{EXPLORE_COPY.numberOfCategoriesExceeded(properties[constants.COUNT_OF_CATEGORIES_DISADV])}
</div>
{/* Number of thresholds exceeded */}
<div className={styles.showThresholdExceed}>
{EXPLORE_COPY.numberOfThresholdsExceeded(properties[constants.TOTAL_NUMBER_OF_DISADVANTAGE_INDICATORS])}
</div>
{/* Send Feedback button */}
<a
className={styles.sendFeedbackBtn}
className={styles.sendFeedbackLink}
// The mailto string must be on a single line otherwise the email does not display subject and body
href={`
mailto:${CONTACT_COPY.FEEDBACK_EMAIL}?subject=${feedbackEmailSubject}&body=${feedbackEmailBody}
mailto:${COMMON_COPY.FEEDBACK_EMAIL}?subject=${feedbackEmailSubject}&body=${feedbackEmailBody}
`}
target={"_blank"}
rel="noreferrer"
>
<Button
type="button">
<div>
{EXPLORE_COPY.COMMUNITY.SEND_FEEDBACK.TITLE}
type="button"
className={styles.sendFeedbackBtn}
>
<div className={styles.buttonContainer}>
<div className={styles.buttonText}>
{EXPLORE_COPY.COMMUNITY.SEND_FEEDBACK.TITLE}
</div>
<img
className={styles.buttonImage}
src={mailIcon}
alt={'tbd'}
/>
</div>
{/* <div>
<img src={mailIcon} alt={'mail icon for email'}/>

View file

@ -9,11 +9,6 @@ $sidePanelLabelFontColor: #171716;
font-weight: 600;
}
@mixin thresholdExceeded {
font-size: medium;
@include u-margin-top('05');
}
.versionInfo {
padding: .5rem 1rem .5rem 1.2rem;
font-size: medium;
@ -25,7 +20,6 @@ $sidePanelLabelFontColor: #171716;
flex-direction: column;
}
.categorization {
display: flex;
flex-direction: column;
@ -48,19 +42,45 @@ $sidePanelLabelFontColor: #171716;
}
}
.showThresholdExceed {
@include thresholdExceeded;
display: block;
}
.hideThresholdExceed {
@include thresholdExceeded;
visibility: hidden;
.showCategoriesExceed {
font-size: small;
@include u-margin-top('05');
}
.sendFeedbackBtn {
.showThresholdExceed {
font-size: small;
@include u-margin-top('05');
}
.sendFeedbackLink {
@include u-margin-top(2);
.sendFeedbackBtn{
@include u-text("blue-70v");
@include u-bg("yellow-20v");
height: 40px;
&:hover {
@include u-bg("yellow-20");
@include u-text("gray-90");
}
.buttonContainer{
display: flex;
.buttonText{
@include u-margin-right(1);
}
.buttonImage{
width: 21px;
margin-top: -3px;
filter: invert(13%) sepia(76%) saturate(5142%) hue-rotate(192deg) brightness(80%) contrast(106%);
}
}
}
}
}
@ -82,14 +102,6 @@ $sidePanelLabelFontColor: #171716;
}
}
// The following class is used in the AccordionItems in the AreaDetail component.
// The Accordion component (parent of AccordionItems) requires some CSS overrides.
// Local styling is not allowing the override.
// The override is needed to push into the bounds of the Accordion component's styles.
// To override this, in globals.scss, we set the this .categoryHeader's vertical alignment by
// setting styles in:
// .usa-accordion__content > *:first-child
// This first child of the accordion content is the category header:
.categoryHeader {
display: flex;
justify-content: space-between;
@ -98,4 +110,17 @@ $sidePanelLabelFontColor: #171716;
@include u-bg('gray-cool-5');
@include u-padding-left(2.5);
@include u-padding-right(2);
}
}
.categorySpacer {
@include u-bg('gray-cool-3');
@include typeset('sans', '2xs', 2);
@include u-text('bold');
margin: 0 -20px 1rem -20px;
@include u-padding-top(2);
@include u-padding-bottom(2);
@include u-padding-left(2.5);
}

View file

@ -10,9 +10,14 @@ declare namespace MapModuleScssNamespace {
isInFocus:string;
versionInfo: string;
showThresholdExceed:string;
hideThresholdExceed:string;
showCategoriesExceed: string;
categoryHeader:string;
sendFeedbackLink: string;
sendFeedbackBtn: string;
buttonContainer: string;
buttonText: string;
buttonImage: string;
categorySpacer: string;
}
}

View file

@ -1,3 +1,4 @@
import AreaDetail from './AreaDetail';
export default AreaDetail;

View file

@ -7,7 +7,7 @@ import * as constants from '../../../data/constants';
describe('rendering of the AreaDetail', () => {
const properties = {
[constants.POVERTY_PROPERTY_PERCENTILE]: .12,
[constants.POVERTY_BELOW_100_PERCENTILE]: .12,
[constants.HIGH_SCHOOL_PROPERTY_PERCENTILE]: .98,
[constants.LINGUISTIC_ISOLATION_PROPERTY_PERCENTILE]: .97,
[constants.UNEMPLOYMENT_PROPERTY_PERCENTILE]: .96,
@ -15,8 +15,10 @@ describe('rendering of the AreaDetail', () => {
[constants.SCORE_PROPERTY_HIGH]: .95,
[constants.GEOID_PROPERTY]: 98729374234,
[constants.TOTAL_POPULATION]: 3435435,
[constants.POVERTY_PROPERTY_PERCENTILE]: .19,
[constants.POVERTY_BELOW_200_PERCENTILE]: .19,
[constants.SIDE_PANEL_STATE]: constants.SIDE_PANEL_STATE_VALUES.NATION,
[constants.COUNT_OF_CATEGORIES_DISADV]: 5,
[constants.TOTAL_NUMBER_OF_DISADVANTAGE_INDICATORS]: 3,
};
@ -49,7 +51,7 @@ describe('rendering of the AreaDetail', () => {
[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.ISLAND_AREAS_POVERTY_LOW_HS_EDU_PERCENTILE_FIELD]: .5,
[constants.SIDE_PANEL_STATE]: constants.SIDE_PANEL_STATE_VALUES.ISLAND_AREAS,
};

View file

@ -34,12 +34,10 @@ exports[`rendering of the Categories checks if component renders 1`] = `
<strong>
identified as disadvantaged
</strong>
</p>
<p>
<strong>
IF
</strong>
@ -61,8 +59,6 @@ exports[`rendering of the Categories checks if component renders 1`] = `
>
expected population loss rate
</a>
</p>
<p>
@ -76,11 +72,11 @@ exports[`rendering of the Categories checks if component renders 1`] = `
>
low income
</a>
AND at or below 20% for
AND 80% or more of adults 15 or older are not enrolled in
<a
href="#high-ed-enroll-rate"
>
higher ed enrollment rate
higher education
</a>
@ -97,12 +93,10 @@ exports[`rendering of the Categories checks if component renders 1`] = `
<strong>
identified as disadvantaged
</strong>
</p>
<p>
<strong>
IF
</strong>
@ -118,8 +112,6 @@ exports[`rendering of the Categories checks if component renders 1`] = `
>
PM2.5 in the air
</a>
</p>
<p>
@ -133,11 +125,11 @@ exports[`rendering of the Categories checks if component renders 1`] = `
>
low income
</a>
AND at or below 20% for
AND 80% or more of adults 15 or older are not enrolled in
<a
href="#high-ed-enroll-rate"
>
higher ed enrollment rate
higher education
</a>
@ -154,7 +146,7 @@ exports[`rendering of the Categories checks if component renders 1`] = `
<strong>
identified as disadvantaged
</strong>
</p>
<p>
@ -190,11 +182,11 @@ exports[`rendering of the Categories checks if component renders 1`] = `
>
low income
</a>
AND at or below 20% for
AND 80% or more of adults 15 or older are not enrolled in
<a
href="#high-ed-enroll-rate"
>
higher ed enrollment rate
higher education
</a>
@ -211,12 +203,10 @@ exports[`rendering of the Categories checks if component renders 1`] = `
<strong>
identified as disadvantaged
</strong>
</p>
<p>
<strong>
IF
</strong>
@ -232,15 +222,12 @@ exports[`rendering of the Categories checks if component renders 1`] = `
>
median home value
</a>
is at or less than
the 90th percentile OR at or above the 90th percentile for the
is at or less than the 90th percentile OR at or above the 90th percentile for the
<a
href="#house-burden"
>
housing cost burden
</a>
</p>
<p>
@ -254,11 +241,11 @@ exports[`rendering of the Categories checks if component renders 1`] = `
>
low income
</a>
AND at or below 20% for
AND 80% or more of adults 15 or older are not enrolled in
<a
href="#high-ed-enroll-rate"
>
higher ed enrollment rate
higher education
</a>
@ -275,12 +262,10 @@ exports[`rendering of the Categories checks if component renders 1`] = `
<strong>
identified as disadvantaged
</strong>
</p>
<p>
<strong>
IF
</strong>
@ -302,8 +287,6 @@ exports[`rendering of the Categories checks if component renders 1`] = `
>
proximity to Risk Management Plan (RMP) facilities
</a>
</p>
<p>
@ -317,11 +300,11 @@ exports[`rendering of the Categories checks if component renders 1`] = `
>
low income
</a>
AND at or below 20% for
AND 80% or more of adults 15 or older are not enrolled in
<a
href="#high-ed-enroll-rate"
>
higher ed enrollment rate
higher education
</a>
@ -338,12 +321,10 @@ exports[`rendering of the Categories checks if component renders 1`] = `
<strong>
identified as disadvantaged
</strong>
</p>
<p>
<strong>
IF
</strong>
@ -353,8 +334,6 @@ exports[`rendering of the Categories checks if component renders 1`] = `
>
wastewater discharge
</a>
</p>
<p>
@ -368,11 +347,11 @@ exports[`rendering of the Categories checks if component renders 1`] = `
>
low income
</a>
AND at or below 20% for
AND 80% or more of adults 15 or older are not enrolled in
<a
href="#high-ed-enroll-rate"
>
higher ed enrollment rate
higher education
</a>
@ -389,12 +368,10 @@ exports[`rendering of the Categories checks if component renders 1`] = `
<strong>
identified as disadvantaged
</strong>
</p>
<p>
<strong>
IF
</strong>
@ -422,8 +399,6 @@ exports[`rendering of the Categories checks if component renders 1`] = `
>
low life expectancy
</a>
</p>
<p>
@ -437,11 +412,11 @@ exports[`rendering of the Categories checks if component renders 1`] = `
>
low income
</a>
AND at or below 20% for
AND 80% or more of adults 15 or older are not enrolled in
<a
href="#high-ed-enroll-rate"
>
higher ed enrollment rate
higher education
</a>
@ -458,12 +433,10 @@ exports[`rendering of the Categories checks if component renders 1`] = `
<strong>
identified as disadvantaged
</strong>
</p>
<p>
<strong>
IF
</strong>
@ -474,21 +447,18 @@ exports[`rendering of the Categories checks if component renders 1`] = `
low median income
</a>
as a percentage of area median income OR
<a
href="#ling-iso"
>
linguistic isolation
</a>
OR
OR
<a
href="#unemploy"
>
unemployment
</a>
OR
percent individuals in households at or below 100% Federal
OR percent individuals in households at or below 100% Federal
<a
href="#poverty"
>
@ -498,23 +468,20 @@ exports[`rendering of the Categories checks if component renders 1`] = `
</p>
<p>
<strong>
AND
</strong>
is at or less than 90% for
10% or more of adults 25 or older have not attained a
<a
href="#high-school"
>
high school degree attainment rate
high school degree
</a>
for adults 25 years and older AND
at or below 20% for
AND 80% or more of adults 15 or older are not enrolled in
<a
href="#high-ed-enroll-rate"
>
higher ed enrollment rate
higher education
</a>

View file

@ -12,12 +12,10 @@ exports[`rendering of the CategoryCard checks if component renders 1`] = `
<strong>
identified as disadvantaged
</strong>
</p>
<p>
<strong>
IF
</strong>
@ -39,8 +37,6 @@ exports[`rendering of the CategoryCard checks if component renders 1`] = `
>
expected population loss rate
</a>
</p>
<p>
@ -54,11 +50,11 @@ exports[`rendering of the CategoryCard checks if component renders 1`] = `
>
low income
</a>
AND at or below 20% for
AND 80% or more of adults 15 or older are not enrolled in
<a
href="#high-ed-enroll-rate"
>
higher ed enrollment rate
higher education
</a>

View file

@ -0,0 +1,80 @@
/* eslint-disable valid-jsdoc */
import React from 'react';
import {useIntl} from 'gatsby-plugin-intl';
import * as styles from './datasetCard.module.scss';
import * as METHODOLOGY_COPY from '../../data/copy/methodology';
interface IDatasetCardProps {
datasetCardProps: METHODOLOGY_COPY.IIndicators
}
/**
* This component will take in a card and render a dataset card
*
* @param {IDatasetCardProps}
* @return {JSX.Element}
*/
const DatasetCard = ({datasetCardProps}:IDatasetCardProps) => {
const intl = useIntl();
return (
<div className={styles.datasetCard} id={datasetCardProps.domID}>
{/* Dataset header */}
<h3 className={styles.datasetCardIndicator}>{datasetCardProps.indicator}</h3>
{/* Dataset description */}
<div className={styles.datasetCardDescription}>
{datasetCardProps.description}
</div>
{/* Dataset note */}
{datasetCardProps.note && <div className={styles.datasetCardDescription}>
<p>{datasetCardProps.note}</p>
</div>}
<ul className={styles.datasetCardList}>
{/* Dataset Used in */}
<li className={styles.datasetCardListItem}>
<span className={styles.datasetCardLabels}>
{intl.formatMessage(METHODOLOGY_COPY.DATASET_CARD_LABELS.USED_IN)}
</span>
{datasetCardProps.usedIn}
</li>
{/* Dataset Responsible Party */}
<li className={styles.datasetCardListItem}>
<span className={styles.datasetCardLabels}>
{intl.formatMessage(METHODOLOGY_COPY.DATASET_CARD_LABELS.RESP_PARTY)}
</span>
{datasetCardProps.responsibleParty}
</li>
{datasetCardProps.sources.map((dataSource, index) => (
<React.Fragment key={index}>
{/* Dataset Source */}
<li className={styles.datasetCardListItemSource}>
<span className={styles.datasetCardLabels}>
{intl.formatMessage(METHODOLOGY_COPY.DATASET_CARD_LABELS.SOURCE)}
</span>
{dataSource.source}
</li>
{/* Dataset Available for */}
<li className={styles.datasetCardListItem}>
<span className={styles.datasetCardLabels}>
{intl.formatMessage(METHODOLOGY_COPY.DATASET_CARD_LABELS.AVAILABLE_FOR)}
</span>
{dataSource.availableFor}
</li>
</React.Fragment>
))}
</ul>
</div>
);
};
export default DatasetCard;

View file

@ -1,68 +1,3 @@
import React from 'react';
import {useIntl} from 'gatsby-plugin-intl';
import * as styles from './datasetCard.module.scss';
import * as METHODOLOGY_COPY from '../../data/copy/methodology';
interface IDatasetCardProps {
datasetCardProps: METHODOLOGY_COPY.IIndicators
}
const DatasetCard = ({datasetCardProps}:IDatasetCardProps) => {
const intl = useIntl();
return (
<div className={styles.datasetCard} id={datasetCardProps.domID}>
{/* Dataset header */}
<h3 className={styles.datasetCardIndicator}>{datasetCardProps.indicator}</h3>
{/* Dataset description */}
<div className={styles.datasetCardDescription}>
{datasetCardProps.description}
</div>
<ul className={styles.datasetCardList}>
{/* Dataset Used in */}
<li className={styles.datasetCardListItem}>
<span className={styles.datasetCardLabels}>
{intl.formatMessage(METHODOLOGY_COPY.DATASET_CARD_LABELS.USED_IN)}
</span>
{datasetCardProps.usedIn}
</li>
{/* Dataset Responsible Party */}
<li className={styles.datasetCardListItem}>
<span className={styles.datasetCardLabels}>
{intl.formatMessage(METHODOLOGY_COPY.DATASET_CARD_LABELS.RESP_PARTY)}
</span>
{datasetCardProps.responsibleParty}
</li>
{datasetCardProps.sources.map((dataSource) => (
<>
{/* Dataset Source */}
<li className={styles.datasetCardListItemSource}>
<span className={styles.datasetCardLabels}>
{intl.formatMessage(METHODOLOGY_COPY.DATASET_CARD_LABELS.SOURCE)}
</span>
{dataSource.source}
</li>
{/* Dataset Available for */}
<li className={styles.datasetCardListItem}>
<span className={styles.datasetCardLabels}>
{intl.formatMessage(METHODOLOGY_COPY.DATASET_CARD_LABELS.AVAILABLE_FOR)}
</span>
{dataSource.availableFor}
</li>
</>
))}
</ul>
</div>
);
};
import DatasetCard from './DatasetCard';
export default DatasetCard;

View file

@ -1,7 +1,7 @@
import * as React from 'react';
import {render} from '@testing-library/react';
import {LocalizedComponent} from '../../../test/testHelpers';
import DatasetCard from '../../DatasetCard';
import DatasetCard from '../DatasetCard';
import * as METHODOLOGY_COPY from '../../../data/copy/methodology';

View file

@ -34,8 +34,8 @@ const DatasetContainer = () => {
<Grid row>
<Grid col={12}>
<div className={styles.datasetCardsContainer}>
{METHODOLOGY_COPY.INDICATORS.map((card) => <DatasetCard
key={card.indicator}
{METHODOLOGY_COPY.INDICATORS.map((card, index) => <DatasetCard
key={index}
datasetCardProps={card}
/>)}
</div>

View file

@ -101,11 +101,11 @@ exports[`rendering of the DatasetContainer checks if various text fields are vis
id="high-ed-enroll-rate"
>
<h3>
Higher ed enrollment rate
Higher education non-enrollment
</h3>
<div>
Percent of people who are currently enrolled in college or graduate school.
Percent of people 15 or older who are not currently enrolled in college, university, or graduate school.
</div>
<ul>
@ -140,7 +140,7 @@ exports[`rendering of the DatasetContainer checks if various text fields are vis
<span>
Available for:
</span>
All U.S. states and the District of Columbia
All U.S. states, the District of Columbia, and Puerto Rico
</li>
</ul>
</div>
@ -380,8 +380,6 @@ exports[`rendering of the DatasetContainer checks if various text fields are vis
<span>
Source:
</span>
<a
class="usa-link usa-link--external"
data-cy=""
@ -391,8 +389,7 @@ exports[`rendering of the DatasetContainer checks if various text fields are vis
>
Fusion of model and monitor data
</a>
from 2017 as compiled by EPAs EJSCREEN, sourced from EPA National Air
Toxics Assessment (NATA) and the U.S. Department of Transportation (DOT) traffic data
from 2017 as compiled by EPAs EJSCREEN, sourced from EPA National Air Toxics Assessment (NATA) and the U.S. Department of Transportation (DOT) traffic data
</li>
<li>
@ -995,23 +992,19 @@ exports[`rendering of the DatasetContainer checks if various text fields are vis
<div>
Average number of years of life a person who has attained a given age can expect to live.
<p>
<strong>
Note:
</strong>
Unlike most of the other datasets, high values of this data indicate low burdens. For
percentile calculations of burden, the percentile is calculated in reverse order, so that the
census tract with the highest life expectancy relative to area life expectancy (lowest burden
on this measure) is at the 0th percentile, and the census tract with the lowest life
expectancy relative to area life expectancy (highest burden on this measure) is at the
100th percentile. Census tracts with the highest number have the lowest life expectancy.
</p>
</div>
<div>
<p>
<strong>
Note:
</strong>
The percentiles for this dataset have been reversed so that census tracts with lower numbers have higher life expectancies and the census tracts with higher numbers have lower life expectancy when compared to life expectancy in the area.
</p>
</div>
<ul>
<li>
<span>
@ -1057,23 +1050,19 @@ exports[`rendering of the DatasetContainer checks if various text fields are vis
<div>
Median income of the census tract calculated as a percent of the areas median income.
<p>
<strong>
Note:
</strong>
Unlike most of the other datasets, high values of this data indicate low burdens. For
percentile calculations of burden, the percentile is calculated in reverse order, so that the
census tract with the highest median income relative to area median income (lowest burden on this
measure) is at the 0th percentile, and the census tract with the lowest median income relative to
area median income (highest burden on this measure) is at the 100th percentile. Census tracts with
the highest number have the lowest median income.
</p>
</div>
<div>
<p>
<strong>
Note:
</strong>
The percentiles for this dataset have been reversed so that census tracts with lower numbers have higher median incomes and census tracts with the higher numbers have lower median income when compared to area median income.
</p>
</div>
<ul>
<li>
<span>
@ -1319,12 +1308,11 @@ exports[`rendering of the DatasetContainer checks if various text fields are vis
id="high-school"
>
<h3>
High school degree attainment rate
High school degree non-attainment
</h3>
<div>
Percent of people ages 25 years or older in a census tract whose
education level is less than a high school diploma.
Percent of people age 25 years or older in a census tract whose education level is less than a high school diploma.
</div>
<ul>

View file

@ -0,0 +1,27 @@
@use '../../styles/design-system.scss' as *;
// styles for all burden containers
@mixin baseBurdenContainer {
display: flex;
@include u-text('bold');
.burdenQuestion {
flex: 0 1 77%;
@include typeset('sans', '2xs', 2);
}
.burdenValue {
margin-left: 2.2rem;
}
}
// styles for first burden container
.exceedBurdenContainer {
@include baseBurdenContainer();
@include u-padding-bottom(1);
}
// styles for second burden container
// .exceedBurdenContainer ~ .exceedBurdenContainer {
// @include baseBurdenContainer();
// }

View file

@ -0,0 +1,14 @@
declare namespace ExceedBurdenNamespace {
export interface IExceedBurden {
exceedBurdenContainer: string;
burdenQuestion: string;
burdenValue: string;
}
}
declare const ExceedBurdenModule: ExceedBurdenNamespace.IExceedBurden & {
/** WARNING: Only available when `css-loader` is used without `style-loader` or `mini-css-extract-plugin` */
locals: ExceedBurdenNamespace.IExceedBurden;
};
export = ExceedBurdenModule;

View file

@ -0,0 +1,45 @@
import * as React from 'react';
import {render} from '@testing-library/react';
import {LocalizedComponent} from '../../test/testHelpers';
import ExceedBurden from './ExceedBurden';
import * as EXPLORE_COPY from '../../data/copy/explore';
describe('test rendering of Exceeds one or more burdens when', () => {
it('is burdended', () => {
const {asFragment} = render(
<LocalizedComponent>
<ExceedBurden text={EXPLORE_COPY.SIDE_PANEL_SPACERS.EXCEED_ONE_OR_MORE} isBurdened={true}/>
</LocalizedComponent>,
);
expect(asFragment()).toMatchSnapshot();
});
it('is NOT burdended', () => {
const {asFragment} = render(
<LocalizedComponent>
<ExceedBurden text={EXPLORE_COPY.SIDE_PANEL_SPACERS.EXCEED_ONE_OR_MORE} isBurdened={false}/>
</LocalizedComponent>,
);
expect(asFragment()).toMatchSnapshot();
});
});
describe('test rendering of Exceeds both socioeco burdens when', () => {
it('is burdended', () => {
const {asFragment} = render(
<LocalizedComponent>
<ExceedBurden text={EXPLORE_COPY.SIDE_PANEL_SPACERS.EXCEED_ONE_OR_MORE} isBurdened={true}/>
</LocalizedComponent>,
);
expect(asFragment()).toMatchSnapshot();
});
it('is NOT burdended', () => {
const {asFragment} = render(
<LocalizedComponent>
<ExceedBurden text={EXPLORE_COPY.SIDE_PANEL_SPACERS.EXCEED_BOTH_SOCIO} isBurdened={false}/>
</LocalizedComponent>,
);
expect(asFragment()).toMatchSnapshot();
});
});

View file

@ -0,0 +1,23 @@
import React from 'react';
import * as styles from './ExceedBurden.module.scss';
import * as EXPLORE_COPY from '../../data/copy/explore';
interface IExceedBurden {
text: React.ReactElement;
isBurdened: boolean;
}
const ExceedBurden = ({text, isBurdened}:IExceedBurden) => {
return (
<div className={styles.exceedBurdenContainer}>
<div className={styles.burdenQuestion}>
{text}
</div>
<div className={styles.burdenValue}>
{isBurdened ? EXPLORE_COPY.SIDE_PANEL_SPACERS.YES : EXPLORE_COPY.SIDE_PANEL_SPACERS.NO}
</div>
</div>
);
};
export default ExceedBurden;

View file

@ -0,0 +1,53 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`test rendering of Exceeds both socioeco burdens when is NOT burdended 1`] = `
<DocumentFragment>
<div>
<div>
At or above both associated thresholds?
</div>
<div>
No
</div>
</div>
</DocumentFragment>
`;
exports[`test rendering of Exceeds both socioeco burdens when is burdended 1`] = `
<DocumentFragment>
<div>
<div>
At or above at least one threshold?
</div>
<div>
Yes
</div>
</div>
</DocumentFragment>
`;
exports[`test rendering of Exceeds one or more burdens when is NOT burdended 1`] = `
<DocumentFragment>
<div>
<div>
At or above at least one threshold?
</div>
<div>
No
</div>
</div>
</DocumentFragment>
`;
exports[`test rendering of Exceeds one or more burdens when is burdended 1`] = `
<DocumentFragment>
<div>
<div>
At or above at least one threshold?
</div>
<div>
Yes
</div>
</div>
</DocumentFragment>
`;

View file

@ -0,0 +1,3 @@
import ExceedBurden from './ExceedBurden';
export default ExceedBurden;

View file

@ -4,14 +4,12 @@
@mixin indicator {
display: flex;
flex-direction: column;
@include u-padding-bottom(3);
&:last-child {
border-bottom: none;
@include u-padding-bottom(0);
}
@include u-padding-top(1.5);
@include u-padding-bottom(1.5);
.indicatorRow {
display: flex;
justify-content: space-between;
@media screen and (max-width: $mobileBreakpoint) {
flex: 1 0 40%;
@ -21,15 +19,16 @@
}
.indicatorName {
flex: 0 1 77%;
// flex: 0 1 77%;
flex-basis: 60%;
display: flex;
flex-direction: column;
@include typeset('sans', '2xs', 2);
@include u-text('bold');
@include u-text('medium');
.indicatorDesc {
@include typeset('sans', '3xs', 2);
@include u-text('normal');
@include u-text('thin');
max-width: 12rem;
@include u-margin-top(0);
@media screen and (max-width: 1024px) {
@ -38,13 +37,47 @@
}
}
.indicatorValue {
margin-left: 2.2rem;
.indicatorSuperscript {
top: -0.2em
.indicatorValueCol {
display: flex;
flex-direction: column;
.indicatorValueRow {
display: flex;
align-self: end;
.indicatorValue {
margin-left: 2.2rem;
.indicatorSuperscript {
top: -0.2em
}
}
.indicatorArrow {
margin-bottom: -.375rem;
img {
max-width: none;
height: 1.5rem;
width: 1.5rem;
}
.unavailable {
opacity: .2;
}
}
}
}
.indicatorValueSubText{
display: flex;
flex-direction: column;
align-self: flex-end;
text-align: right;
@include typeset('sans', '3xs', 2);
@include u-text('thin');
}
}
}
}
@ -55,5 +88,27 @@
.disadvantagedIndicator {
@include indicator;
@include u-text('blue-warm-70v');
@include u-bg('blue-warm-10');
// A darker bg color:
// background-color: #D2DAE3;
// Add a border
// border: 1px solid #1A4480;
margin: 0 -20px 1px -20px;
@include u-padding-left(2.5);
@include u-padding-right(2.5);
// Overwrite indicator mixin with bolder fonts for disadv. indicator
.indicatorRow {
.indicatorName {
@include u-text('bold');
.indicatorDesc {
@include u-text('normal');
}
}
}
}

View file

@ -4,8 +4,13 @@ declare namespace IndicatorNamespace {
indicatorBoxAdditional:string;
indicatorRow:string;
indicatorName:string;
indicatorValueCol:string;
indicatorValueRow:string;
indicatorValue:string;
indicatorSuperscript:string;
indicatorArrow:string;
unavailable:string;
indicatorValueSubText:string;
indicatorDesc:string;
disadvantagedIndicator:string;
}

View file

@ -1,13 +1,18 @@
import * as React from 'react';
import {render} from '@testing-library/react';
import {render, screen} from '@testing-library/react';
import {LocalizedComponent} from '../../test/testHelpers';
import Indicator, {readablePercentile} from './Indicator';
import {indicatorInfo} from '../AreaDetail';
import Indicator, {IndicatorValueIcon, IndicatorValueSubText, DisplayStatUnit} from './Indicator';
import {indicatorInfo} from '../AreaDetail/AreaDetail';
import * as EXPLORE_COPY from '../../data/copy/explore';
const highSchool:indicatorInfo = {
label: 'some label',
description: 'some description',
value: 97,
isDisadvagtaged: true,
isPercent: true,
threshold: 20,
};
describe('rendering of the Indicator', () => {
@ -22,9 +27,160 @@ describe('rendering of the Indicator', () => {
});
});
describe('tests the readablePercentile function', () => {
expect(readablePercentile(.98)).toEqual(98);
expect(readablePercentile(.07)).toEqual(7);
expect(readablePercentile(.123)).toEqual(12);
expect(readablePercentile(.789)).toEqual(79);
describe('test rendering of Indicator value icons', () => {
it('renders the up arrow when value is above threshold', () => {
const {asFragment} = render(
<LocalizedComponent>
<IndicatorValueIcon
value={90}
isAboveThresh={true}
/>
</LocalizedComponent>,
);
expect(asFragment()).toMatchSnapshot();
screen.getByAltText(EXPLORE_COPY.SIDE_PANEL_VALUES.IMG_ALT_TEXT.ARROW_UP.defaultMessage);
});
it('renders the down arrow when the value is above the threshold', () => {
const {asFragment} = render(
<LocalizedComponent>
<IndicatorValueIcon
value={13}
isAboveThresh={false}
/>
</LocalizedComponent>,
);
expect(asFragment()).toMatchSnapshot();
screen.getByAltText(EXPLORE_COPY.SIDE_PANEL_VALUES.IMG_ALT_TEXT.ARROW_DOWN.defaultMessage);
});
it('renders the down arrow when the value is zero', () => {
const {asFragment} = render(
<LocalizedComponent>
<IndicatorValueIcon
value={0}
isAboveThresh={false}
/>
</LocalizedComponent>,
);
expect(asFragment()).toMatchSnapshot();
screen.getByAltText(EXPLORE_COPY.SIDE_PANEL_VALUES.IMG_ALT_TEXT.ARROW_DOWN.defaultMessage);
});
it('renders the unavailable icon when the value is null', () => {
const {asFragment} = render(
<LocalizedComponent>
<IndicatorValueIcon
value={null}
isAboveThresh={false}
/>
</LocalizedComponent>,
);
expect(asFragment()).toMatchSnapshot();
screen.getByAltText(EXPLORE_COPY.SIDE_PANEL_VALUES.IMG_ALT_TEXT.UNAVAILABLE.defaultMessage);
});
});
describe('test rendering of Indicator value sub-text', () => {
it('renders the "above 90 percentile"', () => {
const {asFragment} = render(
<LocalizedComponent>
<IndicatorValueSubText
value={95}
isAboveThresh={true}
threshold={90}
isPercent={false}
/>
</LocalizedComponent>,
);
expect(asFragment()).toMatchSnapshot();
console.log(asFragment());
});
it('renders the "below 90 percentile"', () => {
const {asFragment} = render(
<LocalizedComponent>
<IndicatorValueSubText
value={89}
isAboveThresh={false}
threshold={90}
isPercent={false}
/>
</LocalizedComponent>,
);
expect(asFragment()).toMatchSnapshot();
});
it('renders the "data is not available"', () => {
const {asFragment} = render(
<LocalizedComponent>
<IndicatorValueSubText
value={null}
isAboveThresh={false}
threshold={90}
isPercent={false}
/>
</LocalizedComponent>,
);
expect(asFragment()).toMatchSnapshot();
});
});
describe('test that the unit suffix renders correctly', ()=> {
it('renders correctly when the value is a percentile', () => {
const lowLife:indicatorInfo = {
label: 'some label',
description: 'some description',
value: 97,
isDisadvagtaged: true,
isPercent: false,
threshold: 20,
};
const {asFragment} = render(
<LocalizedComponent>
<DisplayStatUnit
indicator={lowLife}
displayStat={90}
/>
</LocalizedComponent>,
);
expect(asFragment()).toMatchSnapshot();
});
it('renders correctly when the value is a percent', () => {
const lowLife:indicatorInfo = {
label: 'some label',
description: 'some description',
value: 97,
isDisadvagtaged: true,
isPercent: true,
threshold: 20,
};
const {asFragment} = render(
<LocalizedComponent>
<DisplayStatUnit
indicator={lowLife}
displayStat={90}
/>
</LocalizedComponent>,
);
expect(asFragment()).toMatchSnapshot();
});
it('renders correctly when the value is a null', () => {
const lowLife:indicatorInfo = {
label: 'some label',
description: 'some description',
value: null,
isDisadvagtaged: true,
isPercent: false,
};
const {asFragment} = render(
<LocalizedComponent>
<DisplayStatUnit
indicator={lowLife}
displayStat={null}
/>
</LocalizedComponent>,
);
expect(asFragment()).toMatchSnapshot();
});
});

View file

@ -1,18 +1,126 @@
import React from 'react';
import {indicatorInfo} from '../AreaDetail';
import {useIntl} from 'gatsby-plugin-intl';
import {indicatorInfo} from '../AreaDetail/AreaDetail';
import * as styles from './Indicator.module.scss';
import * as constants from '../../data/constants';
import * as EXPLORE_COPY from '../../data/copy/explore';
// @ts-ignore
import downArrow from '/node_modules/uswds/dist/img/usa-icons/arrow_downward.svg';
// @ts-ignore
import upArrow from '/node_modules/uswds/dist/img/usa-icons/arrow_upward.svg';
// @ts-ignore
import unAvailable from '/node_modules/uswds/dist/img/usa-icons/do_not_disturb.svg';
interface IIndicator {
indicator: indicatorInfo,
}
export const readablePercentile = (percentile: number | null) => {
return percentile !== null ? Math.round(percentile * 100) : 'N/A';
interface IIndicatorValueIcon {
value: number | null,
isAboveThresh: boolean,
};
interface IIndicatorValueSubText {
value: number | null,
isAboveThresh: boolean,
threshold: number,
isPercent: boolean | undefined,
}
interface IDisplayStatUnit {
indicator: indicatorInfo,
displayStat: number | null,
}
/**
* This component will determine what indicator's icon should be (arrowUp, arrowDown or unavailable) and
* return the appropriate JSX.
*
* @param {number | null} props
* @return {JSX.Element}
*/
export const IndicatorValueIcon = ({value, isAboveThresh}: IIndicatorValueIcon) => {
const intl = useIntl();
if (value == null) {
return <img className={styles.unavailable}
src={unAvailable}
alt={intl.formatMessage(EXPLORE_COPY.SIDE_PANEL_VALUES.IMG_ALT_TEXT.UNAVAILABLE)}
/>;
} else {
return isAboveThresh ?
<img
src={upArrow}
alt={intl.formatMessage(EXPLORE_COPY.SIDE_PANEL_VALUES.IMG_ALT_TEXT.ARROW_UP)}
/> :
<img
src={downArrow}
alt={intl.formatMessage(EXPLORE_COPY.SIDE_PANEL_VALUES.IMG_ALT_TEXT.ARROW_DOWN)}
/>;
}
};
/**
* This component will determine the sub-text of the indicator's value, some examples could be
* "above 90th percentile"
* "below 20 percent"
* "data is not available"
*
* Todo: refactor into single component, add to i18n and add to tests
*
* @return {JSX.Element}
*/
export const IndicatorValueSubText = ({value, isAboveThresh, threshold, isPercent}:IIndicatorValueSubText) => {
return value == null ?
<div>
{EXPLORE_COPY.SIDE_PANEL_VALUES.UNAVAILBLE_MSG}
</div> :
<React.Fragment>
<div>
{
isAboveThresh ?
EXPLORE_COPY.SIDE_PANEL_VALUES.ABOVE :
EXPLORE_COPY.SIDE_PANEL_VALUES.BELOW
}
{`${threshold ? threshold : 90}`}
{!isPercent && `th`}
</div>
<div>
{
isPercent ?
EXPLORE_COPY.SIDE_PANEL_VALUES.PERCENT :
EXPLORE_COPY.SIDE_PANEL_VALUES.PERCENTILE
}
</div>
</React.Fragment>;
};
/**
* This component will return the value suffix as either a percent or
* ordinal value of the displayed statistic
*
* @return {JSX.Element}
*/
export const DisplayStatUnit = ({indicator, displayStat}:IDisplayStatUnit) => {
if (indicator.value !== null) {
return indicator.isPercent ?
<span>{`%`}</span> :
<sup className={styles.indicatorSuperscript}>
<span>{getSuperscriptOrdinal(displayStat)}</span>
</sup>;
} else {
return <React.Fragment></React.Fragment>;
}
};
// Todo: Add internationalization to superscript ticket #582
export const getSuperscriptOrdinal = (percentile: number | string) => {
export const getSuperscriptOrdinal = (percentile: number | string | null) => {
if (percentile === null) return '';
if (typeof percentile === 'number') {
const englishOrdinalRules = new Intl.PluralRules('en', {
type: 'ordinal',
@ -29,26 +137,66 @@ export const getSuperscriptOrdinal = (percentile: number | string) => {
}
};
/**
* This component will return the list element which will be the indicator row in the side panel
*
* @param {IIndicator} indicator
* @return {JSX.Element}
*/
const Indicator = ({indicator}:IIndicator) => {
// Convert the decimal value to a stat to display
const displayStat = indicator.value !== null ? Math.round(indicator.value * 100) : null;
// If the threshold exists, set it, otherwise set it to the default value
const threshold = indicator.threshold ? indicator.threshold : constants.DEFAULT_THRESHOLD_PERCENTILE;
// A boolean to represent if the indicator is above or below the threshold
const isAboveThresh = displayStat !== null && displayStat >= threshold ? true : false;
return (
<li
className={indicator.isDisadvagtaged ? styles.disadvantagedIndicator : styles.indicatorBoxMain}
data-cy={'indicatorBox'}>
data-cy={'indicatorBox'}
data-testid='indicator-box'>
<div className={styles.indicatorRow}>
{/* Indicator name and description*/}
<div className={styles.indicatorName}>
{indicator.label}
<div className={styles.indicatorDesc}>
{indicator.description}
</div>
</div>
<div className={styles.indicatorValue}>
{readablePercentile(indicator.value)}
{indicator.isPercent ?
<span>{`%`}</span> :
<sup className={styles.indicatorSuperscript}>
<span>{getSuperscriptOrdinal(readablePercentile(indicator.value))}</span>
</sup>
}
{/* Indicator value, icon and subtext */}
<div className={styles.indicatorValueCol}>
<div className={styles.indicatorValueRow}>
{/* Indicator value */}
<div className={styles.indicatorValue}>
{displayStat}
<DisplayStatUnit indicator={indicator} displayStat={displayStat}/>
</div>
{/* Indicator icon - up arrow, down arrow, or unavailable */}
<div className={styles.indicatorArrow}>
<IndicatorValueIcon
value={displayStat}
isAboveThresh={isAboveThresh}
/>
</div>
</div>
{/* Indicator sub-text */}
<div className={styles.indicatorValueSubText}>
<IndicatorValueSubText
value={displayStat}
isAboveThresh={isAboveThresh}
threshold={threshold}
isPercent={indicator.isPercent}
/>
</div>
</div>
</div>
</li>

View file

@ -4,6 +4,7 @@ exports[`rendering of the Indicator checks if component renders 1`] = `
<DocumentFragment>
<li
data-cy="indicatorBox"
data-testid="indicator-box"
>
<div>
<div>
@ -13,14 +14,116 @@ exports[`rendering of the Indicator checks if component renders 1`] = `
</div>
</div>
<div>
9700
<sup>
<span>
th
</span>
</sup>
<div>
<div>
9700
<span>
%
</span>
</div>
<div>
<img
alt="an icon for the up arrow"
src="test-file-stub"
/>
</div>
</div>
<div>
<div>
above 20
</div>
<div>
percent
</div>
</div>
</div>
</div>
</li>
</DocumentFragment>
`;
exports[`test rendering of Indicator value icons renders the down arrow when the value is above the threshold 1`] = `
<DocumentFragment>
<img
alt="an icon for the down arrow"
src="test-file-stub"
/>
</DocumentFragment>
`;
exports[`test rendering of Indicator value icons renders the down arrow when the value is zero 1`] = `
<DocumentFragment>
<img
alt="an icon for the down arrow"
src="test-file-stub"
/>
</DocumentFragment>
`;
exports[`test rendering of Indicator value icons renders the unavailable icon when the value is null 1`] = `
<DocumentFragment>
<img
alt="an icon to represent data is unavailable"
src="test-file-stub"
/>
</DocumentFragment>
`;
exports[`test rendering of Indicator value icons renders the up arrow when value is above threshold 1`] = `
<DocumentFragment>
<img
alt="an icon for the up arrow"
src="test-file-stub"
/>
</DocumentFragment>
`;
exports[`test rendering of Indicator value sub-text renders the "above 90 percentile" 1`] = `
<DocumentFragment>
<div>
above 90th
</div>
<div>
percentile
</div>
</DocumentFragment>
`;
exports[`test rendering of Indicator value sub-text renders the "below 90 percentile" 1`] = `
<DocumentFragment>
<div>
below 90th
</div>
<div>
percentile
</div>
</DocumentFragment>
`;
exports[`test rendering of Indicator value sub-text renders the "data is not available" 1`] = `
<DocumentFragment>
<div>
data is not available
</div>
</DocumentFragment>
`;
exports[`test that the unit suffix renders correctly renders correctly when the value is a null 1`] = `<DocumentFragment />`;
exports[`test that the unit suffix renders correctly renders correctly when the value is a percent 1`] = `
<DocumentFragment>
<span>
%
</span>
</DocumentFragment>
`;
exports[`test that the unit suffix renders correctly renders correctly when the value is a percentile 1`] = `
<DocumentFragment>
<sup>
<span>
th
</span>
</sup>
</DocumentFragment>
`;

View file

@ -66,3 +66,7 @@
}
}
}
.alert {
@include u-margin-top(4);
}

View file

@ -9,6 +9,7 @@ declare namespace J40HeaderNamespace {
title2BetaPill: string;
betaPill: string;
navLinks: string;
alert: string;
}
}

View file

@ -5,6 +5,7 @@ import {
NavMenuButton,
PrimaryNav,
Grid,
Alert,
} from '@trussworks/react-uswds';
import BetaBanner from '../BetaBanner';
import J40MainGridContainer from '../J40MainGridContainer';
@ -16,6 +17,8 @@ import siteLogo from '../../images/j40-logo-v2.png';
import * as styles from './J40Header.module.scss';
import * as COMMON_COPY from '../../data/copy/common';
const isAlertValid = new Date < COMMON_COPY.ALERTS.EXPIRATION_DATE;
const J40Header = () => {
const intl = useIntl();
const [mobileNavOpen, setMobileNavOpen] = useState(false);
@ -67,8 +70,6 @@ const J40Header = () => {
<GovernmentBanner />
<BetaBanner/>
{/* Remove Usabilty Banner testing deployment to main again!*/}
{/* Logo and Navigation */}
<J40MainGridContainer>
@ -106,6 +107,17 @@ const J40Header = () => {
</Grid>
</J40MainGridContainer>
{/* Alert */}
{isAlertValid && <J40MainGridContainer>
<Alert
className={styles.alert}
type="info"
heading={intl.formatMessage(COMMON_COPY.ALERTS.CENSUS_TRACT.TITLE)}>
{COMMON_COPY.ALERTS.CENSUS_TRACT_DESCRIPTION}
</Alert>
</J40MainGridContainer>
}
</Header>
);
};

View file

@ -268,6 +268,40 @@ exports[`rendering of the J40Header checks if component renders 1`] = `
</div>
</div>
</div>
<div
class="grid-container-desktop-lg"
data-testid="gridContainer"
>
<div
class="usa-alert usa-alert--info"
data-testid="alert"
>
<div
class="usa-alert__body"
>
<h4
class="usa-alert__heading"
>
Improvements to the map on the Explore the tool page
</h4>
<p
class="usa-alert__text"
>
View improvements made to the display of the information for each census tract and
<a
class="usa-link usa-link--external"
data-cy=""
href="mailto:Screeningtool-Support@omb.eop.gov"
rel="noreferrer"
target="_blank"
>
send feedback
</a>
.
</p>
</div>
</div>
</div>
</header>
</DocumentFragment>
`;

View file

@ -27,12 +27,13 @@ import AreaDetail from './AreaDetail';
import MapInfoPanel from './mapInfoPanel';
import MapSearch from './MapSearch';
import TerritoryFocusControl from './territoryFocusControl';
import {getOSBaseMap} from '../data/getOSBaseMap';
// Styles and constants
import {getOSBaseMap} from '../data/getOSBaseMap';
import 'maplibre-gl/dist/maplibre-gl.css';
import * as constants from '../data/constants';
import * as styles from './J40Map.module.scss';
import * as COMMON_COPY from '../data/copy/common';
declare global {
@ -54,6 +55,49 @@ export interface IDetailViewInterface {
properties: constants.J40Properties,
};
/**
* This function will determine the URL for the map tiles. It will read in a string that will designate either
* high or low tiles. It will allow to overide the URL to the pipeline staging tile URL via feature flag.
* Lastly, it allows to set the tiles to be local or via the CDN as well.
*
* @param {string} tilesetName
* @returns {string}
*/
export const featureURLForTilesetName = (tilesetName: string): string => {
const flags = useFlags();
const pipelineStagingBaseURL = `https://justice40-data.s3.amazonaws.com/data-pipeline-staging`;
const XYZ_SUFFIX = '{z}/{x}/{y}.pbf';
if ('stage_hash' in flags) {
// Check if the stage_hash is valid
const regex = /^[0-9]{4}\/[a-f0-9]{40}$/;
if (!regex.test(flags['stage_hash'])) {
console.error(COMMON_COPY.CONSOLE_ERROR.STAGE_URL);
}
return `${pipelineStagingBaseURL}/${flags['stage_hash']}/data/score/tiles/${tilesetName}/${XYZ_SUFFIX}`;
} else {
// The feature tile base URL and path can either point locally or the CDN.
// This is selected based on the DATA_SOURCE env variable.
const featureTileBaseURL = process.env.DATA_SOURCE === 'local' ?
process.env.GATSBY_LOCAL_TILES_BASE_URL :
process.env.GATSBY_CDN_TILES_BASE_URL;
const featureTilePath = process.env.DATA_SOURCE === 'local' ?
process.env.GATSBY_DATA_PIPELINE_SCORE_PATH_LOCAL :
process.env.GATSBY_DATA_PIPELINE_SCORE_PATH;
return [
featureTileBaseURL,
featureTilePath,
process.env.GATSBY_MAP_TILES_PATH,
tilesetName,
XYZ_SUFFIX,
].join('/');
}
};
const J40Map = ({location}: IJ40Interface) => {
/**
@ -304,7 +348,7 @@ const J40Map = ({location}: IJ40Interface) => {
id={constants.LOW_ZOOM_SOURCE_NAME}
type="vector"
promoteId={constants.GEOID_PROPERTY}
tiles={[constants.FEATURE_TILE_LOW_ZOOM_URL]}
tiles={[featureURLForTilesetName('low')]}
maxzoom={constants.GLOBAL_MAX_ZOOM_LOW}
minzoom={constants.GLOBAL_MIN_ZOOM_LOW}
>
@ -330,7 +374,7 @@ const J40Map = ({location}: IJ40Interface) => {
id={constants.HIGH_ZOOM_SOURCE_NAME}
type="vector"
promoteId={constants.GEOID_PROPERTY}
tiles={[constants.FEATURE_TILE_HIGH_ZOOM_URL]}
tiles={[featureURLForTilesetName('high')]}
maxzoom={constants.GLOBAL_MAX_ZOOM_HIGH}
minzoom={constants.GLOBAL_MIN_ZOOM_HIGH}
>

View file

@ -17,6 +17,12 @@ interface ILanguageProps {
isDesktop: boolean
}
/**
* Language component that will allow the user to change languages
*
* @param {boolean} isDesktop
* @return {JSX.Element | null}
*/
const Language = ({isDesktop}:ILanguageProps) => {
const flags = useFlags();

View file

@ -1,20 +0,0 @@
@use '../../styles/design-system.scss' as *;
.lowIncomeContainer {
border: 1px solid #DFE1E2;
@include u-margin-top(4);
@include u-padding-left(4);
@include u-padding-right(3);
@include u-padding-bottom(4);
.lowIncomeTitle {
@include typeset('sans', 'xs', 3);
@include u-text('semibold');
}
.lowIncomeText {
@include typeset('sans', 'xs', 3);
@include u-text('light');
}
};

View file

@ -1,14 +0,0 @@
declare namespace LowIncomeNamespace {
export interface ILowIncomeScss {
lowIncomeContainer: string;
lowIncomeTitle: string;
lowIncomeText: string;
}
}
declare const LowIncomeScssModule: LowIncomeNamespace.ILowIncomeScss & {
/** WARNING: Only available when `css-loader` is used without `style-loader` or `mini-css-extract-plugin` */
locals: LowIncomeNamespace.ILowIncomeScss;
};
export = LowIncomeScssModule;

View file

@ -1,26 +0,0 @@
import React from 'react';
import {useIntl} from 'gatsby-plugin-intl';
import * as METHODOLOGY_COPY from '../../data/copy/methodology';
import * as styles from './LowIncome.module.scss';
const LowIncome = () => {
const intl = useIntl();
return (
<div className={styles.lowIncomeContainer}>
<p className={styles.lowIncomeTitle}>
<sup>*</sup>
{' '}
{intl.formatMessage(METHODOLOGY_COPY.LOW_INCOME.HEADING)}
</p>
<p className={styles.lowIncomeText}>
{intl.formatMessage(METHODOLOGY_COPY.LOW_INCOME.INFO)}
</p>
</div>
);
};
export default LowIncome;

View file

@ -1,20 +0,0 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`rendering of the LowIncome checks if component renders 1`] = `
<DocumentFragment>
<div>
<p>
<sup>
*
</sup>
Low Income
</p>
<p>
At or above 65th percentile for percent of census tract population of households where household
income is at or below 200% of the Federal poverty level
</p>
</div>
</DocumentFragment>
`;

View file

@ -1,3 +0,0 @@
import LowIncome from './LowIncome';
export default LowIncome;

View file

@ -17,29 +17,10 @@ const MapWrapper = ({location}: IMapWrapperProps) => {
<J40Map location={location}/>
</Grid>
<Grid row>
<Grid col={7}>
<div className={styles.mapCaptionTextLink}>
{EXPLORE_COPY.DOWNLOAD_DRAFT.PARAGRAPH_1}
</div>
</Grid>
</Grid>
<Grid row>
<Grid col={7}>
<h2>{EXPLORE_COPY.NOTE_ON_TERRITORIES.INTRO}</h2>
<p>{EXPLORE_COPY.NOTE_ON_TERRITORIES.PARA_1}</p>
<p>{EXPLORE_COPY.NOTE_ON_TERRITORIES.PARA_2}</p>
<p>{EXPLORE_COPY.NOTE_ON_TERRITORIES.PARA_3}</p>
<p>{EXPLORE_COPY.NOTE_ON_TERRITORIES.PARA_4}</p>
</Grid>
</Grid>
<Grid row>
<Grid col={7}>
<h2>{EXPLORE_COPY.NOTE_ON_TRIBAL_NATIONS.INTRO}</h2>
<p>{EXPLORE_COPY.NOTE_ON_TRIBAL_NATIONS.PARA_1}</p>
</Grid>
<Grid desktop={{col: 7}} tablet={{col: 10}} col={12}>
<div className={styles.mapCaptionTextLink}>
{EXPLORE_COPY.DOWNLOAD_DRAFT.PARAGRAPH_1}
</div>
</Grid>
</>
);

View file

@ -12,18 +12,18 @@ exports[`rendering of the MethodologyFormula checks if component renders 1`] = `
<p>
<span>
<strong>
IF
</span>
</strong>
the census tract is above the threshold for one or more environmental or climate indicators
</p>
<p>
<span>
<strong>
AND
</span>
</strong>
the census tract is above the threshold for the socioeconomic indicators
</p>

View file

@ -1,10 +1,11 @@
@use '../../styles/design-system.scss' as *;
.tagContainer {
align-self: flex-end;
@include u-margin-bottom(1);
@include u-margin-right(1);
.tag {
@include u-bg("yellow-20v");
@include u-bg("gray-cool-10");
color: black;
border-radius: 5px;
@include u-text('bold');
@ -12,6 +13,8 @@
}
.container {
display: flex;
flex-direction: column;
@include u-padding-top(2.5);
.link, .link:visited {

View file

@ -1,6 +1,5 @@
import React from 'react';
import {Link} from 'gatsby';
import {useIntl} from 'gatsby-plugin-intl';
import {useIntl, Link} from 'gatsby-plugin-intl';
import {Button, Tag} from '@trussworks/react-uswds';
import * as styles from './PublicEngageButton.module.scss';

View file

@ -8,11 +8,11 @@ exports[`rendering of the PublicEngageButton checks if component renders 1`] = `
class="usa-tag"
data-testid="tag"
>
NEW
UPDATED
</span>
</div>
<a
href="/public-engagement"
href="/en/public-engagement"
>
<button
class="usa-button usa-button--icon"

View file

@ -19,8 +19,9 @@ export interface IPublicEvent {
DESC: JSX.Element,
NUMBER: Number,
IMAGE: React.ReactElement | string,
EXPIRED_IMG: React.ReactElement | string,
FIELDS: JSX.Element,
REG_LINK: string,
REG_LINK?: string | null,
DATA_CY: string,
}
}
@ -29,24 +30,27 @@ export interface IPublicEvent {
const PublicEvent = ({event}:IPublicEvent) => {
const intl = useIntl();
const eventName = event.NUMBER === 0 ?
`CEJST ${intl.formatMessage(event.NAME)}` :
`CEJST ${intl.formatMessage(event.NAME)} #${event.NUMBER}`;
const isEventExpired = new Date() > event.DATE;
return (
<CollectionItem
variantComponent={
<CollectionThumbnail src={event.IMAGE} alt="Alt text" />
<CollectionThumbnail src={isEventExpired ? event.EXPIRED_IMG : event.IMAGE} alt="Alt text" />
}>
{/* Heading */}
<CollectionHeading>
<LinkTypeWrapper
linkText={`CEJST
${intl.formatMessage(event.NAME)}
#${event.NUMBER}
`}
{isEventExpired ? eventName : <LinkTypeWrapper
linkText={eventName}
internal={false}
url={event.REG_LINK}
openUrlNewTab={true}
dataCy={event.DATA_CY}
/>
/>}
</CollectionHeading>
{/* Description */}
@ -65,7 +69,7 @@ const PublicEvent = ({event}:IPublicEvent) => {
{/* Registration Link */}
<CollectionDescription className={styles.description}>
<a href={event.REG_LINK} target={'_blank'} rel="noreferrer">
<Button type='button'>
<Button type='button' disabled={isEventExpired ? true : false}>
{intl.formatMessage(PUBLIC_ENGAGE_COPY.EVENT_FIELDS.REG_LINK)}
</Button>
</a>

View file

@ -16,18 +16,7 @@ exports[`rendering of the PublicEvent checks if component renders 1`] = `
<h3
class="usa-collection__heading"
>
<a
class="usa-link usa-link--external"
data-cy="mar-9-reg-link-block"
href="https://pitc.zoomgov.com/webinar/register/WN_D-Om_xXhTtiLv71y3Rr1CQ"
rel="noreferrer"
target="_blank"
>
CEJST
training session
#1
</a>
CEJST training session #1
</h3>
<p
class="usa-collection__description"
@ -59,6 +48,7 @@ exports[`rendering of the PublicEvent checks if component renders 1`] = `
<button
class="usa-button"
data-testid="button"
disabled=""
type="button"
>
Registration link

View file

@ -0,0 +1,21 @@
@use '../../styles/design-system.scss' as *;
.sidePanelInfoContainer {
display: flex;
flex-direction: column;
@include u-padding-right(4);
@include u-padding-left(4);
@include u-padding-bottom(4);
.sidePanelInfoHeading {
@include u-padding-top(2);
font-size: x-large;
line-height: 1.9rem;
}
.sidePanelInfoIcon {
@include u-height(5);
@include u-margin-top(4);
@include u-margin-bottom(-2)
}
}

View file

@ -1,12 +1,8 @@
declare namespace MapIntroductionModuleScssNamespace {
export interface IMapIntroductionModuleScss {
mapIntroContainer: string;
mapIntroHeader: string;
mapIntroText: string;
mapIntroLightbulb: string;
didYouKnowBox: string
didYouKnow: string
didYouKnowText: string
sidePanelInfoContainer: string;
sidePanelInfoHeading: string;
sidePanelInfoIcon: string;
}
}

View file

@ -1,16 +1,16 @@
import * as React from 'react';
import {render} from '@testing-library/react';
import SidePanelInfo from './SidePanelInfo';
import {LocalizedComponent} from '../../test/testHelpers';
import LowIncome from './LowIncome';
describe('rendering of the LowIncome', () => {
describe('rendering of the component', () => {
const {asFragment} = render(
<LocalizedComponent>
<LowIncome />
<SidePanelInfo />
</LocalizedComponent>,
);
it('checks if component renders', () => {
it('expects the render to match snapshot', () => {
expect(asFragment()).toMatchSnapshot();
});
});

View file

@ -0,0 +1,60 @@
import React from 'react';
import {useIntl} from 'gatsby-plugin-intl';
// @ts-ignore
import puzzle from '../../images/sidePanelIcons/puzzle.svg';
// @ts-ignore
import bellCurve from '../../images/sidePanelIcons/bellCurve.svg';
// @ts-ignore
import pieChart from '../../images/sidePanelIcons/pieChart.svg';
// @ts-ignore
import upDown from '../../images/sidePanelIcons/upDown.svg';
import * as styles from './SidePanelInfo.module.scss';
import * as EXPLORE_COPY from '../../data/copy/explore';
const MapIntroduction = () => {
const intl = useIntl();
return (
<aside className={styles.sidePanelInfoContainer}>
<header tabIndex={0} className={styles.sidePanelInfoHeading}>
{intl.formatMessage(EXPLORE_COPY.SIDE_PANEL_INITIAL_STATE.TITLE)}
</header>
<p tabIndex={0}>
{intl.formatMessage(EXPLORE_COPY.SIDE_PANEL_INITIAL_STATE.PARA1)}
</p>
<img tabIndex={0} className={styles.sidePanelInfoIcon}
src={puzzle}
alt={intl.formatMessage(EXPLORE_COPY.SIDE_PANEL_INITIAL_STATE.ALT_TEXT_ICON1)}
/>
<p tabIndex={0}>
{intl.formatMessage(EXPLORE_COPY.SIDE_PANEL_INITIAL_STATE.PARA2)}
</p>
<img tabIndex={0} className={styles.sidePanelInfoIcon}
src={bellCurve}
alt={intl.formatMessage(EXPLORE_COPY.SIDE_PANEL_INITIAL_STATE.ALT_TEXT_ICON2)}
/>
<p tabIndex={0}>
{intl.formatMessage(EXPLORE_COPY.SIDE_PANEL_INITIAL_STATE.PARA3)}
</p>
<img tabIndex={0} className={styles.sidePanelInfoIcon}
src={pieChart}
alt={intl.formatMessage(EXPLORE_COPY.SIDE_PANEL_INITIAL_STATE.ALT_TEXT_ICON3)}
/>
<p tabIndex={0}>
{intl.formatMessage(EXPLORE_COPY.SIDE_PANEL_INITIAL_STATE.PARA4)}
</p>
<img tabIndex={0} className={styles.sidePanelInfoIcon}
src={upDown}
alt={intl.formatMessage(EXPLORE_COPY.SIDE_PANEL_INITIAL_STATE.ALT_TEXT_ICON4)}
/>
<p tabIndex={0}>
{EXPLORE_COPY.SIDE_PANEL_INITIAL_STATE_PARA5}
</p>
</aside>
);
};
export default MapIntroduction;

View file

@ -0,0 +1,76 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`rendering of the component expects the render to match snapshot 1`] = `
<DocumentFragment>
<aside>
<header
tabindex="0"
>
Things to know
</header>
<p
tabindex="0"
>
This tool identifies communities that are marginalized, underserved, and overburdened by pollution. These communities are located in census tracts that are at or above the thresholds in one or more of eight categories of criteria.
</p>
<img
alt="
An icon that has depicts pieces of a block selected mimicing the census block census tracts
"
src="test-file-stub"
tabindex="0"
/>
<p
tabindex="0"
>
The tool uses census tracts that represent about 4,000 people, which is the smallest unit of geography for which consistent data can be displayed on the tool.
</p>
<img
alt="
An icon that a bell curve or gaussian distribution
"
src="test-file-stub"
tabindex="0"
/>
<p
tabindex="0"
>
The tool ranks each census tract using percentiles that show how much burden each tract experiences relative to all other tracts, for each criteria.
</p>
<img
alt="
An icon that depicts a part of pie chart being removed
"
src="test-file-stub"
tabindex="0"
/>
<p
tabindex="0"
>
Percentages are used for certain variables, i.e. those relating to high school achievement rate and to the share of individuals not currently enrolled in higher education.
</p>
<img
alt="
An icon that has an up arrow and a down arrow
"
src="test-file-stub"
tabindex="0"
/>
<p
tabindex="0"
>
Thresholds for each category determine if a tract should be identified as disadvantaged because it has exceeded a certain value for the relevant indicators.
</p>
</aside>
</DocumentFragment>
`;

View file

@ -0,0 +1,3 @@
import SidePanelInfo from './SidePanelInfo';
export default SidePanelInfo;

View file

@ -8,29 +8,74 @@ exports[`simulate app starting up, no click on map should match the snapshot of
class="someClassName"
>
<aside>
<header>
Zoom and select a census tract to view data
<header
tabindex="0"
>
Things to know
</header>
<div>
<img
alt="icon showing a lightbulb"
src="test-file-stub"
/>
<div>
<div>
Did you know?
</div>
<cite>
A census tract is generally between 1,200 to 8,000 people, with an average size of 4,000 people.
Census tracts are small, relatively permanent subdivisions of a county defined by the
U.S. Census Bureau and usually cover a contiguous area. The census tract level currently represents the
smallest geographical unit for which publicly-available and nationally-consistent datasets can
be consistently displayed on the tool.
<p
tabindex="0"
>
This tool identifies communities that are marginalized, underserved, and overburdened by pollution. These communities are located in census tracts that are at or above the thresholds in one or more of eight categories of criteria.
</cite>
</div>
</div>
</p>
<img
alt="
An icon that has depicts pieces of a block selected mimicing the census block census tracts
"
src="test-file-stub"
tabindex="0"
/>
<p
tabindex="0"
>
The tool uses census tracts that represent about 4,000 people, which is the smallest unit of geography for which consistent data can be displayed on the tool.
</p>
<img
alt="
An icon that a bell curve or gaussian distribution
"
src="test-file-stub"
tabindex="0"
/>
<p
tabindex="0"
>
The tool ranks each census tract using percentiles that show how much burden each tract experiences relative to all other tracts, for each criteria.
</p>
<img
alt="
An icon that depicts a part of pie chart being removed
"
src="test-file-stub"
tabindex="0"
/>
<p
tabindex="0"
>
Percentages are used for certain variables, i.e. those relating to high school achievement rate and to the share of individuals not currently enrolled in higher education.
</p>
<img
alt="
An icon that has an up arrow and a down arrow
"
src="test-file-stub"
tabindex="0"
/>
<p
tabindex="0"
>
Thresholds for each category determine if a tract should be identified as disadvantaged because it has exceeded a certain value for the relevant indicators.
</p>
</aside>
</div>
</DocumentFragment>

View file

@ -1,6 +1,6 @@
import React from 'react';
import MapIntroduction from './mapIntroduction';
import AreaDetail from './AreaDetail';
import SidePanelInfo from './SidePanelInfo';
interface IMapInfoPanelProps {
className: string,
@ -13,7 +13,7 @@ const MapInfoPanel = ({className, featureProperties, selectedFeatureId}:IMapInfo
<div className={className} >
{(featureProperties && selectedFeatureId ) ?
<AreaDetail properties={featureProperties} /> :
<MapIntroduction />
<SidePanelInfo />
}
</div>
);

View file

@ -1,34 +0,0 @@
.mapIntroContainer {
padding: 20px 20px;
}
.mapIntroHeader {
font-size: xx-large;
line-height: 1.9rem;
padding-top: 0.8rem;
padding-left: 0.3rem;
}
.mapIntroText {
display: flex;
margin-top: 2.4rem;
}
.mapIntroLightbulb {
flex: 1 0 10%;
align-self: flex-start;
}
.didYouKnowBox {
padding-left: 0.4rem;
padding-top: 0.2rem;
font-size: large;
}
.didYouKnow {
font-weight: 600;
}
.didYouKnowText {
width: 95%;
padding-top: 0.3rem;
line-height: 1.5rem;
}

View file

@ -1,16 +0,0 @@
import * as React from 'react';
import {render, screen} from '@testing-library/react';
import MapIntroduction from './mapIntroduction';
import {LocalizedComponent} from '../../src/test/testHelpers';
describe('rendering of the component', () => {
render(
<LocalizedComponent>
<MapIntroduction />
</LocalizedComponent>,
);
it('renders the title', () => {
expect(screen.getByRole('banner')).toHaveTextContent('Zoom and select a census tract to view data');
});
});

View file

@ -1,32 +0,0 @@
import React from 'react';
import {useIntl} from 'gatsby-plugin-intl';
// @ts-ignore
import lightbulbIcon from '/node_modules/uswds/dist/img/usa-icons/lightbulb_outline.svg';
import * as styles from './mapIntroduction.module.scss';
import * as EXPLORE_COPY from '../data/copy/explore';
const MapIntroduction = () => {
const intl = useIntl();
return (
<aside className={styles.mapIntroContainer}>
<header className={styles.mapIntroHeader}>
{intl.formatMessage(EXPLORE_COPY.SIDE_PANEL_INITIAL_STATE.TITLE)}
</header>
<div className={styles.mapIntroText}>
<img className={styles.mapIntroLightbulb} src={lightbulbIcon} alt={'icon showing a lightbulb'}/>
<div className={styles.didYouKnowBox}>
<div className={styles.didYouKnow}>
{intl.formatMessage(EXPLORE_COPY.SIDE_PANEL_INITIAL_STATE.DID_YOU_KNOW)}
</div>
<cite className={styles.didYouKnowText}>
{intl.formatMessage(EXPLORE_COPY.SIDE_PANEL_INITIAL_STATE.CBG_DEFINITION)}
</cite>
</div>
</div>
</aside>
);
};
export default MapIntroduction;

View file

@ -1,18 +1,20 @@
@use '../styles/design-system.scss' as *;
@mixin baseTerritoryFocus {
position: absolute;
left: .75em;
z-index: 1;
}
.territoryFocusContainer {
// styles for mobile-lg (480px) and greater widths
@include at-media('mobile-lg') {
position: absolute;
left: .75em;
@include baseTerritoryFocus;
top: units(card-lg);
z-index: 10;
}
};
position: absolute;
left: .75em;
@include baseTerritoryFocus;
top: units(9);
z-index: 10;
}

View file

@ -4,44 +4,37 @@ import {isMobile as isMobileReactDeviceDetect} from 'react-device-detect';
export const isMobile = isMobileReactDeviceDetect;
const XYZ_SUFFIX = '{z}/{x}/{y}.pbf';
export const featureURLForTilesetName = (tilesetName: string): string => {
// The feature tile base URL and path can either point locally or the CDN.
// This is selected based on the DATA_SOURCE env variable.
const featureTileBaseURL = process.env.DATA_SOURCE === 'local' ?
process.env.GATSBY_LOCAL_TILES_BASE_URL :
process.env.GATSBY_CDN_TILES_BASE_URL;
const featureTilePath = process.env.DATA_SOURCE === 'local' ?
process.env.GATSBY_DATA_PIPELINE_SCORE_PATH_LOCAL :
process.env.GATSBY_DATA_PIPELINE_SCORE_PATH;
return [
featureTileBaseURL,
featureTilePath,
process.env.GATSBY_MAP_TILES_PATH,
tilesetName,
XYZ_SUFFIX,
].join('/');
};
export const FEATURE_TILE_HIGH_ZOOM_URL = featureURLForTilesetName('high');
export const FEATURE_TILE_LOW_ZOOM_URL = featureURLForTilesetName('low');
// Staging links for testing:
// export const FEATURE_TILE_HIGH_ZOOM_URL = `https://justice40-data.s3.amazonaws.com/data-pipeline-staging/1297/deee14dd93b783c8d366434dc8438a281b5c89df/data/score/tiles/high/${XYZ_SUFFIX}`;
// export const FEATURE_TILE_LOW_ZOOM_URL = `https://justice40-data.s3.amazonaws.com/data-pipeline-staging/1297/deee14dd93b783c8d366434dc8438a281b5c89df/data/score/tiles/low/${XYZ_SUFFIX}`;
// Performance markers
export const PERFORMANCE_MARKER_MAP_IDLE = 'MAP_IDLE';
// ******* PROPERTIES FROM TILE SERVER **************
export type J40Properties = { [key: string]: any };
// Properties
export const SCORE_PROPERTY_HIGH = 'SM_PFS';
export const SCORE_PROPERTY_LOW = 'M_SCORE';
// ****** SIDE PANEL BACKEND SIGNALS ***********
// Set the threshold percentile used by most indicators in the side panel
export const DEFAULT_THRESHOLD_PERCENTILE = 90;
// General Census Track Info
export const GEOID_PROPERTY = 'GEOID10';
export const COUNTY_NAME = 'CF';
export const STATE_NAME = 'SF';
export const TOTAL_POPULATION = 'TPF';
/**
* The SCORE_BOUNDAY_THRESHOLD will determine if the tract is disadvantaged
* or not. Currently all values are railed to 0 or 1. If the
* SCORE_PROPERTY_HIGH is greater than SCORE_BOUNDARY_THRESHOLD,
* the tract will be considered disadvantaged.
*/
export const SCORE_BOUNDARY_THRESHOLD = 0.6;
// Determines the X of Y threshold exceeded
export const TOTAL_NUMBER_OF_DISADVANTAGE_INDICATORS = 'TC';
export const TOTAL_NUMBER_OF_INDICATORS = 'THRHLD';
export const COUNT_OF_CATEGORIES_DISADV = 'CC';
export const SIDE_PANEL_STATE = 'UI_EXP';
export const SIDE_PANEL_STATE_VALUES = {
NATION: 'Nation',
@ -49,102 +42,142 @@ export const SIDE_PANEL_STATE_VALUES = {
ISLAND_AREAS: 'Island Areas',
};
export const THRHLD = 'TERRITORY_THRESHOLD';
// Indicator values:
export const ASTHMA_PERCENTILE = 'AF_PFS';
export const COUNTY_NAME = 'CF';
export const DIABETES_PERCENTILE = 'DF_PFS';
export const DIESEL_MATTER_PERCENTILE = 'DSF_PFS';
export const ENERGY_PERCENTILE = 'EBF_PFS';
export const HEART_PERCENTILE = 'HDF_PFS';
export const HIGH_SCHOOL_PROPERTY_PERCENTILE = `HSEF`;
export const HOUSING_BURDEN_PROPERTY_PERCENTILE = 'HBF_PFS';
export const LEAD_PAINT_PERCENTILE = 'LPF_PFS';
export const LIFE_PERCENTILE = 'LLEF_PFS';
export const LINGUISTIC_ISOLATION_PROPERTY_PERCENTILE = 'LIF_PFS';
export const LOW_MEDIAN_INCOME_PERCENTILE = 'LMI_PFS';
export const PM25_PERCENTILE = 'PM25F_PFS';
export const POVERTY_PROPERTY_PERCENTILE = 'P200_PFS';
export const STATE_NAME = 'SF';
export const TOTAL_POPULATION = 'TPF';
export const TRAFFIC_PERCENTILE = 'TF_PFS';
export const UNEMPLOYMENT_PROPERTY_PERCENTILE = 'UF_PFS';
export const WASTEWATER_PERCENTILE = 'WF_PFS';
export const EXP_AGRICULTURE_LOSS_PERCENTILE = 'EALR_PFS';
export const EXP_BUILDING_LOSS_PERCENTILE = 'EBLR_PFS';
export const EXP_POPULATION_LOSS_PERCENTILE = 'EPLR_PFS';
export const MEDIAN_HOME_VALUE_PERCENTILE = 'MHVF_PFS';
export const POVERTY_BELOW_100_PERCENTILE = 'P100_PFS';
export const POVERTY_BELOW_200_PERCENTILE = 'P200_PFS';
export const PROXIMITY_NPL_SITES_PERCENTILE = 'NPL_PFS';
export const PROXIMITY_RMP_SITES_PERCENTILE = 'RMP_PFS';
export const PROXIMITY_TSDF_SITES_PERCENTILE = 'TSDF_PFS';
export const HIGHER_ED_PERCENTILE = 'CA';
export const ISLAND_AREAS_UNEMPLOYMENT_LOW_HS_EDU_PERCENTILE_FIELD= 'IAULHSE_PFS';
export const ISLAND_AREAS_POVERTY_LOW_HS_EDU_PERCENTILE_FIELD= 'IAPLHSE_PFS';
export const ISLAND_AREAS_LOW_MEDIAN_INCOME_LOW_HS_EDU_PERCENTILE_FIELD= 'IALMILHSE_PFS';
export const ISLAND_AREAS_LOW_HS_EDU_PERCENTILE_FIELD= 'IALHE_PFS';
export const ISLAND_AREAS_HS_EDU_PERCENTAGE_FIELD= 'IAHSEF';
// Category booleans (disadvantaged or not):
// Climate category
export const IS_CLIMATE_FACTOR_DISADVANTAGED_M = 'M_CLT';
export const IS_ENERGY_FACTOR_DISADVANTAGED_M = 'M_ENY';
export const IS_TRANSPORT_FACTOR_DISADVANTAGED_M = 'M_TRN';
export const IS_HOUSING_FACTOR_DISADVANTAGED_M = 'M_HSG';
export const IS_POLLUTION_FACTOR_DISADVANTAGED_M = 'M_PLN';
export const IS_WATER_FACTOR_DISADVANTAGED_M = 'M_WTR';
export const IS_HEALTH_FACTOR_DISADVANTAGED_M = 'M_HLTH';
export const IS_WORKFORCE_FACTOR_DISADVANTAGED_M = 'M_WKFC';
export const IS_CLIMATE_EXCEED_ONE_OR_MORE_INDICATORS_M = 'M_CLT_EOMI';
// Total indicators values:
export const TOTAL_NUMBER_OF_DISADVANTAGE_INDICATORS = 'TC';
export const TOTAL_NUMBER_OF_INDICATORS = 'THRHLD';
export const EXP_AGRICULTURE_LOSS_PERCENTILE = 'EALR_PFS';
export const IS_EXCEEDS_THRESH_FOR_EXP_AGR_LOSS = 'EAL_ET';
// Indicator booleans (disadvangted or not): (GTE = greater than or equal)
export const IS_GTE_90_EXP_POP_LOSS_AND_IS_LOW_INCOME = 'EPLRLI';
export const IS_GTE_90_EXP_AGR_LOSS_AND_IS_LOW_INCOME = 'EALRLI';
export const IS_GTE_90_EXP_BLD_LOSS_AND_IS_LOW_INCOME = 'EBLRLI';
export const IS_GTE_90_PM25_AND_IS_LOW_INCOME = 'PM25LI';
export const IS_GTE_90_ENERGY_BURDEN_AND_IS_LOW_INCOME = 'EBLI';
export const IS_GTE_90_DIESEL_PM_AND_IS_LOW_INCOME = 'DPMLI';
export const IS_GTE_90_TRAFFIC_PROX_AND_IS_LOW_INCOME = 'TPLI';
export const IS_GTE_90_LEAD_PAINT_AND_MEDIAN_HOME_VAL_AND_IS_LOW_INCOME = 'LPMHVLI';
export const IS_GTE_90_HOUSE_BURDEN_AND_IS_LOW_INCOME = 'HBLI';
export const IS_GTE_90_RMP_AND_IS_LOW_INCOME = 'RMPLI';
export const IS_GTE_90_SUPERFUND_AND_IS_LOW_INCOME = 'SFLI';
export const IS_GTE_90_HAZARD_WASTE_AND_IS_LOW_INCOME = 'HWLI';
export const IS_GTE_90_WASTEWATER_AND_IS_LOW_INCOME = 'WDLI';
export const IS_GTE_90_DIABETES_AND_IS_LOW_INCOME = 'DLI';
export const IS_GTE_90_ASTHMA_AND_IS_LOW_INCOME = 'ALI';
export const IS_GTE_90_HEART_DISEASE_AND_IS_LOW_INCOME = 'HDLI';
export const IS_GTE_90_LOW_LIFE_EXP_AND_IS_LOW_INCOME = 'LLELI';
export const IS_GTE_90_LINGUISITIC_ISO_AND_IS_LOW_INCOME = 'LILHSE';
export const IS_GTE_90_BELOW_100_POVERTY_AND_LOW_HIGH_SCHOOL_EDU = 'PLHSE';
export const IS_GTE_90_LOW_MEDIAN_INCOME_AND_LOW_HIGH_SCHOOL_EDU = 'LMILHSE';
export const IS_GTE_90_UNEMPLOYMENT_AND_LOW_HIGH_SCHOOL_EDU = 'ULHSE';
export const EXP_BUILDING_LOSS_PERCENTILE = 'EBLR_PFS';
export const IS_EXCEEDS_THRESH_FOR_EXP_BLD_LOSS = 'EBL_ET';
export const EXP_POPULATION_LOSS_PERCENTILE = 'EPLR_PFS';
export const IS_EXCEEDS_THRESH_FOR_EXP_POP_LOSS = 'EPL_ET';
export const IS_EXCEED_BOTH_SOCIO_INDICATORS_M = 'M_EBSI';
export const POVERTY_BELOW_200_PERCENTILE = 'P200_PFS';
export const IS_FEDERAL_POVERTY_LEVEL_200 = 'FPL200S';
export const IS_HIGHER_ED_PERCENTILE = 'CA_LT20';
export const TOTAL_THRESHOLD_CRITERIA = 'TC';
export const IS_GTE_90_ISLAND_AREA_UNEMPLOYMENT_AND_IS_LOW_HS_EDU_2009 = 'IAULHSE';
export const IS_GTE_90_ISLAND_AREA_BELOW_100_POVERTY_AND_IS_LOW_HS_EDU_2009 = 'IAPLHSE';
export const IS_GTE_90_ISLAND_AREA_LOW_MEDIAN_INCOME_AND_IS_LOW_HS_EDU_2009 = 'IALMILHSE';
export const ISLAND_AREA_LOW_HS_EDU = 'IALHE';
export const IS_LOW_HS_EDUCATION_LOW_HIGHER_ED_PRIORITIZED = 'LHE';
// The name of the layer within the tiles that contains the score
export const SCORE_SOURCE_LAYER = 'blocks';
export const HIGHER_ED_PERCENTILE = 'CA';
export const IS_HIGHER_ED_PERCENTILE = 'CA_LT20';
export const NON_HIGHER_ED_PERCENTILE = 'NCA';
// Energy category
export const IS_ENERGY_FACTOR_DISADVANTAGED_M = 'M_ENY';
export const IS_ENERGY_EXCEED_ONE_OR_MORE_INDICATORS_M = 'M_ENY_EOMI';
export const ENERGY_PERCENTILE = 'EBF_PFS';
export const IS_EXCEEDS_THRESH_FOR_ENERGY_BURDEN = 'EB_ET';
export const PM25_PERCENTILE = 'PM25F_PFS';
export const IS_EXCEEDS_THRESH_FOR_PM25 = 'PM25_ET';
// Transport category
export const IS_TRANSPORT_FACTOR_DISADVANTAGED_M = 'M_TRN';
export const IS_TRANSPORT_EXCEED_ONE_OR_MORE_INDICATORS_M = 'M_TRN_EOMI';
export const DIESEL_MATTER_PERCENTILE = 'DSF_PFS';
export const IS_EXCEEDS_THRESH_FOR_DIESEL_PM = 'DS_ET';
export const TRAFFIC_PERCENTILE = 'TF_PFS';
export const IS_EXCEEDS_THRESH_FOR_TRAFFIC_PROX = 'TP_ET';
// Housing category
export const IS_HOUSING_FACTOR_DISADVANTAGED_M = 'M_HSG';
export const IS_HOUSING_EXCEED_ONE_OR_MORE_INDICATORS_M = 'M_HSG_EOMI';
export const HOUSING_BURDEN_PROPERTY_PERCENTILE = 'HBF_PFS';
export const IS_EXCEEDS_THRESH_FOR_HOUSE_BURDEN = 'HB_ET';
export const LEAD_PAINT_PERCENTILE = 'LPF_PFS';
export const IS_EXCEEDS_THRESH_FOR_LEAD_PAINT_AND_MEDIAN_HOME_VAL = 'LPP_ET';
// export const MEDIAN_HOME_VALUE_PERCENTILE = 'MHVF_PFS'; // No longer showing in UI
// Pollution category
export const IS_POLLUTION_FACTOR_DISADVANTAGED_M = 'M_PLN';
export const IS_POLLUTION_EXCEED_ONE_OR_MORE_INDICATORS_M = 'M_PLN_EOMI';
export const PROXIMITY_TSDF_SITES_PERCENTILE = 'TSDF_PFS';
export const IS_EXCEEDS_THRESH_FOR_HAZARD_WASTE = 'TSDF_ET';
export const PROXIMITY_NPL_SITES_PERCENTILE = 'NPL_PFS';
export const IS_EXCEEDS_THRESH_FOR_SUPERFUND = 'NPL_ET';
export const PROXIMITY_RMP_SITES_PERCENTILE = 'RMP_PFS';
export const IS_EXCEEDS_THRESH_FOR_RMP = 'RMP_ET';
// Water category
export const IS_WATER_FACTOR_DISADVANTAGED_M = 'M_WTR';
export const IS_WATER_EXCEED_ONE_OR_MORE_INDICATORS_M = 'M_WTR_EOMI';
export const WASTEWATER_PERCENTILE = 'WF_PFS';
export const IS_EXCEEDS_THRESH_FOR_WASTEWATER = 'WD_ET';
// Health category
export const IS_HEALTH_FACTOR_DISADVANTAGED_M = 'M_HLTH';
export const IS_HEALTH_EXCEED_ONE_OR_MORE_INDICATORS_M = 'M_HLTH_EOMI';
export const ASTHMA_PERCENTILE = 'AF_PFS';
export const IS_EXCEEDS_THRESH_FOR_ASTHMA = 'A_ET';
export const DIABETES_PERCENTILE = 'DF_PFS';
export const IS_EXCEEDS_THRESH_FOR_DIABETES = 'DB_ET';
export const HEART_PERCENTILE = 'HDF_PFS';
export const IS_EXCEEDS_THRESH_FOR_HEART_DISEASE = 'HD_ET';
export const LIFE_PERCENTILE = 'LLEF_PFS';
export const IS_EXCEEDS_THRESH_FOR_LOW_LIFE_EXP = 'LLE_ET';
// Workforce category
export const IS_WORKFORCE_FACTOR_DISADVANTAGED_M = 'M_WKFC';
export const IS_WORKFORCE_EXCEED_ONE_OR_MORE_INDICATORS_M = 'M_WKFC_EOMI';
export const LINGUISTIC_ISOLATION_PROPERTY_PERCENTILE = 'LIF_PFS';
export const IS_EXCEEDS_THRESH_FOR_LINGUISITIC_ISO = 'LISO_ET';
export const LOW_MEDIAN_INCOME_PERCENTILE = 'LMI_PFS';
export const IS_EXCEEDS_THRESH_FOR_LOW_MEDIAN_INCOME = 'LMI_ET';
export const ISLAND_AREAS_LOW_MEDIAN_INCOME_LOW_HS_EDU_PERCENTILE_FIELD= 'IALMILHSE_PFS';
export const IS_EXCEEDS_THRESH_FOR_ISLAND_AREA_LOW_MEDIAN_INCOME = 'IA_LMI_ET';
export const UNEMPLOYMENT_PROPERTY_PERCENTILE = 'UF_PFS';
export const IS_EXCEEDS_THRESH_FOR_UNEMPLOYMENT = 'UN_ET';
export const ISLAND_AREAS_UNEMPLOYMENT_LOW_HS_EDU_PERCENTILE_FIELD= 'IAULHSE_PFS';
export const IS_EXCEEDS_THRESH_FOR_ISLAND_AREA_UNEMPLOYMENT = 'IA_UN_ET';
export const POVERTY_BELOW_100_PERCENTILE = 'P100_PFS';
export const IS_EXCEEDS_THRESH_FOR_BELOW_100_POVERTY = 'POV_ET';
export const ISLAND_AREAS_POVERTY_LOW_HS_EDU_PERCENTILE_FIELD= 'IAPLHSE_PFS';
export const IS_EXCEEDS_THRESH_FOR_ISLAND_AREA_BELOW_100_POVERTY = 'IA_POV_ET';
export const IS_WORKFORCE_EXCEED_BOTH_SOCIO_INDICATORS_M = 'M_WKFC_EBSI';
export const HIGH_SCHOOL_PROPERTY_PERCENTILE = `HSEF`;
export const IS_LOW_HS_EDUCATION_LOW_HIGHER_ED_PRIORITIZED = 'LHE';
export const ISLAND_AREAS_HS_EDU_PERCENTAGE_FIELD= 'IAHSEF';
export const ISLAND_AREA_LOW_HS_EDU = 'IALHE';
// ********** MAP CONSTANTS ***************
// Source name constants
export const BASE_MAP_SOURCE_NAME = 'base-map-source-name';
export const HIGH_ZOOM_SOURCE_NAME = 'high-zoom-source-name';
export const LOW_ZOOM_SOURCE_NAME = 'low-zoom-source-name';
// Layer ID constants
export const SCORE_SOURCE_LAYER = 'blocks'; // The name of the layer within the tiles that contains the score
export const BASE_MAP_LAYER_ID = 'base-map-layer-id';
export const HIGH_ZOOM_LAYER_ID = 'high-zoom-layer-id';
export const PRIORITIZED_HIGH_ZOOM_LAYER_ID = 'prioritized-high-zoom-layer-id';
@ -152,6 +185,10 @@ export const LOW_ZOOM_LAYER_ID = 'low-zoom-layer-id';
export const FEATURE_BORDER_LAYER_ID = 'feature-border-layer-id';
export const SELECTED_FEATURE_BORDER_LAYER_ID = 'selected-feature-border-layer-id';
// Used in layer filters:
export const SCORE_PROPERTY_LOW = 'M_SCORE';
export const SCORE_PROPERTY_HIGH = 'SM_PFS';
// Zoom
export const GLOBAL_MIN_ZOOM = 3;
export const GLOBAL_MAX_ZOOM = 22;
@ -177,13 +214,6 @@ export const PRIORITIZED_FEATURE_FILL_COLOR = '#768FB3';
export const FEATURE_BORDER_WIDTH = 0.8;
export const SELECTED_FEATURE_BORDER_WIDTH = 5.0;
/**
* This threshold will determine if the feature is prioritized
* or not. Currently all values are railed to 0 or 1 so this value
* doesn't really matter.
*/
export const SCORE_BOUNDARY_THRESHOLD = 0.6;
// Bounds - these bounds can be obtained by using the getCurrentMapBoundingBox() function in the map
export const GLOBAL_MAX_BOUNDS: LngLatBoundsLike = [
[-180.118306, 5.499550],

View file

@ -0,0 +1,5 @@
# How to i18n copy for J40
1. Note that description fields can not have line feed or carriage returns or they will render a /n in the en.json file.
2. Use bold, italic function in common.tsx
3. Use <FormattedNumber> and <FormattedDate> for these data types.

View file

@ -1,8 +1,8 @@
/* eslint-disable max-len */
import React from 'react';
import {defineMessages} from 'react-intl';
import {FormattedMessage} from 'gatsby-plugin-intl';
import LinkTypeWrapper from '../../components/LinkTypeWrapper';
import {italicFn, linkFn} from './common';
export const EXEC_ORDER_LINK = 'https://www.federalregister.gov/documents/2021/02/01/2021-02177/tackling-the-climate-crisis-at-home-and-abroad#:~:text=Sec.%20223.%20Justice40,40-percent%20goal.';
@ -10,28 +10,28 @@ export const PAGE = defineMessages({
TILE: {
id: 'about.page.title.text',
defaultMessage: 'About',
description: 'about page title text',
description: 'Navigate to the About page. This is the about page title text',
},
HEADING: {
id: 'index.heading.about.us',
id: 'about.page.heading.text',
defaultMessage: 'About',
description: 'main heading for about page',
description: 'Navigate to the About page. This is the first heading',
},
HEADING_1: {
id: 'index.heading.screentool',
id: 'about.page.heading.1.text',
defaultMessage: 'Screening tool',
description: 'heading for about screening tool',
description: 'Navigate to the About page. This is the second heading',
},
HEADING1_DESCRIPTION2: {
id: 'about.page.sub.header.1.text.2',
defaultMessage: 'The current version of the tool is in a public beta form and'+
' will be updated based on feedback and research.',
description: 'about page sub header text',
description: 'Navigate to the About page. This is first heading description',
},
HEADING_2: {
id: 'index.heading.justice40',
id: 'about.page.sub.header.2.text',
defaultMessage: 'The Justice40 Initiative',
description: 'heading for about justice 40',
description: 'Navigate to the About page. This is the third heading',
},
HEADING2_DESCRIPTION1: {
id: 'about.page.sub.header.2.text.1',
@ -43,7 +43,7 @@ export const PAGE = defineMessages({
housing, training and workforce development, the remediation and reduction of legacy pollution,
and the development of critical clean water infrastructure.
`,
description: 'about page sub header text',
description: 'Navigate to the About page. This is the third heading description',
},
});
@ -51,9 +51,9 @@ export const HEADING_1 = {
DESCRIPTION_1:
<FormattedMessage
id={'about.page.sub.header.1.text.1'}
description={'about page sub header text'}
description={'Navigate to the About page. This is the second heading description'}
defaultMessage={`
In {eoLink} on {tacklingItalics}, President Biden directed the Council on Environmental Quality (CEQ)
In <link1>Executive Order 14008</link1> on <italictag>Tackling the Climate Crisis at Home and Abroad</italictag>, President Biden directed the Council on Environmental Quality (CEQ)
to create a Climate and Economic Justice Screening Tool. The purpose of the tool is to help
Federal agencies identify disadvantaged communities that are marginalized, underserved, and
overburdened by pollution. The current version of the tool provides socioeconomic, environmental,
@ -61,13 +61,8 @@ export const HEADING_1 = {
tool identifies disadvantaged communities through publicly-available, nationally-consistent datasets.
`}
values={{
eoLink: <LinkTypeWrapper
linkText={'Executive Order 14008'}
internal={false}
url={EXEC_ORDER_LINK}
openUrlNewTab={true}
/>,
tacklingItalics: <i>Tackling the Climate Crisis at Home and Abroad</i>,
link1: linkFn(EXEC_ORDER_LINK, false, true),
italictag: italicFn,
}}
/>,
};
@ -79,16 +74,11 @@ export const HEADING_2 = {
description={'about page sub header text'}
defaultMessage={`
Read more about the Justice40 Initiative in President Bidens
{eoLink} on {tacklingItalics}.
<link1>Executive Order 14008</link1> on <italictag>Tackling the Climate Crisis at Home and Abroad</italictag>.
`}
values={{
eoLink: <LinkTypeWrapper
linkText={'Executive Order 14008'}
internal={false}
url={EXEC_ORDER_LINK}
openUrlNewTab={true}
/>,
tacklingItalics: <i>Tackling the Climate Crisis at Home and Abroad</i>,
link1: linkFn(EXEC_ORDER_LINK, false, true),
italictag: italicFn,
}}
/>,
};
@ -98,81 +88,81 @@ export const GITHUB_LINK = 'https://github.com/usds/justice40-tool';
export const HOW_TO_GET_STARTED = defineMessages({
TITLE: {
id: 'howToGetStarted.title',
id: 'about.page.howToGetStarted.title',
defaultMessage: 'How to get started',
description: 'sub heading of page',
description: 'Navigate to the About page. This is the sub heading of page',
},
FEDERAL_PM_HEADING: {
id: 'federal.pm.heading',
id: 'about.page.federal.pm.heading',
defaultMessage: 'Federal program managers',
description: 'sub heading of page',
description: 'Navigate to the About page. This is the sub heading of page',
},
FEDERAL_PM_INFO: {
id: 'federal.pm.info',
id: 'about.page.federal.pm.info',
defaultMessage: `
Download the tools current list of communities, explore data that may be useful to your
program, and provide feedback on the tool.
`,
description: 'sub heading of page',
description: 'Navigate to the About page. This is the sub heading of page',
},
FEDERAL_PM_LINK_TEXT: {
id: 'federal.pm.link',
id: 'about.page.federal.pm.link',
defaultMessage: 'Methodology & data',
description: 'link text to go to methodology page',
description: 'link text to Navigate to the About page. This is the go to methodology page',
},
COMMUNITY_MEMBERS_HEADING: {
id: 'community.members.heading',
id: 'about.page.community.members.heading',
defaultMessage: 'Community members',
description: 'sub heading of page',
description: 'Navigate to the About page. This is the sub heading of page',
},
COMMUNITY_MEMBERS_INFO: {
id: 'community.members.info',
id: 'about.page.community.members.info',
defaultMessage: `
Explore data about communities across the U.S., including your own, and provide feedback on the tool.
`,
description: 'sub heading of page',
description: 'Navigate to the About page. This is the sub heading of page',
},
COMMUNITY_MEMBERS_LINK_TEXT: {
id: 'community.members.link',
id: 'about.page.community.members.link',
defaultMessage: 'Explore the tool',
description: 'link to explore the tool page',
description: 'link to Navigate to the About page. This is the explore the tool page',
},
});
export const GET_INVOLVED = defineMessages({
TITLE: {
id: 'getInvolved.title',
id: 'about.page.getInvolved.title',
defaultMessage: 'Get involved',
description: 'sub heading of page',
description: 'Navigate to the About page. This is the sub heading of page',
},
SEND_FEEDBACK_HEADING: {
id: 'send.feedback.heading',
id: 'about.page.send.feedback.heading',
defaultMessage: 'Send feedback',
description: 'sending feedback heading',
description: 'Navigate to the About page. This is the sending feedback heading',
},
SEND_FEEDBACK_INFO: {
id: 'send.feedback.info',
id: 'about.page.send.feedback.info',
defaultMessage: `
Have ideas about data and information that reflect the experiences and conditions of your community?
`,
description: 'sending feedback information',
description: 'Navigate to the About page. This is the sending feedback information',
},
JOIN_OSC_HEADING: {
id: 'join.opensource.heading',
id: 'about.page.join.opensource.heading',
defaultMessage: 'Join the open source community',
description: 'join the community heading',
description: 'Navigate to the About page. This is the join the community heading',
},
JOIN_OSC_INFO: {
id: 'join.open.source.info',
id: 'about.page.join.open.source.info',
defaultMessage: `
The tools code is open source, which means it is available for the public to view and contribute to it.
`,
description: 'info on joining open source community',
description: 'info on Navigate to the About page. This is the joining open source community',
},
JOIN_OSC_LINK_TEXT: {
id: 'join.open.source.link',
id: 'about.page.join.open.source.link',
defaultMessage: 'Check it out on GitHub',
description: 'link to github repository',
description: 'Navigate to the About page. This is the link to github repository',
},
});

View file

@ -1,120 +1,162 @@
/* eslint-disable max-len */
/* eslint-disable react/display-name */
import React from 'react';
import {FormattedMessage} from 'gatsby-plugin-intl';
import {defineMessages} from 'react-intl';
import LinkTypeWrapper from '../../components/LinkTypeWrapper';
/*
* i18n curried functions from react-intl (aka format.js)
* using ver3 of the docs as this is what gatsby-plugin-intl uses:
* https://formatjs.io/docs/react-intl/upgrade-guide-3x#enhanced-formattedmessage--formatmessage-rich-text-formatting
*
* */
export const italicFn = (str:string) => <i>{str}</i>;
export const boldFn = (str:string) => <strong>{str}</strong>;
export const simpleLink = (href:string) => (str:string) => <a href={href}>{str}</a>;
// eslint-disable-next-line max-len
export const linkFn = (to:string, isInternal:boolean, isOpenNewTab:boolean) => (str:string) => <LinkTypeWrapper linkText={str} internal={isInternal} url={to} openUrlNewTab={isOpenNewTab}/>;
export const FEEDBACK_EMAIL = 'Screeningtool-Support@omb.eop.gov';
// Beta Banner
export const BETA_BANNER = defineMessages({
TITLE: {
id: 'banner.beta.title',
id: 'common.pages.banner.beta.title',
defaultMessage: 'This is a beta site.',
description: 'the main title of the beta banner',
description: 'Navigate to the about page. This is the main title of the beta banner',
},
INFO: {
id: 'banner.beta.info',
id: 'common.pages.banner.beta.info',
defaultMessage: `It is an early, in-progress version of the tool with limited datasets that will
be regularly updated.`,
description: 'the main info of the beta banner',
description: 'Navigate to the about page. This is the main info of the beta banner',
},
});
// Alerts
// Expiration month is zero-based: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/getMonth
export const ALERTS = {
CENSUS_TRACT: defineMessages({
TITLE: {
id: 'common.pages.alerts.census.tract.title',
defaultMessage: 'Improvements to the map on the Explore the tool page',
description: 'Navigate to any page. This the title of the alert that informs the user that new census tract information is available',
},
}),
EXPIRATION_DATE: new Date(2022, 3, 15), // Set expiration for Apr 15th 2022.
CENSUS_TRACT_DESCRIPTION: <FormattedMessage
id={'common.pages.alerts.census.tract.description'}
defaultMessage={`View improvements made to the display of the information for each census tract and <link1>send feedback</link1>.`}
description={`Navigate to any page. This the title of the alert that informs the user that new census tract information is available`}
values={{
link1: linkFn(`mailto:${FEEDBACK_EMAIL}`, false, true),
}}
/>,
};
// Header
export const HEADER = defineMessages({
TITLE_LINE_1: {
id: 'header.title.line1',
id: 'common.pages.header.title.line1',
defaultMessage: `Climate and Economic Justice`,
description: 'Title in nav header line 1 of 2',
description: 'Navigate to the about page. This is Title in nav header line 1 of 2',
},
TITLE_LINE_2: {
id: 'header.title.line2',
id: 'common.pages.header.title.line2',
defaultMessage: `Screening Tool`,
description: 'Title in nav header line 2 of 2',
description: 'Navigate to the about page. This is Title in nav header line 2 of 2',
},
ABOUT: {
id: 'header.about',
id: 'common.pages.header.about',
defaultMessage: 'About',
description: 'Header navigate item to the about page',
description: 'Navigate to the about page. This is Header navigate item to the about page',
},
EXPLORE: {
id: 'header.explore',
id: 'common.pages.header.explore',
defaultMessage: 'Explore the tool',
description: 'Header navigate item to the Explore the tool page',
description: 'Navigate to the about page. This is Header navigate item to the Explore the tool page',
},
METHODOLOGY: {
id: 'header.methodology',
id: 'common.pages.header.methodology',
defaultMessage: 'Methodology & data',
description: 'Header navigate item to the Methodology page',
description: 'Navigate to the about page. This is Header navigate item to the Methodology page',
},
CONTACT: {
id: 'header.contact',
id: 'common.pages.header.contact',
defaultMessage: 'Contact',
description: 'Header navigate item to the Contact page',
description: 'Navigate to the about page. This is Header navigate item to the Contact page',
},
});
// Footer
export const FOOTER = defineMessages({
ARIA_LABEL: {
id: 'footer.arialabel',
id: 'common.pages.footer.arialabel',
defaultMessage: 'Footer navigation',
description: 'aria-label text for whole footer',
description: 'Navigate to the about page. This is aria-label text for whole footer',
},
TITLE: {
id: 'footer.logo.title',
id: 'common.pages.footer.logo.title',
defaultMessage: 'Council on Environmental Quality',
description: 'Footer under logo',
description: 'Navigate to the about page. This is Footer under logo',
},
MORE_INFO: {
id: 'footer.moreinfoheader',
id: 'common.pages.footer.moreinfoheader',
defaultMessage: 'More information',
description: 'Footer column header',
description: 'Navigate to the about page. This is Footer column header',
},
WHITEHOUSE: {
id: 'footer.whitehouse.text',
id: 'common.pages.footer.whitehouse.text',
defaultMessage: 'Whitehouse.gov',
description: 'Footer Whitehouse.gov link text',
description: 'Navigate to the about page. This is Footer Whitehouse.gov link text',
},
WHITEHOUSE_LINK: {
id: 'footer.whitehouse.link',
id: 'common.pages.footer.whitehouse.link',
defaultMessage: 'https://www.whitehouse.gov/',
description: 'Footer Whitehouse.gov link text',
description: 'Navigate to the about page. This is Footer Whitehouse.gov link text',
},
FOIA: {
id: 'footer.foia.text',
id: 'common.pages.footer.foia.text',
defaultMessage: 'Freedom of Information Act (FOIA)',
description: 'Footer FOIA link text',
description: 'Navigate to the about page. This is Footer FOIA link text',
},
PRIVACY: {
id: 'footer.privacy.text',
id: 'common.pages.footer.privacy.text',
defaultMessage: 'Privacy Policy',
description: 'Footer privacy policy link text',
description: 'Navigate to the about page. This is Footer privacy policy link text',
},
PRIVACY_LINK: {
id: 'footer.privacy.link',
id: 'common.pages.footer.privacy.link',
defaultMessage: 'https://www.whitehouse.gov/privacy/',
description: 'Footer privacy policy link text',
description: 'Navigate to the about page. This is Footer privacy policy link text',
},
LOGO_ALT: {
id: 'footer.whitehouselogoalt',
id: 'common.pages.footer.whitehouselogoalt',
defaultMessage: 'Whitehouse logo',
description: 'Footer Whitehouse logo alt text',
description: 'Navigate to the about page. This is Footer Whitehouse logo alt text',
},
QUESTIONS: {
id: 'footer.questionsheader',
id: 'common.pages.footer.questionsheader',
defaultMessage: 'Have a question about government services?',
description: 'Footer column header',
description: 'Navigate to the about page. This is Footer column header',
},
FIND_CONTACT: {
id: 'footer.findcontact',
id: 'common.pages.footer.findcontact',
defaultMessage: 'Find a contact at USA.gov',
description: 'Footer find contact link text',
description: 'Navigate to the about page. This is Footer find contact link text',
},
FIND_CONTACT_LINK: {
id: 'footer.findcontact.link',
id: 'common.pages.footer.findcontact.link',
defaultMessage: 'https://www.usa.gov/',
description: 'Footer find contact link text',
description: 'Navigate to the about page. This is Footer find contact link text',
},
CONTACT: {
id: 'footer.contactheader',
id: 'common.pages.footer.contactheader',
defaultMessage: 'Contact',
description: 'Footer column header',
description: 'Navigate to the about page. This is Footer column header',
},
});
@ -126,4 +168,11 @@ export const FOOTER_CEQ_ADDRESS = {
}
;
export const CONSOLE_ERROR = defineMessages({
STAGE_URL: {
id: 'common.pages.console.error.stage.url',
defaultMessage: `
Please check stage_hash value. It must be a 4 digit decimal value / 40 digit hexadecimal value`,
description: 'Navigate to the about page. This is console error staging URL',
},
});

View file

@ -1,33 +1,34 @@
/* eslint-disable max-len */
import React from 'react';
import {defineMessages} from 'react-intl';
import {FormattedMessage, Link} from 'gatsby-plugin-intl';
import LinkTypeWrapper from '../../components/LinkTypeWrapper';
import {FormattedMessage} from 'gatsby-plugin-intl';
import * as COMMON_COPY from './common';
export const PAGE_INTRO = defineMessages({
PAGE_TILE: {
id: 'contact.page.title.text',
defaultMessage: 'Contact',
description: 'contact page title text',
description: 'Navigate to the contact page, this is the contact page title text',
},
PAGE_HEADING: {
id: 'contact.page.header.text',
defaultMessage: 'Contact',
description: 'contact page header text',
description: 'Navigate to the contact page, this is the contact page header text',
},
PAGE_SUB_HEADING: {
id: 'contact.page.sub.header.text',
defaultMessage: 'Email us',
description: 'contact page sub header text',
description: 'Navigate to the contact page, this is the contact page sub header text',
},
PAGE_DESCRIPTION: {
id: 'contact.page.sub.header.text',
defaultMessage: 'Email us',
description: 'contact page sub header text',
description: 'Navigate to the contact page, this is the contact page sub header text',
},
SURVEY_TEXT: {
id: 'fab.survey.text',
id: 'contact.page.fab.survey.text',
defaultMessage: `Help improve the site & data`,
description: 'text for floating action button',
description: 'Navigate to the contact page, this is the text for floating action button',
},
});
@ -35,18 +36,17 @@ export const CENSUS_TRACT_FEEDBACK = {
TITLE: <FormattedMessage
id={'contact.page.census.tract.feedback.title'}
defaultMessage={`Census tract feedback`}
description={'census tract feedback section'}
description={'Navigate to the contact page, this is the census tract feedback section'}
/>,
PARAGRAPH1: <FormattedMessage
id={'contact.page.census.tract.feedback.para1'}
defaultMessage={`
To provide feedback about a specific census tract, either select the send feedback button after
selecting a census tract on the {exploreLink} page or use the email address provided above. Please
include the census tract ID, county, and state or territory information, in addition to your feedback.
To provide feedback about a specific census tract, either select the send feedback button after
selecting a census tract on the <link1>Explore the tool</link1> page or use the email address provided above. Please include the census tract ID, county, and state or territory information, in addition to your feedback.
`}
description={'census tract feedback section'}
description={'Navigate to the contact page, this is the census tract feedback section'}
values={{
exploreLink: <Link to={'/cejst'}>Explore the tool</Link>,
link1: COMMON_COPY.linkFn('/cejst', true, false),
}}
/>,
PARAGRAPH2: <FormattedMessage
@ -55,21 +55,16 @@ export const CENSUS_TRACT_FEEDBACK = {
If there are specific data indicators that could be improved or changed, please include that
information in the body of the email.
`}
description={'census tract feedback section'}
description={'Navigate to the contact page, this is the census tract feedback section'}
/>,
PARAGRAPH3: <FormattedMessage
id={'contact.page.census.tract.feedback.para3'}
defaultMessage={`
In addition, you can provide feedback on the tool via this {improvementSurvey}.
In addition, you can provide feedback on the tool via this <link1>survey</link1>.
`}
description={'census tract feedback section'}
description={'Navigate to the contact page, this is the census tract feedback section'}
values={{
improvementSurvey: <LinkTypeWrapper
linkText={'survey'}
internal={false}
url={`https://www.surveymonkey.com/r/cejst-survey`}
openUrlNewTab={true}
/>,
link1: COMMON_COPY.linkFn('https://www.surveymonkey.com/r/cejst-survey', false, true),
}}
/>,
};
@ -79,5 +74,3 @@ export const CONTACT_VIA_EMAIL = {
DESCRIPTION: 'Contact page body text',
DEFAULT_MESSAGE: `For general feedback, email {general_email_address}.`,
};
export const FEEDBACK_EMAIL = 'Screeningtool-Support@omb.eop.gov';

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,56 +1,66 @@
/* eslint-disable max-len */
import {defineMessages} from 'react-intl';
import mar9 from '../../images/eventDates/mar9.svg';
import mar10 from '../../images/eventDates/mar10.svg';
import mar16 from '../../images/eventDates/mar16.svg';
import mar22 from '../../images/eventDates/mar22.svg';
import mar30 from '../../images/eventDates/mar30.svg';
import mar31 from '../../images/eventDates/mar31.svg';
import apr15 from '../../images/eventDates/apr15.svg';
import mar9Exp from '../../images/eventDates/mar9-inactive.svg';
import mar10Exp from '../../images/eventDates/mar10-inactive.svg';
import mar16Exp from '../../images/eventDates/mar16-inactive.svg';
import mar22Exp from '../../images/eventDates/mar22-inactive.svg';
import mar30Exp from '../../images/eventDates/mar30-inactive.svg';
import mar31Exp from '../../images/eventDates/mar31-inactive.svg';
import apr15Exp from '../../images/eventDates/apr15-inactive.svg';
export const PAGE_INTRO = defineMessages({
PAGE_TILE: {
id: 'publiceng.page.title.text',
id: 'public.eng.page.title.text',
defaultMessage: 'Public engagement opportunities',
description: 'publiceng page title text',
description: 'Navigate to the the public engagement page, this will be the publiceng page title text',
},
PAGE_HEADING1: {
id: 'publiceng.page.heading1.text',
id: 'public.eng.page.heading1.text',
defaultMessage: 'Public engagement opportunities',
description: 'publiceng page header text',
description: 'Navigate to the the public engagement page, this will be the publiceng page header text',
},
PAGE_HEADING2: {
id: 'publiceng.page.sub.header2.text',
id: 'public.eng.page.sub.header2.text',
defaultMessage: 'Find an event',
description: 'publiceng page sub header text',
description: 'Navigate to the the public engagement page, this will be the publiceng page sub header text',
},
PAGE_DESCRIPTION1: {
id: 'publiceng.page.description1.text',
id: 'public.eng.page.description1.text',
defaultMessage: `
CEQ is hosting engagement opportunities to connect with the public about the current version of the
tool. These sessions are an opportunity to obtain training on the tool or to provide feedback on the
beta version of the tool. CEQ hopes that members of the public will join these engagements to learn
about the tool, have their questions answered, and share feedback.
`,
description: 'publiceng page description 1 text',
description: 'Navigate to the the public engagement page, this will be the publiceng page description 1 text',
},
PAGE_DESCRIPTION2: {
id: 'publiceng.page.description2.text',
id: 'public.eng.page.description2.text',
defaultMessage: `
Pre-registration is required to participate and speak at the sessions.
`,
description: 'publiceng page description 2 text',
description: 'Navigate to the the public engagement page, this will be the publiceng page description 2 text',
},
PAGE_DESCRIPTION3: {
id: 'publiceng.page.description3.text',
id: 'public.eng.page.description3.text',
defaultMessage: `
As they become available, additional public trainings and engagement opportunities on the Climate
and Economic Justice Screening Tool will also be posted on this page.
`,
description: 'publiceng page description 3 text',
description: 'Navigate to the the public engagement page, this will be the publiceng page description 3 text',
},
SURVEY_TEXT: {
id: 'fab.survey.text',
defaultMessage: `Help improve the site & data`,
description: 'text for floating action button',
description: 'Navigate to the the public engagement page, this will be the text for floating action button',
},
});
@ -58,12 +68,12 @@ export const PUBLIC_ENG_BUTTON = defineMessages({
LABEL: {
id: 'public.eng.page.button.label',
defaultMessage: `Public Engagement`,
description: 'public engagement button label',
description: 'Navigate to the the public engagement page, this will be the public engagement button label',
},
TAG_LABEL: {
id: 'public.eng.page.tag.label',
defaultMessage: `NEW`,
description: 'public engagement tag label',
defaultMessage: `UPDATED`,
description: 'Navigate to the the public engagement page, this will be the public engagement tag label',
},
});
@ -72,7 +82,7 @@ export const EVENT_TYPES = {
NAME: {
id: 'public.eng.page.event.training.sess.name',
defaultMessage: `training session`,
description: 'public engagement page event training session name',
description: 'Navigate to the the public engagement page, this will be the public engagement page event training session name',
},
DESCRIPTION: {
id: 'public.eng.page.event.training.description',
@ -83,14 +93,14 @@ export const EVENT_TYPES = {
use the current version of the tool. The presenters at these webinars will be available to
provide technical support and address issues related to accessing and using the tool.
`,
description: 'public engagement page event training session description',
description: 'Navigate to the the public engagement page, this will be the public engagement page event training session description',
},
}),
LISTENING_SESS: defineMessages({
NAME: {
id: 'public.eng.page.event.listening.sess.name',
defaultMessage: `listening session`,
description: 'public engagement page event listening session name',
description: 'Navigate to the the public engagement page, this will be the public engagement page event listening session name',
},
DESCRIPTION: {
id: 'public.eng.page.event.listening.sess.description',
@ -101,52 +111,82 @@ export const EVENT_TYPES = {
tool to ensure that it reflects the environmental, climate and other challenges that communities
are experiencing.
`,
description: 'public engagement page event listening session description',
description: 'Navigate to the the public engagement page, this will be the public engagement page event listening session description',
},
}),
WHEJAC_DAY1: defineMessages({
NAME: {
id: 'public.eng.page.event.whejac.meeting.day.1.name',
defaultMessage: `Public WHEJAC meeting day one`,
description: 'public engagement page event WHEJAC meeting day 1 name',
},
DESCRIPTION: {
id: 'public.eng.page.event.whejac.meeting.day.1.description',
defaultMessage: `
Members of the public are encouraged to provide comments relevant to the beta version of the Climate and Economic Justice Screening Tool that was developed by CEQ and federal government agencies implementation of the Justice40 Initiative will be considered by the WHEJAC during the public meeting.
`,
description: 'public engagement page event WHEJAC day 1 description',
},
}),
WHEJAC_DAY2: defineMessages({
NAME: {
id: 'public.eng.page.event.whejac.meeting.day.2.name',
defaultMessage: `Public WHEJAC meeting day two`,
description: 'public engagement page event WHEJAC meeting day 2 name',
},
DESCRIPTION: {
id: 'public.eng.page.event.whejac.meeting.day.2.description',
defaultMessage: `
Members of the public are encouraged to attend and hear updates and discussion from the WHEJAC Climate and Economic Justice Screening Tool workgroup, the Justice40 workgroup, and the WHEJAC business time and meeting conversation during which the WHEJAC will use reflect on the meeting proceedings and public comment period; provide workgroup updates; discuss action items and finalize next steps.
`,
description: 'public engagement page event WHEJAC day 2 description',
},
}),
};
export const EVENT_FIELDS = defineMessages({
EVENT_INFO: {
id: 'publiceng.page.event.info.label',
id: 'public.eng.page.event.info.label',
defaultMessage: 'Event info',
description: 'public engagement page event info label',
description: 'Navigate to the the public engagement page, this will be the public engagement page event info label',
},
REG_LINK: {
id: 'publiceng.page.event.reglink.label',
id: 'public.eng.page.event.reglink.label',
defaultMessage: 'Registration link',
description: 'public engagment page event registration link label',
description: 'Navigate to the the public engagement page, this will be the public engagment page event registration link label',
},
});
export const EVENTS = [
{
DATE: new Date(2022, 9, 3),
DATE: new Date(2022, 2, 9),
NAME: EVENT_TYPES.TRAINING_SESS.NAME,
DESC: EVENT_TYPES.TRAINING_SESS.DESCRIPTION,
NUMBER: 1,
IMAGE: mar9,
EXPIRED_IMG: mar9Exp,
FIELDS: defineMessages({
INFO: {
id: 'public.eng.page.event.training.1.info',
defaultMessage: `March 9th (4:00 - 5:00 PM EST)`,
description: 'public engagement page event training session 1 date',
description: 'Navigate to the the public engagement page, this will be the public engagement page event training session 1 date',
},
}),
REG_LINK: `https://pitc.zoomgov.com/webinar/register/WN_D-Om_xXhTtiLv71y3Rr1CQ`,
DATA_CY: `mar-9-reg-link-block`,
},
{
DATE: new Date(2022, 10, 3),
DATE: new Date(2022, 2, 10),
NAME: EVENT_TYPES.TRAINING_SESS.NAME,
DESC: EVENT_TYPES.TRAINING_SESS.DESCRIPTION,
NUMBER: 2,
IMAGE: mar10,
EXPIRED_IMG: mar10Exp,
FIELDS: defineMessages({
INFO: {
id: 'public.eng.page.event.training.2.info',
defaultMessage: `March 10th (4:00 - 5:00 PM EST)`,
description: 'public engagement page event training session 2 date',
description: 'Navigate to the the public engagement page, this will be the public engagement page event training session 2 date',
},
}),
REG_LINK: `https://pitc.zoomgov.com/webinar/register/WN_QsSqshI4TpmRBkI6nVlWxQ`,
@ -154,16 +194,17 @@ export const EVENTS = [
},
{
DATE: new Date(2022, 16, 3),
DATE: new Date(2022, 2, 16),
NAME: EVENT_TYPES.TRAINING_SESS.NAME,
DESC: EVENT_TYPES.TRAINING_SESS.DESCRIPTION,
NUMBER: 3,
IMAGE: mar16,
EXPIRED_IMG: mar16Exp,
FIELDS: defineMessages({
INFO: {
id: 'public.eng.page.event.training.3.info',
defaultMessage: `March 16th (4:00 - 5:00 PM EST)`,
description: 'public engagement page event training session 3 date',
description: 'Navigate to the the public engagement page, this will be the public engagement page event training session 3 date',
},
}),
REG_LINK: `https://pitc.zoomgov.com/webinar/register/WN_q86iMtpwTESYa6f0xpIk7g`,
@ -171,16 +212,17 @@ export const EVENTS = [
},
{
DATE: new Date(2022, 22, 3),
DATE: new Date(2022, 2, 22),
NAME: EVENT_TYPES.LISTENING_SESS.NAME,
DESC: EVENT_TYPES.LISTENING_SESS.DESCRIPTION,
NUMBER: 1,
IMAGE: mar22,
EXPIRED_IMG: mar22Exp,
FIELDS: defineMessages({
INFO: {
id: 'public.eng.page.event.listening.1.info',
defaultMessage: `March 22nd (4:00 - 5:00 PM EST)`,
description: 'public engagement page event listening session 1 date',
description: 'Navigate to the the public engagement page, this will be the public engagement page event listening session 1 date',
},
}),
REG_LINK: `https://pitc.zoomgov.com/webinar/register/WN_YT7_uLZqScGHgyAcTCuJjA`,
@ -188,16 +230,51 @@ export const EVENTS = [
},
{
DATE: new Date(2022, 15, 4),
DATE: new Date(2022, 30, 2),
NAME: EVENT_TYPES.WHEJAC_DAY1.NAME,
DESC: EVENT_TYPES.WHEJAC_DAY1.DESCRIPTION,
NUMBER: 0,
IMAGE: mar30,
EXPIRED_IMG: mar30Exp,
FIELDS: defineMessages({
INFO: {
id: 'public.eng.page.whejac.meeting.day.1.info',
defaultMessage: `March 30th (3:00 - 7:00 PM EST)`,
description: 'public engagement page event WHEJAC',
},
}),
REG_LINK: `https://usepa.zoomgov.com/webinar/register/WN_wCwVP1dtT0auAR5kfucVtw`,
DATA_CY: `mar-30-reg-link-block`,
},
{
DATE: new Date(2022, 31, 2),
NAME: EVENT_TYPES.WHEJAC_DAY2.NAME,
DESC: EVENT_TYPES.WHEJAC_DAY2.DESCRIPTION,
NUMBER: 0,
IMAGE: mar31,
EXPIRED_IMG: mar31Exp,
FIELDS: defineMessages({
INFO: {
id: 'public.eng.page.whejac.meeting.day.1.info',
defaultMessage: `March 31th (3:00 - 7:30 PM EST)`,
description: 'public engagement page event WHEJAC',
},
}),
REG_LINK: `https://usepa.zoomgov.com/webinar/register/WN_wCwVP1dtT0auAR5kfucVtw`,
DATA_CY: `mar-31-reg-link-block`,
},
{
DATE: new Date(2022, 3, 15),
NAME: EVENT_TYPES.LISTENING_SESS.NAME,
DESC: EVENT_TYPES.LISTENING_SESS.DESCRIPTION,
NUMBER: 2,
IMAGE: apr15,
EXPIRED_IMG: apr15Exp,
FIELDS: defineMessages({
INFO: {
id: 'public.eng.page.event.listening.2.info',
defaultMessage: `April 15th (4:00 - 5:00 PM EST)`,
description: 'public engagement page event listening session 2 date',
description: 'Navigate to the the public engagement page, this will be the public engagement page event listening session 2 date',
},
}),
REG_LINK: `https://pitc.zoomgov.com/webinar/register/WN_dLw3xChiTlaOLGdHXQWk0w`,

View file

@ -1,5 +1,6 @@
import {Style} from 'maplibre-gl';
import * as constants from '../data/constants';
import {featureURLForTilesetName} from '../components/J40Map';
// *********** BASE MAP SOURCES ***************
const imageSuffix = constants.isMobile ? '' : '@2x';
@ -50,7 +51,7 @@ export const getOSBaseMap = () : Style => {
// Our current tippecanoe command does not set an id.
// The below line promotes the GEOID10 property to the ID
'promoteId': constants.GEOID_PROPERTY,
'tiles': [constants.FEATURE_TILE_HIGH_ZOOM_URL],
'tiles': [featureURLForTilesetName('high')],
// Setting maxzoom here enables 'overzooming'
// e.g. continued zooming beyond the max bounds.
// More here: https://docs.mapbox.com/help/glossary/overzoom/
@ -66,7 +67,7 @@ export const getOSBaseMap = () : Style => {
// to give us a favorable tradeoff between performance and fidelity.
'type': 'vector',
'promoteId': constants.GEOID_PROPERTY,
'tiles': [constants.FEATURE_TILE_LOW_ZOOM_URL],
'tiles': [featureURLForTilesetName('low')],
'minzoom': constants.GLOBAL_MIN_ZOOM_LOW,
'maxzoom': constants.GLOBAL_MAX_ZOOM_LOW,
},

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 88 83.5"><defs><style>.cls-1{fill:#c9c9c9;}.cls-2{clip-path:url(#clip-path);}.cls-3{isolation:isolate;}.cls-4{clip-path:url(#clip-path-2);}.cls-5{fill:none;stroke:#c9c9c9;stroke-miterlimit:10;}.cls-6{fill:#fff;}</style><clipPath id="clip-path" transform="translate(4.5 4.5)"><rect class="cls-1" x="0.5" y="0.5" width="78" height="39"/></clipPath><clipPath id="clip-path-2" transform="translate(4.5 4.5)"><rect class="cls-1" x="0.5" y="0.5" width="79" height="39"/></clipPath></defs><g id="Layer_2" data-name="Layer 2"><g id="Layer_1-2" data-name="Layer 1"><rect class="cls-1" x="5" y="5" width="78" height="39"/><g class="cls-2"><g class="cls-3"><rect class="cls-1" x="5" y="5" width="79" height="39"/><g class="cls-4"><rect class="cls-1" x="5" y="5" width="78" height="39"/><g class="cls-2"><rect class="cls-1" width="88" height="49"/></g></g></g></g><rect class="cls-5" x="5" y="5" width="78" height="78"/><g class="cls-3"><path class="cls-6" d="M19.68,26.5l4.66-13h2.77l4.65,13H29.14l-1.06-3H23.4l-1.09,3ZM24,21.19h3.46L25.73,16Z" transform="translate(4.5 4.5)"/><path class="cls-6" d="M33.72,26.5v-13H38.5a6.27,6.27,0,0,1,2.55.49,4.26,4.26,0,0,1,1.85,6,3.67,3.67,0,0,1-1.61,1.4,5.62,5.62,0,0,1-2.44.5H36.36V26.5Zm2.61-6.68h2.44a2.19,2.19,0,0,0,1.62-.63A2.16,2.16,0,0,0,41,17.62a2,2,0,0,0-.66-1.55,2.43,2.43,0,0,0-1.62-.57H36.33Z" transform="translate(4.5 4.5)"/><path class="cls-6" d="M55.56,26.5H52.83l-2.12-5H48.08v5H45.46v-13H51A5.71,5.71,0,0,1,53.5,14,3.22,3.22,0,0,1,55,15.35a4.16,4.16,0,0,1,.47,2,4.1,4.1,0,0,1-.32,1.74,3.49,3.49,0,0,1-.83,1.17,5.26,5.26,0,0,1-1.13.77Zm-5.08-7a2.41,2.41,0,0,0,1.67-.56,1.91,1.91,0,0,0,.62-1.46,1.77,1.77,0,0,0-.6-1.42,2.16,2.16,0,0,0-1.5-.53H48.08v4Z" transform="translate(4.5 4.5)"/></g><path class="cls-1" d="M33.41,66.5V56.75H31.09V55.27a6.34,6.34,0,0,0,1.8-.21,2.12,2.12,0,0,0,1-.62,1.75,1.75,0,0,0,.41-.95h1.74v13Z" transform="translate(4.5 4.5)"/><path class="cls-1" d="M40.17,53.49h8.36l-.1,2.16H42.25L42,58.78a6.35,6.35,0,0,1,1.38-.59A5.33,5.33,0,0,1,44.8,58a5.5,5.5,0,0,1,2.34.49,3.86,3.86,0,0,1,1.63,1.44,4.22,4.22,0,0,1,.61,2.3,4.38,4.38,0,0,1-.63,2.38A4,4,0,0,1,47,66.16a6.18,6.18,0,0,1-2.69.54,6.83,6.83,0,0,1-2.38-.4A6,6,0,0,1,40,65.22a4.81,4.81,0,0,1-1.21-1.58l2-1.22a7.12,7.12,0,0,0,.79,1.11,3.61,3.61,0,0,0,1,.77,3.06,3.06,0,0,0,1.36.28A2.72,2.72,0,0,0,45.91,64a2,2,0,0,0,.71-1.62,2.1,2.1,0,0,0-.32-1.13,2.25,2.25,0,0,0-.88-.79,2.8,2.8,0,0,0-1.3-.28,4.56,4.56,0,0,0-.75.06,2.61,2.61,0,0,0-.72.26,4.69,4.69,0,0,0-.81.52.49.49,0,0,1-.17.06.44.44,0,0,1-.19-.07l-1.91-.88Z" transform="translate(4.5 4.5)"/></g></g></svg>

After

Width:  |  Height:  |  Size: 2.6 KiB

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 88 83.5"><defs><style>.cls-1{fill:#c9c9c9;}.cls-2{clip-path:url(#clip-path);}.cls-3{isolation:isolate;}.cls-4{clip-path:url(#clip-path-2);}.cls-5{fill:none;stroke:#c9c9c9;stroke-miterlimit:10;}.cls-6{fill:#fff;}</style><clipPath id="clip-path" transform="translate(4.5 4.5)"><rect class="cls-1" x="0.5" y="0.5" width="78" height="39"/></clipPath><clipPath id="clip-path-2" transform="translate(4.5 4.5)"><rect class="cls-1" x="0.5" y="0.5" width="79" height="39"/></clipPath></defs><g id="Layer_2" data-name="Layer 2"><g id="Layer_1-2" data-name="Layer 1"><rect class="cls-1" x="5" y="5" width="78" height="39"/><g class="cls-2"><g class="cls-3"><rect class="cls-1" x="5" y="5" width="79" height="39"/><g class="cls-4"><rect class="cls-1" x="5" y="5" width="78" height="39"/><g class="cls-2"><rect class="cls-1" width="88" height="49"/></g></g></g></g><rect class="cls-5" x="5" y="5" width="78" height="78"/><g class="cls-3"><path class="cls-6" d="M20.64,26.5v-13h3.81l3,9.27,3-9.27h3.81v13H31.59V16.55l-3.13,10H26.4l-3.12-9.9v9.9Z" transform="translate(4.5 4.5)"/><path class="cls-6" d="M36.19,26.5l4.66-13h2.77l4.66,13H45.66l-1.06-3H39.92l-1.09,3Zm4.31-5.31H44L42.25,16Z" transform="translate(4.5 4.5)"/><path class="cls-6" d="M60.33,26.5H57.6l-2.12-5H52.85v5H50.23v-13h5.49a5.71,5.71,0,0,1,2.55.49,3.22,3.22,0,0,1,1.45,1.37,4.16,4.16,0,0,1,.47,2,4.1,4.1,0,0,1-.32,1.74A3.49,3.49,0,0,1,59,20.28a5.26,5.26,0,0,1-1.13.77Zm-5.08-7a2.37,2.37,0,0,0,1.67-.57,1.87,1.87,0,0,0,.62-1.45,1.81,1.81,0,0,0-.6-1.43,2.21,2.21,0,0,0-1.5-.52H52.85v4Z" transform="translate(4.5 4.5)"/></g><path class="cls-1" d="M33.68,66.5V56.75H31.36V55.27a6.42,6.42,0,0,0,1.81-.21,2.17,2.17,0,0,0,1-.62,1.74,1.74,0,0,0,.4-.95h1.75v13Z" transform="translate(4.5 4.5)"/><path class="cls-1" d="M44.11,53.31A4.38,4.38,0,0,1,47.77,55a8,8,0,0,1,1.34,5A8,8,0,0,1,47.79,65a4.81,4.81,0,0,1-7.38,0,8,8,0,0,1-1.33-5,9.65,9.65,0,0,1,.62-3.66,4.88,4.88,0,0,1,1.73-2.29A4.65,4.65,0,0,1,44.11,53.31Zm0,11.24a1.8,1.8,0,0,0,1.7-1A8.11,8.11,0,0,0,46.35,60a8.53,8.53,0,0,0-.55-3.57,1.81,1.81,0,0,0-1.7-1.08,1.84,1.84,0,0,0-1.72,1.09A8.32,8.32,0,0,0,41.82,60a7.71,7.71,0,0,0,.56,3.47A1.84,1.84,0,0,0,44.11,64.55Z" transform="translate(4.5 4.5)"/></g></g></svg>

After

Width:  |  Height:  |  Size: 2.3 KiB

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 88 83.5"><defs><style>.cls-1{fill:#c9c9c9;}.cls-2{clip-path:url(#clip-path);}.cls-3{isolation:isolate;}.cls-4{clip-path:url(#clip-path-2);}.cls-5{fill:none;stroke:#c9c9c9;stroke-miterlimit:10;}.cls-6{fill:#fff;}</style><clipPath id="clip-path" transform="translate(4.5 4.5)"><rect class="cls-1" x="0.5" y="0.5" width="78" height="39"/></clipPath><clipPath id="clip-path-2" transform="translate(4.5 4.5)"><rect class="cls-1" x="0.5" y="0.5" width="79" height="39"/></clipPath></defs><g id="Layer_2" data-name="Layer 2"><g id="Layer_1-2" data-name="Layer 1"><rect class="cls-1" x="5" y="5" width="78" height="39"/><g class="cls-2"><g class="cls-3"><rect class="cls-1" x="5" y="5" width="79" height="39"/><g class="cls-4"><rect class="cls-1" x="5" y="5" width="78" height="39"/><g class="cls-2"><rect class="cls-1" width="88" height="49"/></g></g></g></g><rect class="cls-5" x="5" y="5" width="78" height="78"/><g class="cls-3"><path class="cls-6" d="M20.64,26.5v-13h3.81l3,9.27,3-9.27h3.81v13H31.59V16.55l-3.13,10H26.4l-3.12-9.9v9.9Z" transform="translate(4.5 4.5)"/><path class="cls-6" d="M36.19,26.5l4.66-13h2.77l4.66,13H45.66l-1.06-3H39.92l-1.09,3Zm4.31-5.31H44L42.25,16Z" transform="translate(4.5 4.5)"/><path class="cls-6" d="M60.33,26.5H57.6l-2.12-5H52.85v5H50.23v-13h5.49a5.71,5.71,0,0,1,2.55.49,3.22,3.22,0,0,1,1.45,1.37,4.16,4.16,0,0,1,.47,2,4.1,4.1,0,0,1-.32,1.74A3.49,3.49,0,0,1,59,20.28a5.26,5.26,0,0,1-1.13.77Zm-5.08-7a2.37,2.37,0,0,0,1.67-.57,1.87,1.87,0,0,0,.62-1.45,1.81,1.81,0,0,0-.6-1.43,2.21,2.21,0,0,0-1.5-.52H52.85v4Z" transform="translate(4.5 4.5)"/></g><path class="cls-1" d="M33.41,66.5V56.75H31.09V55.27a6.34,6.34,0,0,0,1.8-.21,2.12,2.12,0,0,0,1-.62,1.75,1.75,0,0,0,.41-.95h1.74v13Z" transform="translate(4.5 4.5)"/><path class="cls-1" d="M40.17,53.49h8.36l-.1,2.16H42.25L42,58.78a6.15,6.15,0,0,1,1.38-.59A5.33,5.33,0,0,1,44.8,58a5.5,5.5,0,0,1,2.34.49,3.86,3.86,0,0,1,1.63,1.44,4.22,4.22,0,0,1,.61,2.3,4.38,4.38,0,0,1-.63,2.38A4,4,0,0,1,47,66.16a6.18,6.18,0,0,1-2.69.54,6.83,6.83,0,0,1-2.38-.4A6,6,0,0,1,40,65.22a4.81,4.81,0,0,1-1.21-1.58l2-1.22a6.51,6.51,0,0,0,.79,1.11,3.61,3.61,0,0,0,1,.77,3.06,3.06,0,0,0,1.36.28A2.72,2.72,0,0,0,45.91,64a2,2,0,0,0,.71-1.62,2.1,2.1,0,0,0-.32-1.13,2.16,2.16,0,0,0-.88-.78,2.68,2.68,0,0,0-1.3-.29,4.38,4.38,0,0,0-.75.06,2.61,2.61,0,0,0-.72.26,5.39,5.39,0,0,0-.81.52.49.49,0,0,1-.17.06.44.44,0,0,1-.19-.07l-1.91-.88Z" transform="translate(4.5 4.5)"/></g></g></svg>

After

Width:  |  Height:  |  Size: 2.5 KiB

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 88 83.5"><defs><style>.cls-1{fill:#c9c9c9;}.cls-2{clip-path:url(#clip-path);}.cls-3{isolation:isolate;}.cls-4{clip-path:url(#clip-path-2);}.cls-5{fill:none;stroke:#c9c9c9;stroke-miterlimit:10;}.cls-6{fill:#fff;}</style><clipPath id="clip-path" transform="translate(4.5 4.5)"><rect class="cls-1" x="0.5" y="0.5" width="78" height="39"/></clipPath><clipPath id="clip-path-2" transform="translate(4.5 4.5)"><rect class="cls-1" x="0.5" y="0.5" width="79" height="39"/></clipPath></defs><g id="Layer_2" data-name="Layer 2"><g id="Layer_1-2" data-name="Layer 1"><rect class="cls-1" x="5" y="5" width="78" height="39"/><g class="cls-2"><g class="cls-3"><rect class="cls-1" x="5" y="5" width="79" height="39"/><g class="cls-4"><rect class="cls-1" x="5" y="5" width="78" height="39"/><g class="cls-2"><rect class="cls-1" width="88" height="49"/></g></g></g></g><rect class="cls-5" x="5" y="5" width="78" height="78"/><g class="cls-3"><path class="cls-6" d="M20.64,26.5v-13h3.81l3,9.27,3-9.27h3.81v13H31.59V16.55l-3.13,10H26.4l-3.12-9.9v9.9Z" transform="translate(4.5 4.5)"/><path class="cls-6" d="M36.19,26.5l4.66-13h2.77l4.66,13H45.66l-1.06-3H39.92l-1.09,3Zm4.31-5.31H44L42.25,16Z" transform="translate(4.5 4.5)"/><path class="cls-6" d="M60.33,26.5H57.6l-2.12-5H52.85v5H50.23v-13h5.49a5.71,5.71,0,0,1,2.55.49,3.3,3.3,0,0,1,1.46,1.37,4.27,4.27,0,0,1,.46,2,4.1,4.1,0,0,1-.32,1.74A3.49,3.49,0,0,1,59,20.28a5,5,0,0,1-1.13.77Zm-5.08-7a2.37,2.37,0,0,0,1.67-.57,1.87,1.87,0,0,0,.62-1.45,1.81,1.81,0,0,0-.6-1.43,2.21,2.21,0,0,0-1.5-.52H52.85v4Z" transform="translate(4.5 4.5)"/></g><path class="cls-1" d="M33.54,66.5V56.75H31.22V55.27a6.34,6.34,0,0,0,1.8-.21,2.12,2.12,0,0,0,1-.62,1.68,1.68,0,0,0,.41-.95H36.2v13Z" transform="translate(4.5 4.5)"/><path class="cls-1" d="M44.4,53.31a5.59,5.59,0,0,1,2.26.44A4.27,4.27,0,0,1,48.35,55a3.6,3.6,0,0,1,.72,2H46.66a2.3,2.3,0,0,0-.79-1.25,2.52,2.52,0,0,0-3,.11A3,3,0,0,0,42,57.4a6.08,6.08,0,0,0-.15,2.22,2.94,2.94,0,0,1,.76-.73,3.85,3.85,0,0,1,1-.46,4.2,4.2,0,0,1,1.18-.16,5.1,5.1,0,0,1,2.31.49,3.73,3.73,0,0,1,1.55,1.39,3.92,3.92,0,0,1,.55,2.1,4.2,4.2,0,0,1-.62,2.28,4.46,4.46,0,0,1-1.74,1.59,5.63,5.63,0,0,1-2.58.58,5.11,5.11,0,0,1-2.87-.8,5.22,5.22,0,0,1-1.85-2.25,8.32,8.32,0,0,1-.64-3.4,9.6,9.6,0,0,1,.65-3.7,5.31,5.31,0,0,1,1.88-2.4A5,5,0,0,1,44.4,53.31Zm-.19,6.92a2.49,2.49,0,0,0-1.07.24,2.66,2.66,0,0,0-.85.63,1.21,1.21,0,0,0-.33.78,3.59,3.59,0,0,0,.28,1.5,2.16,2.16,0,0,0,.79,1,2,2,0,0,0,1.17.34,2.3,2.3,0,0,0,1.14-.29,2.27,2.27,0,0,0,.82-.81,2.38,2.38,0,0,0,.3-1.2,2.32,2.32,0,0,0-.29-1.2,1.8,1.8,0,0,0-.81-.71A2.66,2.66,0,0,0,44.21,60.23Z" transform="translate(4.5 4.5)"/></g></g></svg>

After

Width:  |  Height:  |  Size: 2.7 KiB

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 88 83.5"><defs><style>.cls-1{fill:#c9c9c9;}.cls-2{clip-path:url(#clip-path);}.cls-3{isolation:isolate;}.cls-4{clip-path:url(#clip-path-2);}.cls-5{fill:none;stroke:#c9c9c9;stroke-miterlimit:10;}.cls-6{fill:#fff;}</style><clipPath id="clip-path" transform="translate(4.5 4.5)"><rect class="cls-1" x="0.5" y="0.5" width="78" height="39"/></clipPath><clipPath id="clip-path-2" transform="translate(4.5 4.5)"><rect class="cls-1" x="0.5" y="0.5" width="79" height="39"/></clipPath></defs><g id="Layer_2" data-name="Layer 2"><g id="Layer_1-2" data-name="Layer 1"><rect class="cls-1" x="5" y="5" width="78" height="39"/><g class="cls-2"><g class="cls-3"><rect class="cls-1" x="5" y="5" width="79" height="39"/><g class="cls-4"><rect class="cls-1" x="5" y="5" width="78" height="39"/><g class="cls-2"><rect class="cls-1" width="88" height="49"/></g></g></g></g><rect class="cls-5" x="5" y="5" width="78" height="78"/><g class="cls-3"><path class="cls-6" d="M20.64,26.5v-13h3.81l3,9.28,3-9.28h3.81v13H31.59V16.56L28.46,26.5H26.4l-3.12-9.9v9.9Z" transform="translate(4.5 4.5)"/><path class="cls-6" d="M36.19,26.5l4.66-13h2.77l4.66,13H45.66l-1.06-3H39.92l-1.09,3Zm4.31-5.31H44L42.25,16Z" transform="translate(4.5 4.5)"/><path class="cls-6" d="M60.33,26.5H57.6l-2.12-5H52.85v5H50.23v-13h5.49a5.71,5.71,0,0,1,2.55.49,3.22,3.22,0,0,1,1.45,1.37,4.16,4.16,0,0,1,.47,2,4.1,4.1,0,0,1-.32,1.74A3.49,3.49,0,0,1,59,20.28a5.26,5.26,0,0,1-1.13.77Zm-5.08-7a2.41,2.41,0,0,0,1.67-.56,1.91,1.91,0,0,0,.62-1.46,1.77,1.77,0,0,0-.6-1.42,2.16,2.16,0,0,0-1.5-.53H52.85v4Z" transform="translate(4.5 4.5)"/></g><path class="cls-1" d="M29.83,66.5v-2a3.73,3.73,0,0,1,.37-1.72,4.25,4.25,0,0,1,1-1.26,8.38,8.38,0,0,1,1.33-.94c.49-.27,1-.52,1.46-.76s.93-.48,1.33-.73a3.66,3.66,0,0,0,1-.81,1.59,1.59,0,0,0,.37-1.06A1.62,1.62,0,0,0,36.09,56a2.1,2.1,0,0,0-1.48-.5,2.52,2.52,0,0,0-1.67.57,2.6,2.6,0,0,0-.85,1.71H29.58a4.59,4.59,0,0,1,.58-2.25,4.11,4.11,0,0,1,1.69-1.61,6.09,6.09,0,0,1,2.83-.59,5.85,5.85,0,0,1,2.51.49,3.85,3.85,0,0,1,1.64,1.38A4.07,4.07,0,0,1,39,58.93a3.94,3.94,0,0,1-.95,1.22,7.5,7.5,0,0,1-1.31.88c-.47.26-.94.49-1.41.7s-.91.44-1.3.66a3.62,3.62,0,0,0-1,.76,1.51,1.51,0,0,0-.36,1v.12h6.64V66.5Z" transform="translate(4.5 4.5)"/><path class="cls-1" d="M41.26,66.5v-2a3.73,3.73,0,0,1,.37-1.72,4.25,4.25,0,0,1,1-1.26,8.38,8.38,0,0,1,1.33-.94c.49-.27,1-.52,1.46-.76s.93-.48,1.33-.73a3.66,3.66,0,0,0,1-.81,1.59,1.59,0,0,0,.37-1.06A1.62,1.62,0,0,0,47.52,56a2.1,2.1,0,0,0-1.48-.5,2.52,2.52,0,0,0-1.67.57,2.6,2.6,0,0,0-.85,1.71H41a4.59,4.59,0,0,1,.58-2.25,4.11,4.11,0,0,1,1.69-1.61,6.09,6.09,0,0,1,2.83-.59,5.85,5.85,0,0,1,2.51.49,3.85,3.85,0,0,1,1.64,1.38,4.07,4.07,0,0,1,.21,3.75,3.94,3.94,0,0,1-.95,1.22,7.5,7.5,0,0,1-1.31.88c-.47.26-.94.49-1.41.7s-.91.44-1.3.66a3.62,3.62,0,0,0-1,.76,1.51,1.51,0,0,0-.36,1v.12h6.63V66.5Z" transform="translate(4.5 4.5)"/></g></g></svg>

After

Width:  |  Height:  |  Size: 2.9 KiB

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 88 83.5"><defs><style>.cls-1{fill:#c9c9c9;}.cls-2{clip-path:url(#clip-path);}.cls-3{isolation:isolate;}.cls-4{clip-path:url(#clip-path-2);}.cls-5{fill:none;stroke:#c9c9c9;stroke-miterlimit:10;}.cls-6{fill:#fff;}</style><clipPath id="clip-path" transform="translate(4.5 4.5)"><rect class="cls-1" x="0.5" y="0.5" width="78" height="39"/></clipPath><clipPath id="clip-path-2" transform="translate(4.5 4.5)"><rect class="cls-1" x="0.5" y="0.5" width="79" height="39"/></clipPath></defs><g id="Layer_2" data-name="Layer 2"><g id="Layer_1-2" data-name="Layer 1"><rect class="cls-1" x="5" y="5" width="78" height="39"/><g class="cls-2"><g class="cls-3"><rect class="cls-1" x="5" y="5" width="79" height="39"/><g class="cls-4"><rect class="cls-1" x="5" y="5" width="78" height="39"/><g class="cls-2"><rect class="cls-1" width="88" height="49"/></g></g></g></g><rect class="cls-5" x="5" y="5" width="78" height="78"/><g class="cls-3"><path class="cls-6" d="M20.64,26.5v-13h3.81l3,9.28,3-9.28h3.81v13H31.59V16.56L28.46,26.5H26.4l-3.12-9.9v9.9Z" transform="translate(4.5 4.5)"/><path class="cls-6" d="M36.19,26.5l4.66-13h2.77l4.66,13H45.66l-1.06-3H39.92l-1.09,3Zm4.31-5.31H44L42.25,16Z" transform="translate(4.5 4.5)"/><path class="cls-6" d="M60.33,26.5H57.6l-2.12-5H52.85v5H50.23v-13h5.49a5.71,5.71,0,0,1,2.55.49,3.3,3.3,0,0,1,1.46,1.37,4.27,4.27,0,0,1,.46,2,4.1,4.1,0,0,1-.32,1.74A3.49,3.49,0,0,1,59,20.28a5,5,0,0,1-1.13.77Zm-5.08-7a2.37,2.37,0,0,0,1.67-.57,1.87,1.87,0,0,0,.62-1.45,1.77,1.77,0,0,0-.6-1.42,2.16,2.16,0,0,0-1.5-.53H52.85v4Z" transform="translate(4.5 4.5)"/></g><path class="cls-1" d="M29.35,57.49A3.89,3.89,0,0,1,30,55.16a4,4,0,0,1,1.78-1.39,6.51,6.51,0,0,1,2.5-.46,8.28,8.28,0,0,1,2.6.37,4,4,0,0,1,1.8,1.16,3,3,0,0,1,.65,2,2.7,2.7,0,0,1-.55,1.69A3.79,3.79,0,0,1,37,59.66a4.57,4.57,0,0,1,1.33.6,3.14,3.14,0,0,1,1,1,2.89,2.89,0,0,1,.37,1.51,3.27,3.27,0,0,1-.42,1.68,3.81,3.81,0,0,1-1.17,1.23,5.76,5.76,0,0,1-1.73.74,8.83,8.83,0,0,1-2.1.24,6.51,6.51,0,0,1-2.67-.52,3.82,3.82,0,0,1-1.69-1.45,4.29,4.29,0,0,1-.61-2.25H31.8a2.42,2.42,0,0,0,.87,1.6,2.62,2.62,0,0,0,1.6.49,3.65,3.65,0,0,0,1.39-.23,2,2,0,0,0,.89-.65,1.55,1.55,0,0,0,.31-1,1.52,1.52,0,0,0-.32-1,2.2,2.2,0,0,0-.89-.64,4,4,0,0,0-1.29-.25l-1.24,0V58.75l1.11-.06a3.48,3.48,0,0,0,1.23-.26,2.08,2.08,0,0,0,.81-.63,1.4,1.4,0,0,0,.29-.89,1.26,1.26,0,0,0-.29-.82,2,2,0,0,0-.82-.55,3.43,3.43,0,0,0-1.2-.2,3,3,0,0,0-1.14.21,1.91,1.91,0,0,0-.86.68,2.47,2.47,0,0,0-.39,1.26Z" transform="translate(4.5 4.5)"/><path class="cls-1" d="M46.21,53.31A4.35,4.35,0,0,1,49.87,55a7.94,7.94,0,0,1,1.35,5A8,8,0,0,1,49.89,65a4.8,4.8,0,0,1-7.37,0,8,8,0,0,1-1.33-5,9.66,9.66,0,0,1,.61-3.66,5,5,0,0,1,1.74-2.29A4.64,4.64,0,0,1,46.21,53.31Zm0,11.24a1.79,1.79,0,0,0,1.7-1A8.11,8.11,0,0,0,48.45,60a8.37,8.37,0,0,0-.55-3.57,1.79,1.79,0,0,0-1.7-1.08,1.82,1.82,0,0,0-1.71,1.09A8.16,8.16,0,0,0,43.93,60a7.88,7.88,0,0,0,.55,3.47A1.84,1.84,0,0,0,46.21,64.55Z" transform="translate(4.5 4.5)"/></g></g></svg>

After

Width:  |  Height:  |  Size: 3 KiB

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 88 83.5"><defs><style>.cls-1,.cls-6{fill:none;}.cls-2{clip-path:url(#clip-path);}.cls-3{isolation:isolate;}.cls-4{clip-path:url(#clip-path-2);}.cls-5{fill:#005ea2;}.cls-6{stroke:#005ea2;stroke-miterlimit:10;}.cls-7{fill:#fff;}</style><clipPath id="clip-path" transform="translate(4.5 4.5)"><rect class="cls-1" x="0.5" y="0.5" width="78" height="39"/></clipPath><clipPath id="clip-path-2" transform="translate(4.5 4.5)"><rect class="cls-1" x="0.5" y="0.5" width="79" height="39"/></clipPath></defs><g id="Layer_2" data-name="Layer 2"><g id="Layer_1-2" data-name="Layer 1"><g class="cls-2"><g class="cls-3"><g class="cls-4"><g class="cls-2"><rect class="cls-5" width="88" height="49"/></g></g></g></g><rect class="cls-6" x="5" y="5" width="78" height="78"/><g class="cls-3"><path class="cls-7" d="M20.64,26.5v-13h3.81l3,9.27,3-9.27h3.81v13H31.59V16.55l-3.13,10H26.4l-3.12-9.9v9.9Z" transform="translate(4.5 4.5)"/><path class="cls-7" d="M36.19,26.5l4.66-13h2.77l4.66,13H45.66l-1.06-3H39.92l-1.09,3Zm4.31-5.31H44L42.25,16Z" transform="translate(4.5 4.5)"/><path class="cls-7" d="M60.33,26.5H57.6l-2.12-5H52.85v5H50.23v-13h5.49a5.71,5.71,0,0,1,2.55.49,3.3,3.3,0,0,1,1.46,1.37,4.27,4.27,0,0,1,.46,2,4.1,4.1,0,0,1-.32,1.74A3.49,3.49,0,0,1,59,20.28a5,5,0,0,1-1.13.77Zm-5.08-7a2.37,2.37,0,0,0,1.67-.57,1.87,1.87,0,0,0,.62-1.45,1.81,1.81,0,0,0-.6-1.43,2.21,2.21,0,0,0-1.5-.52H52.85v4Z" transform="translate(4.5 4.5)"/></g><path class="cls-5" d="M29.35,57.49A3.89,3.89,0,0,1,30,55.16a4,4,0,0,1,1.78-1.39,6.51,6.51,0,0,1,2.5-.46,8.28,8.28,0,0,1,2.6.37,4,4,0,0,1,1.8,1.16,3,3,0,0,1,.65,2,2.7,2.7,0,0,1-.55,1.69A3.79,3.79,0,0,1,37,59.66a4.57,4.57,0,0,1,1.33.6,3.14,3.14,0,0,1,1,1,2.89,2.89,0,0,1,.37,1.51,3.27,3.27,0,0,1-.42,1.68,3.81,3.81,0,0,1-1.17,1.23,5.76,5.76,0,0,1-1.73.74,8.83,8.83,0,0,1-2.1.24,6.51,6.51,0,0,1-2.67-.52,3.82,3.82,0,0,1-1.69-1.45,4.29,4.29,0,0,1-.61-2.25H31.8a2.39,2.39,0,0,0,.87,1.6,2.62,2.62,0,0,0,1.6.49,3.65,3.65,0,0,0,1.39-.23,2,2,0,0,0,.89-.65,1.55,1.55,0,0,0,.31-1,1.52,1.52,0,0,0-.32-1,2.2,2.2,0,0,0-.89-.64,4,4,0,0,0-1.29-.25l-1.24,0V58.75l1.11-.06a3.48,3.48,0,0,0,1.23-.26,2.08,2.08,0,0,0,.81-.63,1.39,1.39,0,0,0,.29-.88,1.27,1.27,0,0,0-.29-.83,2,2,0,0,0-.82-.55,3.43,3.43,0,0,0-1.2-.2,3,3,0,0,0-1.14.21,1.91,1.91,0,0,0-.86.68,2.47,2.47,0,0,0-.39,1.26Z" transform="translate(4.5 4.5)"/><path class="cls-5" d="M46.21,53.31A4.35,4.35,0,0,1,49.87,55a7.94,7.94,0,0,1,1.35,5A8,8,0,0,1,49.89,65a4.8,4.8,0,0,1-7.37,0,8,8,0,0,1-1.33-5,9.66,9.66,0,0,1,.61-3.66,5,5,0,0,1,1.74-2.29A4.64,4.64,0,0,1,46.21,53.31Zm0,11.24a1.79,1.79,0,0,0,1.7-1A8.11,8.11,0,0,0,48.45,60a8.37,8.37,0,0,0-.55-3.57,1.78,1.78,0,0,0-1.7-1.07,1.81,1.81,0,0,0-1.71,1.08A8.16,8.16,0,0,0,43.93,60a7.88,7.88,0,0,0,.55,3.47A1.84,1.84,0,0,0,46.21,64.55Z" transform="translate(4.5 4.5)"/></g></g></svg>

After

Width:  |  Height:  |  Size: 2.8 KiB

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 88 83.5"><defs><style>.cls-1{fill:#c9c9c9;}.cls-2{clip-path:url(#clip-path);}.cls-3{isolation:isolate;}.cls-4{clip-path:url(#clip-path-2);}.cls-5{fill:none;stroke:#c9c9c9;stroke-miterlimit:10;}.cls-6{fill:#fff;}</style><clipPath id="clip-path" transform="translate(4.5 4.5)"><rect class="cls-1" x="0.5" y="0.5" width="78" height="39"/></clipPath><clipPath id="clip-path-2" transform="translate(4.5 4.5)"><rect class="cls-1" x="0.5" y="0.5" width="79" height="39"/></clipPath></defs><g id="Layer_2" data-name="Layer 2"><g id="Layer_1-2" data-name="Layer 1"><rect class="cls-1" x="5" y="5" width="78" height="39"/><g class="cls-2"><g class="cls-3"><rect class="cls-1" x="5" y="5" width="79" height="39"/><g class="cls-4"><rect class="cls-1" x="5" y="5" width="78" height="39"/><g class="cls-2"><rect class="cls-1" width="88" height="49"/></g></g></g></g><rect class="cls-5" x="5" y="5" width="78" height="78"/><g class="cls-3"><path class="cls-6" d="M20.64,26.5v-13h3.81l3,9.28,3-9.28h3.81v13H31.59V16.56L28.46,26.5H26.4l-3.12-9.9v9.9Z" transform="translate(4.5 4.5)"/><path class="cls-6" d="M36.19,26.5l4.66-13h2.77l4.66,13H45.66l-1.06-3H39.91l-1.08,3Zm4.31-5.31H44L42.25,16Z" transform="translate(4.5 4.5)"/><path class="cls-6" d="M60.33,26.5H57.6l-2.12-5H52.85v5H50.23v-13h5.49a5.71,5.71,0,0,1,2.55.49,3.22,3.22,0,0,1,1.45,1.37,4.16,4.16,0,0,1,.47,2,4.1,4.1,0,0,1-.32,1.74A3.49,3.49,0,0,1,59,20.28a5.26,5.26,0,0,1-1.13.77Zm-5.08-7a2.37,2.37,0,0,0,1.67-.57,1.87,1.87,0,0,0,.62-1.45,1.77,1.77,0,0,0-.6-1.42,2.16,2.16,0,0,0-1.5-.53H52.85v4Z" transform="translate(4.5 4.5)"/></g><path class="cls-1" d="M31.28,57.49a3.77,3.77,0,0,1,2.44-3.72,6.52,6.52,0,0,1,2.51-.46,8.26,8.26,0,0,1,2.59.37,4,4,0,0,1,1.8,1.16,2.9,2.9,0,0,1,.65,2,2.7,2.7,0,0,1-.55,1.69,3.79,3.79,0,0,1-1.82,1.17,4.57,4.57,0,0,1,1.33.6,3.14,3.14,0,0,1,1,1,2.89,2.89,0,0,1,.37,1.51,3.27,3.27,0,0,1-.42,1.68A3.71,3.71,0,0,1,40,65.72a5.76,5.76,0,0,1-1.73.74,8.77,8.77,0,0,1-2.1.24,6.51,6.51,0,0,1-2.67-.52,3.82,3.82,0,0,1-1.69-1.45,4.39,4.39,0,0,1-.61-2.25h2.53a2.42,2.42,0,0,0,.87,1.6,2.62,2.62,0,0,0,1.6.49,3.65,3.65,0,0,0,1.39-.23,2,2,0,0,0,.89-.65,1.55,1.55,0,0,0,.31-1,1.52,1.52,0,0,0-.32-1,2.13,2.13,0,0,0-.89-.64,3.84,3.84,0,0,0-1.29-.25l-1.24,0V58.75l1.11-.06a3.48,3.48,0,0,0,1.23-.26,2,2,0,0,0,.81-.63,1.4,1.4,0,0,0,.29-.89,1.21,1.21,0,0,0-.29-.82,1.89,1.89,0,0,0-.82-.55,3.43,3.43,0,0,0-1.2-.2,3,3,0,0,0-1.14.21,2,2,0,0,0-.86.68,2.38,2.38,0,0,0-.38,1.26Z" transform="translate(4.5 4.5)"/><path class="cls-1" d="M45.47,66.5V56.75H43.15V55.27a6.34,6.34,0,0,0,1.8-.21,2.12,2.12,0,0,0,1-.62,1.75,1.75,0,0,0,.41-.95h1.74v13Z" transform="translate(4.5 4.5)"/></g></g></svg>

After

Width:  |  Height:  |  Size: 2.7 KiB

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 88 83.5"><defs><style>.cls-1,.cls-6{fill:none;}.cls-2{clip-path:url(#clip-path);}.cls-3{isolation:isolate;}.cls-4{clip-path:url(#clip-path-2);}.cls-5{fill:#005ea2;}.cls-6{stroke:#005ea2;stroke-miterlimit:10;}.cls-7{fill:#fff;}</style><clipPath id="clip-path" transform="translate(4.5 4.5)"><rect class="cls-1" x="0.5" y="0.5" width="78" height="39"/></clipPath><clipPath id="clip-path-2" transform="translate(4.5 4.5)"><rect class="cls-1" x="0.5" y="0.5" width="79" height="39"/></clipPath></defs><g id="Layer_2" data-name="Layer 2"><g id="Layer_1-2" data-name="Layer 1"><g class="cls-2"><g class="cls-3"><g class="cls-4"><g class="cls-2"><rect class="cls-5" width="88" height="49"/></g></g></g></g><rect class="cls-6" x="5" y="5" width="78" height="78"/><g class="cls-3"><path class="cls-7" d="M20.64,26.5v-13h3.81l3,9.27,3-9.27h3.81v13H31.59V16.55l-3.13,10H26.4l-3.12-9.9v9.9Z" transform="translate(4.5 4.5)"/><path class="cls-7" d="M36.19,26.5l4.66-13h2.77l4.66,13H45.66l-1.06-3H39.92l-1.09,3Zm4.31-5.31H44L42.25,16Z" transform="translate(4.5 4.5)"/><path class="cls-7" d="M60.33,26.5H57.6l-2.12-5H52.85v5H50.23v-13h5.49a5.71,5.71,0,0,1,2.55.49,3.22,3.22,0,0,1,1.45,1.37,4.16,4.16,0,0,1,.47,2,4.1,4.1,0,0,1-.32,1.74A3.49,3.49,0,0,1,59,20.28a5.26,5.26,0,0,1-1.13.77Zm-5.08-7a2.37,2.37,0,0,0,1.67-.57,1.87,1.87,0,0,0,.62-1.45,1.81,1.81,0,0,0-.6-1.43,2.21,2.21,0,0,0-1.5-.52H52.85v4Z" transform="translate(4.5 4.5)"/></g><path class="cls-5" d="M31.28,57.49a3.77,3.77,0,0,1,2.44-3.72,6.52,6.52,0,0,1,2.51-.46,8.26,8.26,0,0,1,2.59.37,4,4,0,0,1,1.8,1.16,2.9,2.9,0,0,1,.65,2,2.7,2.7,0,0,1-.55,1.69,3.79,3.79,0,0,1-1.82,1.17,4.57,4.57,0,0,1,1.33.6,3.14,3.14,0,0,1,1,1,2.89,2.89,0,0,1,.37,1.51,3.27,3.27,0,0,1-.42,1.68A3.61,3.61,0,0,1,40,65.72a5.76,5.76,0,0,1-1.73.74,8.77,8.77,0,0,1-2.1.24,6.51,6.51,0,0,1-2.67-.52,3.82,3.82,0,0,1-1.69-1.45,4.39,4.39,0,0,1-.61-2.25h2.53a2.39,2.39,0,0,0,.87,1.6,2.62,2.62,0,0,0,1.6.49,3.65,3.65,0,0,0,1.39-.23,2,2,0,0,0,.89-.65,1.55,1.55,0,0,0,.31-1,1.52,1.52,0,0,0-.32-1,2.13,2.13,0,0,0-.89-.64,3.84,3.84,0,0,0-1.29-.25l-1.24,0V58.75l1.11-.06a3.48,3.48,0,0,0,1.23-.26,2,2,0,0,0,.81-.63,1.39,1.39,0,0,0,.29-.88,1.22,1.22,0,0,0-.29-.83,1.89,1.89,0,0,0-.82-.55,3.43,3.43,0,0,0-1.2-.2,3,3,0,0,0-1.14.21,2,2,0,0,0-.86.68,2.38,2.38,0,0,0-.38,1.26Z" transform="translate(4.5 4.5)"/><path class="cls-5" d="M45.47,66.5V56.75H43.15V55.27a6.34,6.34,0,0,0,1.8-.21,2.12,2.12,0,0,0,1-.62,1.75,1.75,0,0,0,.41-.95h1.74v13Z" transform="translate(4.5 4.5)"/></g></g></svg>

After

Width:  |  Height:  |  Size: 2.5 KiB

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 88 83.5"><defs><style>.cls-1{fill:#c9c9c9;}.cls-2{clip-path:url(#clip-path);}.cls-3{isolation:isolate;}.cls-4{clip-path:url(#clip-path-2);}.cls-5{fill:none;stroke:#c9c9c9;stroke-miterlimit:10;}.cls-6{fill:#fff;}</style><clipPath id="clip-path" transform="translate(4.5 4.5)"><rect class="cls-1" x="0.5" y="0.5" width="78" height="39"/></clipPath><clipPath id="clip-path-2" transform="translate(4.5 4.5)"><rect class="cls-1" x="0.5" y="0.5" width="79" height="39"/></clipPath></defs><g id="Layer_2" data-name="Layer 2"><g id="Layer_1-2" data-name="Layer 1"><rect class="cls-1" x="5" y="5" width="78" height="39"/><g class="cls-2"><g class="cls-3"><rect class="cls-1" x="5" y="5" width="79" height="39"/><g class="cls-4"><rect class="cls-1" x="5" y="5" width="78" height="39"/><g class="cls-2"><rect class="cls-1" width="88" height="49"/></g></g></g></g><rect class="cls-5" x="5" y="5" width="78" height="78"/><g class="cls-3"><path class="cls-6" d="M20.64,26.5v-13h3.81l3,9.28,3-9.28h3.81v13H31.59V16.56L28.46,26.5H26.4l-3.12-9.9v9.9Z" transform="translate(4.5 4.5)"/><path class="cls-6" d="M36.19,26.5l4.66-13h2.77l4.66,13H45.66l-1.06-3H39.91l-1.08,3Zm4.31-5.31H44L42.25,16Z" transform="translate(4.5 4.5)"/><path class="cls-6" d="M60.33,26.5H57.6l-2.12-5H52.85v5H50.23v-13h5.49a5.71,5.71,0,0,1,2.55.49,3.22,3.22,0,0,1,1.45,1.37,4.16,4.16,0,0,1,.47,2,4.1,4.1,0,0,1-.32,1.74A3.49,3.49,0,0,1,59,20.28a5.26,5.26,0,0,1-1.13.77Zm-5.08-7a2.41,2.41,0,0,0,1.67-.56,1.91,1.91,0,0,0,.62-1.46,1.77,1.77,0,0,0-.6-1.42,2.16,2.16,0,0,0-1.5-.53H52.85v4Z" transform="translate(4.5 4.5)"/></g><path class="cls-1" d="M39.88,66.7a5.56,5.56,0,0,1-2.27-.47,4.37,4.37,0,0,1-1.72-1.32,3.42,3.42,0,0,1-.74-2h2.5a2.15,2.15,0,0,0,.72,1.23,2.11,2.11,0,0,0,1.4.47,3,3,0,0,0,1.64-.44,2.71,2.71,0,0,0,1.07-1.41,6.16,6.16,0,0,0,.24-2.52,2.63,2.63,0,0,1-.69.84,3.56,3.56,0,0,1-1,.55,4.59,4.59,0,0,1-1.33.19,5.3,5.3,0,0,1-2.34-.5,3.81,3.81,0,0,1-1.6-1.42,4,4,0,0,1-.58-2.19,4.19,4.19,0,0,1,2.32-3.85A5.63,5.63,0,0,1,40,53.31a4.85,4.85,0,0,1,4.71,3,8.4,8.4,0,0,1,.64,3.39,10,10,0,0,1-.66,3.89,4.92,4.92,0,0,1-1.9,2.32A5.46,5.46,0,0,1,39.88,66.7Zm.23-7a2.4,2.4,0,0,0,1.07-.25,2.5,2.5,0,0,0,.85-.62,1.17,1.17,0,0,0,.33-.78,3.41,3.41,0,0,0-.27-1.5,2.09,2.09,0,0,0-2-1.3,2.12,2.12,0,0,0-1.1.29,2,2,0,0,0-.77.81A2.6,2.6,0,0,0,38,57.6a2.07,2.07,0,0,0,.6,1.58A2.17,2.17,0,0,0,40.11,59.74Z" transform="translate(4.5 4.5)"/></g></g></svg>

After

Width:  |  Height:  |  Size: 2.4 KiB

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 187.87 129.8"><defs><style>.cls-1{fill:#fff;}</style></defs><g id="Layer_2" data-name="Layer 2"><g id="Layer_1-2" data-name="Layer 1"><g id="XMPp2J.tif"><path d="M20.86,125.3a4.11,4.11,0,0,0,3.75-1.81,132.6,132.6,0,0,0,24-49.64C51.18,63.55,53,53.07,55.25,42.7c2-9.22,4.6-18.28,10.64-25.79C74.19,6.6,84.69-.14,98.3,0c16.36.18,28.16,8.39,35.82,22.58,4.13,7.64,5.43,16.16,6.48,24.66,2,15.9,3.66,31.84,9.41,47A126.16,126.16,0,0,0,166,123.46a4,4,0,0,0,3.71,1.86M35.23,125.1h120.5c-.32-.58-.48-.94-.7-1.26a124.66,124.66,0,0,1-19.9-49.53c-1.79-10.47-2.91-21-4.51-31.55-1.05-6.93-2.78-13.66-6.74-19.62C116.93,12.7,103.79,7,92.3,9.94c-11.25,2.9-19.12,10-23.7,20.69C64.6,40,63.19,50.1,61.31,60,58,77.67,53,94.74,44.17,110.48,41.37,115.39,38.23,120.1,35.23,125.1Z"/><path class="cls-1" d="M35.23,125.1c3.07-5,6.18-9.71,8.94-14.62C53,94.74,57.94,77.67,61.23,60c1.88-9.94,3.25-20,7.29-29.41C73.1,20,81,12.84,92.22,9.94c11.49-3,24.63,2.76,31.58,13.2,4,6,5.69,12.69,6.74,19.62,1.6,10.5,2.72,21.08,4.51,31.55A124.66,124.66,0,0,0,155,123.84c.22.32.38.68.7,1.26Z"/></g><rect y="120.8" width="187.87" height="9"/></g></g></svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 157.03 156.92"><g id="Layer_2" data-name="Layer 2"><g id="Layer_1-2" data-name="Layer 1"><path d="M94.41,126.85h-.94l-3.44,0V79c0-5.94-3.36-10.31-9-11.69a18.4,18.4,0,0,0-4-.35H35.89L30.2,67l-.08-3.4C29.42,34.52,52.26,2,90.36.09a63.39,63.39,0,0,1,66.59,60,64,64,0,0,1,0,7.06,63.26,63.26,0,0,1-62.51,59.72ZM77.57,60a24.69,24.69,0,0,1,5,.51l.11,0C91.51,62.64,97,69.73,97,79v40.78a56.32,56.32,0,0,0,52.9-53.07,57.38,57.38,0,0,0,0-6.29A56.38,56.38,0,0,0,90.72,7.08C58.3,8.71,38.31,35.15,37.16,60H77.57Z"/><path d="M68,156.92h0A68.29,68.29,0,0,1,1.52,102.5,83.24,83.24,0,0,1,.34,92.9C.25,91.8.16,90.69.06,89.6a8.52,8.52,0,0,1,2.13-6.78A9.29,9.29,0,0,1,9.41,80c2.74.06,5.54,0,8.24,0l4.2,0H67.63c4.09,0,6.92,1.55,8.39,4.62A10.49,10.49,0,0,1,77,89v10.7c0,2.16,0,4.55,0,8.88v39.37a8.44,8.44,0,0,1-9,9Zm-58.78-70a2.48,2.48,0,0,0-1.84.61A1.63,1.63,0,0,0,7,88.88c.11,1.17.21,2.31.3,3.45a74.42,74.42,0,0,0,1.06,8.76A61.6,61.6,0,0,0,68,149.92a2.4,2.4,0,0,0,1.63-.4,2.43,2.43,0,0,0,.4-1.6V108.55c0-4.33,0-6.73,0-8.89V89a3.31,3.31,0,0,0-.32-1.42c-.11-.23-.29-.61-2.06-.61H17.7c-2.75,0-5.6,0-8.43,0Z"/></g></g></svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 139.87 142.74"><defs><style>.cls-1{fill:#fff;}.cls-2{fill:#231f20;}.cls-3{fill:#bcbeca;}.cls-4{fill:#0c3556;}</style></defs><g id="Layer_2" data-name="Layer 2"><g id="Layer_1-2" data-name="Layer 1"><path class="cls-1" d="M109.09,88.25h-2.28l-32.21.84c-2.14.06-3,.85-3,2.9v47.46c0,2,1,2.94,3,2.93q31.2-.1,62.38-.26c2.06,0,2.89-.86,2.89-2.94V75.85c0-2.13-.88-3-3-3H112.09c-2.18,0-3,.84-3,3ZM47.16,28.87V3.15c0-2.32-.77-3.13-3-3.13H3C1,0,.05.86.06,2.79Q.17,34,.31,65.29c0,2.11.79,2.81,3,2.86H67.09c2.55,0,3.29-.61,3.3-2.82V31.67c0-2-.83-2.78-2.85-2.78H47.16Zm5.14-24h82.51v63h4.75V3.31c0-2.58-.73-3.29-3.36-3.29H52.3Zm-47.16,133v-66H.35v67.3c0,2.87.71,3.57,3.6,3.57H66.61V138Z"/><path class="cls-2" d="M39.44,5.06v-5H136.2c2.63,0,3.36.74,3.36,3.41V83.72h-4.75V5.06Z"/><path class="cls-2" d="M5.14,137.9H76.25v4.79H4c-2.89,0-3.6-.7-3.6-3.57V65.42H5.14Z"/><path class="cls-3" d="M76.54,93.89c.63,0,1.15-.09,1.67-.1l31.91-.71c2.44,0,2.22-.77,2.33-3.28.14-3.49.2-7,.3-10.47,0-.53,1.1-1,1.15-1.63h21v60H76.54Z"/><path class="cls-3" d="M65.51,33.67V63.41H6.66c-1.47,0-1.78-.5-1.78-1.84V5.48A2.12,2.12,0,0,1,5,4.89H42.41V30.45c0,2.38.79,3.18,3.14,3.18h20Z"/><path class="cls-4" d="M108.91,88.32V75.83c0-2.15.86-3,3-3h24.58c2.14,0,3,.88,3,3v63.62c0,2.09-.82,3-2.88,3q-31,.15-62.09.25c-2,0-3-.91-3-2.94V92.09c0-2.07.82-2.85,3-2.91C85.27,88.87,107.8,88.32,108.91,88.32Zm-32.4,5.59v43.8h58.14v-60H113.71c0,.58-.13,1.11-.15,1.63-.1,3.49-.16,7-.3,10.46-.1,2.52-.88,3.23-3.31,3.29l-31.76.7-1.68.12Z"/><path class="cls-4" d="M47.16,28.87H67.5c2,0,2.84.78,2.85,2.78V65.31c0,2.21-.75,2.82-3.3,2.82H3.25c-2.16,0-2.94-.75-3-2.86Q.1,34,0,2.77C0,.84.91,0,2.9,0H44.1c2.25,0,3,.81,3,3.13V26.85Zm18.35,4.8h-20c-2.35,0-3.14-.8-3.14-3.18V4.93H4.91c0,.28-.07.44-.07.59V61.61c0,1.34.31,1.84,1.78,1.84q28.61-.08,57.22,0h1.63Z"/></g></g></svg>

After

Width:  |  Height:  |  Size: 1.8 KiB

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 151.87 98.06"><defs><style>.cls-1{fill:none;}.cls-2{clip-path:url(#clip-path);}.cls-3{clip-path:url(#clip-path-2);}.cls-4{clip-path:url(#clip-path-3);}.cls-5{clip-path:url(#clip-path-4);}</style><clipPath id="clip-path" transform="translate(5.98 5.98)"><rect class="cls-1" width="71.75" height="71.75"/></clipPath><clipPath id="clip-path-2" transform="translate(5.98 5.98)"><polygon class="cls-1" points="38.86 59.8 38.86 23.41 55.58 40.12 59.79 35.88 35.88 11.96 11.96 35.88 16.17 40.09 32.89 23.41 32.89 59.8 38.86 59.8"/></clipPath><clipPath id="clip-path-3" transform="translate(5.98 5.98)"><rect class="cls-1" x="68.16" y="14.35" width="71.75" height="71.75"/></clipPath><clipPath id="clip-path-4" transform="translate(5.98 5.98)"><polygon class="cls-1" points="127.95 50.23 123.74 46.01 107.03 62.7 107.03 26.31 101.05 26.31 101.05 62.7 84.34 46.01 80.12 50.23 104.04 74.15 127.95 50.23"/></clipPath></defs><g id="Layer_2" data-name="Layer 2"><g id="Layer_1-2" data-name="Layer 1"><g class="cls-2"><g class="cls-3"><rect width="83.71" height="83.71"/></g></g><g class="cls-4"><g class="cls-5"><rect x="68.16" y="14.35" width="83.71" height="83.71"/></g></g><rect x="19.62" y="73.44" width="44.46" height="5"/><rect x="87.99" y="21.42" width="44.46" height="5"/></g></g></svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

File diff suppressed because it is too large Load diff

View file

@ -268,6 +268,40 @@ exports[`rendering of the DatasetContainer checks if various text fields are vis
</div>
</div>
</div>
<div
class="grid-container-desktop-lg"
data-testid="gridContainer"
>
<div
class="usa-alert usa-alert--info"
data-testid="alert"
>
<div
class="usa-alert__body"
>
<h4
class="usa-alert__heading"
>
Improvements to the map on the Explore the tool page
</h4>
<p
class="usa-alert__text"
>
View improvements made to the display of the information for each census tract and
<a
class="usa-link usa-link--external"
data-cy=""
href="mailto:Screeningtool-Support@omb.eop.gov"
rel="noreferrer"
target="_blank"
>
send feedback
</a>
.
</p>
</div>
</div>
</div>
</header>
<main
id="main-content"
@ -288,11 +322,11 @@ exports[`rendering of the DatasetContainer checks if various text fields are vis
class="usa-tag"
data-testid="tag"
>
NEW
UPDATED
</span>
</div>
<a
href="/public-engagement"
href="/en/public-engagement"
>
<button
class="usa-button usa-button--icon"
@ -333,15 +367,14 @@ exports[`rendering of the DatasetContainer checks if various text fields are vis
</h3>
<p>
To provide feedback about a specific census tract, either select the send feedback button after
To provide feedback about a specific census tract, either select the send feedback button after
selecting a census tract on the
<a
href="/en/cejst"
>
Explore the tool
</a>
page or use the email address provided above. Please
include the census tract ID, county, and state or territory information, in addition to your feedback.
page or use the email address provided above. Please include the census tract ID, county, and state or territory information, in addition to your feedback.
</p>
<p>

View file

@ -268,6 +268,40 @@ exports[`rendering of the DatasetContainer checks if various text fields are vis
</div>
</div>
</div>
<div
class="grid-container-desktop-lg"
data-testid="gridContainer"
>
<div
class="usa-alert usa-alert--info"
data-testid="alert"
>
<div
class="usa-alert__body"
>
<h4
class="usa-alert__heading"
>
Improvements to the map on the Explore the tool page
</h4>
<p
class="usa-alert__text"
>
View improvements made to the display of the information for each census tract and
<a
class="usa-link usa-link--external"
data-cy=""
href="mailto:Screeningtool-Support@omb.eop.gov"
rel="noreferrer"
target="_blank"
>
send feedback
</a>
.
</p>
</div>
</div>
</div>
</header>
<main
id="main-content"
@ -290,11 +324,11 @@ exports[`rendering of the DatasetContainer checks if various text fields are vis
class="usa-tag"
data-testid="tag"
>
NEW
UPDATED
</span>
</div>
<a
href="/public-engagement"
href="/en/public-engagement"
>
<button
class="usa-button usa-button--icon"

View file

@ -268,6 +268,40 @@ exports[`rendering of the DatasetContainer checks if various text fields are vis
</div>
</div>
</div>
<div
class="grid-container-desktop-lg"
data-testid="gridContainer"
>
<div
class="usa-alert usa-alert--info"
data-testid="alert"
>
<div
class="usa-alert__body"
>
<h4
class="usa-alert__heading"
>
Improvements to the map on the Explore the tool page
</h4>
<p
class="usa-alert__text"
>
View improvements made to the display of the information for each census tract and
<a
class="usa-link usa-link--external"
data-cy=""
href="mailto:Screeningtool-Support@omb.eop.gov"
rel="noreferrer"
target="_blank"
>
send feedback
</a>
.
</p>
</div>
</div>
</div>
</header>
<main
id="main-content"
@ -288,11 +322,11 @@ exports[`rendering of the DatasetContainer checks if various text fields are vis
class="usa-tag"
data-testid="tag"
>
NEW
UPDATED
</span>
</div>
<a
href="/public-engagement"
href="/en/public-engagement"
>
<button
class="usa-button usa-button--icon"
@ -334,18 +368,18 @@ exports[`rendering of the DatasetContainer checks if various text fields are vis
<p>
<span>
<strong>
IF
</span>
</strong>
the census tract is above the threshold for one or more environmental or climate indicators
</p>
<p>
<span>
<strong>
AND
</span>
</strong>
the census tract is above the threshold for the socioeconomic indicators
</p>
@ -380,7 +414,7 @@ exports[`rendering of the DatasetContainer checks if various text fields are vis
(.csv and .xlsx).
<span>
Last updated: 2/18/22
Last updated: 02/18/22
</span>
</div>
<div>
@ -444,12 +478,10 @@ exports[`rendering of the DatasetContainer checks if various text fields are vis
<strong>
identified as disadvantaged
</strong>
</p>
<p>
<strong>
IF
</strong>
@ -471,8 +503,6 @@ exports[`rendering of the DatasetContainer checks if various text fields are vis
>
expected population loss rate
</a>
</p>
<p>
@ -486,11 +516,11 @@ exports[`rendering of the DatasetContainer checks if various text fields are vis
>
low income
</a>
AND at or below 20% for
AND 80% or more of adults 15 or older are not enrolled in
<a
href="#high-ed-enroll-rate"
>
higher ed enrollment rate
higher education
</a>
@ -507,12 +537,10 @@ exports[`rendering of the DatasetContainer checks if various text fields are vis
<strong>
identified as disadvantaged
</strong>
</p>
<p>
<strong>
IF
</strong>
@ -528,8 +556,6 @@ exports[`rendering of the DatasetContainer checks if various text fields are vis
>
PM2.5 in the air
</a>
</p>
<p>
@ -543,11 +569,11 @@ exports[`rendering of the DatasetContainer checks if various text fields are vis
>
low income
</a>
AND at or below 20% for
AND 80% or more of adults 15 or older are not enrolled in
<a
href="#high-ed-enroll-rate"
>
higher ed enrollment rate
higher education
</a>
@ -564,7 +590,7 @@ exports[`rendering of the DatasetContainer checks if various text fields are vis
<strong>
identified as disadvantaged
</strong>
</p>
<p>
@ -600,11 +626,11 @@ exports[`rendering of the DatasetContainer checks if various text fields are vis
>
low income
</a>
AND at or below 20% for
AND 80% or more of adults 15 or older are not enrolled in
<a
href="#high-ed-enroll-rate"
>
higher ed enrollment rate
higher education
</a>
@ -621,12 +647,10 @@ exports[`rendering of the DatasetContainer checks if various text fields are vis
<strong>
identified as disadvantaged
</strong>
</p>
<p>
<strong>
IF
</strong>
@ -642,15 +666,12 @@ exports[`rendering of the DatasetContainer checks if various text fields are vis
>
median home value
</a>
is at or less than
the 90th percentile OR at or above the 90th percentile for the
is at or less than the 90th percentile OR at or above the 90th percentile for the
<a
href="#house-burden"
>
housing cost burden
</a>
</p>
<p>
@ -664,11 +685,11 @@ exports[`rendering of the DatasetContainer checks if various text fields are vis
>
low income
</a>
AND at or below 20% for
AND 80% or more of adults 15 or older are not enrolled in
<a
href="#high-ed-enroll-rate"
>
higher ed enrollment rate
higher education
</a>
@ -685,12 +706,10 @@ exports[`rendering of the DatasetContainer checks if various text fields are vis
<strong>
identified as disadvantaged
</strong>
</p>
<p>
<strong>
IF
</strong>
@ -712,8 +731,6 @@ exports[`rendering of the DatasetContainer checks if various text fields are vis
>
proximity to Risk Management Plan (RMP) facilities
</a>
</p>
<p>
@ -727,11 +744,11 @@ exports[`rendering of the DatasetContainer checks if various text fields are vis
>
low income
</a>
AND at or below 20% for
AND 80% or more of adults 15 or older are not enrolled in
<a
href="#high-ed-enroll-rate"
>
higher ed enrollment rate
higher education
</a>
@ -748,12 +765,10 @@ exports[`rendering of the DatasetContainer checks if various text fields are vis
<strong>
identified as disadvantaged
</strong>
</p>
<p>
<strong>
IF
</strong>
@ -763,8 +778,6 @@ exports[`rendering of the DatasetContainer checks if various text fields are vis
>
wastewater discharge
</a>
</p>
<p>
@ -778,11 +791,11 @@ exports[`rendering of the DatasetContainer checks if various text fields are vis
>
low income
</a>
AND at or below 20% for
AND 80% or more of adults 15 or older are not enrolled in
<a
href="#high-ed-enroll-rate"
>
higher ed enrollment rate
higher education
</a>
@ -799,12 +812,10 @@ exports[`rendering of the DatasetContainer checks if various text fields are vis
<strong>
identified as disadvantaged
</strong>
</p>
<p>
<strong>
IF
</strong>
@ -832,8 +843,6 @@ exports[`rendering of the DatasetContainer checks if various text fields are vis
>
low life expectancy
</a>
</p>
<p>
@ -847,11 +856,11 @@ exports[`rendering of the DatasetContainer checks if various text fields are vis
>
low income
</a>
AND at or below 20% for
AND 80% or more of adults 15 or older are not enrolled in
<a
href="#high-ed-enroll-rate"
>
higher ed enrollment rate
higher education
</a>
@ -868,12 +877,10 @@ exports[`rendering of the DatasetContainer checks if various text fields are vis
<strong>
identified as disadvantaged
</strong>
</p>
<p>
<strong>
IF
</strong>
@ -884,21 +891,18 @@ exports[`rendering of the DatasetContainer checks if various text fields are vis
low median income
</a>
as a percentage of area median income OR
<a
href="#ling-iso"
>
linguistic isolation
</a>
OR
OR
<a
href="#unemploy"
>
unemployment
</a>
OR
percent individuals in households at or below 100% Federal
OR percent individuals in households at or below 100% Federal
<a
href="#poverty"
>
@ -908,23 +912,20 @@ exports[`rendering of the DatasetContainer checks if various text fields are vis
</p>
<p>
<strong>
AND
</strong>
is at or less than 90% for
10% or more of adults 25 or older have not attained a
<a
href="#high-school"
>
high school degree attainment rate
high school degree
</a>
for adults 25 years and older AND
at or below 20% for
AND 80% or more of adults 15 or older are not enrolled in
<a
href="#high-ed-enroll-rate"
>
higher ed enrollment rate
higher education
</a>
@ -1031,11 +1032,11 @@ exports[`rendering of the DatasetContainer checks if various text fields are vis
id="high-ed-enroll-rate"
>
<h3>
Higher ed enrollment rate
Higher education non-enrollment
</h3>
<div>
Percent of people who are currently enrolled in college or graduate school.
Percent of people 15 or older who are not currently enrolled in college, university, or graduate school.
</div>
<ul>
@ -1070,7 +1071,7 @@ exports[`rendering of the DatasetContainer checks if various text fields are vis
<span>
Available for:
</span>
All U.S. states and the District of Columbia
All U.S. states, the District of Columbia, and Puerto Rico
</li>
</ul>
</div>
@ -1310,8 +1311,6 @@ exports[`rendering of the DatasetContainer checks if various text fields are vis
<span>
Source:
</span>
<a
class="usa-link usa-link--external"
data-cy=""
@ -1321,8 +1320,7 @@ exports[`rendering of the DatasetContainer checks if various text fields are vis
>
Fusion of model and monitor data
</a>
from 2017 as compiled by EPAs EJSCREEN, sourced from EPA National Air
Toxics Assessment (NATA) and the U.S. Department of Transportation (DOT) traffic data
from 2017 as compiled by EPAs EJSCREEN, sourced from EPA National Air Toxics Assessment (NATA) and the U.S. Department of Transportation (DOT) traffic data
</li>
<li>
@ -1925,23 +1923,19 @@ exports[`rendering of the DatasetContainer checks if various text fields are vis
<div>
Average number of years of life a person who has attained a given age can expect to live.
<p>
<strong>
Note:
</strong>
Unlike most of the other datasets, high values of this data indicate low burdens. For
percentile calculations of burden, the percentile is calculated in reverse order, so that the
census tract with the highest life expectancy relative to area life expectancy (lowest burden
on this measure) is at the 0th percentile, and the census tract with the lowest life
expectancy relative to area life expectancy (highest burden on this measure) is at the
100th percentile. Census tracts with the highest number have the lowest life expectancy.
</p>
</div>
<div>
<p>
<strong>
Note:
</strong>
The percentiles for this dataset have been reversed so that census tracts with lower numbers have higher life expectancies and the census tracts with higher numbers have lower life expectancy when compared to life expectancy in the area.
</p>
</div>
<ul>
<li>
<span>
@ -1987,23 +1981,19 @@ exports[`rendering of the DatasetContainer checks if various text fields are vis
<div>
Median income of the census tract calculated as a percent of the areas median income.
<p>
<strong>
Note:
</strong>
Unlike most of the other datasets, high values of this data indicate low burdens. For
percentile calculations of burden, the percentile is calculated in reverse order, so that the
census tract with the highest median income relative to area median income (lowest burden on this
measure) is at the 0th percentile, and the census tract with the lowest median income relative to
area median income (highest burden on this measure) is at the 100th percentile. Census tracts with
the highest number have the lowest median income.
</p>
</div>
<div>
<p>
<strong>
Note:
</strong>
The percentiles for this dataset have been reversed so that census tracts with lower numbers have higher median incomes and census tracts with the higher numbers have lower median income when compared to area median income.
</p>
</div>
<ul>
<li>
<span>
@ -2249,12 +2239,11 @@ exports[`rendering of the DatasetContainer checks if various text fields are vis
id="high-school"
>
<h3>
High school degree attainment rate
High school degree non-attainment
</h3>
<div>
Percent of people ages 25 years or older in a census tract whose
education level is less than a high school diploma.
Percent of people age 25 years or older in a census tract whose education level is less than a high school diploma.
</div>
<ul>

View file

@ -6,7 +6,6 @@ import HowYouCanHelp from '../components/HowYouCanHelp';
import J40MainGridContainer from '../components/J40MainGridContainer';
import Layout from '../components/layout';
import MapWrapper from '../components/MapWrapper';
import MapLegend from '../components/MapLegend';
import PublicEngageButton from '../components/PublicEngageButton';
import * as EXPLORE_COPY from '../data/copy/explore';
@ -31,16 +30,16 @@ const CEJSTPage = ({location}: IMapPageProps) => {
</section>
<Grid row gap className={'j40-mb5-mt3'}>
<Grid col={12} tablet={{col: 6}}>
{/* Gradually increase width of the Grid as the width decreases from desktop to mobile*/}
{/* desktop = 7 columns, tablet = 10 columns and mobile = 12 columns (full width) */}
<Grid desktop={{col: 7}} tablet={{col: 10}} col={12}>
<section>
<p>
{EXPLORE_COPY.PAGE_DESCRIPTION}
</p>
</section>
</Grid>
<Grid col={12} tablet={{col: 6}}>
<MapLegend />
</Grid>
</Grid>
</J40MainGridContainer>
@ -48,6 +47,21 @@ const CEJSTPage = ({location}: IMapPageProps) => {
<MapWrapper location={location}/>
</J40MainGridContainer>
<J40MainGridContainer>
<Grid desktop={{col: 7}} tablet={{col: 10}} col={12}>
<h2>{EXPLORE_COPY.NOTE_ON_TERRITORIES.INTRO}</h2>
<p>{EXPLORE_COPY.NOTE_ON_TERRITORIES.PARA_1}</p>
<p>{EXPLORE_COPY.NOTE_ON_TERRITORIES.PARA_2}</p>
<p>{EXPLORE_COPY.NOTE_ON_TERRITORIES.PARA_3}</p>
<p>{EXPLORE_COPY.NOTE_ON_TERRITORIES.PARA_4}</p>
</Grid>
<Grid desktop={{col: 7}} tablet={{col: 10}} col={12}>
<h2>{EXPLORE_COPY.NOTE_ON_TRIBAL_NATIONS.INTRO}</h2>
<p>{EXPLORE_COPY.NOTE_ON_TRIBAL_NATIONS.PARA_1}</p>
</Grid>
</J40MainGridContainer>
<J40MainGridContainer>
<Grid row>
<Grid col>

View file

@ -8,6 +8,7 @@ import LinkTypeWrapper from '../components/LinkTypeWrapper';
import PublicEngageButton from '../components/PublicEngageButton';
import * as CONTACT_COPY from '../data/copy/contact';
import * as COMMON_COPY from '../data/copy/common';
interface IContactPageProps {
location: Location;
}
@ -38,9 +39,9 @@ const ContactPage = ({location}: IContactPageProps) => {
values={{
general_email_address:
<LinkTypeWrapper
linkText= {CONTACT_COPY.FEEDBACK_EMAIL}
linkText= {COMMON_COPY.FEEDBACK_EMAIL}
internal= {false}
url= {`mailto:${CONTACT_COPY.FEEDBACK_EMAIL}`}
url= {`mailto:${COMMON_COPY.FEEDBACK_EMAIL}`}
openUrlNewTab= {true}
/>,
}}/>

View file

@ -8,7 +8,7 @@ import Layout from '../components/layout';
import PublicEngageButton from '../components/PublicEngageButton';
import * as ABOUT_COPY from '../data/copy/about';
import * as CONTACT_COPY from '../data/copy/contact';
import * as COMMON_COPY from '../data/copy/common';
// @ts-ignore
import aboutUSMapImg from '../images/about-usmap-1.svg';
@ -118,8 +118,8 @@ const IndexPage = ({location}: IndexPageProps) => {
size={'small'}
imgSrc={commentIcon}
header={intl.formatMessage(ABOUT_COPY.GET_INVOLVED.SEND_FEEDBACK_HEADING)}
linkText={`Email: ${CONTACT_COPY.FEEDBACK_EMAIL}`}
url={`mailto:${CONTACT_COPY.FEEDBACK_EMAIL}`}
linkText={`Email: ${COMMON_COPY.FEEDBACK_EMAIL}`}
url={`mailto:${COMMON_COPY.FEEDBACK_EMAIL}`}
openUrlNewTab={true}
internal={false}>
<p>

View file

@ -302,12 +302,16 @@ This section will outline styles that are component specific
}
}
// This is to allow the first child in the accordions which is the header showing INDICATOR and
// PERCENTILE (0-100) to push into the container's margin to match mock
.usa-accordion__content > *:first-child {
margin: -10px -20px 10px -20px;
.usa-accordion__content {
padding-bottom: 0;
}
//As per Mikel Maron's (MapBox advocate) suggestion to use svg data URI override:
a.mapboxgl-ctrl-logo {
background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg width='88' height='23' viewBox='0 0 88 23' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' fill-rule='evenodd'%3E %3Cdefs%3E %3Cpath id='logo' d='M11.5 2.25c5.105 0 9.25 4.145 9.25 9.25s-4.145 9.25-9.25 9.25-9.25-4.145-9.25-9.25 4.145-9.25 9.25-9.25zM6.997 15.983c-.051-.338-.828-5.802 2.233-8.873a4.395 4.395 0 013.13-1.28c1.27 0 2.49.51 3.39 1.42.91.9 1.42 2.12 1.42 3.39 0 1.18-.449 2.301-1.28 3.13C12.72 16.93 7 16 7 16l-.003-.017zM15.3 10.5l-2 .8-.8 2-.8-2-2-.8 2-.8.8-2 .8 2 2 .8z'/%3E %3Cpath id='text' d='M50.63 8c.13 0 .23.1.23.23V9c.7-.76 1.7-1.18 2.73-1.18 2.17 0 3.95 1.85 3.95 4.17s-1.77 4.19-3.94 4.19c-1.04 0-2.03-.43-2.74-1.18v3.77c0 .13-.1.23-.23.23h-1.4c-.13 0-.23-.1-.23-.23V8.23c0-.12.1-.23.23-.23h1.4zm-3.86.01c.01 0 .01 0 .01-.01.13 0 .22.1.22.22v7.55c0 .12-.1.23-.23.23h-1.4c-.13 0-.23-.1-.23-.23V15c-.7.76-1.69 1.19-2.73 1.19-2.17 0-3.94-1.87-3.94-4.19 0-2.32 1.77-4.19 3.94-4.19 1.03 0 2.02.43 2.73 1.18v-.75c0-.12.1-.23.23-.23h1.4zm26.375-.19a4.24 4.24 0 00-4.16 3.29c-.13.59-.13 1.19 0 1.77a4.233 4.233 0 004.17 3.3c2.35 0 4.26-1.87 4.26-4.19 0-2.32-1.9-4.17-4.27-4.17zM60.63 5c.13 0 .23.1.23.23v3.76c.7-.76 1.7-1.18 2.73-1.18 1.88 0 3.45 1.4 3.84 3.28.13.59.13 1.2 0 1.8-.39 1.88-1.96 3.29-3.84 3.29-1.03 0-2.02-.43-2.73-1.18v.77c0 .12-.1.23-.23.23h-1.4c-.13 0-.23-.1-.23-.23V5.23c0-.12.1-.23.23-.23h1.4zm-34 11h-1.4c-.13 0-.23-.11-.23-.23V8.22c.01-.13.1-.22.23-.22h1.4c.13 0 .22.11.23.22v.68c.5-.68 1.3-1.09 2.16-1.1h.03c1.09 0 2.09.6 2.6 1.55.45-.95 1.4-1.55 2.44-1.56 1.62 0 2.93 1.25 2.9 2.78l.03 5.2c0 .13-.1.23-.23.23h-1.41c-.13 0-.23-.11-.23-.23v-4.59c0-.98-.74-1.71-1.62-1.71-.8 0-1.46.7-1.59 1.62l.01 4.68c0 .13-.11.23-.23.23h-1.41c-.13 0-.23-.11-.23-.23v-4.59c0-.98-.74-1.71-1.62-1.71-.85 0-1.54.79-1.6 1.8v4.5c0 .13-.1.23-.23.23zm53.615 0h-1.61c-.04 0-.08-.01-.12-.03-.09-.06-.13-.19-.06-.28l2.43-3.71-2.39-3.65a.213.213 0 01-.03-.12c0-.12.09-.21.21-.21h1.61c.13 0 .24.06.3.17l1.41 2.37 1.4-2.37a.34.34 0 01.3-.17h1.6c.04 0 .08.01.12.03.09.06.13.19.06.28l-2.37 3.65 2.43 3.7c0 .05.01.09.01.13 0 .12-.09.21-.21.21h-1.61c-.13 0-.24-.06-.3-.17l-1.44-2.42-1.44 2.42a.34.34 0 01-.3.17zm-7.12-1.49c-1.33 0-2.42-1.12-2.42-2.51 0-1.39 1.08-2.52 2.42-2.52 1.33 0 2.42 1.12 2.42 2.51 0 1.39-1.08 2.51-2.42 2.52zm-19.865 0c-1.32 0-2.39-1.11-2.42-2.48v-.07c.02-1.38 1.09-2.49 2.4-2.49 1.32 0 2.41 1.12 2.41 2.51 0 1.39-1.07 2.52-2.39 2.53zm-8.11-2.48c-.01 1.37-1.09 2.47-2.41 2.47s-2.42-1.12-2.42-2.51c0-1.39 1.08-2.52 2.4-2.52 1.33 0 2.39 1.11 2.41 2.48l.02.08zm18.12 2.47c-1.32 0-2.39-1.11-2.41-2.48v-.06c.02-1.38 1.09-2.48 2.41-2.48s2.42 1.12 2.42 2.51c0 1.39-1.09 2.51-2.42 2.51z'/%3E %3C/defs%3E %3Cmask id='clip'%3E %3Crect x='0' y='0' width='100%25' height='100%25' fill='white'/%3E %3Cuse xlink:href='%23logo'/%3E %3Cuse xlink:href='%23text'/%3E %3C/mask%3E %3Cg id='outline' opacity='0.3' stroke='%23000' stroke-width='3'%3E %3Ccircle mask='url(/studio-manual/assets/%23clip)' cx='11.5' cy='11.5' r='9.25'/%3E %3Cuse xlink:href='%23text' mask='url(/studio-manual/assets/%23clip)'/%3E %3C/g%3E %3Cg id='fill' opacity='0.9' fill='%23fff'%3E %3Cuse xlink:href='%23logo'/%3E %3Cuse xlink:href='%23text'/%3E %3C/g%3E %3C/svg%3E") !important;
};
/*
***************************************
* PUBLIC EVENT STYLES

View file

@ -17,6 +17,9 @@ fields:
- score_name: Total threshold criteria exceeded
label: Total threshold criteria exceeded
format: int64
- score_name: Total categories exceeded
label: Total categories exceeded
format: int64
- score_name: Definition M (communities)
label: Identified as disadvantaged
format: bool

View file

@ -21,6 +21,9 @@ sheets:
- score_name: Total threshold criteria exceeded
label: Total threshold criteria exceeded
format: int64
- score_name: Total categories exceeded
label: Total categories exceeded
format: int64
- score_name: Definition M (communities)
label: Identified as disadvantaged
format: bool

View file

@ -0,0 +1,56 @@
# This is a temporary file. We should make sure this *type* of information is maintained when we refactor.
fields:
- score_name: Total threshold criteria exceeded
notes: Lists out the total number of criteria (where each category has one or more criteria) exceeded. For example, a tract that exceeds the 90th percentile for linguistic isolation (1) and unemployment (2), and meets the training and workforce development socioeconomic criteria (high school attainment rate and low percentage of higher ed students) would have a 2 in this field.
- score_name: Definition M (communities)
notes: True / False variable for whether a tract is a Disadvantaged Community (DAC)
- score_name: Is low income and has a low percent of higher ed students?
notes: Associated socioeconomic criterion for all thresholds except those included in training and workforce development
- score_name: Greater than or equal to the 90th percentile for expected agriculture loss rate, is low income, and has a low percent of higher ed students?
category: climate change
- score_name: Greater than or equal to the 90th percentile for expected building loss rate, is low income, and has a low percent of higher ed students?
category: climate change
- score_name: Greater than or equal to the 90th percentile for expected population loss rate, is low income, and has a low percent of higher ed students?
category: climate change
- score_name: Greater than or equal to the 90th percentile for energy burden, is low income, and has a low percent of higher ed students?
category: clean energy and energy efficiency
- score_name: Greater than or equal to the 90th percentile for PM2.5 exposure, is low income, and has a low percent of higher ed students?
category: clean energy and energy efficiency
- score_name: Greater than or equal to the 90th percentile for diesel particulate matter, is low income, and has a low percent of higher ed students?
category: clean transit
- score_name: Greater than or equal to the 90th percentile for traffic proximity, is low income, and has a low percent of higher ed students?
category: clean transit
- score_name: Greater than or equal to the 90th percentile for housing burden, is low income, and has a low percent of higher ed students?
category: affordable and sustainable housing
- score_name: Greater than or equal to the 90th percentile for lead paint, the median house value is less than 90th percentile, is low income, and has a low percent of higher ed students?
category: affordable and sustainable housing
- score_name: Greater than or equal to the 90th percentile for proximity to hazardous waste facilities, is low income, and has a low percent of higher ed students?
category: reduction and remediation of legacy pollution
- score_name: Greater than or equal to the 90th percentile for proximity to superfund sites, is low income, and has a low percent of higher ed students?
category: reduction and remediation of legacy pollution
- score_name: Greater than or equal to the 90th percentile for proximity to RMP sites, is low income, and has a low percent of higher ed students?
category: reduction and remediation of legacy pollution
- score_name: Greater than or equal to the 90th percentile for wastewater discharge, is low income, and has a low percent of higher ed students?
category: critical clean water and waste infrastructure
- score_name: Greater than or equal to the 90th percentile for asthma, is low income, and has a low percent of higher ed students?
category: health burdens
- score_name: Greater than or equal to the 90th percentile for diabetes, is low income, and has a low percent of higher ed students?
category: health burdens
- score_name: Greater than or equal to the 90th percentile for heart disease, is low income, and has a low percent of higher ed students?
category: health burdens
- score_name: Greater than or equal to the 90th percentile for low life expectancy, is low income, and has a low percent of higher ed students?
category: health burdens
- score_name: Greater than or equal to the 90th percentile for low median household income as a percent of area median income, has low HS attainment, and has a low percent of higher ed students?
category: training and workforce development
- score_name: Greater than or equal to the 90th percentile for households in linguistic isolation, has low HS attainment, and has a low percent of higher ed students?
category: training and workforce development
- score_name: Greater than or equal to the 90th percentile for unemployment, has low HS attainment, and has a low percent of higher ed students?
category: training and workforce development
- score_name: Greater than or equal to the 90th percentile for households at or below 100% federal poverty level, has low HS attainment, and has a low percent of higher ed students?
category: training and workforce development
- score_name: Greater than or equal to the 90th percentile for unemployment and has low HS education in 2009 (island areas)?
category: training and workforce development
- score_name: Greater than or equal to the 90th percentile for households at or below 100% federal poverty level and has low HS education in 2009 (island areas)?
category: training and workforce development
- score_name: Greater than or equal to the 90th percentile for low median household income as a percent of area median income and has low HS education in 2009 (island areas)?
category: training and workforce development

View file

@ -1,5 +1,6 @@
from pathlib import Path
import datetime
from data_pipeline.config import settings
from data_pipeline.score import field_names
@ -54,10 +55,44 @@ SCORE_DOWNLOADABLE_CSV_FILE_PATH = (
SCORE_DOWNLOADABLE_EXCEL_FILE_PATH = (
SCORE_DOWNLOADABLE_DIR / f"communities-{timestamp_str}.xlsx"
)
SCORE_DOWNLOADABLE_CODEBOOK_FILE_PATH = (
SCORE_DOWNLOADABLE_DIR / f"codebook-{timestamp_str}.csv"
)
SCORE_DOWNLOADABLE_ZIP_FILE_PATH = (
SCORE_DOWNLOADABLE_DIR / "Screening_Tool_Data.zip"
)
# For the codebook
CEJST_SCORE_COLUMN_NAME = "score_name"
CSV_FORMAT = "csv_format"
CSV_LABEL_FIELD = "csv_label"
EXCEL_LABEL_FIELD = "excel_label"
NOTES_FIELD = "notes"
THRESHOLD_CATEGORY_FIELD = "threshold_category"
CALCULATION_NOTES_FIELD = "calculation_notes"
CSV_FIELD_TYPE_FIELD = "csv_field_type"
CODEBOOK_COLUMNS = [
CSV_LABEL_FIELD,
EXCEL_LABEL_FIELD,
CEJST_SCORE_COLUMN_NAME,
CSV_FIELD_TYPE_FIELD,
CALCULATION_NOTES_FIELD,
THRESHOLD_CATEGORY_FIELD,
NOTES_FIELD,
]
LOSS_RATE_STRING = "loss rate"
LOW_STRING = "Low "
ISLAND_STRING = "island areas"
PERCENTILE_EXPLANATION = (
"All percentiles are floored (rounded down to the nearest percentile). "
+ "For example, 89.7th percentile is rounded down to 89 for this field."
)
LOW_PERCENTILE_EXPLANATION = "This percentile is reversed, meaning the lowest raw numbers become the highest percentiles."
ISLAND_AREAS_EXPLANATION = (
"Because not all data is available for the Nation, Puerto Rico, "
+ "and the Island Areas, this uses different underlying data for the island areas."
)
# Column subsets
CENSUS_COUNTIES_COLUMNS = ["USPS", "GEOID", "NAME"]
@ -186,11 +221,37 @@ TILES_SCORE_COLUMNS = {
field_names.POVERTY_LOW_HS_LOW_HIGHER_ED_FIELD: "PLHSE",
field_names.LOW_MEDIAN_INCOME_LOW_HS_LOW_HIGHER_ED_FIELD: "LMILHSE",
field_names.UNEMPLOYMENT_LOW_HS_LOW_HIGHER_ED_FIELD: "ULHSE",
# new booleans only for the environmental factors
field_names.EXPECTED_POPULATION_LOSS_EXCEEDS_PCTILE_THRESHOLD: "EPL_ET",
field_names.EXPECTED_AGRICULTURAL_LOSS_EXCEEDS_PCTILE_THRESHOLD: "EAL_ET",
field_names.EXPECTED_BUILDING_LOSS_EXCEEDS_PCTILE_THRESHOLD: "EBL_ET",
field_names.ENERGY_BURDEN_EXCEEDS_PCTILE_THRESHOLD: "EB_ET",
field_names.PM25_EXCEEDS_PCTILE_THRESHOLD: "PM25_ET",
field_names.DIESEL_EXCEEDS_PCTILE_THRESHOLD: "DS_ET",
field_names.TRAFFIC_PROXIMITY_PCTILE_THRESHOLD: "TP_ET",
field_names.LEAD_PAINT_PROXY_PCTILE_THRESHOLD: "LPP_ET",
field_names.HOUSING_BURDEN_PCTILE_THRESHOLD: "HB_ET",
field_names.RMP_PCTILE_THRESHOLD: "RMP_ET",
field_names.NPL_PCTILE_THRESHOLD: "NPL_ET",
field_names.TSDF_PCTILE_THRESHOLD: "TSDF_ET",
field_names.WASTEWATER_PCTILE_THRESHOLD: "WD_ET",
field_names.DIABETES_PCTILE_THRESHOLD: "DB_ET",
field_names.ASTHMA_PCTILE_THRESHOLD: "A_ET",
field_names.HEART_DISEASE_PCTILE_THRESHOLD: "HD_ET",
field_names.LOW_LIFE_EXPECTANCY_PCTILE_THRESHOLD: "LLE_ET",
field_names.UNEMPLOYMENT_PCTILE_THRESHOLD: "UN_ET",
field_names.LINGUISTIC_ISOLATION_PCTILE_THRESHOLD: "LISO_ET",
field_names.POVERTY_PCTILE_THRESHOLD: "POV_ET",
field_names.LOW_MEDIAN_INCOME_PCTILE_THRESHOLD: "LMI_ET",
field_names.ISLAND_LOW_MEDIAN_INCOME_PCTILE_THRESHOLD: "IA_LMI_ET",
field_names.ISLAND_UNEMPLOYMENT_PCTILE_THRESHOLD: "IA_UN_ET",
field_names.ISLAND_POVERTY_PCTILE_THRESHOLD: "IA_POV_ET",
field_names.FPL_200_SERIES: "FPL200S",
field_names.THRESHOLD_COUNT: "TC",
field_names.CATEGORY_COUNT: "CC",
field_names.ISLAND_AREAS_UNEMPLOYMENT_LOW_HS_EDUCATION_FIELD: "IAULHSE",
field_names.ISLAND_AREAS_POVERTY_LOW_HS_EDUCATION_FIELD: "IAPLHSE",
field_names.ISLAND_AREAS_LOW_MEDIAN_INCOME_LOW_HS_EDUCATION_FIELD: "IALMILHSE",
field_names.ISLAND_AREAS_LOW_HS_EDUCATION_FIELD: "IALHE",
# Percentiles for Island areas' workforce columns
field_names.LOW_CENSUS_DECENNIAL_AREA_MEDIAN_INCOME_PERCENT_FIELD_2009
+ field_names.PERCENTILE_FIELD_SUFFIX: "IALMILHSE_PFS",
@ -201,6 +262,7 @@ TILES_SCORE_COLUMNS = {
+ field_names.ISLAND_AREAS_PERCENTILE_ADJUSTMENT_FIELD
+ field_names.PERCENTILE_FIELD_SUFFIX: "IAULHSE_PFS",
field_names.LOW_HS_EDUCATION_LOW_HIGHER_ED_FIELD: "LHE",
field_names.ISLAND_AREAS_LOW_HS_EDUCATION_FIELD: "IALHE",
# Percentage of HS Degree completion for Islands
field_names.CENSUS_DECENNIAL_HIGH_SCHOOL_ED_FIELD_2009: "IAHSEF",
field_names.COLLEGE_ATTENDANCE_FIELD: "CA",

View file

@ -9,7 +9,7 @@ from data_pipeline.content.schemas.download_schemas import (
)
from data_pipeline.etl.base import ExtractTransformLoad
from data_pipeline.etl.score.etl_utils import floor_series
from data_pipeline.etl.score.etl_utils import floor_series, create_codebook
from data_pipeline.utils import (
get_module_logger,
zip_files,
@ -452,7 +452,15 @@ class PostScoreETL(ExtractTransformLoad):
def _load_excel_from_df(
self, excel_df: pd.DataFrame, excel_path: Path
) -> None:
) -> dict:
"""Creates excel file from score data using configs from yml file and returns
contents of the yml file.
First it reads the yaml dictionary from the excel.yml config and adjusts the
format of the excel file.
Then it produces the excel file from the score data.
"""
# open excel yaml config
excel_csv_config = load_yaml_dict_from_file(
@ -502,6 +510,7 @@ class PostScoreETL(ExtractTransformLoad):
worksheet.set_column(0, num_cols - 1, num_excel_cols_width)
writer.save()
return excel_csv_config
def _load_tile_csv(
self, score_tiles_df: pd.DataFrame, tile_score_path: Path
@ -516,12 +525,13 @@ class PostScoreETL(ExtractTransformLoad):
downloadable_info_path.mkdir(parents=True, exist_ok=True)
csv_path = constants.SCORE_DOWNLOADABLE_CSV_FILE_PATH
excel_path = constants.SCORE_DOWNLOADABLE_EXCEL_FILE_PATH
codebook_path = constants.SCORE_DOWNLOADABLE_CODEBOOK_FILE_PATH
zip_path = constants.SCORE_DOWNLOADABLE_ZIP_FILE_PATH
# TODO: reinstate when PDF is added back
# pdf_path = constants.SCORE_DOWNLOADABLE_PDF_FILE_PATH
logger.info("Writing downloadable excel")
self._load_excel_from_df(
excel_config = self._load_excel_from_df(
excel_df=self.output_score_county_state_merged_df,
excel_path=excel_path,
)
@ -538,10 +548,39 @@ class PostScoreETL(ExtractTransformLoad):
)
downloadable_df.to_csv(csv_path, index=False)
logger.info("Creating codebook for download zip")
# consolidate all excel fields from the config yml. The codebook
# code takes in a list of fields, but the excel config file
# has a slightly different format to allow for sheets within the
# workbook. This pulls all fields from all potential sheets into one
# list of dictionaries that specify information on each field.
excel_fields = []
for sheet in excel_config["sheets"]:
excel_fields.extend(sheet["fields"])
# load supplemental codebook yml
field_descriptions_for_codebook_config = load_yaml_dict_from_file(
self.CONTENT_CONFIG / "field_descriptions_for_codebook.yml"
)
# create codebook
codebook_df = create_codebook(
downloadable_csv_config=downloadable_csv_config["fields"],
excel_config=excel_fields,
field_descriptions_for_codebook=field_descriptions_for_codebook_config[
"fields"
],
)
# load codebook to disk
codebook_df.to_csv(codebook_path, index=False)
logger.info("Compressing files")
files_to_compress = [
csv_path,
excel_path,
codebook_path,
] # add pdf_path here to include PDF
zip_files(zip_path, files_to_compress)

View file

@ -1,15 +1,17 @@
import os
import sys
from pathlib import Path
from collections import namedtuple
import numpy as np
import pandas as pd
from data_pipeline.config import settings
from data_pipeline.utils import (
download_file_from_url,
get_module_logger,
)
from data_pipeline.score import field_names
from . import constants
logger = get_module_logger(__name__)
@ -108,3 +110,198 @@ def floor_series(series: pd.Series, number_of_decimals: int) -> pd.Series:
)
return floored_series
def _create_df_from_yaml_contents(
fields_list_from_yaml: list,
fields_to_store_in_codebook: list,
) -> pd.DataFrame:
"""Helper function to create a dataframe from yaml fields to get used for
all three configs: csv, excel, and supplemental codebook information yaml
This function does:
1. Creates a dictionary to be converted to a dataframe. Pandas easily converts
dictionaries of the form {column_name: [value_1, value_2, value_3]} to
dataframes, where column_name is the name of the column and the list of values
is (by numerical index) the values for the series.
Column names here are dictated by the fields_to_store_in_codebook list, a named
tuple that includes the name of the field in the yaml and the name the field will
take in the codebook. For example, both the csv and excel configs use the name "label",
but in the codebook, we want one of these fields to be "csv_label" and the other
to be "excel_label".
2. Cycles through the fields specified in the yaml fields list. Each field includes
some additional details, and so the function appends that information to the dictionary
lists, as described above. If the field is missing, appends a null value so that the row's
value is blank. This is an artifact of constructing a dataframe from a dictionary of lists.
3. Returns a dataframe indexed by the column name used in CEJST data (i.e., the
score name field that is consistent across all yamls and in our own usa.csv).
"""
# this becomes the codebook frame for each yaml source. In particular,
# the key becomes column names, and the lists store their values. We hard-set the
# first column name to be the CEJST_SCORE_COLUMN_NAME because this should be
# the same across the board for every component codebook.
codebook_dictionary = {
field.new_label_in_codebook: [] for field in fields_to_store_in_codebook
}
codebook_dictionary[constants.CEJST_SCORE_COLUMN_NAME] = []
# we reshape the data from a list of dictionaries to a dictionary of lists
# so that we can cast it as a dataframe
for single_field_details in fields_list_from_yaml:
assert constants.CEJST_SCORE_COLUMN_NAME in single_field_details, (
"Error: the yaml codebook should crosswalk to the native column "
+ f"from the CEJST pipeline, called {constants.CEJST_SCORE_COLUMN_NAME}"
)
# Since every single YAML file should have a score column name
# that is the the same, this appends each to the list in the dictionary.
# When pandas converts a dictionary of form {column_name: [val_1, val_2, val_3]},
# the dataframe has a column named "column_name" with sequential val_1, 2, and 3.
codebook_dictionary[constants.CEJST_SCORE_COLUMN_NAME].append(
single_field_details[constants.CEJST_SCORE_COLUMN_NAME]
)
for field_information in fields_to_store_in_codebook:
try:
codebook_dictionary[
field_information.new_label_in_codebook
].append(
single_field_details[field_information.existing_yaml_label]
)
# a key error occurs when the field is not specified for the
# column in the yaml file; when this happens, a null value should be
# appended to the list in the dictionary, since the dataframe will
# use the keys as column names and lists as values.
# this allows us to have optional fields in the yaml file.
except KeyError:
assert (
field_information.new_label_in_codebook
!= constants.CEJST_SCORE_COLUMN_NAME
)
codebook_dictionary[
field_information.new_label_in_codebook
].append(np.nan)
return pd.DataFrame(codebook_dictionary).set_index(
constants.CEJST_SCORE_COLUMN_NAME
)
def _get_datatype(
input_column_name: str,
input_column_type: str,
percentile_string: str = field_names.PERCENTILE_FIELD_SUFFIX,
loss_rate_string: str = constants.LOSS_RATE_STRING,
) -> str:
"""Helper to convert datatype
Note: eventually, this will either be programmatically set, or will be included in the yaml, depending on
the refactor that we do
"""
return_column_type = input_column_type
if percentile_string in input_column_name:
return_column_type = "percentile"
elif loss_rate_string in input_column_name:
return_column_type = "rate"
return return_column_type
def _get_calculation_notes(column_name: str) -> str:
"""Produces calculation notes
Note: eventually, this will either be programmatically set, or will be included in the yaml, depending on
the refactor that we do
"""
calculation_notes = []
if field_names.PERCENTILE_FIELD_SUFFIX in column_name:
calculation_notes += [constants.PERCENTILE_EXPLANATION]
if constants.LOW_STRING in column_name:
calculation_notes += [constants.LOW_PERCENTILE_EXPLANATION]
if constants.ISLAND_STRING in column_name:
calculation_notes += [constants.ISLAND_AREAS_EXPLANATION]
return " ".join(calculation_notes)
def create_codebook(
downloadable_csv_config: dict,
excel_config: dict,
field_descriptions_for_codebook: dict,
) -> pd.DataFrame:
"""Runs through all logic of creating the codebook.
First it reads in each component yaml file for the codebook.
Then it merges all of them.
Finally, it applies any transforms to the columns (like getting the
datatype or adding calculation_notes.
"""
CodebookLabelFields = namedtuple(
"CodebookLabelFields",
["new_label_in_codebook", "existing_yaml_label"],
)
# parse data from component yamls
csv_codes_df = _create_df_from_yaml_contents(
fields_list_from_yaml=downloadable_csv_config,
fields_to_store_in_codebook=[
CodebookLabelFields(
new_label_in_codebook=constants.CSV_LABEL_FIELD,
existing_yaml_label="label",
),
CodebookLabelFields(
new_label_in_codebook=constants.CSV_FORMAT,
existing_yaml_label="format",
),
],
)
excel_codes_df = _create_df_from_yaml_contents(
fields_list_from_yaml=excel_config,
fields_to_store_in_codebook=[
CodebookLabelFields(
new_label_in_codebook=constants.EXCEL_LABEL_FIELD,
existing_yaml_label="label",
)
],
)
field_descriptions_for_codebook_df = _create_df_from_yaml_contents(
fields_list_from_yaml=field_descriptions_for_codebook,
fields_to_store_in_codebook=[
CodebookLabelFields(
new_label_in_codebook=constants.NOTES_FIELD,
existing_yaml_label="notes",
),
CodebookLabelFields(
new_label_in_codebook=constants.THRESHOLD_CATEGORY_FIELD,
existing_yaml_label="category",
),
],
)
# join all sources on the column name
merged_codebook_df = pd.concat(
[csv_codes_df, excel_codes_df, field_descriptions_for_codebook_df],
join="outer",
axis=1,
).reset_index()
# add field type column
merged_codebook_df[
constants.CSV_FIELD_TYPE_FIELD
] = merged_codebook_df.apply(
lambda x: _get_datatype(
input_column_name=x[constants.CEJST_SCORE_COLUMN_NAME],
input_column_type=x[constants.CSV_FORMAT],
),
axis=1,
)
# get calculation notes column
merged_codebook_df[constants.CALCULATION_NOTES_FIELD] = merged_codebook_df[
constants.CEJST_SCORE_COLUMN_NAME
].apply(_get_calculation_notes)
# This is temporary. Right now, our variable names are all
# plain English. After the refactor, we will have new names
# that are programmatic, and the CEJST_SCORE_COLUMN will
# be dropped in favor of the explanation.
return merged_codebook_df[constants.CODEBOOK_COLUMNS].rename(
columns={constants.CEJST_SCORE_COLUMN_NAME: "Description"}
)

File diff suppressed because one or more lines are too long

Some files were not shown because too many files have changed in this diff Show more