mirror of
https://github.com/DOI-DO/j40-cejst-2.git
synced 2025-02-22 09:41:26 -08:00
Merge pull request #81 from agilesix/cfelix/feature-20250122
Candidate features merge 20250122
This commit is contained in:
commit
b65d8273ac
23 changed files with 22294 additions and 13573 deletions
4
.github/workflows/deploy_frontend_main.yml
vendored
4
.github/workflows/deploy_frontend_main.yml
vendored
|
@ -16,7 +16,7 @@ jobs:
|
||||||
working-directory: client
|
working-directory: client
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
node-version: [14.x]
|
node-version: [18.x]
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- name: Use Node.js ${{ matrix.node-version }}
|
- name: Use Node.js ${{ matrix.node-version }}
|
||||||
|
@ -84,4 +84,4 @@ jobs:
|
||||||
PATHS: "/*"
|
PATHS: "/*"
|
||||||
AWS_REGION: "us-east-1"
|
AWS_REGION: "us-east-1"
|
||||||
AWS_ACCESS_KEY_ID: ${{ secrets.CLIENT_DEV_AWS_ACCESS_KEY_ID }}
|
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 }}
|
||||||
|
|
4
.github/workflows/pr_frontend.yml
vendored
4
.github/workflows/pr_frontend.yml
vendored
|
@ -5,7 +5,7 @@ concurrency:
|
||||||
group: ${{ github.workflow }}-${{ github.event.pull_request.number }}
|
group: ${{ github.workflow }}-${{ github.event.pull_request.number }}
|
||||||
cancel-in-progress: true
|
cancel-in-progress: true
|
||||||
env:
|
env:
|
||||||
node-version: 14.x
|
node-version: 18.x
|
||||||
jobs:
|
jobs:
|
||||||
# JOB to run change detection
|
# JOB to run change detection
|
||||||
detect-fe-changes:
|
detect-fe-changes:
|
||||||
|
@ -62,4 +62,4 @@ jobs:
|
||||||
- name: Spanish translation test
|
- name: Spanish translation test
|
||||||
run: npm run test:intl-translations
|
run: npm run test:intl-translations
|
||||||
# - name: Check for security vulnerabilities
|
# - name: Check for security vulnerabilities
|
||||||
# run: npm audit --production
|
# run: npm audit --production
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
v14.17.1
|
v18.20.6
|
||||||
|
|
|
@ -30,11 +30,14 @@ When(`I click on the {string} button in the navigation`, (page) => {
|
||||||
|
|
||||||
When(`I look for the {string} CTA`, (ctaString) => {
|
When(`I look for the {string} CTA`, (ctaString) => {
|
||||||
cy.get(`[data-cy="${hyphenizeString(ctaString)}-block"]`).as('CTA_block');
|
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) => {
|
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:
|
// Common Thens:
|
||||||
|
|
|
@ -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
|
// 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({
|
actions.setWebpackConfig({
|
||||||
devtool: 'eval-source-map',
|
devtool: 'eval-source-map',
|
||||||
resolve: {
|
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
34954
client/package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
@ -39,7 +39,7 @@
|
||||||
"@testing-library/jest-dom": "^5.16.5",
|
"@testing-library/jest-dom": "^5.16.5",
|
||||||
"@testing-library/react": "^11.2.7",
|
"@testing-library/react": "^11.2.7",
|
||||||
"@types/d3-ease": "^3.0.0",
|
"@types/d3-ease": "^3.0.0",
|
||||||
"@types/jest": "^26.0.24",
|
"@types/jest": "^27.5.2",
|
||||||
"@types/js-search": "^1.4.4",
|
"@types/js-search": "^1.4.4",
|
||||||
"@types/maplibre-gl": "^1.14.0",
|
"@types/maplibre-gl": "^1.14.0",
|
||||||
"@types/node": "^15.14.9",
|
"@types/node": "^15.14.9",
|
||||||
|
@ -47,8 +47,8 @@
|
||||||
"@types/react-dom": "^17.0.14",
|
"@types/react-dom": "^17.0.14",
|
||||||
"@types/react-helmet": "^6.1.5",
|
"@types/react-helmet": "^6.1.5",
|
||||||
"@types/react-test-renderer": "^17.0.1",
|
"@types/react-test-renderer": "^17.0.1",
|
||||||
"@typescript-eslint/eslint-plugin": "^4.33.0",
|
"@typescript-eslint/eslint-plugin": "^5.62.0",
|
||||||
"@typescript-eslint/parser": "^4.33.0",
|
"@typescript-eslint/parser": "^5.62.0",
|
||||||
"axe-core": "^4.4.1",
|
"axe-core": "^4.4.1",
|
||||||
"babel-jest": "^27.5.1",
|
"babel-jest": "^27.5.1",
|
||||||
"babel-preset-gatsby": "^1.14.0",
|
"babel-preset-gatsby": "^1.14.0",
|
||||||
|
@ -58,11 +58,11 @@
|
||||||
"eslint": "^7.32.0",
|
"eslint": "^7.32.0",
|
||||||
"eslint-config-google": "^0.14.0",
|
"eslint-config-google": "^0.14.0",
|
||||||
"eslint-plugin-cypress": "^2.12.1",
|
"eslint-plugin-cypress": "^2.12.1",
|
||||||
"eslint-plugin-formatjs": "^2.21.0",
|
"eslint-plugin-formatjs": "2.19.1",
|
||||||
"eslint-plugin-react": "^7.29.4",
|
"eslint-plugin-react": "^7.29.4",
|
||||||
"gatsby": "^3.14.6",
|
"gatsby": "^3.14.6",
|
||||||
"gatsby-cli": "^3.14.2",
|
"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-prettier-eslint": "^1.0.6",
|
||||||
"gatsby-plugin-react-helmet": "^4.14.0",
|
"gatsby-plugin-react-helmet": "^4.14.0",
|
||||||
"gatsby-plugin-sass": "^4.14.0",
|
"gatsby-plugin-sass": "^4.14.0",
|
||||||
|
@ -80,11 +80,11 @@
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@sentry/gatsby": "^7.7.0",
|
"@sentry/gatsby": "^7.7.0",
|
||||||
"@trussworks/react-uswds": "^3.1.0",
|
"@trussworks/react-uswds": "^3.2.0",
|
||||||
"@turf/bbox": "^6.5.0",
|
"@turf/bbox": "^6.5.0",
|
||||||
"d3-ease": "^3.0.1",
|
"d3-ease": "^3.0.1",
|
||||||
"gatsby-plugin-env-variables": "^2.2.0",
|
"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",
|
"gatsby-plugin-sitemap": "^4.10.0",
|
||||||
"js-search": "^2.0.1",
|
"js-search": "^2.0.1",
|
||||||
"maplibre-gl": "^1.14.0",
|
"maplibre-gl": "^1.14.0",
|
||||||
|
@ -96,8 +96,7 @@
|
||||||
"react-intl": "^5.24.7",
|
"react-intl": "^5.24.7",
|
||||||
"react-map-gl": "^6.1.19",
|
"react-map-gl": "^6.1.19",
|
||||||
"react-tooltip": "^4.2.21",
|
"react-tooltip": "^4.2.21",
|
||||||
"react-use": "^17.3.2",
|
"react-use": "^17.3.2"
|
||||||
"uswds": "^2.13.3"
|
|
||||||
},
|
},
|
||||||
"cypress-cucumber-preprocessor": {
|
"cypress-cucumber-preprocessor": {
|
||||||
"nonGlobalStepDefinitions": false
|
"nonGlobalStepDefinitions": false
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
18
client/src/components/CreateReportPanel/CreateReportPanel.module.scss.d.ts
vendored
Normal file
18
client/src/components/CreateReportPanel/CreateReportPanel.module.scss.d.ts
vendored
Normal 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;
|
|
@ -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;
|
3
client/src/components/CreateReportPanel/index.tsx
Normal file
3
client/src/components/CreateReportPanel/index.tsx
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
import CreateReportPanel from './CreateReportPanel';
|
||||||
|
|
||||||
|
export default CreateReportPanel;
|
|
@ -16,9 +16,11 @@ exports[`rendering of the GovernmentBanner checks if component renders 1`] = `
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="usa-banner__inner"
|
class="usa-banner__inner"
|
||||||
|
data-testid="banner-header-inner-div"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="grid-col-auto"
|
class="grid-col-auto"
|
||||||
|
data-testid="banner-header-flag-div"
|
||||||
>
|
>
|
||||||
<img
|
<img
|
||||||
alt="U.S. flag"
|
alt="U.S. flag"
|
||||||
|
@ -28,6 +30,7 @@ exports[`rendering of the GovernmentBanner checks if component renders 1`] = `
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="grid-col-fill tablet:grid-col-auto"
|
class="grid-col-fill tablet:grid-col-auto"
|
||||||
|
data-testid="banner-header-grid-div"
|
||||||
>
|
>
|
||||||
<p
|
<p
|
||||||
class="usa-banner__header-text"
|
class="usa-banner__header-text"
|
||||||
|
@ -109,19 +112,38 @@ exports[`rendering of the GovernmentBanner checks if component renders 1`] = `
|
||||||
<br />
|
<br />
|
||||||
A
|
A
|
||||||
<strong>
|
<strong>
|
||||||
lock (
|
lock (
|
||||||
<span
|
<span
|
||||||
class="icon-lock"
|
class="icon-lock"
|
||||||
>
|
>
|
||||||
<img
|
<svg
|
||||||
alt="lock"
|
aria-labelledby="banner-lock-title banner-lock-description"
|
||||||
class="usa-banner__lock-image"
|
class="usa-banner__lock-image"
|
||||||
|
focusable="false"
|
||||||
|
height="64"
|
||||||
role="img"
|
role="img"
|
||||||
src="data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz48c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjUyIiBoZWlnaHQ9IjY0IiB2aWV3Qm94PSIwIDAgNTIgNjQiPjx0aXRsZT5sb2NrPC90aXRsZT48cGF0aCBmaWxsPSIjMUIxQjFCIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik0yNiAwYzEwLjQ5MyAwIDE5IDguNTA3IDE5IDE5djloM2E0IDQgMCAwIDEgNCA0djI4YTQgNCAwIDAgMS00IDRINGE0IDQgMCAwIDEtNC00VjMyYTQgNCAwIDAgMSA0LTRoM3YtOUM3IDguNTA3IDE1LjUwNyAwIDI2IDB6bTAgOGMtNS45NzkgMC0xMC44NDMgNC43Ny0xMC45OTYgMTAuNzEyTDE1IDE5djloMjJ2LTljMC02LjA3NS00LjkyNS0xMS0xMS0xMXoiLz48L3N2Zz4="
|
viewBox="0 0 52 64"
|
||||||
title="Lock"
|
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>
|
</span>
|
||||||
)
|
)
|
||||||
</strong>
|
</strong>
|
||||||
or
|
or
|
||||||
<strong>
|
<strong>
|
||||||
|
|
|
@ -21,9 +21,11 @@ exports[`rendering of the J40Header checks if component renders 1`] = `
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="usa-banner__inner"
|
class="usa-banner__inner"
|
||||||
|
data-testid="banner-header-inner-div"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="grid-col-auto"
|
class="grid-col-auto"
|
||||||
|
data-testid="banner-header-flag-div"
|
||||||
>
|
>
|
||||||
<img
|
<img
|
||||||
alt="U.S. flag"
|
alt="U.S. flag"
|
||||||
|
@ -33,6 +35,7 @@ exports[`rendering of the J40Header checks if component renders 1`] = `
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="grid-col-fill tablet:grid-col-auto"
|
class="grid-col-fill tablet:grid-col-auto"
|
||||||
|
data-testid="banner-header-grid-div"
|
||||||
>
|
>
|
||||||
<p
|
<p
|
||||||
class="usa-banner__header-text"
|
class="usa-banner__header-text"
|
||||||
|
@ -114,19 +117,38 @@ exports[`rendering of the J40Header checks if component renders 1`] = `
|
||||||
<br />
|
<br />
|
||||||
A
|
A
|
||||||
<strong>
|
<strong>
|
||||||
lock (
|
lock (
|
||||||
<span
|
<span
|
||||||
class="icon-lock"
|
class="icon-lock"
|
||||||
>
|
>
|
||||||
<img
|
<svg
|
||||||
alt="lock"
|
aria-labelledby="banner-lock-title banner-lock-description"
|
||||||
class="usa-banner__lock-image"
|
class="usa-banner__lock-image"
|
||||||
|
focusable="false"
|
||||||
|
height="64"
|
||||||
role="img"
|
role="img"
|
||||||
src="data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz48c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjUyIiBoZWlnaHQ9IjY0IiB2aWV3Qm94PSIwIDAgNTIgNjQiPjx0aXRsZT5sb2NrPC90aXRsZT48cGF0aCBmaWxsPSIjMUIxQjFCIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik0yNiAwYzEwLjQ5MyAwIDE5IDguNTA3IDE5IDE5djloM2E0IDQgMCAwIDEgNCA0djI4YTQgNCAwIDAgMS00IDRINGE0IDQgMCAwIDEtNC00VjMyYTQgNCAwIDAgMSA0LTRoM3YtOUM3IDguNTA3IDE1LjUwNyAwIDI2IDB6bTAgOGMtNS45NzkgMC0xMC44NDMgNC43Ny0xMC45OTYgMTAuNzEyTDE1IDE5djloMjJ2LTljMC02LjA3NS00LjkyNS0xMS0xMS0xMXoiLz48L3N2Zz4="
|
viewBox="0 0 52 64"
|
||||||
title="Lock"
|
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>
|
</span>
|
||||||
)
|
)
|
||||||
</strong>
|
</strong>
|
||||||
or
|
or
|
||||||
<strong>
|
<strong>
|
||||||
|
@ -161,24 +183,11 @@ exports[`rendering of the J40Header checks if component renders 1`] = `
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<div
|
<div>
|
||||||
class="usa-alert usa-alert--info"
|
<strong>
|
||||||
data-testid="alert"
|
This tool has been updated.
|
||||||
>
|
</strong>
|
||||||
<div
|
The 2.0 version of the tool was released on Dec 20, 2024.
|
||||||
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>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
|
|
|
@ -12,7 +12,8 @@ import ReactMapGL, {
|
||||||
Popup,
|
Popup,
|
||||||
FlyToInterpolator,
|
FlyToInterpolator,
|
||||||
FullscreenControl,
|
FullscreenControl,
|
||||||
MapRef} from 'react-map-gl';
|
MapRef,
|
||||||
|
} from 'react-map-gl';
|
||||||
import {useIntl} from 'gatsby-plugin-intl';
|
import {useIntl} from 'gatsby-plugin-intl';
|
||||||
import bbox from '@turf/bbox';
|
import bbox from '@turf/bbox';
|
||||||
import * as d3 from 'd3-ease';
|
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 constants from '../data/constants';
|
||||||
import * as styles from './J40Map.module.scss';
|
import * as styles from './J40Map.module.scss';
|
||||||
import * as EXPLORE_COPY from '../data/copy/explore';
|
import * as EXPLORE_COPY from '../data/copy/explore';
|
||||||
|
import CreateReportPanel from './CreateReportPanel';
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
interface Window {
|
interface Window {
|
||||||
|
@ -63,6 +65,8 @@ export interface IMapFeature {
|
||||||
type: string;
|
type: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const MAX_SELECTED_TRACTS = 20;
|
||||||
|
|
||||||
const J40Map = ({location}: IJ40Interface) => {
|
const J40Map = ({location}: IJ40Interface) => {
|
||||||
/**
|
/**
|
||||||
* Initializes the zoom, and the map's center point (lat, lng) via the URL hash #{z}/{lat}/{long}
|
* 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,
|
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 [detailViewData, setDetailViewData] = useState<IDetailViewInterface>();
|
||||||
const [transitionInProgress, setTransitionInProgress] = useState<boolean>(false);
|
const [transitionInProgress, setTransitionInProgress] = useState<boolean>(false);
|
||||||
const [geolocationInProgress, setGeolocationInProgress] = useState<boolean>(false);
|
const [geolocationInProgress, setGeolocationInProgress] = useState<boolean>(false);
|
||||||
const [isMobileMapState, setIsMobileMapState] = 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 [selectTractId, setSelectTractId] = useState<string | undefined>(undefined);
|
||||||
const {width: windowWidth} = useWindowSize();
|
const {width: windowWidth} = useWindowSize();
|
||||||
|
|
||||||
|
@ -110,23 +116,84 @@ const J40Map = ({location}: IJ40Interface) => {
|
||||||
const flags = useFlags();
|
const flags = useFlags();
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
|
|
||||||
const selectedFeatureId = (selectedFeature && selectedFeature.id) || '';
|
|
||||||
|
|
||||||
const zoomLatLngHash = mapRef.current?.getMap()._hash._getCurrentHash();
|
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.
|
* Selects the provided feature on the map.
|
||||||
* @param feature the feature to select
|
* @param feature the feature to select
|
||||||
|
* @param isMultiSelectKeyDown true if the multi select key is down
|
||||||
*/
|
*/
|
||||||
const selectFeatureOnMap = (feature: IMapFeature) => {
|
const selectFeaturesOnMap = (feature: IMapFeature, isMultiSelectKeyDown: boolean = false) => {
|
||||||
if (feature) {
|
const featuresList = updateSelectedFeatures(feature, isMultiSelectKeyDown || inMultiSelectMode);
|
||||||
// Get the current selected feature's bounding box:
|
if (featuresList.length > 0) {
|
||||||
const [minLng, minLat, maxLng, maxLat] = bbox(feature);
|
const [minLng, minLat, maxLng, maxLat] = getFeaturesBbox(featuresList);
|
||||||
|
|
||||||
// Set the selectedFeature ID
|
// Go to area of the selected feature(s)
|
||||||
setSelectedFeature(feature);
|
|
||||||
|
|
||||||
// Go to the newly selected feature (as long as it's not an Alaska Point)
|
|
||||||
goToPlace([
|
goToPlace([
|
||||||
[minLng, minLat],
|
[minLng, minLat],
|
||||||
[maxLng, maxLat],
|
[maxLng, maxLat],
|
||||||
|
@ -213,14 +280,15 @@ const J40Map = ({location}: IJ40Interface) => {
|
||||||
default:
|
default:
|
||||||
break;
|
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
|
// This else clause will fire when the user clicks on the map and will ignore other controls
|
||||||
// such as the search box and buttons.
|
// such as the search box and buttons.
|
||||||
|
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
const feature = event.features && event.features[0];
|
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 newViewPort = new WebMercatorViewport({height: viewport.height!, width: viewport.width!});
|
||||||
const {longitude, latitude, zoom} = newViewPort.fitBounds(
|
const {longitude, latitude, zoom} = newViewPort.fitBounds(
|
||||||
bounds as [[number, number], [number, number]], {
|
bounds as [[number, number], [number, number]], {
|
||||||
// padding: 200, // removing padding and offset in favor of a zoom offset below
|
// padding: 200, // removing padding and offset in favor of a zoom offset below
|
||||||
// offset: [0, -100],
|
// offset: [0, -100],
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -266,8 +334,8 @@ const J40Map = ({location}: IJ40Interface) => {
|
||||||
*/
|
*/
|
||||||
// eslint-disable-next-line max-len
|
// eslint-disable-next-line max-len
|
||||||
const featureSelectionZoomLevel = (zoom - 1) < constants.GLOBAL_MIN_ZOOM_FEATURE_BORDER + .1 ?
|
const featureSelectionZoomLevel = (zoom - 1) < constants.GLOBAL_MIN_ZOOM_FEATURE_BORDER + .1 ?
|
||||||
constants.GLOBAL_MIN_ZOOM_FEATURE_BORDER :
|
constants.GLOBAL_MIN_ZOOM_FEATURE_BORDER :
|
||||||
zoom - 1;
|
zoom - 1;
|
||||||
|
|
||||||
setViewport({
|
setViewport({
|
||||||
...viewport,
|
...viewport,
|
||||||
|
@ -304,7 +372,8 @@ const J40Map = ({location}: IJ40Interface) => {
|
||||||
filter: ['==', constants.GEOID_PROPERTY, selectTractId],
|
filter: ['==', constants.GEOID_PROPERTY, selectTractId],
|
||||||
});
|
});
|
||||||
if (geoidSearchResults && geoidSearchResults.length > 0) {
|
if (geoidSearchResults && geoidSearchResults.length > 0) {
|
||||||
selectFeatureOnMap(geoidSearchResults[0]);
|
// TODO, support searching for a list of tracts
|
||||||
|
selectFeaturesOnMap(geoidSearchResults[0]);
|
||||||
}
|
}
|
||||||
setSelectTractId(undefined);
|
setSelectTractId(undefined);
|
||||||
}
|
}
|
||||||
|
@ -321,6 +390,23 @@ const J40Map = ({location}: IJ40Interface) => {
|
||||||
setGeolocationInProgress(true);
|
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 (
|
return (
|
||||||
<>
|
<>
|
||||||
|
@ -355,15 +441,15 @@ const J40Map = ({location}: IJ40Interface) => {
|
||||||
// access token is j40StylesReadToken
|
// access token is j40StylesReadToken
|
||||||
mapboxApiAccessToken={
|
mapboxApiAccessToken={
|
||||||
process.env.MAPBOX_STYLES_READ_TOKEN ?
|
process.env.MAPBOX_STYLES_READ_TOKEN ?
|
||||||
process.env.MAPBOX_STYLES_READ_TOKEN : ''}
|
process.env.MAPBOX_STYLES_READ_TOKEN : ''}
|
||||||
|
|
||||||
// ****** Map state props: ******
|
// ****** Map state props: ******
|
||||||
// http://visgl.github.io/react-map-gl/docs/api-reference/interactive-map#map-state
|
// http://visgl.github.io/react-map-gl/docs/api-reference/interactive-map#map-state
|
||||||
{...viewport}
|
{...viewport}
|
||||||
mapStyle={
|
mapStyle={
|
||||||
process.env.MAPBOX_STYLES_READ_TOKEN ?
|
process.env.MAPBOX_STYLES_READ_TOKEN ?
|
||||||
'mapbox://styles/justice40/cl9g30qh7000p15l9cp1ftw16' :
|
'mapbox://styles/justice40/cl9g30qh7000p15l9cp1ftw16' :
|
||||||
'https://basemaps.cartocdn.com/gl/voyager-gl-style/style.json'
|
'https://basemaps.cartocdn.com/gl/voyager-gl-style/style.json'
|
||||||
}
|
}
|
||||||
width="100%"
|
width="100%"
|
||||||
// Ajusting this height with a conditional statement will not render the map on staging.
|
// Ajusting this height with a conditional statement will not render the map on staging.
|
||||||
|
@ -406,13 +492,12 @@ const J40Map = ({location}: IJ40Interface) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
<MapTractLayers
|
<MapTractLayers
|
||||||
selectedFeature={selectedFeature}
|
selectedFeatures={selectedFeatures}
|
||||||
selectedFeatureId={selectedFeatureId}
|
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{/* This is the first overlayed row on the map: Search and Geolocation */}
|
{/* This is the first overlayed row on the map: Search and Geolocation */}
|
||||||
<div className={styles.mapHeaderRow}>
|
<div className={styles.mapHeaderRow}>
|
||||||
<MapSearch goToPlace={goToPlace}/>
|
<MapSearch goToPlace={goToPlace} />
|
||||||
|
|
||||||
{/* Geolocate Icon */}
|
{/* Geolocate Icon */}
|
||||||
<div className={styles.geolocateBox}>
|
<div className={styles.geolocateBox}>
|
||||||
|
@ -420,8 +505,8 @@ const J40Map = ({location}: IJ40Interface) => {
|
||||||
windowWidth > constants.USWDS_BREAKPOINTS.MOBILE_LG - 1 &&
|
windowWidth > constants.USWDS_BREAKPOINTS.MOBILE_LG - 1 &&
|
||||||
<div className={
|
<div className={
|
||||||
(geolocationInProgress && !isGeolocateLocked) ?
|
(geolocationInProgress && !isGeolocateLocked) ?
|
||||||
styles.geolocateMessage :
|
styles.geolocateMessage :
|
||||||
styles.geolocateMessageHide
|
styles.geolocateMessageHide
|
||||||
}>
|
}>
|
||||||
{intl.formatMessage(EXPLORE_COPY.MAP.GEOLOC_MSG_LOCATING)}
|
{intl.formatMessage(EXPLORE_COPY.MAP.GEOLOC_MSG_LOCATING)}
|
||||||
</div>
|
</div>
|
||||||
|
@ -432,7 +517,6 @@ const J40Map = ({location}: IJ40Interface) => {
|
||||||
onClick={onClickGeolocate}
|
onClick={onClickGeolocate}
|
||||||
trackUserLocation={windowWidth < constants.USWDS_BREAKPOINTS.MOBILE_LG}
|
trackUserLocation={windowWidth < constants.USWDS_BREAKPOINTS.MOBILE_LG}
|
||||||
showUserHeading={windowWidth < constants.USWDS_BREAKPOINTS.MOBILE_LG}
|
showUserHeading={windowWidth < constants.USWDS_BREAKPOINTS.MOBILE_LG}
|
||||||
disabledLabel={intl.formatMessage(EXPLORE_COPY.MAP.GEOLOC_MSG_DISABLED)}
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -440,15 +524,15 @@ const J40Map = ({location}: IJ40Interface) => {
|
||||||
|
|
||||||
{/* This is the second row overlayed on the map, it will add the navigation controls
|
{/* This is the second row overlayed on the map, it will add the navigation controls
|
||||||
of the zoom in and zoom out buttons */}
|
of the zoom in and zoom out buttons */}
|
||||||
{ windowWidth > constants.USWDS_BREAKPOINTS.MOBILE_LG && <NavigationControl
|
{windowWidth > constants.USWDS_BREAKPOINTS.MOBILE_LG && <NavigationControl
|
||||||
showCompass={false}
|
showCompass={false}
|
||||||
className={styles.navigationControl}
|
className={styles.navigationControl}
|
||||||
/> }
|
/>}
|
||||||
|
|
||||||
{/* This is the third row overlayed on the map, it will show shortcut buttons to
|
{/* This is the third row overlayed on the map, it will show shortcut buttons to
|
||||||
pan/zoom to US territories */}
|
pan/zoom to US territories */}
|
||||||
{ windowWidth > constants.USWDS_BREAKPOINTS.MOBILE_LG &&
|
{windowWidth > constants.USWDS_BREAKPOINTS.MOBILE_LG &&
|
||||||
<TerritoryFocusControl onClick={onClick}/> }
|
<TerritoryFocusControl onClick={onClick} />}
|
||||||
|
|
||||||
{/* Enable fullscreen pop-up behind a feature flag */}
|
{/* Enable fullscreen pop-up behind a feature flag */}
|
||||||
{('fs' in flags && detailViewData && !transitionInProgress) && (
|
{('fs' in flags && detailViewData && !transitionInProgress) && (
|
||||||
|
@ -468,18 +552,27 @@ const J40Map = ({location}: IJ40Interface) => {
|
||||||
/>
|
/>
|
||||||
</Popup>
|
</Popup>
|
||||||
)}
|
)}
|
||||||
{'fs' in flags ? <FullscreenControl className={styles.fullscreenControl}/> :'' }
|
{'fs' in flags ? <FullscreenControl className={styles.fullscreenControl} /> : ''}
|
||||||
|
|
||||||
</ReactMapGL>
|
</ReactMapGL>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
<Grid desktop={{col: 3}}>
|
<Grid desktop={{col: 3}}>
|
||||||
<MapInfoPanel
|
{inMultiSelectMode ?
|
||||||
className={styles.mapInfoPanel}
|
<CreateReportPanel
|
||||||
featureProperties={detailViewData?.properties}
|
className={styles.mapInfoPanel}
|
||||||
selectedFeatureId={selectedFeature?.id}
|
featureList={selectedFeatures}
|
||||||
hash={zoomLatLngHash}
|
deleteTractHandler={onReportDeleteTract}
|
||||||
/>
|
exitHandler={onReportExit}
|
||||||
|
maxNumTracts={MAX_SELECTED_TRACTS}
|
||||||
|
showTooManyTractsAlert={showTooManyTractsAlert}
|
||||||
|
/> :
|
||||||
|
<MapInfoPanel
|
||||||
|
className={styles.mapInfoPanel}
|
||||||
|
featureProperties={detailViewData?.properties}
|
||||||
|
hash={zoomLatLngHash}
|
||||||
|
/>
|
||||||
|
}
|
||||||
</Grid>
|
</Grid>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import React, {useMemo} from 'react';
|
import React from 'react';
|
||||||
import {Source, Layer} from 'react-map-gl';
|
import {Source, Layer} from 'react-map-gl';
|
||||||
import {MapGeoJSONFeature} from 'maplibre-gl';
|
import {MapGeoJSONFeature} from 'maplibre-gl';
|
||||||
|
|
||||||
|
@ -9,8 +9,7 @@ import * as constants from '../../data/constants';
|
||||||
import * as COMMON_COPY from '../../data/copy/common';
|
import * as COMMON_COPY from '../../data/copy/common';
|
||||||
|
|
||||||
interface IMapTractLayers {
|
interface IMapTractLayers {
|
||||||
selectedFeatureId: string | number,
|
selectedFeatures: MapGeoJSONFeature[] | undefined,
|
||||||
selectedFeature: MapGeoJSONFeature | undefined,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -65,10 +64,10 @@ export const featureURLForTilesetName = (tilesetName: string): string => {
|
||||||
* @return {Style}
|
* @return {Style}
|
||||||
*/
|
*/
|
||||||
const MapTractLayers = ({
|
const MapTractLayers = ({
|
||||||
selectedFeatureId,
|
selectedFeatures,
|
||||||
selectedFeature,
|
|
||||||
}: IMapTractLayers) => {
|
}: 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 (
|
return (
|
||||||
<>
|
<>
|
||||||
|
|
|
@ -5,14 +5,12 @@ import SidePanelInfo from './SidePanelInfo';
|
||||||
interface IMapInfoPanelProps {
|
interface IMapInfoPanelProps {
|
||||||
className: string,
|
className: string,
|
||||||
featureProperties: { [key:string]: string | number } | undefined,
|
featureProperties: { [key:string]: string | number } | undefined,
|
||||||
selectedFeatureId: string | number | undefined
|
|
||||||
hash: string[],
|
hash: string[],
|
||||||
}
|
}
|
||||||
|
|
||||||
const MapInfoPanel = ({
|
const MapInfoPanel = ({
|
||||||
className,
|
className,
|
||||||
featureProperties,
|
featureProperties,
|
||||||
selectedFeatureId,
|
|
||||||
hash,
|
hash,
|
||||||
}:IMapInfoPanelProps) => {
|
}:IMapInfoPanelProps) => {
|
||||||
return (
|
return (
|
||||||
|
@ -22,7 +20,7 @@ const MapInfoPanel = ({
|
||||||
there are two states, namely showing the AreaDetail or SidePanelInfo. When a feature
|
there are two states, namely showing the AreaDetail or SidePanelInfo. When a feature
|
||||||
is selected, show the AreaDetail. When not selected show SidePanelInfo
|
is selected, show the AreaDetail. When not selected show SidePanelInfo
|
||||||
*/}
|
*/}
|
||||||
{(featureProperties && selectedFeatureId) ?
|
{(featureProperties) ?
|
||||||
<AreaDetail
|
<AreaDetail
|
||||||
properties={featureProperties}
|
properties={featureProperties}
|
||||||
hash={hash}
|
hash={hash}
|
||||||
|
|
|
@ -21,9 +21,11 @@ exports[`rendering of the DatasetContainer checks if various text fields are vis
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="usa-banner__inner"
|
class="usa-banner__inner"
|
||||||
|
data-testid="banner-header-inner-div"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="grid-col-auto"
|
class="grid-col-auto"
|
||||||
|
data-testid="banner-header-flag-div"
|
||||||
>
|
>
|
||||||
<img
|
<img
|
||||||
alt="U.S. flag"
|
alt="U.S. flag"
|
||||||
|
@ -33,6 +35,7 @@ exports[`rendering of the DatasetContainer checks if various text fields are vis
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="grid-col-fill tablet:grid-col-auto"
|
class="grid-col-fill tablet:grid-col-auto"
|
||||||
|
data-testid="banner-header-grid-div"
|
||||||
>
|
>
|
||||||
<p
|
<p
|
||||||
class="usa-banner__header-text"
|
class="usa-banner__header-text"
|
||||||
|
@ -114,19 +117,38 @@ exports[`rendering of the DatasetContainer checks if various text fields are vis
|
||||||
<br />
|
<br />
|
||||||
A
|
A
|
||||||
<strong>
|
<strong>
|
||||||
lock (
|
lock (
|
||||||
<span
|
<span
|
||||||
class="icon-lock"
|
class="icon-lock"
|
||||||
>
|
>
|
||||||
<img
|
<svg
|
||||||
alt="lock"
|
aria-labelledby="banner-lock-title banner-lock-description"
|
||||||
class="usa-banner__lock-image"
|
class="usa-banner__lock-image"
|
||||||
|
focusable="false"
|
||||||
|
height="64"
|
||||||
role="img"
|
role="img"
|
||||||
src="data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz48c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjUyIiBoZWlnaHQ9IjY0IiB2aWV3Qm94PSIwIDAgNTIgNjQiPjx0aXRsZT5sb2NrPC90aXRsZT48cGF0aCBmaWxsPSIjMUIxQjFCIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik0yNiAwYzEwLjQ5MyAwIDE5IDguNTA3IDE5IDE5djloM2E0IDQgMCAwIDEgNCA0djI4YTQgNCAwIDAgMS00IDRINGE0IDQgMCAwIDEtNC00VjMyYTQgNCAwIDAgMSA0LTRoM3YtOUM3IDguNTA3IDE1LjUwNyAwIDI2IDB6bTAgOGMtNS45NzkgMC0xMC44NDMgNC43Ny0xMC45OTYgMTAuNzEyTDE1IDE5djloMjJ2LTljMC02LjA3NS00LjkyNS0xMS0xMS0xMXoiLz48L3N2Zz4="
|
viewBox="0 0 52 64"
|
||||||
title="Lock"
|
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>
|
</span>
|
||||||
)
|
)
|
||||||
</strong>
|
</strong>
|
||||||
or
|
or
|
||||||
<strong>
|
<strong>
|
||||||
|
@ -161,24 +183,11 @@ exports[`rendering of the DatasetContainer checks if various text fields are vis
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<div
|
<div>
|
||||||
class="usa-alert usa-alert--info"
|
<strong>
|
||||||
data-testid="alert"
|
This tool has been updated.
|
||||||
>
|
</strong>
|
||||||
<div
|
The 2.0 version of the tool was released on Dec 20, 2024.
|
||||||
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>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
|
|
|
@ -21,9 +21,11 @@ exports[`rendering of the DatasetContainer checks if various text fields are vis
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="usa-banner__inner"
|
class="usa-banner__inner"
|
||||||
|
data-testid="banner-header-inner-div"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="grid-col-auto"
|
class="grid-col-auto"
|
||||||
|
data-testid="banner-header-flag-div"
|
||||||
>
|
>
|
||||||
<img
|
<img
|
||||||
alt="U.S. flag"
|
alt="U.S. flag"
|
||||||
|
@ -33,6 +35,7 @@ exports[`rendering of the DatasetContainer checks if various text fields are vis
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="grid-col-fill tablet:grid-col-auto"
|
class="grid-col-fill tablet:grid-col-auto"
|
||||||
|
data-testid="banner-header-grid-div"
|
||||||
>
|
>
|
||||||
<p
|
<p
|
||||||
class="usa-banner__header-text"
|
class="usa-banner__header-text"
|
||||||
|
@ -114,19 +117,38 @@ exports[`rendering of the DatasetContainer checks if various text fields are vis
|
||||||
<br />
|
<br />
|
||||||
A
|
A
|
||||||
<strong>
|
<strong>
|
||||||
lock (
|
lock (
|
||||||
<span
|
<span
|
||||||
class="icon-lock"
|
class="icon-lock"
|
||||||
>
|
>
|
||||||
<img
|
<svg
|
||||||
alt="lock"
|
aria-labelledby="banner-lock-title banner-lock-description"
|
||||||
class="usa-banner__lock-image"
|
class="usa-banner__lock-image"
|
||||||
|
focusable="false"
|
||||||
|
height="64"
|
||||||
role="img"
|
role="img"
|
||||||
src="data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz48c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjUyIiBoZWlnaHQ9IjY0IiB2aWV3Qm94PSIwIDAgNTIgNjQiPjx0aXRsZT5sb2NrPC90aXRsZT48cGF0aCBmaWxsPSIjMUIxQjFCIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik0yNiAwYzEwLjQ5MyAwIDE5IDguNTA3IDE5IDE5djloM2E0IDQgMCAwIDEgNCA0djI4YTQgNCAwIDAgMS00IDRINGE0IDQgMCAwIDEtNC00VjMyYTQgNCAwIDAgMSA0LTRoM3YtOUM3IDguNTA3IDE1LjUwNyAwIDI2IDB6bTAgOGMtNS45NzkgMC0xMC44NDMgNC43Ny0xMC45OTYgMTAuNzEyTDE1IDE5djloMjJ2LTljMC02LjA3NS00LjkyNS0xMS0xMS0xMXoiLz48L3N2Zz4="
|
viewBox="0 0 52 64"
|
||||||
title="Lock"
|
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>
|
</span>
|
||||||
)
|
)
|
||||||
</strong>
|
</strong>
|
||||||
or
|
or
|
||||||
<strong>
|
<strong>
|
||||||
|
@ -161,24 +183,11 @@ exports[`rendering of the DatasetContainer checks if various text fields are vis
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<div
|
<div>
|
||||||
class="usa-alert usa-alert--info"
|
<strong>
|
||||||
data-testid="alert"
|
This tool has been updated.
|
||||||
>
|
</strong>
|
||||||
<div
|
The 2.0 version of the tool was released on Dec 20, 2024.
|
||||||
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>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
|
|
|
@ -21,9 +21,11 @@ exports[`rendering of the DatasetContainer checks if various text fields are vis
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="usa-banner__inner"
|
class="usa-banner__inner"
|
||||||
|
data-testid="banner-header-inner-div"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="grid-col-auto"
|
class="grid-col-auto"
|
||||||
|
data-testid="banner-header-flag-div"
|
||||||
>
|
>
|
||||||
<img
|
<img
|
||||||
alt="U.S. flag"
|
alt="U.S. flag"
|
||||||
|
@ -33,6 +35,7 @@ exports[`rendering of the DatasetContainer checks if various text fields are vis
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="grid-col-fill tablet:grid-col-auto"
|
class="grid-col-fill tablet:grid-col-auto"
|
||||||
|
data-testid="banner-header-grid-div"
|
||||||
>
|
>
|
||||||
<p
|
<p
|
||||||
class="usa-banner__header-text"
|
class="usa-banner__header-text"
|
||||||
|
@ -114,19 +117,38 @@ exports[`rendering of the DatasetContainer checks if various text fields are vis
|
||||||
<br />
|
<br />
|
||||||
A
|
A
|
||||||
<strong>
|
<strong>
|
||||||
lock (
|
lock (
|
||||||
<span
|
<span
|
||||||
class="icon-lock"
|
class="icon-lock"
|
||||||
>
|
>
|
||||||
<img
|
<svg
|
||||||
alt="lock"
|
aria-labelledby="banner-lock-title banner-lock-description"
|
||||||
class="usa-banner__lock-image"
|
class="usa-banner__lock-image"
|
||||||
|
focusable="false"
|
||||||
|
height="64"
|
||||||
role="img"
|
role="img"
|
||||||
src="data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz48c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjUyIiBoZWlnaHQ9IjY0IiB2aWV3Qm94PSIwIDAgNTIgNjQiPjx0aXRsZT5sb2NrPC90aXRsZT48cGF0aCBmaWxsPSIjMUIxQjFCIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik0yNiAwYzEwLjQ5MyAwIDE5IDguNTA3IDE5IDE5djloM2E0IDQgMCAwIDEgNCA0djI4YTQgNCAwIDAgMS00IDRINGE0IDQgMCAwIDEtNC00VjMyYTQgNCAwIDAgMSA0LTRoM3YtOUM3IDguNTA3IDE1LjUwNyAwIDI2IDB6bTAgOGMtNS45NzkgMC0xMC44NDMgNC43Ny0xMC45OTYgMTAuNzEyTDE1IDE5djloMjJ2LTljMC02LjA3NS00LjkyNS0xMS0xMS0xMXoiLz48L3N2Zz4="
|
viewBox="0 0 52 64"
|
||||||
title="Lock"
|
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>
|
</span>
|
||||||
)
|
)
|
||||||
</strong>
|
</strong>
|
||||||
or
|
or
|
||||||
<strong>
|
<strong>
|
||||||
|
@ -161,24 +183,11 @@ exports[`rendering of the DatasetContainer checks if various text fields are vis
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<div
|
<div>
|
||||||
class="usa-alert usa-alert--info"
|
<strong>
|
||||||
data-testid="alert"
|
This tool has been updated.
|
||||||
>
|
</strong>
|
||||||
<div
|
The 2.0 version of the tool was released on Dec 20, 2024.
|
||||||
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>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
|
|
|
@ -21,9 +21,11 @@ exports[`rendering of the DatasetContainer checks if various text fields are vis
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="usa-banner__inner"
|
class="usa-banner__inner"
|
||||||
|
data-testid="banner-header-inner-div"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="grid-col-auto"
|
class="grid-col-auto"
|
||||||
|
data-testid="banner-header-flag-div"
|
||||||
>
|
>
|
||||||
<img
|
<img
|
||||||
alt="U.S. flag"
|
alt="U.S. flag"
|
||||||
|
@ -33,6 +35,7 @@ exports[`rendering of the DatasetContainer checks if various text fields are vis
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="grid-col-fill tablet:grid-col-auto"
|
class="grid-col-fill tablet:grid-col-auto"
|
||||||
|
data-testid="banner-header-grid-div"
|
||||||
>
|
>
|
||||||
<p
|
<p
|
||||||
class="usa-banner__header-text"
|
class="usa-banner__header-text"
|
||||||
|
@ -114,19 +117,38 @@ exports[`rendering of the DatasetContainer checks if various text fields are vis
|
||||||
<br />
|
<br />
|
||||||
A
|
A
|
||||||
<strong>
|
<strong>
|
||||||
lock (
|
lock (
|
||||||
<span
|
<span
|
||||||
class="icon-lock"
|
class="icon-lock"
|
||||||
>
|
>
|
||||||
<img
|
<svg
|
||||||
alt="lock"
|
aria-labelledby="banner-lock-title banner-lock-description"
|
||||||
class="usa-banner__lock-image"
|
class="usa-banner__lock-image"
|
||||||
|
focusable="false"
|
||||||
|
height="64"
|
||||||
role="img"
|
role="img"
|
||||||
src="data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz48c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjUyIiBoZWlnaHQ9IjY0IiB2aWV3Qm94PSIwIDAgNTIgNjQiPjx0aXRsZT5sb2NrPC90aXRsZT48cGF0aCBmaWxsPSIjMUIxQjFCIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik0yNiAwYzEwLjQ5MyAwIDE5IDguNTA3IDE5IDE5djloM2E0IDQgMCAwIDEgNCA0djI4YTQgNCAwIDAgMS00IDRINGE0IDQgMCAwIDEtNC00VjMyYTQgNCAwIDAgMSA0LTRoM3YtOUM3IDguNTA3IDE1LjUwNyAwIDI2IDB6bTAgOGMtNS45NzkgMC0xMC44NDMgNC43Ny0xMC45OTYgMTAuNzEyTDE1IDE5djloMjJ2LTljMC02LjA3NS00LjkyNS0xMS0xMS0xMXoiLz48L3N2Zz4="
|
viewBox="0 0 52 64"
|
||||||
title="Lock"
|
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>
|
</span>
|
||||||
)
|
)
|
||||||
</strong>
|
</strong>
|
||||||
or
|
or
|
||||||
<strong>
|
<strong>
|
||||||
|
@ -161,24 +183,11 @@ exports[`rendering of the DatasetContainer checks if various text fields are vis
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<div
|
<div>
|
||||||
class="usa-alert usa-alert--info"
|
<strong>
|
||||||
data-testid="alert"
|
This tool has been updated.
|
||||||
>
|
</strong>
|
||||||
<div
|
The 2.0 version of the tool was released on Dec 20, 2024.
|
||||||
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>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
|
|
|
@ -21,9 +21,11 @@ exports[`rendering of the DatasetContainer checks if various text fields are vis
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="usa-banner__inner"
|
class="usa-banner__inner"
|
||||||
|
data-testid="banner-header-inner-div"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="grid-col-auto"
|
class="grid-col-auto"
|
||||||
|
data-testid="banner-header-flag-div"
|
||||||
>
|
>
|
||||||
<img
|
<img
|
||||||
alt="U.S. flag"
|
alt="U.S. flag"
|
||||||
|
@ -33,6 +35,7 @@ exports[`rendering of the DatasetContainer checks if various text fields are vis
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="grid-col-fill tablet:grid-col-auto"
|
class="grid-col-fill tablet:grid-col-auto"
|
||||||
|
data-testid="banner-header-grid-div"
|
||||||
>
|
>
|
||||||
<p
|
<p
|
||||||
class="usa-banner__header-text"
|
class="usa-banner__header-text"
|
||||||
|
@ -114,19 +117,38 @@ exports[`rendering of the DatasetContainer checks if various text fields are vis
|
||||||
<br />
|
<br />
|
||||||
A
|
A
|
||||||
<strong>
|
<strong>
|
||||||
lock (
|
lock (
|
||||||
<span
|
<span
|
||||||
class="icon-lock"
|
class="icon-lock"
|
||||||
>
|
>
|
||||||
<img
|
<svg
|
||||||
alt="lock"
|
aria-labelledby="banner-lock-title banner-lock-description"
|
||||||
class="usa-banner__lock-image"
|
class="usa-banner__lock-image"
|
||||||
|
focusable="false"
|
||||||
|
height="64"
|
||||||
role="img"
|
role="img"
|
||||||
src="data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz48c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjUyIiBoZWlnaHQ9IjY0IiB2aWV3Qm94PSIwIDAgNTIgNjQiPjx0aXRsZT5sb2NrPC90aXRsZT48cGF0aCBmaWxsPSIjMUIxQjFCIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik0yNiAwYzEwLjQ5MyAwIDE5IDguNTA3IDE5IDE5djloM2E0IDQgMCAwIDEgNCA0djI4YTQgNCAwIDAgMS00IDRINGE0IDQgMCAwIDEtNC00VjMyYTQgNCAwIDAgMSA0LTRoM3YtOUM3IDguNTA3IDE1LjUwNyAwIDI2IDB6bTAgOGMtNS45NzkgMC0xMC44NDMgNC43Ny0xMC45OTYgMTAuNzEyTDE1IDE5djloMjJ2LTljMC02LjA3NS00LjkyNS0xMS0xMS0xMXoiLz48L3N2Zz4="
|
viewBox="0 0 52 64"
|
||||||
title="Lock"
|
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>
|
</span>
|
||||||
)
|
)
|
||||||
</strong>
|
</strong>
|
||||||
or
|
or
|
||||||
<strong>
|
<strong>
|
||||||
|
@ -161,24 +183,11 @@ exports[`rendering of the DatasetContainer checks if various text fields are vis
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<div
|
<div>
|
||||||
class="usa-alert usa-alert--info"
|
<strong>
|
||||||
data-testid="alert"
|
This tool has been updated.
|
||||||
>
|
</strong>
|
||||||
<div
|
The 2.0 version of the tool was released on Dec 20, 2024.
|
||||||
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>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
|
|
|
@ -21,9 +21,11 @@ exports[`rendering of the Privacy Policy page matches Privacy Policy page snapsh
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="usa-banner__inner"
|
class="usa-banner__inner"
|
||||||
|
data-testid="banner-header-inner-div"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="grid-col-auto"
|
class="grid-col-auto"
|
||||||
|
data-testid="banner-header-flag-div"
|
||||||
>
|
>
|
||||||
<img
|
<img
|
||||||
alt="U.S. flag"
|
alt="U.S. flag"
|
||||||
|
@ -33,6 +35,7 @@ exports[`rendering of the Privacy Policy page matches Privacy Policy page snapsh
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="grid-col-fill tablet:grid-col-auto"
|
class="grid-col-fill tablet:grid-col-auto"
|
||||||
|
data-testid="banner-header-grid-div"
|
||||||
>
|
>
|
||||||
<p
|
<p
|
||||||
class="usa-banner__header-text"
|
class="usa-banner__header-text"
|
||||||
|
@ -114,19 +117,38 @@ exports[`rendering of the Privacy Policy page matches Privacy Policy page snapsh
|
||||||
<br />
|
<br />
|
||||||
A
|
A
|
||||||
<strong>
|
<strong>
|
||||||
lock (
|
lock (
|
||||||
<span
|
<span
|
||||||
class="icon-lock"
|
class="icon-lock"
|
||||||
>
|
>
|
||||||
<img
|
<svg
|
||||||
alt="lock"
|
aria-labelledby="banner-lock-title banner-lock-description"
|
||||||
class="usa-banner__lock-image"
|
class="usa-banner__lock-image"
|
||||||
|
focusable="false"
|
||||||
|
height="64"
|
||||||
role="img"
|
role="img"
|
||||||
src="data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz48c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjUyIiBoZWlnaHQ9IjY0IiB2aWV3Qm94PSIwIDAgNTIgNjQiPjx0aXRsZT5sb2NrPC90aXRsZT48cGF0aCBmaWxsPSIjMUIxQjFCIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik0yNiAwYzEwLjQ5MyAwIDE5IDguNTA3IDE5IDE5djloM2E0IDQgMCAwIDEgNCA0djI4YTQgNCAwIDAgMS00IDRINGE0IDQgMCAwIDEtNC00VjMyYTQgNCAwIDAgMSA0LTRoM3YtOUM3IDguNTA3IDE1LjUwNyAwIDI2IDB6bTAgOGMtNS45NzkgMC0xMC44NDMgNC43Ny0xMC45OTYgMTAuNzEyTDE1IDE5djloMjJ2LTljMC02LjA3NS00LjkyNS0xMS0xMS0xMXoiLz48L3N2Zz4="
|
viewBox="0 0 52 64"
|
||||||
title="Lock"
|
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>
|
</span>
|
||||||
)
|
)
|
||||||
</strong>
|
</strong>
|
||||||
or
|
or
|
||||||
<strong>
|
<strong>
|
||||||
|
@ -161,24 +183,11 @@ exports[`rendering of the Privacy Policy page matches Privacy Policy page snapsh
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<div
|
<div>
|
||||||
class="usa-alert usa-alert--info"
|
<strong>
|
||||||
data-testid="alert"
|
This tool has been updated.
|
||||||
>
|
</strong>
|
||||||
<div
|
The 2.0 version of the tool was released on Dec 20, 2024.
|
||||||
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>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
|
|
|
@ -21,9 +21,11 @@ exports[`rendering of the DatasetContainer checks if various text fields are vis
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="usa-banner__inner"
|
class="usa-banner__inner"
|
||||||
|
data-testid="banner-header-inner-div"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="grid-col-auto"
|
class="grid-col-auto"
|
||||||
|
data-testid="banner-header-flag-div"
|
||||||
>
|
>
|
||||||
<img
|
<img
|
||||||
alt="U.S. flag"
|
alt="U.S. flag"
|
||||||
|
@ -33,6 +35,7 @@ exports[`rendering of the DatasetContainer checks if various text fields are vis
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="grid-col-fill tablet:grid-col-auto"
|
class="grid-col-fill tablet:grid-col-auto"
|
||||||
|
data-testid="banner-header-grid-div"
|
||||||
>
|
>
|
||||||
<p
|
<p
|
||||||
class="usa-banner__header-text"
|
class="usa-banner__header-text"
|
||||||
|
@ -114,19 +117,38 @@ exports[`rendering of the DatasetContainer checks if various text fields are vis
|
||||||
<br />
|
<br />
|
||||||
A
|
A
|
||||||
<strong>
|
<strong>
|
||||||
lock (
|
lock (
|
||||||
<span
|
<span
|
||||||
class="icon-lock"
|
class="icon-lock"
|
||||||
>
|
>
|
||||||
<img
|
<svg
|
||||||
alt="lock"
|
aria-labelledby="banner-lock-title banner-lock-description"
|
||||||
class="usa-banner__lock-image"
|
class="usa-banner__lock-image"
|
||||||
|
focusable="false"
|
||||||
|
height="64"
|
||||||
role="img"
|
role="img"
|
||||||
src="data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz48c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjUyIiBoZWlnaHQ9IjY0IiB2aWV3Qm94PSIwIDAgNTIgNjQiPjx0aXRsZT5sb2NrPC90aXRsZT48cGF0aCBmaWxsPSIjMUIxQjFCIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik0yNiAwYzEwLjQ5MyAwIDE5IDguNTA3IDE5IDE5djloM2E0IDQgMCAwIDEgNCA0djI4YTQgNCAwIDAgMS00IDRINGE0IDQgMCAwIDEtNC00VjMyYTQgNCAwIDAgMSA0LTRoM3YtOUM3IDguNTA3IDE1LjUwNyAwIDI2IDB6bTAgOGMtNS45NzkgMC0xMC44NDMgNC43Ny0xMC45OTYgMTAuNzEyTDE1IDE5djloMjJ2LTljMC02LjA3NS00LjkyNS0xMS0xMS0xMXoiLz48L3N2Zz4="
|
viewBox="0 0 52 64"
|
||||||
title="Lock"
|
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>
|
</span>
|
||||||
)
|
)
|
||||||
</strong>
|
</strong>
|
||||||
or
|
or
|
||||||
<strong>
|
<strong>
|
||||||
|
@ -161,24 +183,11 @@ exports[`rendering of the DatasetContainer checks if various text fields are vis
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<div
|
<div>
|
||||||
class="usa-alert usa-alert--info"
|
<strong>
|
||||||
data-testid="alert"
|
This tool has been updated.
|
||||||
>
|
</strong>
|
||||||
<div
|
The 2.0 version of the tool was released on Dec 20, 2024.
|
||||||
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>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
|
|
Loading…
Add table
Reference in a new issue