Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
390 changes: 195 additions & 195 deletions CareTogetherCMS.sln

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions src/caretogether-pwa/src/AppRoutes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ import { InboxScreen } from './Inbox/InboxScreen';
import { FamilyScreenRoute } from './Families/FamilyScreenRoute';
import { ClientsScreenRoute } from './V1Cases/ClientsScreenRoute';
import { V1Referrals } from './V1Referrals/V1Referrals';
import { Volunteers } from './Volunteers/Volunteers';
import { VolunteersScreenRoute } from './Volunteers/VolunteersScreenRoute';
import { Communities } from './Communities/Communities';
import { Reports } from './Reports/Reports';
import { Settings } from './Settings/SettingsRoutes';
Expand Down Expand Up @@ -191,7 +191,7 @@ function AuthorizedLocationContextWrapper({
<Route path="clients/*" element={<ClientsScreenRoute />} />
<Route path="cases/*" element={<CasesToClientsRedirect />} />
<Route path="referrals/*" element={<V1Referrals />} />
<Route path="volunteers/*" element={<Volunteers />} />
<Route path="volunteers/*" element={<VolunteersScreenRoute />} />
<Route path="communities/*" element={<Communities />} />
<Route path="reports/*" element={<Reports />} />
<Route path="settings/*" element={<Settings />} />
Expand Down
4 changes: 2 additions & 2 deletions src/caretogether-pwa/src/Shell/shellLayoutConstants.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
const CHAT_WIDGET_SAFE_HEIGHT = 96;
const MOBILE_BOTTOM_NAV_HEIGHT = 56;
const CHAT_WIDGET_SAFE_HEIGHT = 90;
const DESKTOP_APP_BAR_HEIGHT = 48;
const TABLET_APP_BAR_HEIGHT = 64;
const MOBILE_APP_BAR_HEIGHT = 56;

export const EXPANDED_DRAWER_WIDTH = 190;
export const COLLAPSED_DRAWER_WIDTH = 48;
export const MOBILE_BOTTOM_NAV_HEIGHT = 56;

export const DESKTOP_BOTTOM_SAFE_AREA = CHAT_WIDGET_SAFE_HEIGHT;
export const MOBILE_BOTTOM_SAFE_AREA =
Expand Down
28 changes: 15 additions & 13 deletions src/caretogether-pwa/src/Utilities/wideTablePageSx.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,20 @@
const FEATUREBASE_CHAT_WIDGET_SAFE_HEIGHT = 96;
const MOBILE_BOTTOM_NAVIGATION_HEIGHT = 56;
const MOBILE_BOTTOM_SAFE_HEIGHT =
FEATUREBASE_CHAT_WIDGET_SAFE_HEIGHT + MOBILE_BOTTOM_NAVIGATION_HEIGHT;
import {
DESKTOP_BOTTOM_SAFE_AREA,
MOBILE_BOTTOM_NAV_HEIGHT,
MOBILE_BOTTOM_SAFE_AREA,
SHELL_APP_BAR_HEIGHT,
} from '../Shell/shellLayoutConstants';

function wideTablePageSx(hasFeaturebaseChat: boolean) {
const bottomOffset = hasFeaturebaseChat
? {
xs: `${MOBILE_BOTTOM_SAFE_HEIGHT}px`,
sm: `${MOBILE_BOTTOM_SAFE_HEIGHT}px`,
md: `${FEATUREBASE_CHAT_WIDGET_SAFE_HEIGHT}px`,
xs: `${MOBILE_BOTTOM_SAFE_AREA}px`,
sm: `${MOBILE_BOTTOM_SAFE_AREA}px`,
md: `${DESKTOP_BOTTOM_SAFE_AREA}px`,
}
: {
xs: `${MOBILE_BOTTOM_NAVIGATION_HEIGHT}px`,
sm: `${MOBILE_BOTTOM_NAVIGATION_HEIGHT}px`,
xs: `${MOBILE_BOTTOM_NAV_HEIGHT}px`,
sm: `${MOBILE_BOTTOM_NAV_HEIGHT}px`,
md: '0px',
};

Expand All @@ -21,9 +23,9 @@ function wideTablePageSx(hasFeaturebaseChat: boolean) {
flexDirection: 'column',
flexWrap: 'nowrap',
height: {
xs: `calc(100dvh - 56px - ${bottomOffset.xs})`,
sm: `calc(100dvh - 64px - ${bottomOffset.sm})`,
md: `calc(100dvh - 48px - ${bottomOffset.md})`,
xs: `calc(100dvh - ${SHELL_APP_BAR_HEIGHT.xs} - ${bottomOffset.xs})`,
sm: `calc(100dvh - ${SHELL_APP_BAR_HEIGHT.sm} - ${bottomOffset.sm})`,
md: `calc(100dvh - ${SHELL_APP_BAR_HEIGHT.md} - ${bottomOffset.md})`,
},
// ShellRootLayout always reserves Featurebase space; reclaim it when chat is hidden.
minHeight: 0,
Expand All @@ -36,7 +38,7 @@ function wideTablePageSx(hasFeaturebaseChat: boolean) {

return {
...sx,
marginBottom: `-${FEATUREBASE_CHAT_WIDGET_SAFE_HEIGHT}px`,
marginBottom: `-${DESKTOP_BOTTOM_SAFE_AREA}px`,
} as const;
}

Expand Down
23 changes: 9 additions & 14 deletions src/caretogether-pwa/src/V1Cases/ClientsBrowserToolbarV2.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import {
Sort as SortIcon,
} from '@mui/icons-material';
import {
Box,
Button,
FormControl,
InputAdornment,
Expand All @@ -15,13 +14,8 @@ import {
TextField,
} from '@mui/material';
import type { SelectChangeEvent } from '@mui/material/Select';
import type {
AssignedIndividualVolunteer,
Person,
} from '../GeneratedClient';
import type {
AssignmentFilterSelectionsByRole,
} from '../FunctionAssignments/assignmentRoleColumns';
import type { AssignedIndividualVolunteer, Person } from '../GeneratedClient';
import type { AssignmentFilterSelectionsByRole } from '../FunctionAssignments/assignmentRoleColumns';
import { AssignmentRoleFilters } from '../FunctionAssignments/AssignmentRoleFilters';
import { PartneringFamiliesSortMode } from './PartneringFamilies/sortPartneringFamilies';
import { ArrangementsFilter } from './PartneringFamilies/types';
Expand Down Expand Up @@ -88,14 +82,16 @@ export function ClientsBrowserToolbarV2({
assignmentRoles.length > 0 &&
!!assignmentPersonLookup &&
!!onAssignmentFilterChange;
const shouldRenderMoreFilters =
customFieldCount > 0 && !!onMoreFiltersClick;
const shouldRenderMoreFilters = customFieldCount > 0 && !!onMoreFiltersClick;

return (
<Stack
direction={{ xs: 'column', md: 'row' }}
spacing={1}
sx={{ alignItems: { xs: 'stretch', md: 'center' } }}
direction={{ xs: 'column', sm: 'row' }}
sx={{
alignItems: { xs: 'stretch', sm: 'center' },
flexWrap: { xs: 'nowrap', sm: 'wrap' },
gap: 1,
}}
>
<TextField
slotProps={{
Expand Down Expand Up @@ -196,7 +192,6 @@ export function ClientsBrowserToolbarV2({
More Filters ({activeCustomFieldFilterCount}/{customFieldCount})
</Button>
)}
<Box sx={{ flex: 1 }} />
</Stack>
);
}
12 changes: 5 additions & 7 deletions src/caretogether-pwa/src/V1Cases/ClientsScreenV2.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -160,17 +160,15 @@ export function ClientsScreenV2() {
<Box
sx={{
...wideTablePageSx(hasFeaturebaseChat),
boxSizing: 'border-box',
display: 'flex',
flexDirection: 'column',
gap: 2,
px: { xs: 2, md: 3 },
py: { xs: 2, md: 3 },
}}
>
<Stack spacing={2.5} sx={{ flex: 1, minHeight: 0 }}>
<Box>
<Typography className="ph-unmask" {...v2Typography.pageTitle}>
<Typography
className="ph-unmask"
{...v2Typography.pageTitle}
sx={{ mt: 2 }}
>
Clients
</Typography>
<Typography
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import { Box, Stack, Typography } from '@mui/material';
import { VolunteerRoleApprovalStatusChip } from './VolunteerRoleApprovalStatusChip';
import { VolunteerApprovalRolesPresentation } from './VolunteerApprovalTab/volunteerApprovalRolePresentation';

type Props = {
roles: VolunteerApprovalRolesPresentation;
};

function RoleChipList({
roles,
}: {
roles: VolunteerApprovalRolesPresentation['familyRoles'];
}) {
return (
<Box sx={{ display: 'flex', flexWrap: 'wrap' }}>
{roles.map((role) => (
<VolunteerRoleApprovalStatusChip
key={role.roleName}
sx={{ margin: '.125rem .25rem .125rem 0' }}
roleName={role.roleName}
status={role.status}
/>
))}
</Box>
);
}

export function VolunteerApprovalRolesCellV2({ roles }: Props) {
return (
<Stack spacing={0.5} sx={{ minWidth: 0, py: 0.5, width: '100%' }}>
<Box
sx={{
alignItems: 'flex-start',
display: 'grid',
gap: 1,
gridTemplateColumns: '80px minmax(0, 1fr)',
}}
>
<Typography sx={{ minWidth: 'max-content' }}>Family:</Typography>
<RoleChipList roles={roles.familyRoles} />
</Box>
<Box
sx={{
alignItems: 'flex-start',
display: 'grid',
gap: 1,
gridTemplateColumns: '80px minmax(0, 1fr)',
}}
>
<Typography sx={{ minWidth: 'max-content' }}>Individual:</Typography>
<RoleChipList roles={roles.individualRoles} />
</Box>
</Stack>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import Grid from '../../Generic/GridLegacyCompat';
import {
Box,
Checkbox,
Chip,
TableCell,
TableRow,
Typography,
Expand All @@ -17,7 +16,7 @@ import { VolunteerRoleApprovalStatusChip } from '../VolunteerRoleApprovalStatusC
import { familyLastName } from './familyLastName';
import { LazyLoadMountTrigger } from '../../Utilities/LazyLoadMountTrigger';
import { LazyLoad } from '../../Utilities/reactLazyLoadInterop';
import { sortByPolicyOrder } from '../../Generic/sortByPolicyOrder';
import { renderVolunteerCustomFieldValue } from './volunteerCustomFieldPresentation';

type VolunteerApprovalTableItemProps = {
volunteerFamily: CombinedFamilyInfo;
Expand All @@ -43,35 +42,6 @@ function getRowGroupHeight(
return 39 + (activeAdultsCount + activeChildrenCount) * 33;
}

function renderCustomFieldValue(
value: unknown,
validValues?: string[]
): React.ReactNode {
if (value === null || typeof value === 'undefined') {
return '';
}
if (value === true) {
return 'Yes';
}
if (value === false) {
return 'No';
}
if (Array.isArray(value)) {
const sortedValue =
validValues && validValues.length > 0
? sortByPolicyOrder(value.map(String), validValues)
: value;
return (
<Box sx={{ display: 'flex', flexWrap: 'wrap', gap: '.25rem' }}>
{sortedValue.map((item) => (
<Chip key={String(item)} size="small" label={String(item)} />
))}
</Box>
);
}
return String(value);
}

function VolunteerApprovalPlaceholderRow(
props: Pick<
VolunteerApprovalTableItemProps,
Expand Down Expand Up @@ -330,7 +300,7 @@ function VolunteerApprovalTableRows(props: VolunteerApprovalTableItemProps) {
familyCustomField?.value ?? volunteerFamilyCustomField?.value;
return (
<TableCell key={customFieldName}>
{renderCustomFieldValue(
{renderVolunteerCustomFieldValue(
familyCustomFieldValue,
fieldPolicy?.validValues
)}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,6 @@
import {
Checkbox,
FormControl,
InputBase,
ListItemText,
MenuItem,
Select,
SelectChangeEvent,
} from '@mui/material';
import { FilterList as FilterListIcon } from '@mui/icons-material';
import { Checkbox, ListItemText, Menu, MenuItem } from '@mui/material';
import { useState } from 'react';
import { VolunteerBrowserFilterButtonV2 } from '../VolunteerBrowserFilterButtonV2';
import { filterOption } from './filterOption';
type VolunteerFilterProps = {
label: string;
Expand All @@ -20,55 +13,34 @@ export function VolunteerFilter({
options,
setSelected,
}: VolunteerFilterProps) {
const [anchorEl, setAnchorEl] = useState<null | HTMLElement>(null);
const selectedCount = options.filter((option) => option.selected).length;
const displayText =
selectedCount === options.length
? label
: `${label} (${selectedCount}/${options.length})`;

const handleChange = (event: SelectChangeEvent<string[]>) => {
const allOptionKeysPlusSelectedOptionValue = event.target.value;
setSelected(allOptionKeysPlusSelectedOptionValue);
};
function handleOptionClick(option: filterOption) {
setSelected(options.map((option) => option.key).concat(option.value ?? ''));
}

return (
<FormControl
sx={{
position: 'relative',
minWidth: { xs: '100%', sm: 0 },
maxWidth: { xs: '100%', sm: '16rem' },
}}
>
<Select
labelId={`volunteer${label}Filter`}
sx={{
minWidth: { xs: '100%', sm: 0 },
maxWidth: '100%',
color: selectedCount === options.length ? '#bdbdbd' : null,
'& .MuiSelect-iconOpen': { transform: 'none' },
'& .MuiSelect-select': {
overflow: 'hidden',
textOverflow: 'ellipsis',
whiteSpace: 'nowrap',
},
}}
multiple
value={options.map((o) => o.key)}
variant="standard"
label={`${label} Filters`}
onChange={handleChange}
input={<InputBase />}
IconComponent={FilterListIcon}
SelectDisplayProps={{ title: displayText }}
renderValue={() => displayText}
<>
<VolunteerBrowserFilterButtonV2
activeCount={selectedCount}
label={label}
totalCount={options.length}
size="small"
onClick={(event) => setAnchorEl(event.currentTarget)}
/>
<Menu
anchorEl={anchorEl}
open={Boolean(anchorEl)}
onClose={() => setAnchorEl(null)}
>
{options.map((option) => (
<MenuItem key={option.key} value={option.value ?? ''}>
<MenuItem key={option.key} onClick={() => handleOptionClick(option)}>
<Checkbox checked={option.selected} />
<ListItemText primary={option.key} />
</MenuItem>
))}
</Select>
</FormControl>
</Menu>
</>
);
}
Loading
Loading