Skip to content

Commit

Permalink
Merge pull request #1016 from greenriver/release-147
Browse files Browse the repository at this point in the history
Release 147
  • Loading branch information
gigxz authored Jan 23, 2025
2 parents 3f428ff + c483e3e commit a028a94
Show file tree
Hide file tree
Showing 30 changed files with 433 additions and 361 deletions.
2 changes: 1 addition & 1 deletion docker/templates/non_proxy_headers.conf.template
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,5 @@ add_header Strict-Transport-Security "max-age=63072000; includeSubdomains;" alwa
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Feature-Policy "geolocation 'self'; midi 'none'; notifications 'none'; push 'none'; sync-xhr 'none'; microphone 'none'; camera 'none'; magnetometer 'none'; gyroscope 'none'; speaker 'none'; vibrate 'none'; fullscreen 'none'; payment 'none'; usb 'none';";
add_header Feature-Policy "geolocation 'self'; midi 'none'; sync-xhr 'none'; microphone 'none'; camera 'none'; magnetometer 'none'; gyroscope 'none'; fullscreen 'none'; payment 'none'; usb 'none';";
add_header Permissions-Policy "geolocation=(self)";
11 changes: 10 additions & 1 deletion src/components/elements/ButtonTooltipContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,16 @@ const ButtonTooltipContainer = ({
if (!title) return children;

return (
<Tooltip title={title} placement='top' arrow {...props}>
<Tooltip
title={title}
placement='top'
// describeChild makes the tooltip text become the `title` of the direct child,
// which is a span in this case. Otherwise it would become the `aria-label` of
// the direct child, which is not valid for spans.
describeChild
arrow
{...props}
>
<span>{children}</span>
</Tooltip>
);
Expand Down
55 changes: 55 additions & 0 deletions src/components/elements/SkipToContentButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import { Button } from '@mui/material';
import { ReactNode } from 'react';

type SkipToContentProps = {
focusTargetId: string;
children?: ReactNode;
};

const SkipToContent: React.FC<SkipToContentProps> = ({
focusTargetId,
children,
}) => {
const handleClick = () => {
const container = document.getElementById(focusTargetId);
if (container) {
// First ensure the container is focusable
if (!container.hasAttribute('tabindex')) {
container.setAttribute('tabindex', '-1');
}
container.focus({ preventScroll: true });
}
};

return (
<Button
variant='contained'
onClick={handleClick}
sx={{
// Use `clip` to hide the button when it isn't focused, without preventing focus entirely (which display:none and visibility:hidden would do)
// `clip` is considered deprecated, but more widely supported than the more modern `clipPath`
clip: 'rect(0 0 0 0)',
clipPath: 'inset(50%)',

// Remove padding, border, and margin
padding: 0,
margin: 0,
border: 'none',
position: 'absolute', // Ensure it doesn't take up any space

'&:focus': {
// On focus, restore clip and other styles so the button is visible and styled normally
clip: 'auto',
clipPath: 'none',
position: 'relative',
padding: '8px 16px',
border: '1px solid',
},
}}
>
{children || 'Skip to Content'}
</Button>
);
};

export default SkipToContent;
8 changes: 7 additions & 1 deletion src/components/layout/BasicBreadcrumbPageLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { ReactNode } from 'react';

import { ContextHeaderAppBar } from './dashboard/contextHeader/ContextHeader';
import Breadcrumbs, { Breadcrumb } from '@/components/elements/Breadcrumbs';
import { FOCUSABLE_MAIN_TARGET_ID } from '@/components/layout/MainLayout';

const BasicBreadcrumbPageLayout = ({
crumbs,
Expand All @@ -21,7 +22,12 @@ const BasicBreadcrumbPageLayout = ({
<Breadcrumbs crumbs={crumbs} />
</Container>
</ContextHeaderAppBar>
<Container component='main' maxWidth={maxWidth} sx={{ pt: 2, pb: 6 }}>
<Container
component='main'
maxWidth={maxWidth}
sx={{ pt: 2, pb: 6 }}
id={FOCUSABLE_MAIN_TARGET_ID}
>
{children}
</Container>
</>
Expand Down
4 changes: 4 additions & 0 deletions src/components/layout/MainLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import PrintViewButton from './PrintViewButton';
import WarehouseLinkBar from './WarehouseLinkBar';

import Loading from '@/components/elements/Loading';
import SkipToContentButton from '@/components/elements/SkipToContentButton';
import MobileMenu from '@/components/layout/nav/MobileMenu';
import ToolbarMenu from '@/components/layout/nav/ToolbarMenu';
import { useIsDashboard } from '@/components/layout/nav/useIsDashboard';
Expand All @@ -29,6 +30,8 @@ interface Props {
children: React.ReactNode;
}

export const FOCUSABLE_MAIN_TARGET_ID = 'focusable-main';

const MainLayout: React.FC<Props> = ({ mobileMenuContext, children }) => {
const { appName } = useHmisAppSettings();
const isPrint = useIsPrintView();
Expand Down Expand Up @@ -99,6 +102,7 @@ const MainLayout: React.FC<Props> = ({ mobileMenuContext, children }) => {
sx={{ px: isMobile ? 1 : 3, minHeight: APP_BAR_HEIGHT }}
disableGutters={isMobile}
>
<SkipToContentButton focusTargetId={FOCUSABLE_MAIN_TARGET_ID} />
<RouterLink
variant='h1'
noWrap
Expand Down
2 changes: 2 additions & 0 deletions src/components/layout/PageContainer.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Typography } from '@mui/material';
import { Box, Container, Stack } from '@mui/system';
import { ReactNode } from 'react';
import { FOCUSABLE_MAIN_TARGET_ID } from '@/components/layout/MainLayout';
import { useIsMobile } from '@/hooks/useIsMobile';

const PageContainer = ({
Expand All @@ -15,6 +16,7 @@ const PageContainer = ({
const isTiny = useIsMobile('sm');
return (
<Container
id={FOCUSABLE_MAIN_TARGET_ID}
component='main'
maxWidth='lg'
sx={{ px: { xs: 1, sm: 3, lg: 4 }, pt: 4, pb: 6 }}
Expand Down
3 changes: 3 additions & 0 deletions src/components/layout/dashboard/DashboardContentContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { DESKTOP_NAV_SIDEBAR_WIDTH } from '../layoutConstants';
import ContextHeader from './contextHeader/ContextHeader';
import DashboardContentNav from './DashboardContentNav';

import { FOCUSABLE_MAIN_TARGET_ID } from '@/components/layout/MainLayout';
import { useIsMobile } from '@/hooks/useIsMobile';
import useMaxPageWidth from '@/hooks/useMaxPageWidth';
import SentryErrorBoundary from '@/modules/errors/components/SentryErrorBoundary';
Expand Down Expand Up @@ -85,6 +86,7 @@ const DashboardContentContainer: React.FC<Props> = ({
handleCloseMobileMenu={handleCloseMobileMenu}
handleCloseDesktopMenu={handleCloseDesktopMenu}
label={navLabel}
skipNavFocusTargetId={FOCUSABLE_MAIN_TARGET_ID}
>
{sidebar}
</DashboardContentNav>
Expand Down Expand Up @@ -121,6 +123,7 @@ const DashboardContentContainer: React.FC<Props> = ({
<Box
key='content'
component='main'
id={FOCUSABLE_MAIN_TARGET_ID}
sx={{
pt: 2,
pb: 8,
Expand Down
12 changes: 11 additions & 1 deletion src/components/layout/dashboard/DashboardContentNav.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
DESKTOP_NAV_SIDEBAR_WIDTH,
STICKY_BAR_HEIGHT,
} from '../layoutConstants';
import SkipToContentButton from '@/components/elements/SkipToContentButton';
import MobileMenu from '@/components/layout/nav/MobileMenu';

interface Props {
Expand All @@ -17,13 +18,16 @@ interface Props {
handleCloseMobileMenu: VoidFunction;
handleCloseDesktopMenu: VoidFunction;
label?: string;
skipNavFocusTargetId: string;
}

const CloseMenuRow = ({
onClose,
label,
skipNavFocusTargetId,
}: {
onClose: VoidFunction;
skipNavFocusTargetId: string;
label?: string;
}) => (
<Stack
Expand All @@ -46,6 +50,7 @@ const CloseMenuRow = ({
) : (
<Box />
)}
<SkipToContentButton focusTargetId={skipNavFocusTargetId} />
<Button
variant='text'
color='grayscale'
Expand All @@ -65,6 +70,7 @@ const DashboardContentNav: React.FC<Props> = ({
handleCloseMobileMenu,
handleCloseDesktopMenu,
label,
skipNavFocusTargetId,
}) => {
const headerHeight = `${STICKY_BAR_HEIGHT}px`;
const height = `calc(100vh - ${headerHeight})`;
Expand Down Expand Up @@ -110,7 +116,11 @@ const DashboardContentNav: React.FC<Props> = ({
})}
>
<Box component='nav' aria-label='sidebar-nav'>
<CloseMenuRow onClose={handleCloseDesktopMenu} label={label} />
<CloseMenuRow
onClose={handleCloseDesktopMenu}
label={label}
skipNavFocusTargetId={skipNavFocusTargetId}
/>
<Box
sx={{
pl: 3,
Expand Down
16 changes: 6 additions & 10 deletions src/modules/admin/components/forms/FormPreview.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Button, Grid } from '@mui/material';
import { Button } from '@mui/material';
import { Stack } from '@mui/system';
import { useCallback, useMemo, useRef, useState } from 'react';
import { generatePath } from 'react-router-dom';
Expand All @@ -19,16 +19,16 @@ import SentryErrorBoundary from '@/modules/errors/components/SentryErrorBoundary
import DynamicForm, {
DynamicFormRef,
} from '@/modules/form/components/DynamicForm';
import FormNavigation from '@/modules/form/components/FormNavigation';
import FormNavigationContainer from '@/modules/form/components/FormNavigationContainer';
import DynamicView from '@/modules/form/components/viewable/DynamicView';
import { FormValues } from '@/modules/form/types';
import {
AlwaysPresentLocalConstants,
createInitialValuesFromSavedValues,
createValuesForSubmit,
getFormStepperItems,
getInitialValues,
getItemMap,
createValuesForSubmit,
} from '@/modules/form/util/formUtil';
import { RootPermissionsFilter } from '@/modules/permissions/PermissionsFilters';
import { AdminDashboardRoutes } from '@/routes/routes';
Expand Down Expand Up @@ -207,13 +207,9 @@ const FormPreview = () => {
</Stack>

<SentryErrorBoundary>
{formStepperItems ? (
<Grid container spacing={2} sx={{ pb: 20, mt: 0 }}>
<FormNavigation items={formStepperItems}>{form}</FormNavigation>
</Grid>
) : (
form
)}
<FormNavigationContainer navItems={formStepperItems}>
{form}
</FormNavigationContainer>
</SentryErrorBoundary>
</>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,9 +89,7 @@ const ProjectConfigTable = ({
recordName='Project Config'
onSuccess={() => evictProjectConfigs()}
onlyIcon
>
Delete
</DeleteMutationButton>
/>
</Box>
),
},
Expand Down
Loading

0 comments on commit a028a94

Please sign in to comment.