Skip to content

Commit a4e047a

Browse files
authored
Merge branch 'dev' into delete-unused-files
2 parents 5277677 + e6bcf04 commit a4e047a

32 files changed

Lines changed: 607 additions & 440 deletions

Makefile

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,11 @@ endif
88
start:
99
docker compose -f docker-compose.nginx.yml up
1010

11+
12+
create-migrations:
13+
make clean-cache
14+
docker compose -f docker-compose.nginx.yml run php php bin/console doctrine:migrations:diff
15+
1116
# set up the database
1217
migrate:
1318
docker compose -f docker-compose.nginx.yml run php php bin/console doctrine:migrations:migrate

assets/css/udoit4-theme.css

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -536,16 +536,15 @@
536536
outline: 2px solid var(--focus-color);
537537
}
538538

539-
540-
dialog {
539+
dialog,
540+
div[role="dialog"] {
541541
width: 90vw;
542542
max-width: 50em;
543543
overflow: hidden;
544544
box-sizing: border-box;
545545
border: none;
546546
border-radius: var(--window-radius);
547547
padding: 0;
548-
background-color: var(--white);
549548
z-index: 100;
550549
box-shadow: 0 0 10px var(--shadow-color);
551550

@@ -554,6 +553,23 @@
554553
max-width: 95vw;
555554
height: 95vh;
556555
max-height: 95vh;
556+
position: fixed;
557+
top: 2vh;
558+
}
559+
560+
&::before {
561+
content: "";
562+
position: fixed;
563+
top: 0;
564+
left: 0;
565+
width: 100vw;
566+
height: 100vh;
567+
background-color: var(--backdrop-color);
568+
z-index: -1;
569+
}
570+
571+
> * {
572+
background-color: var(--white);
557573
}
558574

559575
.dialog-header,
@@ -1305,6 +1321,10 @@
13051321
overflow-wrap: anywhere;
13061322
cursor: pointer;
13071323
}
1324+
1325+
.hidden {
1326+
display: none !important;
1327+
}
13081328
}
13091329

13101330
/* The separator class is for a horizontal line with text in the middle on various forms */

