Merge pull request #1 from titaniumbones/clean-community-build

Clean community build
This commit is contained in:
Eric Nost 2025-01-24 20:49:09 -05:00 committed by GitHub
commit 905b7bb2df
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
29 changed files with 22311 additions and 13582 deletions

View file

@ -16,7 +16,7 @@ jobs:
working-directory: client
strategy:
matrix:
node-version: [14.x]
node-version: [18.x]
steps:
- uses: actions/checkout@v4
- name: Use Node.js ${{ matrix.node-version }}
@ -84,4 +84,4 @@ jobs:
PATHS: "/*"
AWS_REGION: "us-east-1"
AWS_ACCESS_KEY_ID: ${{ secrets.CLIENT_DEV_AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.CLIENT_DEV_AWS_SECRET_ACCESS_KEY }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.CLIENT_DEV_AWS_SECRET_ACCESS_KEY }}

View file

@ -5,7 +5,7 @@ concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number }}
cancel-in-progress: true
env:
node-version: 14.x
node-version: 18.x
jobs:
# JOB to run change detection
detect-fe-changes:
@ -62,4 +62,4 @@ jobs:
- name: Spanish translation test
run: npm run test:intl-translations
# - name: Check for security vulnerabilities
# run: npm audit --production
# run: npm audit --production

View file

