Skip to content

Commit

Permalink
[CNFT1-2939] List view sort options (#1769)
Browse files Browse the repository at this point in the history
* sorting preferences

* saving list sorting
  • Loading branch information
adamloup-enquizit authored and rkrusselenq committed Sep 9, 2024
1 parent 523cc08 commit 40987d4
Show file tree
Hide file tree
Showing 23 changed files with 660 additions and 139 deletions.
12 changes: 12 additions & 0 deletions apps/modernization-ui/src/apps/search/basic/BasicPatient.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import { Link } from 'react-router-dom';
import { displayName } from 'name';
import { asSelectableGender } from 'options/gender';
import { Mapping, Maybe } from 'utils';
import { SortingSelectable } from 'design-system/sorting/preferences';
import { Direction } from 'sorting';

type BasicPatient = {
birthTime?: string | null;
Expand All @@ -28,3 +30,13 @@ const displayProfileLink = (patient: Maybe<BasicPatient>) => (
const displayGender = (patient: Maybe<BasicPatient>) => asSelectableGender(patient?.currSexCd)?.name;

export { withPatient, displayProfileLink, displayGender };

const sorting: SortingSelectable[] = [
{ property: 'relavance', direction: Direction.Descending, name: 'Closest match' },
{ property: 'legalName', direction: Direction.Ascending, name: 'Patient name (A-Z)' },
{ property: 'legalName', direction: Direction.Descending, name: 'Patient name (Z-A)' },
{ property: 'birthday', direction: Direction.Ascending, name: 'Date of birth (Ascending)' },
{ property: 'birthday', direction: Direction.Descending, name: 'Date of birth (Descending)' }
];

export { sorting };
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import { findByValue } from 'options';
import { SearchLayout, SearchResultList } from 'apps/search/layout';
import { useSearchResultDisplay } from 'apps/search/useSearchResultDisplay';
import { Investigation } from 'generated/graphql/schema';
import { SortingPreferenceProvider } from 'design-system/sorting/preferences';
import { sorting } from 'apps/search/basic';
import { InvestigationSearchResultListItem } from './result/list';
import { InvestigationSearchForm } from './InvestigationSearchForm';
import { InvestigationFilterEntry } from './InvestigationFormTypes';
Expand Down Expand Up @@ -34,32 +36,34 @@ const InvestigationSearch = () => {

return (
<ColumnPreferenceProvider id="search.investigations.preferences.columns" defaults={preferences}>
<FormProvider {...form}>
<SearchLayout
onRemoveTerm={handleRemoveTerm}
criteria={() => <InvestigationSearchForm />}
resultsAsList={() => (
<SearchResultList<Investigation>
results={results}
render={(result) => (
<InvestigationSearchResultListItem
result={result}
notificationStatusResolver={notificationStatusResolver}
/>
)}
/>
)}
resultsAsTable={() => (
<InvestigationSearchResultsTable
results={results}
notificationStatusResolver={notificationStatusResolver}
/>
)}
searchEnabled={enabled}
onSearch={search}
onClear={clear}
/>
</FormProvider>
<SortingPreferenceProvider id="search.investigations.preferences.sorting" available={sorting}>
<FormProvider {...form}>
<SearchLayout
onRemoveTerm={handleRemoveTerm}
criteria={() => <InvestigationSearchForm />}
resultsAsList={() => (
<SearchResultList<Investigation>
results={results}
render={(result) => (
<InvestigationSearchResultListItem
result={result}
notificationStatusResolver={notificationStatusResolver}
/>
)}
/>
)}
resultsAsTable={() => (
<InvestigationSearchResultsTable
results={results}
notificationStatusResolver={notificationStatusResolver}
/>
)}
searchEnabled={enabled}
onSearch={search}
onClear={clear}
/>
</FormProvider>
</SortingPreferenceProvider>
</ColumnPreferenceProvider>
);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import { SearchLayout, SearchResultList } from 'apps/search/layout';
import { removeTerm } from 'apps/search/terms';
import { useSearchResultDisplay } from 'apps/search/useSearchResultDisplay';
import { LabReport } from 'generated/graphql/schema';
import { SortingPreferenceProvider } from 'design-system/sorting/preferences';
import { sorting } from 'apps/search/basic';
import { useLaboratoryReportSearch } from './useLaboratoryReportSearch';
import { LabReportFilterEntry, initial as defaultValues } from './labReportFormTypes';
import { LaboratoryReportSearchResultListItem } from './result/list';
Expand Down Expand Up @@ -34,26 +36,31 @@ const LaboratoryReportSearch = () => {

return (
<ColumnPreferenceProvider id="search.laboratory-reports.preferences.columns" defaults={preferences}>
<FormProvider {...form}>
<SearchLayout
onRemoveTerm={handleRemoveTerm}
criteria={() => <LaboratoryReportSearchCriteria />}
resultsAsList={() => (
<SearchResultList<LabReport>
results={results}
render={(result) => (
<LaboratoryReportSearchResultListItem result={result} jurisdictionResolver={findById} />
)}
/>
)}
resultsAsTable={() => (
<LaboratoryReportSearchResultsTable results={results} jurisdictionResolver={findById} />
)}
searchEnabled={enabled}
onSearch={search}
onClear={clear}
/>
</FormProvider>
<SortingPreferenceProvider id="search.laboratory-reports.preferences.sorting" available={sorting}>
<FormProvider {...form}>
<SearchLayout
onRemoveTerm={handleRemoveTerm}
criteria={() => <LaboratoryReportSearchCriteria />}
resultsAsList={() => (
<SearchResultList<LabReport>
results={results}
render={(result) => (
<LaboratoryReportSearchResultListItem
result={result}
jurisdictionResolver={findById}
/>
)}
/>
)}
resultsAsTable={() => (
<LaboratoryReportSearchResultsTable results={results} jurisdictionResolver={findById} />
)}
searchEnabled={enabled}
onSearch={search}
onClear={clear}
/>
</FormProvider>
</SortingPreferenceProvider>
</ColumnPreferenceProvider>
);
};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,62 +1,32 @@
import { ButtonActionMenu } from 'components/ButtonActionMenu/ButtonActionMenu';
import styles from './search-results-list-options.module.scss';
import { Direction, useSorting } from 'sorting';
import { SortField } from 'generated/graphql/schema';
import { useEffect } from 'react';
import { Button } from 'components/button';
import { Icon } from 'design-system/icon';
import classNames from 'classnames';
import { SortingPreferencesPanel } from 'design-system/sorting/preferences';
import { OverlayPanel } from 'overlay';

import styles from './search-results-list-options.module.scss';

type Props = {
disabled?: boolean;
};

const SearchResultsListOptions = ({ disabled = false }: Props) => {
const { sortBy, property, direction } = useSorting();

const savePreferences = (selection: SortField, direction: Direction) => {
localStorage.setItem('searchResultsSortBy', selection);
localStorage.setItem('searchResultsSortDirection', direction);
};

useEffect(() => {
const sortName = localStorage.getItem('searchResultsSortBy');
const sortDirection = localStorage.getItem('searchResultsSortDirection');

if (sortName && sortDirection) {
sortBy(sortName, sortDirection as Direction);
}
}, []);

const isActive = (field: SortField, dir: Direction) => property === field && direction === dir;

const renderSortButton = (field: SortField, dir: Direction, label: string) => (
<Button
className={classNames(styles.optionItem, { [styles.active]: isActive(field, dir) })}
icon={isActive(field, dir) ? <Icon name="check" className={styles.check} /> : undefined}
labelPosition="right"
type="button"
onClick={() => {
sortBy(field, dir);
savePreferences(field, dir);
}}>
{label}
</Button>
);

return (
<ButtonActionMenu
className={styles.option}
ariaLabel="Sort by list"
outline
icon={<Icon className={styles.sortArrow} name="sort_arrow" />}
disabled={disabled}>
{renderSortButton(SortField.Relevance, Direction.Descending, 'Closest match')}
{renderSortButton(SortField.LastNm, Direction.Ascending, 'Patient name (A-Z)')}
{renderSortButton(SortField.LastNm, Direction.Descending, 'Patient name (Z-A)')}
{renderSortButton(SortField.BirthTime, Direction.Ascending, 'Date of birth (Ascending)')}
{renderSortButton(SortField.BirthTime, Direction.Descending, 'Date of birth (Descending)')}
</ButtonActionMenu>
<OverlayPanel
className={styles.options}
position="right"
toggle={({ toggle }) => (
<Button
className={styles.opener}
aria-label="Sort settings"
data-tooltip-position="top"
outline
disabled={disabled}
icon={<Icon name="sort_arrow" className={styles.icon} />}
onClick={toggle}
/>
)}
render={(close) => <SortingPreferencesPanel onClose={close} />}
/>
);
};

Expand Down
Original file line number Diff line number Diff line change
@@ -1,26 +1,14 @@
@use 'styles/colors.scss';

.option {
.sortArrow {
width: 1.75rem;
height: 1.75rem;
margin: 0;
fill: colors.$primary;
}
.options {
--modal-min-width: max-content;
}

.optionItem {
padding: 0.625rem 2.75rem !important;
gap: 0.5rem !important;
.opener {
color: colors.$primary;

&.active {
padding: 0.625rem 1rem !important;

.check {
width: 1.25rem;
height: 1.25rem;
margin: 0 !important;
fill: colors.$primary;
}
.icon {
width: 1.75rem;
height: 1.75rem;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,6 @@ $content-height: calc($search-height - $navigation-height - 3rem);

background-color: colors.$base-white;

overflow-y: clip;

@include borders.bordered();
@include borders.rounded();

Expand Down
40 changes: 22 additions & 18 deletions apps/modernization-ui/src/apps/search/patient/PatientSearch.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import { ColumnPreferenceProvider } from 'design-system/table/preferences';
import { SearchLayout, SearchResultList } from 'apps/search/layout';
import { Term, useSearchResultDisplay } from 'apps/search';
import { PatientSearchResult } from 'generated/graphql/schema';
import { SortingPreferenceProvider } from 'design-system/sorting/preferences';
import { sorting } from 'apps/search/basic';
import { usePatientSearch } from './usePatientSearch';
import { PatientSearchResultListItem } from './result/list';
import { NoPatientResults } from './result/none';
Expand Down Expand Up @@ -37,24 +39,26 @@ const PatientSearch = () => {

return (
<ColumnPreferenceProvider id="search.patients.preferences.columns" defaults={preferences}>
<FormProvider {...form}>
<SearchLayout
onRemoveTerm={handleRemoveTerm}
actions={() => <PatientSearchActions />}
criteria={() => <PatientCriteria />}
resultsAsList={() => (
<SearchResultList<PatientSearchResult>
results={results}
render={(result) => <PatientSearchResultListItem result={result} />}
/>
)}
resultsAsTable={() => <PatientSearchResultTable results={results} />}
searchEnabled={enabled}
onSearch={search}
noResults={() => <NoPatientResults />}
onClear={clear}
/>
</FormProvider>
<SortingPreferenceProvider id="search.patients.preferences.sorting" available={sorting}>
<FormProvider {...form}>
<SearchLayout
onRemoveTerm={handleRemoveTerm}
actions={() => <PatientSearchActions />}
criteria={() => <PatientCriteria />}
resultsAsList={() => (
<SearchResultList<PatientSearchResult>
results={results}
render={(result) => <PatientSearchResultListItem result={result} />}
/>
)}
resultsAsTable={() => <PatientSearchResultTable results={results} />}
searchEnabled={enabled}
onSearch={search}
noResults={() => <NoPatientResults />}
onClear={clear}
/>
</FormProvider>
</SortingPreferenceProvider>
</ColumnPreferenceProvider>
);
};
Expand Down
6 changes: 4 additions & 2 deletions apps/modernization-ui/src/design-system/icon/Icon.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,18 @@ import { SVGProps as ReactSVGProps } from 'react';
import uswds from '@uswds/uswds/img/sprite.svg';
import classNames from 'classnames';

import styles from './icon.module.scss';

type Icons = USWDSIcons | ExtendedIcons;

type Props = { name: Icons } & ReactSVGProps<SVGSVGElement>;

const Icon = ({ name, role = 'img', ...props }: Props) => {
const Icon = ({ name, role = 'img', className, ...props }: Props) => {
const location = resolveLocation(name);

return (
<svg
className={classNames(props.className)}
className={classNames(styles.icon, className)}
role={role}
aria-hidden={props['aria-hidden'] || !props['aria-label'] || !props['aria-labelledby']}
{...props}>
Expand Down
5 changes: 5 additions & 0 deletions apps/modernization-ui/src/design-system/icon/icon.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
.icon {
width: 1rem;
height: 1rem;
fill: currentColor;
}
Loading

0 comments on commit 40987d4

Please sign in to comment.