assets/js/Components/App.js

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ export default function App(initialData) {
4141
const [sessionIssues, setSessionIssues] = useState({})
4242
const [sessionFiles, setSessionFiles] = useState({})
4343
const [welcomeClosed, setWelcomeClosed] = useState(false)
44+
const [modalActive, setModalActive] = useState(false)
4445

4546
// `t` is used for text/translation. It will return the translated string if it exists
4647
// in the settings.labels object.
@@ -369,7 +370,8 @@ export default function App(initialData) {
369370
className={`flex-column flex-grow-1 `
370371
+ `${settings?.user?.roles?.font_size || settings.DEFAULT_USER_SETTINGS.FONT_SIZE} `
371372
+ `${settings?.user?.roles?.font_family || settings.DEFAULT_USER_SETTINGS.FONT_FAMILY} `
372-
+ `${settings?.user?.roles?.dark_mode ? 'dark-mode' : ''}`}>
373+
+ `${settings?.user?.roles?.dark_mode ? 'dark-mode' : ''}`}
374+
lang={settings?.user?.roles?.lang || settings.DEFAULT_USER_SETTINGS.LANGUAGE}>
373375
{ !welcomeClosed ?
374376
( <WelcomePage
375377
t={t}
@@ -381,10 +383,10 @@ export default function App(initialData) {
381383
<Header
382384
t={t}
383385
settings={settings}
384-
hasNewReport={hasNewReport}
386+
modalActive={modalActive}
385387
navigation={navigation}
386-
syncComplete={syncComplete}
387388
handleNavigation={handleNavigation}
389+
syncComplete={syncComplete}
388390
/>
389391

390392
<main role="main" id="main-content">
@@ -416,6 +418,7 @@ export default function App(initialData) {
416418
sessionIssues={sessionIssues}
417419
updateSessionIssue={updateSessionIssue}
418420
processServerError={processServerError}
421+
setModalActive={setModalActive}
419422
/>
420423
}
421424
{('reviewFiles' === navigation) &&
@@ -432,6 +435,7 @@ export default function App(initialData) {
432435
sessionFiles={sessionFiles}
433436
updateSessionFiles={updateSessionFiles}
434437
processServerError={processServerError}
438+
setModalActive={setModalActive}
435439
/>
436440
}
437441
{('reports' === navigation) &&

assets/js/Components/FixIssuesPage.js

Lines changed: 62 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import FixIssuesContentPreview from './Widgets/FixIssuesContentPreview'
77
import LeftArrowIcon from './Icons/LeftArrowIcon'
88
import RightArrowIcon from './Icons/RightArrowIcon'
99
import CloseIcon from './Icons/CloseIcon'
10-
import { FORM_CLASSIFICATIONS, formFromIssue, formNameFromRule, formNames } from '../Services/Ufixit'
10+
import { formNameFromRule } from '../Services/Ufixit'
1111
import * as Html from '../Services/Html'
1212
import Api from '../Services/Api'
1313

@@ -34,14 +34,14 @@ export default function FixIssuesPage({
3434
initialSeverity = '',
3535
initialSearchTerm = '',
3636
contentItemCache,
37-
addContentItemToCache,
3837
report,
3938
sections,
4039
processNewReport,
4140
addMessage,
4241
sessionIssues,
4342
updateSessionIssue,
44-
processServerError
43+
processServerError,
44+
setModalActive
4545
})
4646
{
4747

@@ -66,9 +66,10 @@ export default function FixIssuesPage({
6666

6767
const WIDGET_STATE = settings.WIDGET_STATE
6868

69-
const dialogId = "issue-dialog"
69+
const dialogId = "udoit-issue-dialog"
7070

7171
const [activeIssue, setActiveIssue] = useState(null)
72+
const [mostRecentIssueId, setMostRecentIssueId] = useState(null)
7273
const [tempActiveIssue, setTempActiveIssue] = useState(null)
7374
const [activeContentItem, setActiveContentItem] = useState(null)
7475
const [tempActiveContentItem, setTempActiveContentItem] = useState(null)
@@ -250,6 +251,39 @@ export default function FixIssuesPage({
250251
}
251252
}, [])
252253

254+
const handleEscapeKey = (e) => {
255+
if(e.key === 'Escape' && widgetState === WIDGET_STATE.FIXIT) {
256+
e.preventDefault()
257+
closeDialog()
258+
}
259+
}
260+
261+
// Pull focus into the dialog when it opens, and return focus to the most recently clicked issue when it closes
262+
useEffect(() => {
263+
if(widgetState === WIDGET_STATE.FIXIT) {
264+
const dialog = document.getElementById(dialogId)
265+
if (dialog) {
266+
dialog.addEventListener('keydown', handleEscapeKey)
267+
const title = dialog.querySelector('#ufixit-dialog-title')
268+
if(title) {
269+
title.focus()
270+
}
271+
}
272+
}
273+
else if(widgetState === WIDGET_STATE.LIST) {
274+
if(mostRecentIssueId) {
275+
const issueElement = document.getElementById(`issue-item-${mostRecentIssueId}`)
276+
if(issueElement) {
277+
issueElement.focus()
278+
}
279+
const dialog = document.getElementById(dialogId)
280+
if (dialog) {
281+
dialog.removeEventListener('keydown', handleEscapeKey)
282+
}
283+
}
284+
}
285+
}, [widgetState])
286+
253287
// When the filters or search term changes, update the filtered issues list
254288
useEffect(() => {
255289

@@ -350,9 +384,14 @@ export default function FixIssuesPage({
350384
return
351385
}
352386

353-
setWidgetState(settings.WIDGET_STATE.FIXIT)
354-
const activeIssueClone = JSON.parse(JSON.stringify(activeIssue))
387+
setMostRecentIssueId(activeIssue.id)
388+
389+
// We ONLY want this to trigger events on a real change.
390+
if(widgetState !== WIDGET_STATE.FIXIT) {
391+
openDialog()
392+
}
355393

394+
const activeIssueClone = JSON.parse(JSON.stringify(activeIssue))
356395
activeIssueClone.issueData.initialHtml = Html.getIssueHtml(activeIssueClone.issueData)
357396
setTempActiveIssue(activeIssueClone)
358397

@@ -365,7 +404,6 @@ export default function FixIssuesPage({
365404
setActiveContentItem(null)
366405
}
367406
setShowLearnMore(false)
368-
openDialog()
369407

370408
}, [activeIssue])
371409

@@ -824,34 +862,24 @@ export default function FixIssuesPage({
824862

825863
const openDialog = () => {
826864
setWidgetState(WIDGET_STATE.FIXIT)
827-
828-
const dialog = document.getElementById(dialogId)
829-
if(dialog && !dialog.open) {
830-
dialog.showModal()
831-
832-
const title = dialog.querySelector('#dialog-title')
833-
if(title) {
834-
title.focus()
835-
}
836-
}
865+
setModalActive(true)
837866
}
838867

839868
const closeDialog = () => {
840869
setWidgetState(WIDGET_STATE.LIST)
870+
setModalActive(false)
841871
setActiveIssue(null)
842-
843-
const dialog = document.getElementById(dialogId)
844-
if(dialog) {
845-
dialog.close()
846-
}
847872
}
848873

849874
return (
850875
<>
851876
{ widgetState === settings.WIDGET_STATE.LOADING ? (
852877
<></>
853878
) : (
854-
<>
879+
<div
880+
inert={widgetState === WIDGET_STATE.FIXIT ? "inert" : undefined}
881+
aria-hidden={widgetState === WIDGET_STATE.FIXIT}
882+
>
855883
<h1 className="pageTitle">{t('barriers.title')}</h1>
856884
<p className="pageSubtitle">{t('barriers.subtitle')}</p>
857885

@@ -873,12 +901,19 @@ export default function FixIssuesPage({
873901
groupedList={groupedList}
874902
setActiveIssue={setActiveIssue}
875903
/>
876-
</>
904+
</div>
877905
) }
878-
<dialog id={dialogId} className="dialog-full-screen" onClose={closeDialog} aria-labelledby="dialog-title">
906+
<div
907+
id={dialogId}
908+
role="dialog"
909+
aria-modal="true"
910+
className={`dialog-full-screen ${widgetState === WIDGET_STATE.FIXIT ? 'open' : 'hidden'}`}
911+
onClose={closeDialog}
912+
aria-labelledby="ufixit-dialog-title"
913+
>
879914
<div className="flex-column h-100">
880915
<div className="dialog-header">
881-
<h2 id="dialog-title" tabIndex="-1">{tempActiveIssue?.formLabel}</h2>
916+
<h2 id="ufixit-dialog-title" tabIndex="-1">{tempActiveIssue?.formLabel}</h2>
882917
<CloseIcon
883918
onClick={closeDialog}
884919
onKeyDown={(e) => {
@@ -984,7 +1019,7 @@ export default function FixIssuesPage({
9841019
</div>
9851020
</div>
9861021
</div>
987-
</dialog>
1022+
</div>
9881023
</>
9891024
)
9901025
}

assets/js/Components/Header.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import './Header.css'
1313
export default function Header({
1414
t,
1515
settings,
16+
modalActive,
1617
navigation,
1718
handleNavigation,
1819
syncComplete
@@ -76,7 +77,7 @@ export default function Header({
7677

7778
/* CSS-Only Responsive Mobile menu based on: https://blog.logrocket.com/create-responsive-mobile-menu-css-without-javascript/ */
7879
return (
79-
<header role="banner">
80+
<header role="banner" inert={modalActive ? "inert" : undefined} aria-hidden={!modalActive}>
8081
<a className="skip-link" href="#main-content">{t('menu.nav.skip_to_main')}</a>
8182
<img alt={t('alt.UDOIT')} src={settings?.user?.roles?.dark_mode ? UDOITLogoDark : UDOITLogo}></img>
8283
<input

0 commit comments

Comments
 (0)