Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

VACMS 20307 flippered Facility Locator Progressive Disclosure #34665

Merged
merged 36 commits into from
Feb 26, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
7855f5a
change
eselkin Feb 4, 2025
dbf655c
work on prog
eselkin Feb 5, 2025
5e856dc
working flipper
eselkin Feb 11, 2025
4beb339
fix
eselkin Feb 11, 2025
fc05586
checking error parity with prod
eselkin Feb 11, 2025
7f15113
checking error parity with prod
eselkin Feb 11, 2025
82de822
Merge branch 'main' into VACMS-20307-restore-behavior-add-flag
eselkin Feb 12, 2025
a1b0592
fix resize observer
eselkin Feb 12, 2025
da45a82
sizes
eselkin Feb 13, 2025
7d2d8e5
fix tests
eselkin Feb 13, 2025
ed7d5b5
true vs false in errors
eselkin Feb 13, 2025
1bca3a1
fix tests;
eselkin Feb 13, 2025
43b7875
clean up and fix tests - with flipper on off
eselkin Feb 13, 2025
0df1c1d
Merge branch 'main' into VACMS-20307-restore-behavior-add-flag
eselkin Feb 13, 2025
baf1c77
clean up and fix tests - with flipper on off - last commit cleared al…
eselkin Feb 13, 2025
936c018
fix test
eselkin Feb 14, 2025
41ca1af
cleanup spacing a bit on errors
eselkin Feb 14, 2025
eac6f0a
Merge branch 'main' into VACMS-20307-restore-behavior-add-flag
eselkin Feb 14, 2025
ec95892
test update
eselkin Feb 14, 2025
f5e48f9
changed text on PPMS typeahead error pursuant to figma, changed test
eselkin Feb 14, 2025
86e8853
combine new mobile maps and prog disclosure
eselkin Feb 14, 2025
9c5d029
Merge branch 'main' into VACMS-20307-restore-behavior-add-flag
eselkin Feb 14, 2025
28aed04
map
eselkin Feb 17, 2025
a9d3ce6
optional
eselkin Feb 17, 2025
4f83845
destructuring to simplify
eselkin Feb 17, 2025
f3fd057
removed //removed comment
eselkin Feb 17, 2025
f52f089
merge
eselkin Feb 18, 2025
d724e48
providers
eselkin Feb 19, 2025
2aa93aa
resolve merge conflicts
eselkin Feb 19, 2025
36a4c35
fixing tests - now a lot more tests
eselkin Feb 21, 2025
506cb2e
cleanup
eselkin Feb 21, 2025
f8275c0
fixing tests
eselkin Feb 21, 2025
fece24c
fix test?
eselkin Feb 24, 2025
313e0b3
documentation of featureTogglesToTest
eselkin Feb 24, 2025
3f324d1
fixed tests - used more helpers
eselkin Feb 25, 2025
8251468
delay geolocation result check
eselkin Feb 26, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,7 @@
"local-storage-fallback": "^4.1.2",
"lodash": "^4.17.21",
"mapbox-gl": "^1.12.0",
"mapbox-gl-v3": "npm:mapbox-gl@^3.9.4",
"markdown-it": "^12.3.2",
"markdown-it-link-attributes": "^4.0.0",
"moment": "~2.29.4",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,11 @@ const mbxClient = mbxGeo(mapboxClient);
* @param {Object<T>} query Current searchQuery state (`searchQuery.searchString` at a minimum)
* @returns {Function<T>} A thunk for Redux to process OR a failure action object on bad input
*/
export const genBBoxFromAddress = (query, expandedRadius = false) => {
export const genBBoxFromAddress = (
query,
expandedRadius = false,
useProgressiveDisclosure = false,
) => {
// Prevent empty search request to Mapbox, which would result in error, and
// clear results list to respond with message of no facilities found.
if (!query.searchString) {
Expand Down Expand Up @@ -93,6 +97,7 @@ export const genBBoxFromAddress = (query, expandedRadius = false) => {
? features
: [{ ...features[0], bbox: minBounds }],
query?.facilityType === 'provider',
useProgressiveDisclosure,
);
dispatch({
type: SEARCH_QUERY_UPDATED,
Expand Down
7 changes: 6 additions & 1 deletion src/applications/facility-locator/api/LocatorApi.js
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,12 @@ class LocatorApi {
fetch(url, api.settings)
.then(res => res.json())
.then(
data => resolve(data.data.map(specialty => specialty.attributes)),
data => {
if (data.errors?.length) {
return reject(data.errors[0]);
}
return resolve(data.data.map(specialty => specialty.attributes));
},
error => reject(error),
);
});
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import React from 'react';
import PropTypes from 'prop-types';

function ControlResultsHolder({ children, isSmallDesktop }) {
// If the screen is smaller than small desktop we just return the children
if (!isSmallDesktop) {
return children;
}

return <div id="vertical-oriented-left-controls">{children}</div>;
}

ControlResultsHolder.propTypes = {
children: PropTypes.node.isRequired,
isSmallDesktop: PropTypes.bool.isRequired,
};

export default ControlResultsHolder;
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import React from 'react';
import PropTypes from 'prop-types';

function ControlsAndMapContainer({ children, isSmallDesktop }) {
// If the screen is smaller than small desktop we just return the children
if (!isSmallDesktop) {
return children;
}

return <div id="controls-and-map-container">{children}</div>;
}

ControlsAndMapContainer.propTypes = {
children: PropTypes.node.isRequired,
isSmallDesktop: PropTypes.bool.isRequired,
};

export default ControlsAndMapContainer;
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import React from 'react';
import PropTypes from 'prop-types';

function EmergencyCareAlert({ shouldShow = false }) {
if (!shouldShow) {
return null;
}
return (
<va-alert
slim
full-width
status="info"
class="vads-u-margin-top--1"
data-testid="emergency-care-info-note"
id="emergency-care-info-note"
>
<strong>Note:</strong> If you think your life or health is in danger, call{' '}
<va-telephone contact="911" /> or go to the nearest emergency department
right away.
</va-alert>
);
}

EmergencyCareAlert.propTypes = {
shouldShow: PropTypes.bool,
};

export default EmergencyCareAlert;
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import React, { useEffect, useRef } from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { setFocus } from '../utils/helpers';

function PpmsServiceError({ currentQuery }) {
const shownAlert = useRef(null);
useEffect(
() => {
if (
shownAlert.current &&
currentQuery?.fetchSvcsError &&
!shownAlert.current.hasAttribute('tabindex')
) {
setTimeout(() => {
// We need the timeout because the alert is rendered after the error is set
// and we need to wait for the alert to be rendered before setting focus
// Also, the required field (facilityType) steals focus immediately no matter how it is set
setFocus(shownAlert.current);
}, 50);
}
},
[shownAlert, currentQuery],
);
if (currentQuery?.fetchSvcsError) {
return (
<va-alert
status="error"
class="vads-u-margin-bottom--4"
id="fetch-ppms-services-error"
ref={shownAlert}
>
<h2 slot="headline">We’ve run into a problem</h2>
<p className="vads-u-margin-y--0">
Community provider searches aren’t working right now. Try again later.
</p>
</va-alert>
);
}
return null;
}

PpmsServiceError.propTypes = {
currentQuery: PropTypes.object,
};

const mapStateToProps = state => {
return {
currentQuery: state.searchQuery,
};
};

export default connect(mapStateToProps)(PpmsServiceError);
98 changes: 98 additions & 0 deletions src/applications/facility-locator/components/RenderMap.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
import PropTypes from 'prop-types';
import React, { forwardRef, useEffect } from 'react';
import SearchAreaControl from './SearchAreaControl';

// renderMap does not consider progressive disclosure flipper internally
const RenderMap = forwardRef(
(
{
currentQuery,
handleSearchArea,
isSearching,
mapboxGlContainer,
map,
mobile,
mobileMapUpdateEnabled,
results,
searchAreaButtonEnabled,
selectMobileMapPin,
shouldRenderSearchArea,
smallDesktop,
zoomMessageDivID,
},
ref,
) => {
useEffect(
() => {
if (map) {
map.resize();
}
},
[map],
);
const speakMapInstructions = () => {
const mapInstructionsElement = document.getElementById(
'map-instructions',
);

if (mapInstructionsElement) {
mapInstructionsElement.innerText =
'Search areas on the map up to a maximum of 500 miles. ' +
'Zoom in or out using the zoom in and zoom out buttons. ' +
'Use a keyboard to navigate up, down, left, and right in the map.';
}
};

return (
<>
{!isSearching && (results?.length || 0) > 0 ? (
<h2 className="sr-only">Map of Results</h2>
) : null}
<div id={zoomMessageDivID} aria-live="polite" className="sr-only" />
<p className="sr-only" id="map-instructions" aria-live="assertive" />
<div
id={mapboxGlContainer}
role="application"
aria-label="Find VA locations on an interactive map"
aria-describedby="map-instructions"
onFocus={() => speakMapInstructions()}
ref={ref}
className={
mobile
? 'mobile'
: `${smallDesktop ? 'desktop' : 'tablet'}-map-container`
}
>
{shouldRenderSearchArea && (
<SearchAreaControl
handleSearchArea={handleSearchArea}
isMobile={mobile}
isEnabled={searchAreaButtonEnabled}
mobileMapUpdateEnabled={mobileMapUpdateEnabled}
query={currentQuery}
selectMobileMapPin={selectMobileMapPin}
/>
)}
</div>
</>
);
},
);

RenderMap.propTypes = {
currentQuery: PropTypes.object,
handleSearchArea: PropTypes.func,
isSearching: PropTypes.bool,
map: PropTypes.object,
mapboxGlContainer: PropTypes.string,
mobile: PropTypes.bool,
mobileMapUpdateEnabled: PropTypes.bool,
results: PropTypes.array,
searchAreaButtonEnabled: PropTypes.bool,
selectMobileMapPin: PropTypes.func,
shouldRenderSearchArea: PropTypes.bool,
smallDesktop: PropTypes.bool,
zoomMessageDivID: PropTypes.string,
};

export default RenderMap;
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
})),
);
},
[results],