@ -4,7 +4,15 @@
_[¡Lea esto en español!](README-es.md)_
This repo contains the code, processes, and documentation for the data and tech powering the [Climate and Economic Justice Screening Tool (CEJST)](https://screeningtool.geoplatform.gov).
This repo contains the code, processes, and documentation for the data and tech powering the former [Climate and Economic Justice Screening Tool (CEJST)](https://screeningtool.geoplatform.gov).
## Status January 2025
The old CEJST has been taken offline by the incoming adminsitration. This fork is maintained by communities who stillrequire access to the tool, and who hope to gradually improve it.
**Many of the instructions in the README are not appropriate at the current stage of development.** In particular, the use of Docker and docker-compose is not advised. Instead, in this initial stage, we are only building the main web server (found in `client`). This is a Gatsby website, which uses React components to build a static site in the `client/public` folder. Further instructions are coming soon. For now, thank you for your interest! Please use Github issues to track problems and feature requests.
-------------
## Background

View file

@ -1 +1 @@
v14.17.1
v18.20.6

View file

@ -30,11 +30,14 @@ When(`I click on the {string} button in the navigation`, (page) => {
When(`I look for the {string} CTA`, (ctaString) => {
cy.get(`[data-cy="${hyphenizeString(ctaString)}-block"]`).as('CTA_block');
cy.get('@CTA_block').scrollIntoView().should('be.visible');
cy.get('@CTA_block').scrollIntoView();
cy.get('@CTA_block').should('be.visible');
});
When(`I look for the {string}`, (footer) => {
cy.get(`[data-cy="${hyphenizeString(footer)}-primary-block"]`).scrollIntoView().should('be.visible');
cy.get(`[data-cy="${hyphenizeString(footer)}-primary-block"]`).as('string_block');
cy.get('@string_block').scrollIntoView();
cy.get('@string_block').should('be.visible');
});
// Common Thens:

View file

@ -18,7 +18,7 @@ module.exports = {
image: '/static/favicon.ico',
siteUrl: process.env.SITE_URL || 'http://localhost:8000',
},
pathPrefix: process.env.PATH_PREFIX || '',
pathPrefix: process.env.PATH_PREFIX || 'j40-cejst-2',
plugins: [
{
resolve: 'gatsby-plugin-sass',

View file

@ -5,7 +5,7 @@ path = require('path');
//
// In react-map-gl 7.x this is no longer needed: https://visgl.github.io/react-map-gl/docs/get-started
//
exports.onCreateWebpackConfig = ({stage, loaders, actions}) => {
exports.onCreateWebpackConfig = ({stage, loaders, actions, getConfig}) => {
actions.setWebpackConfig({
devtool: 'eval-source-map',
resolve: {
@ -14,4 +14,18 @@ exports.onCreateWebpackConfig = ({stage, loaders, actions}) => {
},
},
});
if (stage === 'develop') {
const config = getConfig();
// Silence CSS ordering warnings, which aren't a risk with CSS Modules
const miniCssExtractPlugin = config.plugins.find(
(plugin) => plugin.constructor.name === 'MiniCssExtractPlugin',
);
if (miniCssExtractPlugin) {
miniCssExtractPlugin.options.ignoreOrder = true;
}
actions.replaceWebpackConfig(config);
}
};

34954
client/package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -39,7 +39,7 @@
"@testing-library/jest-dom": "^5.16.5",
"@testing-library/react": "^11.2.7",
"@types/d3-ease": "^3.0.0",
"@types/jest": "^26.0.24",
"@types/jest": "^27.5.2",
"@types/js-search": "^1.4.4",
"@types/maplibre-gl": "^1.14.0",
"@types/node": "^15.14.9",
@ -47,8 +47,8 @@
"@types/react-dom": "^17.0.14",
"@types/react-helmet": "^6.1.5",
"@types/react-test-renderer": "^17.0.1",
"@typescript-eslint/eslint-plugin": "^4.33.0",
"@typescript-eslint/parser": "^4.33.0",
"@typescript-eslint/eslint-plugin": "^5.62.0",
"@typescript-eslint/parser": "^5.62.0",
"axe-core": "^4.4.1",
"babel-jest": "^27.5.1",
"babel-preset-gatsby": "^1.14.0",
@ -58,11 +58,11 @@
"eslint": "^7.32.0",
"eslint-config-google": "^0.14.0",
"eslint-plugin-cypress": "^2.12.1",
"eslint-plugin-formatjs": "^2.21.0",
"eslint-plugin-formatjs": "2.19.1",
"eslint-plugin-react": "^7.29.4",
"gatsby": "^3.14.6",
"gatsby-cli": "^3.14.2",
"gatsby-plugin-intl": "^0.3.3",
"gatsby-plugin-intl": "^5.10.0",
"gatsby-plugin-prettier-eslint": "^1.0.6",
"gatsby-plugin-react-helmet": "^4.14.0",
"gatsby-plugin-sass": "^4.14.0",
@ -80,11 +80,11 @@
},
"dependencies": {
"@sentry/gatsby": "^7.7.0",
"@trussworks/react-uswds": "^3.1.0",
"@trussworks/react-uswds": "^3.2.0",
"@turf/bbox": "^6.5.0",
"d3-ease": "^3.0.1",
"gatsby-plugin-env-variables": "^2.2.0",
"gatsby-plugin-robots-txt": "^1.7.0",
"gatsby-plugin-robots-txt": "1.7.1",
"gatsby-plugin-sitemap": "^4.10.0",
"js-search": "^2.0.1",
"maplibre-gl": "^1.14.0",
@ -96,8 +96,7 @@
"react-intl": "^5.24.7",
"react-map-gl": "^6.1.19",
"react-tooltip": "^4.2.21",
"react-use": "^17.3.2",
"uswds": "^2.13.3"
"react-use": "^17.3.2"
},
"cypress-cucumber-preprocessor": {
"nonGlobalStepDefinitions": false

View file

@ -0,0 +1,52 @@
@use '../../styles/design-system.scss' as *;
.createReportContainer {
display: flex;
flex-direction: column;
margin: 0;
padding: 1.2rem 1rem 0 1.2rem;
font-size: medium;
height: 100%;
}
.tractListContainer {
display: flex;
flex-direction: column;
flex-wrap: nowrap;
justify-content: flex-start;
align-items: stretch;
height: 50%;
overflow-y: scroll;
border: grey solid thin;
border-radius: 4px;
margin-top: 0.5rem;
}
.tractListItem {
flex-wrap: nowrap;
padding: 0.25rem;
}
.tractListItemHighlight {
flex-wrap: nowrap;
padding: 0.25rem;
font-weight: bold;
background-color: rgba(195, 222, 251, .5);
}
.tractListItemDelete {
align-content: center;
button:focus {
outline-width: 0;
}
}
.createReportButton {
align-self: center;
padding-top: 1rem;
}
.startOver {
margin-top: 1rem;
align-self: center;
}

View file

@ -0,0 +1,18 @@
declare namespace CreateReportPanelNamespace {
export interface ICreateReportPanelScss {
createReportButton: string;
createReportContainer: string;
startOver: string;
tractListContainer: string;
tractListItem: string;
tractListItemDelete: string;
tractListItemHighlight: string;
}
}
declare const CreateReportPanelScssModule: CreateReportPanelNamespace.ICreateReportPanelScss & {
/** WARNING: Only available when `css-loader` is used without `style-loader` or `mini-css-extract-plugin` */
locals: CreateReportPanelNamespace.ICreateReportPanelScss;
};
export = CreateReportPanelScssModule;

View file

@ -0,0 +1,96 @@
import React, {useEffect, useState} from 'react';
import {MapGeoJSONFeature} from 'maplibre-gl';
import {Button, Alert, Grid} from '@trussworks/react-uswds';
import * as styles from './CreateReportPanel.module.scss';
import * as constants from '../../data/constants';
// @ts-ignore
import deleteIcon from '/node_modules/uswds/dist/img/usa-icons/close.svg';
interface ICreateReportPanel {
deleteTractHandler: (feature: MapGeoJSONFeature) => void,
className: string,
exitHandler: () => void,
featureList: MapGeoJSONFeature[],
maxNumTracts: number,
showTooManyTractsAlert: boolean,
}
const CreateReportPanel = ({
className,
featureList,
maxNumTracts,
showTooManyTractsAlert,
deleteTractHandler,
exitHandler,
}: ICreateReportPanel,
) => {
const [numPrevTracts, setNumPrevTracts] = useState<number>(0);
useEffect(() => {
// If adding a tract then scroll to the bottom of the tract list to always show the last added tract
if (numPrevTracts < featureList.length) {
const container = document.getElementById('j40-create-report-tract-list');
if (container) container.scrollTop = container.scrollHeight;
}
setNumPrevTracts(featureList.length);
}, [featureList, numPrevTracts]);
/**
* Handle the creation of a report.
*/
const handleCreateReport = () => {
if (featureList.length === 1) {
// TODO: One tract report
} else {
// TODO: Multi tract report
}
};
return (
<div id='create-report-panel' className={className}>
<div className={styles.createReportContainer}>
<h4>Create Report</h4>
{showTooManyTractsAlert ?
<Alert type='error' slim headingLevel='h4'>
You can only select up to {maxNumTracts} tracts for a report.
</Alert> :
<Alert type='info' slim headingLevel='h4'>
Select <strong>up to {maxNumTracts}</strong> tracts in the map
</Alert>
}
<p>
<span><strong>{featureList.length} tract{featureList.length === 1 ? '' : 's'}</strong> selected</span>
</p>
<div id='j40-create-report-tract-list' className={styles.tractListContainer}>
{featureList.map((item, index) => (
<Grid row key={index}
className={index === featureList.length - 1 ? styles.tractListItemHighlight : styles.tractListItem}>
<Grid col="auto">
{item.id}, {item.properties[constants.STATE_NAME]}</Grid>
<Grid col="fill" />
<Grid col="auto" className={styles.tractListItemDelete}>
<Button type='button' unstyled
onClick={() => deleteTractHandler(item)}>
<img tabIndex={0} src={deleteIcon}
alt='Need alt message'
/>
</Button>
</Grid>
</Grid>
))}
</div>
<div className={styles.createReportButton} >
<Button type='button' onClick={handleCreateReport}
disabled={featureList.length == 0}>Create Report</Button>
</div>
<div className={styles.startOver}>
<Button type='button' unstyled onClick={exitHandler}>Start Over</Button>
</div>
</div>
</div>
);
};
export default CreateReportPanel;

View file

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

View file

@ -16,9 +16,11 @@ exports[`rendering of the GovernmentBanner checks if component renders 1`] = `
>
<div
class="usa-banner__inner"
data-testid="banner-header-inner-div"
>
<div
class="grid-col-auto"
data-testid="banner-header-flag-div"
>
<img
alt="U.S. flag"
@ -28,6 +30,7 @@ exports[`rendering of the GovernmentBanner checks if component renders 1`] = `
</div>
<div
class="grid-col-fill tablet:grid-col-auto"
data-testid="banner-header-grid-div"
>
<p
class="usa-banner__header-text"
@ -109,19 +112,38 @@ exports[`rendering of the GovernmentBanner checks if component renders 1`] = `
<br />
A
<strong>
lock (
lock (
<span
class="icon-lock"
>
<img
alt="lock"
<svg
aria-labelledby="banner-lock-title banner-lock-description"
class="usa-banner__lock-image"
focusable="false"
height="64"
role="img"
src="data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz48c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjUyIiBoZWlnaHQ9IjY0IiB2aWV3Qm94PSIwIDAgNTIgNjQiPjx0aXRsZT5sb2NrPC90aXRsZT48cGF0aCBmaWxsPSIjMUIxQjFCIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik0yNiAwYzEwLjQ5MyAwIDE5IDguNTA3IDE5IDE5djloM2E0IDQgMCAwIDEgNCA0djI4YTQgNCAwIDAgMS00IDRINGE0IDQgMCAwIDEtNC00VjMyYTQgNCAwIDAgMSA0LTRoM3YtOUM3IDguNTA3IDE1LjUwNyAwIDI2IDB6bTAgOGMtNS45NzkgMC0xMC44NDMgNC43Ny0xMC45OTYgMTAuNzEyTDE1IDE5djloMjJ2LTljMC02LjA3NS00LjkyNS0xMS0xMS0xMXoiLz48L3N2Zz4="
title="Lock"
/>
viewBox="0 0 52 64"
width="52"
xmlns="http://www.w3.org/2000/svg"
>
<title
id="banner-lock-title"
>
Lock
</title>
<desc
id="banner-lock-description"
>
A locked padlock
</desc>
<path
d="M26 0c10.493 0 19 8.507 19 19v9h3a4 4 0 0 1 4 4v28a4 4 0 0 1-4 4H4a4 4 0 0 1-4-4V32a4 4 0 0 1 4-4h3v-9C7 8.507 15.507 0 26 0zm0 8c-5.979 0-10.843 4.77-10.996 10.712L15 19v9h22v-9c0-6.075-4.925-11-11-11z"
fill="#000000"
fill-rule="evenodd"
/>
</svg>
</span>
)
)
</strong>
or
<strong>

View file

@ -10,7 +10,7 @@ import {
import {Link, useIntl} from 'gatsby-plugin-intl';
import React, {useEffect, useState} from 'react';
import {useWindowSize} from 'react-use';
import GovernmentBanner from '../GovernmentBanner';
// import GovernmentBanner from '../GovernmentBanner';
import J40MainGridContainer from '../J40MainGridContainer';
import Language from '../Language';
@ -238,7 +238,7 @@ const J40Header = ({location}:IJ40Header) => {
<Header basic={true} role={'banner'}>
{/* Banners */}
<GovernmentBanner />
{/* <GovernmentBanner /> */}
<UpdateBanner/>
{/* Logo and Navigation */}

View file

@ -21,9 +21,11 @@ exports[`rendering of the J40Header checks if component renders 1`] = `
>
<div
class="usa-banner__inner"
data-testid="banner-header-inner-div"
>
<div
class="grid-col-auto"
data-testid="banner-header-flag-div"
>
<img
alt="U.S. flag"
@ -33,6 +35,7 @@ exports[`rendering of the J40Header checks if component renders 1`] = `
</div>
<div
class="grid-col-fill tablet:grid-col-auto"
data-testid="banner-header-grid-div"
>
<p
class="usa-banner__header-text"
@ -114,19 +117,38 @@ exports[`rendering of the J40Header checks if component renders 1`] = `
<br />
A
<strong>
lock (
lock (
<span
class="icon-lock"
>
<img
alt="lock"
<svg
aria-labelledby="banner-lock-title banner-lock-description"
class="usa-banner__lock-image"
focusable="false"
height="64"
role="img"
src="data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz48c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjUyIiBoZWlnaHQ9IjY0IiB2aWV3Qm94PSIwIDAgNTIgNjQiPjx0aXRsZT5sb2NrPC90aXRsZT48cGF0aCBmaWxsPSIjMUIxQjFCIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik0yNiAwYzEwLjQ5MyAwIDE5IDguNTA3IDE5IDE5djloM2E0IDQgMCAwIDEgNCA0djI4YTQgNCAwIDAgMS00IDRINGE0IDQgMCAwIDEtNC00VjMyYTQgNCAwIDAgMSA0LTRoM3YtOUM3IDguNTA3IDE1LjUwNyAwIDI2IDB6bTAgOGMtNS45NzkgMC0xMC44NDMgNC43Ny0xMC45OTYgMTAuNzEyTDE1IDE5djloMjJ2LTljMC02LjA3NS00LjkyNS0xMS0xMS0xMXoiLz48L3N2Zz4="
title="Lock"
/>
viewBox="0 0 52 64"
width="52"
xmlns="http://www.w3.org/2000/svg"
>
<title
id="banner-lock-title"
>
Lock
</title>
<desc
id="banner-lock-description"
>
A locked padlock
</desc>
<path
d="M26 0c10.493 0 19 8.507 19 19v9h3a4 4 0 0 1 4 4v28a4 4 0 0 1-4 4H4a4 4 0 0 1-4-4V32a4 4 0 0 1 4-4h3v-9C7 8.507 15.507 0 26 0zm0 8c-5.979 0-10.843 4.77-10.996 10.712L15 19v9h22v-9c0-6.075-4.925-11-11-11z"
fill="#000000"
fill-rule="evenodd"
/>
</svg>
</span>
)
)
</strong>
or
<strong>
@ -161,24 +183,11 @@ exports[`rendering of the J40Header checks if component renders 1`] = `
</div>
</div>
<div>
<div
class="usa-alert usa-alert--info"
data-testid="alert"
>
<div
class="usa-alert__body"
>
<h1
class="usa-alert__heading"
>
Version 2.0 of the tool is now available
</h1>
<p
class="usa-alert__text"
>
The Council on Environmental Quality (CEQ) made the 2.0 version of the tool available on Dec 20, 2024.
</p>
</div>
<div>
<strong>
This tool has been updated.
</strong>
The 2.0 version of the tool was released on Dec 20, 2024.
</div>
</div>
<div

View file

@ -12,7 +12,8 @@ import ReactMapGL, {
Popup,
FlyToInterpolator,
FullscreenControl,
MapRef} from 'react-map-gl';
MapRef,
} from 'react-map-gl';
import {useIntl} from 'gatsby-plugin-intl';
import bbox from '@turf/bbox';
import * as d3 from 'd3-ease';
@ -36,6 +37,7 @@ import 'maplibre-gl/dist/maplibre-gl.css';
import * as constants from '../data/constants';
import * as styles from './J40Map.module.scss';
import * as EXPLORE_COPY from '../data/copy/explore';
import CreateReportPanel from './CreateReportPanel';
declare global {
interface Window {
@ -63,6 +65,8 @@ export interface IMapFeature {
type: string;
}
const MAX_SELECTED_TRACTS = 20;
const J40Map = ({location}: IJ40Interface) => {
/**
* Initializes the zoom, and the map's center point (lat, lng) via the URL hash #{z}/{lat}/{long}
@ -86,11 +90,13 @@ const J40Map = ({location}: IJ40Interface) => {
zoom: zoom && parseFloat(zoom) ? parseFloat(zoom) : constants.GLOBAL_MIN_ZOOM,
});
const [selectedFeature, setSelectedFeature] = useState<MapGeoJSONFeature>();
const [selectedFeatures, setSelectedFeatures] = useState<MapGeoJSONFeature[]>([]);
const [detailViewData, setDetailViewData] = useState<IDetailViewInterface>();
const [transitionInProgress, setTransitionInProgress] = useState<boolean>(false);
const [geolocationInProgress, setGeolocationInProgress] = useState<boolean>(false);
const [isMobileMapState, setIsMobileMapState] = useState<boolean>(false);
const [inMultiSelectMode, setInMultiSelectMode] = useState<boolean>(false);
const [showTooManyTractsAlert, setShowTooManyTractsAlert] = useState<boolean>(false);
const [selectTractId, setSelectTractId] = useState<string | undefined>(undefined);
const {width: windowWidth} = useWindowSize();
@ -110,23 +116,84 @@ const J40Map = ({location}: IJ40Interface) => {
const flags = useFlags();
const intl = useIntl();
const selectedFeatureId = (selectedFeature && selectedFeature.id) || '';
const zoomLatLngHash = mapRef.current?.getMap()._hash._getCurrentHash();
/**
* Get the bounding box for one or more features.
* @param featureList the list of features
* @returns the bounding box
*/
const getFeaturesBbox = (featureList: MapGeoJSONFeature[]): number[] => {
if (featureList.length === 0) {
throw new Error('featureList must be a non-empty array to get a bounding box.');
}
// Calculate a max and min lat/lon from all the selected features.
const minLngList: number[] = [];
const minLatList: number[] = [];
const maxLngList: number[] = [];
const maxLatList: number[] = [];
featureList.forEach((feature) => {
const [featMinLng, featMinLat, featMaxLng, featMaxLat] = bbox(feature);
minLngList.push(featMinLng);
minLatList.push(featMinLat);
maxLngList.push(featMaxLng);
maxLatList.push(featMaxLat);
});
const minLng: number = Math.min(...minLngList);
const minLat: number = Math.max(...minLatList);
const maxLng: number = Math.max(...maxLngList);
const maxLat: number = Math.min(...maxLatList);
return [minLng, minLat, maxLng, maxLat];
};
/**
* Updates the state with the list of selected features. This function will:
* - Add the feature to the list if in multi select and the feature does not already exist
* - Remove the feature from the list if in multi select and the feature does already exist
* @param feature the feature to add or remove
* @param isMultiSelect true if in multiselect mode
* @returns the list of zero or more features
*/
const updateSelectedFeatures = (feature: MapGeoJSONFeature, isMultiSelect: boolean): MapGeoJSONFeature[] => {
if (!feature) return selectedFeatures;
// If the feature is in the list then remove it as it is being deselected
const exists = selectedFeatures.some((item) => item.id === feature.id);
let featureList: MapGeoJSONFeature[] = selectedFeatures;
if (exists) {
featureList = selectedFeatures.filter((item) => item.id !== feature.id);
setShowTooManyTractsAlert(false);
} else if (selectedFeatures.length < MAX_SELECTED_TRACTS) {
// Add the feature to the list if in multi select, otherwise replace the list
// with just this one feature.
featureList = isMultiSelect ?
[...selectedFeatures, feature] :
[feature];
} else {
setShowTooManyTractsAlert(true);
}
setSelectedFeatures(featureList);
if (!inMultiSelectMode) {
// Turn on multi select mode any time we select more than one tract.
setInMultiSelectMode(featureList.length > 1);
}
return featureList;
};
/**
* Selects the provided feature on the map.
* @param feature the feature to select
* @param isMultiSelectKeyDown true if the multi select key is down
*/
const selectFeatureOnMap = (feature: IMapFeature) => {
if (feature) {
// Get the current selected feature's bounding box:
const [minLng, minLat, maxLng, maxLat] = bbox(feature);
const selectFeaturesOnMap = (feature: IMapFeature, isMultiSelectKeyDown: boolean = false) => {
const featuresList = updateSelectedFeatures(feature, isMultiSelectKeyDown || inMultiSelectMode);
if (featuresList.length > 0) {
const [minLng, minLat, maxLng, maxLat] = getFeaturesBbox(featuresList);
// Set the selectedFeature ID
setSelectedFeature(feature);
// Go to the newly selected feature (as long as it's not an Alaska Point)
// Go to area of the selected feature(s)
goToPlace([
[minLng, minLat],
[maxLng, maxLat],
@ -213,14 +280,15 @@ const J40Map = ({location}: IJ40Interface) => {
default:
break;
}
} else if (event.target && (event.target as HTMLElement).nodeName == 'DIV' ) {
} else if (event.target && (event.target as HTMLElement).nodeName == 'DIV') {
// This else clause will fire when the user clicks on the map and will ignore other controls
// such as the search box and buttons.
// @ts-ignore
const feature = event.features && event.features[0];
selectFeatureOnMap(feature);
// @ts-ignore
selectFeaturesOnMap(feature, event.srcEvent.ctrlKey);
}
};
@ -251,8 +319,8 @@ const J40Map = ({location}: IJ40Interface) => {
const newViewPort = new WebMercatorViewport({height: viewport.height!, width: viewport.width!});
const {longitude, latitude, zoom} = newViewPort.fitBounds(
bounds as [[number, number], [number, number]], {
// padding: 200, // removing padding and offset in favor of a zoom offset below
// offset: [0, -100],
// padding: 200, // removing padding and offset in favor of a zoom offset below
// offset: [0, -100],
});
/**
@ -266,8 +334,8 @@ const J40Map = ({location}: IJ40Interface) => {
*/
// eslint-disable-next-line max-len
const featureSelectionZoomLevel = (zoom - 1) < constants.GLOBAL_MIN_ZOOM_FEATURE_BORDER + .1 ?
constants.GLOBAL_MIN_ZOOM_FEATURE_BORDER :
zoom - 1;
constants.GLOBAL_MIN_ZOOM_FEATURE_BORDER :
zoom - 1;
setViewport({
...viewport,
@ -304,7 +372,8 @@ const J40Map = ({location}: IJ40Interface) => {
filter: ['==', constants.GEOID_PROPERTY, selectTractId],
});
if (geoidSearchResults && geoidSearchResults.length > 0) {
selectFeatureOnMap(geoidSearchResults[0]);
// TODO, support searching for a list of tracts
selectFeaturesOnMap(geoidSearchResults[0]);
}
setSelectTractId(undefined);
}
@ -321,6 +390,23 @@ const J40Map = ({location}: IJ40Interface) => {
setGeolocationInProgress(true);
};
/**
* Handler for when there is a change in the multi select side panel.
* @param feature the feature that was added or removed
*/
const onReportDeleteTract = (feature: MapGeoJSONFeature) => {
updateSelectedFeatures(feature, true);
};
/**
* Handler for when the multi select is finished.
*/
const onReportExit = () => {
// Clear everything
setSelectedFeatures([]);
setDetailViewData(undefined);
setInMultiSelectMode(false);
};
return (
<>
@ -355,15 +441,15 @@ const J40Map = ({location}: IJ40Interface) => {
// access token is j40StylesReadToken
mapboxApiAccessToken={
process.env.MAPBOX_STYLES_READ_TOKEN ?
process.env.MAPBOX_STYLES_READ_TOKEN : ''}
process.env.MAPBOX_STYLES_READ_TOKEN : ''}
// ****** Map state props: ******
// http://visgl.github.io/react-map-gl/docs/api-reference/interactive-map#map-state
{...viewport}
mapStyle={
process.env.MAPBOX_STYLES_READ_TOKEN ?
'mapbox://styles/justice40/cl9g30qh7000p15l9cp1ftw16' :
'https://basemaps.cartocdn.com/gl/voyager-gl-style/style.json'
'mapbox://styles/justice40/cl9g30qh7000p15l9cp1ftw16' :
'https://basemaps.cartocdn.com/gl/voyager-gl-style/style.json'
}
width="100%"
// Ajusting this height with a conditional statement will not render the map on staging.
@ -406,13 +492,12 @@ const J40Map = ({location}: IJ40Interface) => {
}
<MapTractLayers
selectedFeature={selectedFeature}
selectedFeatureId={selectedFeatureId}
selectedFeatures={selectedFeatures}
/>
{/* This is the first overlayed row on the map: Search and Geolocation */}
<div className={styles.mapHeaderRow}>
<MapSearch goToPlace={goToPlace}/>
<MapSearch goToPlace={goToPlace} />
{/* Geolocate Icon */}
<div className={styles.geolocateBox}>
@ -420,8 +505,8 @@ const J40Map = ({location}: IJ40Interface) => {
windowWidth > constants.USWDS_BREAKPOINTS.MOBILE_LG - 1 &&
<div className={
(geolocationInProgress && !isGeolocateLocked) ?
styles.geolocateMessage :
styles.geolocateMessageHide
styles.geolocateMessage :
styles.geolocateMessageHide
}>
{intl.formatMessage(EXPLORE_COPY.MAP.GEOLOC_MSG_LOCATING)}
</div>
@ -432,7 +517,6 @@ const J40Map = ({location}: IJ40Interface) => {
onClick={onClickGeolocate}
trackUserLocation={windowWidth < constants.USWDS_BREAKPOINTS.MOBILE_LG}
showUserHeading={windowWidth < constants.USWDS_BREAKPOINTS.MOBILE_LG}
disabledLabel={intl.formatMessage(EXPLORE_COPY.MAP.GEOLOC_MSG_DISABLED)}
/>
</div>
@ -440,15 +524,15 @@ const J40Map = ({location}: IJ40Interface) => {
{/* This is the second row overlayed on the map, it will add the navigation controls
of the zoom in and zoom out buttons */}
{ windowWidth > constants.USWDS_BREAKPOINTS.MOBILE_LG && <NavigationControl
{windowWidth > constants.USWDS_BREAKPOINTS.MOBILE_LG && <NavigationControl
showCompass={false}
className={styles.navigationControl}
/> }
/>}
{/* This is the third row overlayed on the map, it will show shortcut buttons to
pan/zoom to US territories */}
{ windowWidth > constants.USWDS_BREAKPOINTS.MOBILE_LG &&
<TerritoryFocusControl onClick={onClick}/> }
{windowWidth > constants.USWDS_BREAKPOINTS.MOBILE_LG &&
<TerritoryFocusControl onClick={onClick} />}
{/* Enable fullscreen pop-up behind a feature flag */}
{('fs' in flags && detailViewData && !transitionInProgress) && (
@ -468,18 +552,27 @@ const J40Map = ({location}: IJ40Interface) => {
/>
</Popup>
)}
{'fs' in flags ? <FullscreenControl className={styles.fullscreenControl}/> :'' }
{'fs' in flags ? <FullscreenControl className={styles.fullscreenControl} /> : ''}
</ReactMapGL>
</Grid>
<Grid desktop={{col: 3}}>
<MapInfoPanel
className={styles.mapInfoPanel}
featureProperties={detailViewData?.properties}
selectedFeatureId={selectedFeature?.id}
hash={zoomLatLngHash}
/>
{inMultiSelectMode ?
<CreateReportPanel
className={styles.mapInfoPanel}
featureList={selectedFeatures}
deleteTractHandler={onReportDeleteTract}
exitHandler={onReportExit}
maxNumTracts={MAX_SELECTED_TRACTS}
showTooManyTractsAlert={showTooManyTractsAlert}
/> :
<MapInfoPanel
className={styles.mapInfoPanel}
featureProperties={detailViewData?.properties}
hash={zoomLatLngHash}
/>
}
</Grid>
</>
);

View file

@ -1,4 +1,4 @@
import React, {useMemo} from 'react';
import React from 'react';
import {Source, Layer} from 'react-map-gl';
import {MapGeoJSONFeature} from 'maplibre-gl';
@ -9,8 +9,7 @@ import * as constants from '../../data/constants';
import * as COMMON_COPY from '../../data/copy/common';
interface IMapTractLayers {
selectedFeatureId: string | number,
selectedFeature: MapGeoJSONFeature | undefined,
selectedFeatures: MapGeoJSONFeature[] | undefined,
}
/**
@ -65,10 +64,10 @@ export const featureURLForTilesetName = (tilesetName: string): string => {
* @return {Style}
*/
const MapTractLayers = ({
selectedFeatureId,
selectedFeature,
selectedFeatures,
}: IMapTractLayers) => {
const filter = useMemo(() => ['in', constants.GEOID_PROPERTY, selectedFeatureId], [selectedFeature]);
const selectedFeatureIds = selectedFeatures ? (selectedFeatures.map((feat) => feat.id)) : [''];
const filter = ['in', constants.GEOID_PROPERTY, ...selectedFeatureIds];
return (
<>

View file

@ -5,14 +5,12 @@ import SidePanelInfo from './SidePanelInfo';
interface IMapInfoPanelProps {
className: string,
featureProperties: { [key:string]: string | number } | undefined,
selectedFeatureId: string | number | undefined
hash: string[],
}
const MapInfoPanel = ({
className,
featureProperties,
selectedFeatureId,
hash,
}:IMapInfoPanelProps) => {
return (
@ -22,7 +20,7 @@ const MapInfoPanel = ({
there are two states, namely showing the AreaDetail or SidePanelInfo. When a feature
is selected, show the AreaDetail. When not selected show SidePanelInfo
*/}
{(featureProperties && selectedFeatureId) ?
{(featureProperties) ?
<AreaDetail
properties={featureProperties}
hash={hash}

View file

@ -36,7 +36,7 @@ export const METH_2_0_RELEASE_DATE = new Date(2024, 11, 20, 11, 59, 59); // Dec
// Update Banner
export const UPDATE_BANNER_HEADING_LARGE = <FormattedMessage
id={'common.pages.alerts.banner.update.heading.large'}
defaultMessage={'Version 2.0 of the tool is now available'}
defaultMessage={'This is an unofficial copy of the CEJST Tool. We are working on an overhaul, but in the meantime some links and text may incorrectly suggest that this site is affiliated with the US Government'}
description={'Alert heading that appears at the top of pages'}
/>;
@ -56,7 +56,7 @@ export const UPDATE_BANNER_CONTENT_LARGE = <FormattedMessage
export const UPDATE_BANNER_CONTENT_SMALL = <FormattedMessage
id={'common.pages.alerts.banner.update.content.small'}
defaultMessage={`<bold>This tool has been updated.</bold> The 2.0 version of the tool was released on {relDate}.`}
defaultMessage={`<bold>This is an unofficial copy of the CEJST Tool.</bold> We are working on an overhaul, but in the meantime some links and text may incorrectly suggest that this site is affiliated with the US Government.`}
description={`Alert body that appears at the top of pages.`}
values={{
bold: boldFn,

View file

@ -88,11 +88,11 @@
"description": "Alert body that appears at the top of pages."
},
"common.pages.alerts.banner.update.content.small": {
"defaultMessage": "<bold>This tool has been updated.</bold> The 2.0 version of the tool was released on {relDate}.",
"defaultMessage": "<bold>This is an unofficial copy of the CEJST Tool.</bold> We are working on an overhaul, but in the meantime some links and text may incorrectly suggest that this site is affiliated with the US Government.",
"description": "Alert body that appears at the top of pages."
},
"common.pages.alerts.banner.update.heading.large": {
"defaultMessage": "Version 2.0 of the tool is now available",
"defaultMessage": "This is an unofficial copy of the CEJST Tool. We are working on an overhaul, but in the meantime some links and text may incorrectly suggest that this site is affiliated with the US Government",
"description": "Alert heading that appears at the top of pages"
},
"common.pages.alerts.census.tract.title": {

View file

@ -21,9 +21,11 @@ exports[`rendering of the DatasetContainer checks if various text fields are vis
>
<div
class="usa-banner__inner"
data-testid="banner-header-inner-div"
>
<div
class="grid-col-auto"
data-testid="banner-header-flag-div"
>
<img
alt="U.S. flag"
@ -33,6 +35,7 @@ exports[`rendering of the DatasetContainer checks if various text fields are vis
</div>
<div
class="grid-col-fill tablet:grid-col-auto"
data-testid="banner-header-grid-div"
>
<p
class="usa-banner__header-text"
@ -114,19 +117,38 @@ exports[`rendering of the DatasetContainer checks if various text fields are vis
<br />
A
<strong>
lock (
lock (
<span
class="icon-lock"
>
<img
alt="lock"
<svg
aria-labelledby="banner-lock-title banner-lock-description"
class="usa-banner__lock-image"
focusable="false"
height="64"
role="img"
src="data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz48c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjUyIiBoZWlnaHQ9IjY0IiB2aWV3Qm94PSIwIDAgNTIgNjQiPjx0aXRsZT5sb2NrPC90aXRsZT48cGF0aCBmaWxsPSIjMUIxQjFCIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik0yNiAwYzEwLjQ5MyAwIDE5IDguNTA3IDE5IDE5djloM2E0IDQgMCAwIDEgNCA0djI4YTQgNCAwIDAgMS00IDRINGE0IDQgMCAwIDEtNC00VjMyYTQgNCAwIDAgMSA0LTRoM3YtOUM3IDguNTA3IDE1LjUwNyAwIDI2IDB6bTAgOGMtNS45NzkgMC0xMC44NDMgNC43Ny0xMC45OTYgMTAuNzEyTDE1IDE5djloMjJ2LTljMC02LjA3NS00LjkyNS0xMS0xMS0xMXoiLz48L3N2Zz4="
title="Lock"
/>
viewBox="0 0 52 64"
width="52"
xmlns="http://www.w3.org/2000/svg"
>
<title
id="banner-lock-title"
>
Lock
</title>
<desc
id="banner-lock-description"
>
A locked padlock
</desc>
<path
d="M26 0c10.493 0 19 8.507 19 19v9h3a4 4 0 0 1 4 4v28a4 4 0 0 1-4 4H4a4 4 0 0 1-4-4V32a4 4 0 0 1 4-4h3v-9C7 8.507 15.507 0 26 0zm0 8c-5.979 0-10.843 4.77-10.996 10.712L15 19v9h22v-9c0-6.075-4.925-11-11-11z"
fill="#000000"
fill-rule="evenodd"
/>
</svg>
</span>
)
)
</strong>
or
<strong>
@ -161,24 +183,11 @@ exports[`rendering of the DatasetContainer checks if various text fields are vis
</div>
</div>
<div>
<div
class="usa-alert usa-alert--info"
data-testid="alert"
>
<div
class="usa-alert__body"
>
<h1
class="usa-alert__heading"
>
Version 2.0 of the tool is now available
</h1>
<p
class="usa-alert__text"
>
The Council on Environmental Quality (CEQ) made the 2.0 version of the tool available on Dec 20, 2024.
</p>
</div>
<div>
<strong>
This tool has been updated.
</strong>
The 2.0 version of the tool was released on Dec 20, 2024.
</div>
</div>
<div

View file

@ -21,9 +21,11 @@ exports[`rendering of the DatasetContainer checks if various text fields are vis
>
<div
class="usa-banner__inner"
data-testid="banner-header-inner-div"
>
<div
class="grid-col-auto"
data-testid="banner-header-flag-div"
>
<img
alt="U.S. flag"
@ -33,6 +35,7 @@ exports[`rendering of the DatasetContainer checks if various text fields are vis
</div>
<div
class="grid-col-fill tablet:grid-col-auto"
data-testid="banner-header-grid-div"
>
<p
class="usa-banner__header-text"
@ -114,19 +117,38 @@ exports[`rendering of the DatasetContainer checks if various text fields are vis
<br />
A
<strong>
lock (
lock (
<span
class="icon-lock"
>
<img
alt="lock"
<svg
aria-labelledby="banner-lock-title banner-lock-description"
class="usa-banner__lock-image"
focusable="false"
height="64"
role="img"
src="data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz48c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjUyIiBoZWlnaHQ9IjY0IiB2aWV3Qm94PSIwIDAgNTIgNjQiPjx0aXRsZT5sb2NrPC90aXRsZT48cGF0aCBmaWxsPSIjMUIxQjFCIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik0yNiAwYzEwLjQ5MyAwIDE5IDguNTA3IDE5IDE5djloM2E0IDQgMCAwIDEgNCA0djI4YTQgNCAwIDAgMS00IDRINGE0IDQgMCAwIDEtNC00VjMyYTQgNCAwIDAgMSA0LTRoM3YtOUM3IDguNTA3IDE1LjUwNyAwIDI2IDB6bTAgOGMtNS45NzkgMC0xMC44NDMgNC43Ny0xMC45OTYgMTAuNzEyTDE1IDE5djloMjJ2LTljMC02LjA3NS00LjkyNS0xMS0xMS0xMXoiLz48L3N2Zz4="
title="Lock"
/>
viewBox="0 0 52 64"
width="52"
xmlns="http://www.w3.org/2000/svg"
>
<title
id="banner-lock-title"
>
Lock
</title>
<desc
id="banner-lock-description"
>
A locked padlock
</desc>
<path
d="M26 0c10.493 0 19 8.507 19 19v9h3a4 4 0 0 1 4 4v28a4 4 0 0 1-4 4H4a4 4 0 0 1-4-4V32a4 4 0 0 1 4-4h3v-9C7 8.507 15.507 0 26 0zm0 8c-5.979 0-10.843 4.77-10.996 10.712L15 19v9h22v-9c0-6.075-4.925-11-11-11z"
fill="#000000"
fill-rule="evenodd"
/>
</svg>
</span>
)
)
</strong>
or
<strong>
@ -161,24 +183,11 @@ exports[`rendering of the DatasetContainer checks if various text fields are vis
</div>
</div>
<div>
<div
class="usa-alert usa-alert--info"
data-testid="alert"
>
<div
class="usa-alert__body"
>
<h1
class="usa-alert__heading"
>
Version 2.0 of the tool is now available
</h1>
<p
class="usa-alert__text"
>
The Council on Environmental Quality (CEQ) made the 2.0 version of the tool available on Dec 20, 2024.
</p>
</div>
<div>
<strong>
This tool has been updated.
</strong>
The 2.0 version of the tool was released on Dec 20, 2024.
</div>
</div>
<div

View file

@ -21,9 +21,11 @@ exports[`rendering of the DatasetContainer checks if various text fields are vis
>
<div
class="usa-banner__inner"
data-testid="banner-header-inner-div"
>
<div
class="grid-col-auto"
data-testid="banner-header-flag-div"
>
<img
alt="U.S. flag"
@ -33,6 +35,7 @@ exports[`rendering of the DatasetContainer checks if various text fields are vis
</div>
<div
class="grid-col-fill tablet:grid-col-auto"
data-testid="banner-header-grid-div"
>
<p
class="usa-banner__header-text"
@ -114,19 +117,38 @@ exports[`rendering of the DatasetContainer checks if various text fields are vis
<br />
A
<strong>
lock (
lock (
<span
class="icon-lock"
>
<img
alt="lock"
<svg
aria-labelledby="banner-lock-title banner-lock-description"
class="usa-banner__lock-image"
focusable="false"
height="64"
role="img"
src="data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz48c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjUyIiBoZWlnaHQ9IjY0IiB2aWV3Qm94PSIwIDAgNTIgNjQiPjx0aXRsZT5sb2NrPC90aXRsZT48cGF0aCBmaWxsPSIjMUIxQjFCIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik0yNiAwYzEwLjQ5MyAwIDE5IDguNTA3IDE5IDE5djloM2E0IDQgMCAwIDEgNCA0djI4YTQgNCAwIDAgMS00IDRINGE0IDQgMCAwIDEtNC00VjMyYTQgNCAwIDAgMSA0LTRoM3YtOUM3IDguNTA3IDE1LjUwNyAwIDI2IDB6bTAgOGMtNS45NzkgMC0xMC44NDMgNC43Ny0xMC45OTYgMTAuNzEyTDE1IDE5djloMjJ2LTljMC02LjA3NS00LjkyNS0xMS0xMS0xMXoiLz48L3N2Zz4="
title="Lock"
/>
viewBox="0 0 52 64"
width="52"
xmlns="http://www.w3.org/2000/svg"
>
<title
id="banner-lock-title"
>
Lock
</title>
<desc
id="banner-lock-description"
>
A locked padlock
</desc>
<path
d="M26 0c10.493 0 19 8.507 19 19v9h3a4 4 0 0 1 4 4v28a4 4 0 0 1-4 4H4a4 4 0 0 1-4-4V32a4 4 0 0 1 4-4h3v-9C7 8.507 15.507 0 26 0zm0 8c-5.979 0-10.843 4.77-10.996 10.712L15 19v9h22v-9c0-6.075-4.925-11-11-11z"
fill="#000000"
fill-rule="evenodd"
/>
</svg>
</span>
)
)
</strong>
or
<strong>
@ -161,24 +183,11 @@ exports[`rendering of the DatasetContainer checks if various text fields are vis
</div>
</div>
<div>
<div
class="usa-alert usa-alert--info"
data-testid="alert"
>
<div
class="usa-alert__body"
>
<h1
class="usa-alert__heading"
>
Version 2.0 of the tool is now available
</h1>
<p
class="usa-alert__text"
>
The Council on Environmental Quality (CEQ) made the 2.0 version of the tool available on Dec 20, 2024.
</p>
</div>
<div>
<strong>
This tool has been updated.
</strong>
The 2.0 version of the tool was released on Dec 20, 2024.
</div>
</div>
<div

View file

@ -21,9 +21,11 @@ exports[`rendering of the DatasetContainer checks if various text fields are vis
>
<div
class="usa-banner__inner"
data-testid="banner-header-inner-div"
>
<div
class="grid-col-auto"
data-testid="banner-header-flag-div"
>
<img
alt="U.S. flag"
@ -33,6 +35,7 @@ exports[`rendering of the DatasetContainer checks if various text fields are vis
</div>
<div
class="grid-col-fill tablet:grid-col-auto"
data-testid="banner-header-grid-div"
>
<p
class="usa-banner__header-text"
@ -114,19 +117,38 @@ exports[`rendering of the DatasetContainer checks if various text fields are vis
<br />
A
<strong>
lock (
lock (
<span
class="icon-lock"
>
<img
alt="lock"
<svg
aria-labelledby="banner-lock-title banner-lock-description"
class="usa-banner__lock-image"
focusable="false"
height="64"
role="img"
src="data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz48c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjUyIiBoZWlnaHQ9IjY0IiB2aWV3Qm94PSIwIDAgNTIgNjQiPjx0aXRsZT5sb2NrPC90aXRsZT48cGF0aCBmaWxsPSIjMUIxQjFCIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik0yNiAwYzEwLjQ5MyAwIDE5IDguNTA3IDE5IDE5djloM2E0IDQgMCAwIDEgNCA0djI4YTQgNCAwIDAgMS00IDRINGE0IDQgMCAwIDEtNC00VjMyYTQgNCAwIDAgMSA0LTRoM3YtOUM3IDguNTA3IDE1LjUwNyAwIDI2IDB6bTAgOGMtNS45NzkgMC0xMC44NDMgNC43Ny0xMC45OTYgMTAuNzEyTDE1IDE5djloMjJ2LTljMC02LjA3NS00LjkyNS0xMS0xMS0xMXoiLz48L3N2Zz4="
title="Lock"
/>
viewBox="0 0 52 64"
width="52"
xmlns="http://www.w3.org/2000/svg"
>
<title
id="banner-lock-title"
>
Lock
</title>
<desc
id="banner-lock-description"
>
A locked padlock
</desc>
<path
d="M26 0c10.493 0 19 8.507 19 19v9h3a4 4 0 0 1 4 4v28a4 4 0 0 1-4 4H4a4 4 0 0 1-4-4V32a4 4 0 0 1 4-4h3v-9C7 8.507 15.507 0 26 0zm0 8c-5.979 0-10.843 4.77-10.996 10.712L15 19v9h22v-9c0-6.075-4.925-11-11-11z"
fill="#000000"
fill-rule="evenodd"
/>
</svg>
</span>
)
)
</strong>
or
<strong>
@ -161,24 +183,11 @@ exports[`rendering of the DatasetContainer checks if various text fields are vis
</div>
</div>
<div>
<div
class="usa-alert usa-alert--info"
data-testid="alert"
>
<div
class="usa-alert__body"
>
<h1
class="usa-alert__heading"
>
Version 2.0 of the tool is now available
</h1>
<p
class="usa-alert__text"
>
The Council on Environmental Quality (CEQ) made the 2.0 version of the tool available on Dec 20, 2024.
</p>
</div>
<div>
<strong>
This tool has been updated.
</strong>
The 2.0 version of the tool was released on Dec 20, 2024.
</div>
</div>
<div

View file

@ -21,9 +21,11 @@ exports[`rendering of the DatasetContainer checks if various text fields are vis
>
<div
class="usa-banner__inner"
data-testid="banner-header-inner-div"
>
<div
class="grid-col-auto"
data-testid="banner-header-flag-div"
>
<img
alt="U.S. flag"
@ -33,6 +35,7 @@ exports[`rendering of the DatasetContainer checks if various text fields are vis
</div>
<div
class="grid-col-fill tablet:grid-col-auto"
data-testid="banner-header-grid-div"
>
<p
class="usa-banner__header-text"
@ -114,19 +117,38 @@ exports[`rendering of the DatasetContainer checks if various text fields are vis
<br />
A
<strong>
lock (
lock (
<span
class="icon-lock"
>
<img
alt="lock"
<svg
aria-labelledby="banner-lock-title banner-lock-description"
class="usa-banner__lock-image"
focusable="false"
height="64"
role="img"
src="data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz48c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjUyIiBoZWlnaHQ9IjY0IiB2aWV3Qm94PSIwIDAgNTIgNjQiPjx0aXRsZT5sb2NrPC90aXRsZT48cGF0aCBmaWxsPSIjMUIxQjFCIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik0yNiAwYzEwLjQ5MyAwIDE5IDguNTA3IDE5IDE5djloM2E0IDQgMCAwIDEgNCA0djI4YTQgNCAwIDAgMS00IDRINGE0IDQgMCAwIDEtNC00VjMyYTQgNCAwIDAgMSA0LTRoM3YtOUM3IDguNTA3IDE1LjUwNyAwIDI2IDB6bTAgOGMtNS45NzkgMC0xMC44NDMgNC43Ny0xMC45OTYgMTAuNzEyTDE1IDE5djloMjJ2LTljMC02LjA3NS00LjkyNS0xMS0xMS0xMXoiLz48L3N2Zz4="
title="Lock"
/>
viewBox="0 0 52 64"
width="52"
xmlns="http://www.w3.org/2000/svg"
>
<title
id="banner-lock-title"
>
Lock
</title>
<desc
id="banner-lock-description"
>
A locked padlock
</desc>
<path
d="M26 0c10.493 0 19 8.507 19 19v9h3a4 4 0 0 1 4 4v28a4 4 0 0 1-4 4H4a4 4 0 0 1-4-4V32a4 4 0 0 1 4-4h3v-9C7 8.507 15.507 0 26 0zm0 8c-5.979 0-10.843 4.77-10.996 10.712L15 19v9h22v-9c0-6.075-4.925-11-11-11z"
fill="#000000"
fill-rule="evenodd"
/>
</svg>
</span>
)
)
</strong>
or
<strong>
@ -161,24 +183,11 @@ exports[`rendering of the DatasetContainer checks if various text fields are vis
</div>
</div>
<div>
<div
class="usa-alert usa-alert--info"
data-testid="alert"
>
<div
class="usa-alert__body"
>
<h1
class="usa-alert__heading"
>
Version 2.0 of the tool is now available
</h1>
<p
class="usa-alert__text"
>
The Council on Environmental Quality (CEQ) made the 2.0 version of the tool available on Dec 20, 2024.
</p>
</div>
<div>
<strong>
This tool has been updated.
</strong>
The 2.0 version of the tool was released on Dec 20, 2024.
</div>
</div>
<div

View file

@ -21,9 +21,11 @@ exports[`rendering of the Privacy Policy page matches Privacy Policy page snapsh
>
<div
class="usa-banner__inner"
data-testid="banner-header-inner-div"
>
<div
class="grid-col-auto"
data-testid="banner-header-flag-div"
>
<img
alt="U.S. flag"
@ -33,6 +35,7 @@ exports[`rendering of the Privacy Policy page matches Privacy Policy page snapsh
</div>
<div
class="grid-col-fill tablet:grid-col-auto"
data-testid="banner-header-grid-div"
>
<p
class="usa-banner__header-text"
@ -114,19 +117,38 @@ exports[`rendering of the Privacy Policy page matches Privacy Policy page snapsh
<br />
A
<strong>
lock (
lock (
<span
class="icon-lock"
>
<img
alt="lock"
<svg
aria-labelledby="banner-lock-title banner-lock-description"
class="usa-banner__lock-image"
focusable="false"
height="64"
role="img"
src="data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz48c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjUyIiBoZWlnaHQ9IjY0IiB2aWV3Qm94PSIwIDAgNTIgNjQiPjx0aXRsZT5sb2NrPC90aXRsZT48cGF0aCBmaWxsPSIjMUIxQjFCIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik0yNiAwYzEwLjQ5MyAwIDE5IDguNTA3IDE5IDE5djloM2E0IDQgMCAwIDEgNCA0djI4YTQgNCAwIDAgMS00IDRINGE0IDQgMCAwIDEtNC00VjMyYTQgNCAwIDAgMSA0LTRoM3YtOUM3IDguNTA3IDE1LjUwNyAwIDI2IDB6bTAgOGMtNS45NzkgMC0xMC44NDMgNC43Ny0xMC45OTYgMTAuNzEyTDE1IDE5djloMjJ2LTljMC02LjA3NS00LjkyNS0xMS0xMS0xMXoiLz48L3N2Zz4="
title="Lock"
/>
viewBox="0 0 52 64"
width="52"
xmlns="http://www.w3.org/2000/svg"
>
<title
id="banner-lock-title"
>
Lock
</title>
<desc
id="banner-lock-description"
>
A locked padlock
</desc>
<path
d="M26 0c10.493 0 19 8.507 19 19v9h3a4 4 0 0 1 4 4v28a4 4 0 0 1-4 4H4a4 4 0 0 1-4-4V32a4 4 0 0 1 4-4h3v-9C7 8.507 15.507 0 26 0zm0 8c-5.979 0-10.843 4.77-10.996 10.712L15 19v9h22v-9c0-6.075-4.925-11-11-11z"
fill="#000000"
fill-rule="evenodd"
/>
</svg>
</span>
)
)
</strong>
or
<strong>
@ -161,24 +183,11 @@ exports[`rendering of the Privacy Policy page matches Privacy Policy page snapsh
</div>
</div>
<div>
<div
class="usa-alert usa-alert--info"
data-testid="alert"
>
<div
class="usa-alert__body"
>
<h1
class="usa-alert__heading"
>
Version 2.0 of the tool is now available
</h1>
<p
class="usa-alert__text"
>
The Council on Environmental Quality (CEQ) made the 2.0 version of the tool available on Dec 20, 2024.
</p>
</div>
<div>
<strong>
This tool has been updated.
</strong>
The 2.0 version of the tool was released on Dec 20, 2024.
</div>
</div>
<div

View file

@ -21,9 +21,11 @@ exports[`rendering of the DatasetContainer checks if various text fields are vis
>
<div
class="usa-banner__inner"
data-testid="banner-header-inner-div"
>
<div
class="grid-col-auto"
data-testid="banner-header-flag-div"
>
<img
alt="U.S. flag"
@ -33,6 +35,7 @@ exports[`rendering of the DatasetContainer checks if various text fields are vis
</div>
<div
class="grid-col-fill tablet:grid-col-auto"
data-testid="banner-header-grid-div"
>
<p
class="usa-banner__header-text"
@ -114,19 +117,38 @@ exports[`rendering of the DatasetContainer checks if various text fields are vis
<br />
A
<strong>
lock (
lock (
<span
class="icon-lock"
>
<img
alt="lock"
<svg
aria-labelledby="banner-lock-title banner-lock-description"
class="usa-banner__lock-image"
focusable="false"
height="64"
role="img"
src="data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz48c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjUyIiBoZWlnaHQ9IjY0IiB2aWV3Qm94PSIwIDAgNTIgNjQiPjx0aXRsZT5sb2NrPC90aXRsZT48cGF0aCBmaWxsPSIjMUIxQjFCIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik0yNiAwYzEwLjQ5MyAwIDE5IDguNTA3IDE5IDE5djloM2E0IDQgMCAwIDEgNCA0djI4YTQgNCAwIDAgMS00IDRINGE0IDQgMCAwIDEtNC00VjMyYTQgNCAwIDAgMSA0LTRoM3YtOUM3IDguNTA3IDE1LjUwNyAwIDI2IDB6bTAgOGMtNS45NzkgMC0xMC44NDMgNC43Ny0xMC45OTYgMTAuNzEyTDE1IDE5djloMjJ2LTljMC02LjA3NS00LjkyNS0xMS0xMS0xMXoiLz48L3N2Zz4="
title="Lock"
/>
viewBox="0 0 52 64"
width="52"
xmlns="http://www.w3.org/2000/svg"
>
<title
id="banner-lock-title"
>
Lock
</title>
<desc
id="banner-lock-description"
>
A locked padlock
</desc>
<path
d="M26 0c10.493 0 19 8.507 19 19v9h3a4 4 0 0 1 4 4v28a4 4 0 0 1-4 4H4a4 4 0 0 1-4-4V32a4 4 0 0 1 4-4h3v-9C7 8.507 15.507 0 26 0zm0 8c-5.979 0-10.843 4.77-10.996 10.712L15 19v9h22v-9c0-6.075-4.925-11-11-11z"
fill="#000000"
fill-rule="evenodd"
/>
</svg>
</span>
)
)
</strong>
or
<strong>
@ -161,24 +183,11 @@ exports[`rendering of the DatasetContainer checks if various text fields are vis
</div>
</div>
<div>
<div
class="usa-alert usa-alert--info"
data-testid="alert"
>
<div
class="usa-alert__body"
>
<h1
class="usa-alert__heading"
>
Version 2.0 of the tool is now available
</h1>
<p
class="usa-alert__text"
>
The Council on Environmental Quality (CEQ) made the 2.0 version of the tool available on Dec 20, 2024.
</p>
</div>
<div>
<strong>
This tool has been updated.
</strong>
The 2.0 version of the tool was released on Dec 20, 2024.
</div>
</div>
<div

View file

@ -37,7 +37,7 @@ services:
environment:
# See the client readme for more info on environment variables:
# https://github.com/usds/justice40-tool/blob/main/client/README.md
DATA_SOURCE: local
DATA_SOURCE: cdn
TZ: America/Los_Angeles
volumes:
- ./client/src:/client/src