Check warning on line 41 in src/applications/facility-locator/components/ResultsList.jsx

View workflow job for this annotation

GitHub Actions / Linting (Files Changed)

src/applications/facility-locator/components/ResultsList.jsx:41:5:React Hook useEffect has missing dependencies: 'currentPage' and 'searchString'. Either include them or remove the dependency array. If 'setResultsData' needs the current value of 'searchString', you can also switch to useReducer instead of useState and read 'searchString' in the reducer.
);

useEffect(
Expand All @@ -47,7 +47,7 @@
recordSearchResultsEvents(props, resultsData);
}
},
[resultsData],

Check warning on line 50 in src/applications/facility-locator/components/ResultsList.jsx

View workflow job for this annotation

GitHub Actions / Linting (Files Changed)

src/applications/facility-locator/components/ResultsList.jsx:50:5:React Hook useEffect has a missing dependency: 'props'. Either include it or remove the dependency array.
);

/**
Expand Down Expand Up @@ -130,7 +130,7 @@
pagination: PropTypes.object,
query: PropTypes.object,
results: PropTypes.array,
searchError: PropTypes.shape(PropTypes.any),
searchError: PropTypes.string,
searchResultMessageRef: PropTypes.object,
searchString: PropTypes.string,
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ const SearchAreaControl = ({
return `${mobileClass} ${radiusClass}`;
};

const buttonClass = `usa-button${!isEnabled ? ' fl-disabled' : ''}`;
const buttonClass = `${!isEnabled ? ' fl-disabled' : ''}`;

const handleClick = e => {
if (e) e.preventDefault();
Expand All @@ -45,8 +45,9 @@ const SearchAreaControl = ({
return (
<div id="search-area-control-container" className={containerClass()}>
<va-button
key={`search-area-control-${isEnabled}`}
id="search-area-control"
className={buttonClass}
class={buttonClass}
text={buttonLabel()}
disabled={!isEnabled}
ariaLive="assertive"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import React from 'react';
import PropTypes from 'prop-types';

function BottomRow({ isSmallDesktop, children }) {
if (isSmallDesktop) {
return <div id="search-controls-bottom-row">{children}</div>;
}
return children;
}

BottomRow.propTypes = {
children: PropTypes.node.isRequired,
isSmallDesktop: PropTypes.bool,
};

export default BottomRow;
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ function Autosuggest({
stateReducer = srClearOnBlur,
isLoading = false,
loadingMessage = '',
useProgressiveDisclosure,
AutosuggestOptionComponent = AutosuggestOption,
}) {
const {
Expand Down Expand Up @@ -76,7 +77,11 @@ function Autosuggest({
'usa-input-error': showError,
})}
>
<div className={`${inputId}-autosuggest-label-container`}>
<div
className={`${inputId}-autosuggest-label-container ${
useProgressiveDisclosure ? 'fl-sm-desktop' : ''
}`}
>
<label className={`${inputId}-label`} {...getLabelProps()}>
{label}
</label>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,18 @@ div[id$="-autosuggest-container"] {
padding-top: 0; // matching style to VaSelect use of usa-error
right: 0;
}
@media (min-width: $small-desktop-screen) {
&.usa-input-error {
margin-left: -0.9rem; // matching Facility Type - can override
}
}
div[class$="-autosuggest-label-container"] {

div[class*="autosuggest-label-container"] {
display: flex;
flex-direction: column;
width: 100%;

@media (min-width: $small-desktop-screen) {
flex-direction: row;
&.fl-sm-desktop {
flex-direction: column;
align-items: flex-start;
}
}
}

Expand All @@ -31,7 +31,7 @@ div[id$="-autosuggest-container"] {
font-size: 1rem;
height: 2.625rem;
line-height: 1.3;
margin: 0.5rem 0 1.875rem;
margin: 0;
position: relative;
width: 100%;

Expand All @@ -53,10 +53,6 @@ div[id$="-autosuggest-container"] {
box-shadow: 0px 2px 6px 1px var(--vads-color-black),
0px 4px 4px 0px var(--vads-color-darker);

@media (min-width: $small-desktop-screen) {
width: 418px;
}

.dropdown-option {
z-index: 1011;
border: 2px solid var(--vads-color-white);
Expand Down
Loading
Loading