Skip to content

Commit 560161e

Browse files
authored
Merge pull request #2818 from devtron-labs/feat/focus-trap
feat: add focus trap and remove visible-modal
2 parents 8649a46 + 7440613 commit 560161e

File tree

25 files changed

+161
-410
lines changed

25 files changed

+161
-410
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
"private": true,
55
"homepage": "/dashboard",
66
"dependencies": {
7-
"@devtron-labs/devtron-fe-common-lib": "1.17.0-pre-13",
7+
"@devtron-labs/devtron-fe-common-lib": "1.17.0-pre-14",
88
"@esbuild-plugins/node-globals-polyfill": "0.2.3",
99
"@rjsf/core": "^5.13.3",
1010
"@rjsf/utils": "^5.13.3",

src/App.tsx

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -168,8 +168,6 @@ const App = () => {
168168
<Route path="/" render={() => <NavigationRoutes reloadVersionConfig={reloadVersionConfig} />} />
169169
<Redirect to={window._env_.K8S_CLIENT ? '/' : `${URLS.LOGIN_SSO}${location.search}`} />
170170
</Switch>
171-
<div id="visible-modal" />
172-
<div id="visible-modal-2" />
173171
</BreadcrumbStore>
174172
</ErrorBoundary>
175173
)

src/Pages/App/CreateAppModal/CreateAppModal.component.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ import { getHostURLConfiguration } from '@Services/service'
3636

3737
import ApplicationInfoForm from './ApplicationInfoForm'
3838
import { CloneApplicationSelectionList } from './CloneApplicationSelectionList'
39-
import { createAppInitialFormErrorState, createAppInitialFormState } from './constants'
39+
import { createAppInitialFormErrorState, createAppInitialFormState, PROJECT_SELECT_INPUT_ID } from './constants'
4040
import HeaderSection from './HeaderSection'
4141
import { createApp } from './service'
4242
import Sidebar from './Sidebar'
@@ -374,7 +374,7 @@ const CreateAppModal = ({ isJobView, handleClose }: CreateAppModalProps) => {
374374
}
375375

376376
return (
377-
<Drawer position="right" width="1024px" onEscape={handleClose}>
377+
<Drawer position="right" width="1024px" onEscape={handleClose} initialFocus={`#${PROJECT_SELECT_INPUT_ID}`}>
378378
<div className="h-100 bg__modal--primary flexbox-col dc__overflow-hidden">
379379
<HeaderSection isJobView={isJobView} handleClose={handleClose} isCloseDisabled={isSubmitting} />
380380
<div className="flexbox flex-grow-1 dc__overflow-hidden">

src/Pages/App/CreateAppModal/ProjectSelector.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import {
2424

2525
import { ReactComponent as ICFolderColor } from '@Icons/ic-folder-color.svg'
2626

27+
import { PROJECT_SELECT_INPUT_ID } from './constants'
2728
import { CreateAppFormStateType, ProjectSelectorProps } from './types'
2829

2930
const ProjectSelector = ({ selectedProjectId, handleProjectIdChange, error }: ProjectSelectorProps) => {
@@ -47,7 +48,7 @@ const ProjectSelector = ({ selectedProjectId, handleProjectIdChange, error }: Pr
4748
<div className="w-300">
4849
<SelectPicker
4950
icon={<ICFolderColor />}
50-
inputId="project"
51+
inputId={PROJECT_SELECT_INPUT_ID}
5152
options={projectOptions}
5253
label="Project"
5354
required
@@ -60,7 +61,6 @@ const ProjectSelector = ({ selectedProjectId, handleProjectIdChange, error }: Pr
6061
value={selectedProject}
6162
onChange={handleChange}
6263
error={error}
63-
autoFocus
6464
/>
6565
</div>
6666
)

src/Pages/App/CreateAppModal/constants.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,3 +39,5 @@ export const createAppInitialFormErrorState: CreateAppFormErrorStateType = {
3939
gitMaterials: null,
4040
workflowConfig: null,
4141
}
42+
43+
export const PROJECT_SELECT_INPUT_ID = 'project'

src/Pages/Shared/LinkedCIDetailsModal/LinkedCIDetailsModal.tsx

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
* limitations under the License.
1515
*/
1616

17-
import { useEffect, useMemo, useRef } from 'react'
17+
import { useMemo, useRef } from 'react'
1818
import { useParams } from 'react-router-dom'
1919

2020
import {
@@ -36,7 +36,6 @@ import {
3636
} from '@devtron-labs/devtron-fe-common-lib'
3737

3838
import { ReactComponent as Close } from '../../../assets/icons/ic-close.svg'
39-
import { preventBodyScroll } from '../../../components/common'
4039
import { API_STATUS_CODES, SELECT_ALL_VALUE } from '../../../config'
4140
import { ALL_ENVIRONMENT_OPTION, SortableKeys } from './constants'
4241
import LinkedCIAppList from './LinkedCIAppList'
@@ -113,14 +112,6 @@ const LinkedCIDetailsModal = ({ handleClose, workflows }: LinkedCIDetailModalPro
113112

114113
const selectedOption = selectOptions.find((option) => option.value === environment) ?? ALL_ENVIRONMENT_OPTION
115114

116-
useEffect(() => {
117-
preventBodyScroll(true)
118-
119-
return () => {
120-
preventBodyScroll(false)
121-
}
122-
}, [])
123-
124115
const showLoadingState = loading || getIsRequestAborted(error)
125116

126117
if (!showLoadingState) {

src/components/ApplicationGroup/Details/TriggerView/BulkCDTrigger.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -394,7 +394,6 @@ const BulkCDTrigger = ({
394394
</div>
395395
<Button
396396
dataTestId="bulk-cd-modal-close"
397-
disabled={isLoading}
398397
onClick={closeBulkCDModal}
399398
size={ComponentSizeType.xs}
400399
icon={<Icon name="ic-close-large" size={null} color={null} />}

src/components/ApplicationGroup/Details/TriggerView/BulkCITrigger.tsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -348,7 +348,6 @@ const BulkCITrigger = ({
348348
icon={<Close />}
349349
showAriaLabelInTippy={false}
350350
style={ButtonStyleType.negativeGrey}
351-
disabled={isLoading}
352351
/>
353352
</div>
354353
)
@@ -807,7 +806,7 @@ const BulkCITrigger = ({
807806
const responseListLength = responseList.length
808807

809808
return (
810-
<Drawer position="right" width="75%" minWidth="1024px" maxWidth="1200px">
809+
<Drawer position="right" width="75%" minWidth="1024px" maxWidth="1200px" onClose={closeBulkCIModal} >
811810
<div className="bg__primary bulk-ci-trigger-container">
812811
<div className="flexbox-col flex-grow-1 dc__overflow-hidden">
813812
{renderHeaderSection()}

src/components/ApplicationGroup/Details/TriggerView/BulkSourceChange.tsx

Lines changed: 14 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,13 @@ import {
2020
Button,
2121
ButtonStyleType,
2222
ButtonVariantType,
23+
ComponentSizeType,
2324
CustomInput,
2425
Drawer,
26+
Icon,
2527
InfoBlock,
2628
} from '@devtron-labs/devtron-fe-common-lib'
2729

28-
import { ReactComponent as Close } from '../../../../assets/icons/ic-cross.svg'
2930
import SourceUpdateResponseModal from './SourceUpdateResponseModal'
3031
import { BulkSourceChangeProps } from './types'
3132

@@ -42,40 +43,6 @@ const BulkSourceChange = ({
4243
const [inputError, setInputError] = useState('')
4344
const [branchName, setBranchName] = useState('')
4445

45-
const closeBulkCIModal = (evt) => {
46-
closePopup(evt)
47-
}
48-
49-
const escKeyPressHandler = (evt): void => {
50-
if (evt && evt.key === 'Escape' && typeof closePopup === 'function') {
51-
evt.preventDefault()
52-
closeBulkCIModal(evt)
53-
}
54-
}
55-
const outsideClickHandler = (evt): void => {
56-
if (
57-
sourceChangeDetailRef.current &&
58-
!sourceChangeDetailRef.current.contains(evt.target) &&
59-
typeof closePopup === 'function'
60-
) {
61-
closeBulkCIModal(evt)
62-
}
63-
}
64-
65-
useEffect(() => {
66-
document.addEventListener('keydown', escKeyPressHandler)
67-
return (): void => {
68-
document.removeEventListener('keydown', escKeyPressHandler)
69-
}
70-
}, [escKeyPressHandler])
71-
72-
useEffect(() => {
73-
document.addEventListener('click', outsideClickHandler)
74-
return (): void => {
75-
document.removeEventListener('click', outsideClickHandler)
76-
}
77-
}, [outsideClickHandler])
78-
7946
useEffect(() => {
8047
setShowResponseModal(responseList.length > 0)
8148
}, [responseList])
@@ -92,15 +59,16 @@ const BulkSourceChange = ({
9259
const renderHeaderSection = (): JSX.Element | null => (
9360
<div className="flex flex-justify dc__border-bottom px-20 py-16">
9461
<h2 className="fs-16 fw-6 lh-1-43 m-0">Change branch for {selectedAppCount} applications</h2>
95-
<button
96-
type="button"
97-
className="dc__transparent flex icon-dim-24"
98-
disabled={loading}
99-
onClick={closeBulkCIModal}
100-
aria-label="close"
101-
>
102-
<Close className="icon-dim-24" />
103-
</button>
62+
<Button
63+
dataTestId="close"
64+
ariaLabel="close"
65+
icon={<Icon name="ic-close-large" color={null} />}
66+
showAriaLabelInTippy={false}
67+
onClick={closePopup}
68+
size={ComponentSizeType.medium}
69+
style={ButtonStyleType.negativeGrey}
70+
variant={ButtonVariantType.borderLess}
71+
/>
10472
</div>
10573
)
10674

@@ -140,7 +108,7 @@ const BulkSourceChange = ({
140108
<div className="flexbox dc__gap-12">
141109
<Button
142110
dataTestId="cancel_button"
143-
onClick={closeBulkCIModal}
111+
onClick={closePopup}
144112
text="Cancel"
145113
style={ButtonStyleType.neutral}
146114
variant={ButtonVariantType.secondary}
@@ -178,6 +146,7 @@ const BulkSourceChange = ({
178146
width="75%"
179147
minWidth={showResponseModal ? '1024px' : '600px'}
180148
maxWidth={showResponseModal ? '1200px' : '600px'}
149+
onEscape={closePopup}
181150
>
182151
<div className="bg__primary bulk-ci-trigger-container" ref={sourceChangeDetailRef}>
183152
<div className="flexbox-col flex-grow-1 dc__overflow-hidden">

src/components/ApplicationGroup/Details/TriggerView/EnvTriggerView.tsx

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,6 @@ import {
4141
ApiQueuingWithBatch,
4242
usePrompt,
4343
SourceTypeMap,
44-
preventBodyScroll,
4544
ToastManager,
4645
ToastVariantType,
4746
BlockedStateData,
@@ -713,7 +712,6 @@ export default function EnvTriggerView({ filteredAppIds, isVirtualEnv }: AppGrou
713712
setShowMaterialRegexModal(showRegexModal)
714713
}
715714
getWorkflowStatusData(_workflows)
716-
preventBodyScroll(true)
717715
})
718716
}
719717

@@ -819,7 +817,6 @@ export default function EnvTriggerView({ filteredAppIds, isVirtualEnv }: AppGrou
819817
}
820818
setWorkflowID(_workflowId)
821819
getWorkflowStatusData(_workflows)
822-
preventBodyScroll(true)
823820
})
824821
}
825822

@@ -953,7 +950,6 @@ export default function EnvTriggerView({ filteredAppIds, isVirtualEnv }: AppGrou
953950
setFilteredWorkflows(_workflows)
954951
setSelectedCDNode({ id: +cdNodeId, name: _selectedNode.name, type: _selectedNode.type })
955952
setMaterialType(MATERIAL_TYPE.inputMaterialList)
956-
preventBodyScroll(true)
957953

958954
const newParams = new URLSearchParams(location.search)
959955
newParams.set(isApprovalNode ? 'approval-node' : 'cd-node', cdNodeId.toString())
@@ -1007,7 +1003,6 @@ export default function EnvTriggerView({ filteredAppIds, isVirtualEnv }: AppGrou
10071003
setFilteredWorkflows(_workflows)
10081004
setSelectedCDNode({ id: +cdNodeId, name: _selectedNode.name, type: _selectedNode.type })
10091005
setMaterialType(MATERIAL_TYPE.rollbackMaterialList)
1010-
preventBodyScroll(true)
10111006
getWorkflowStatusData(_workflows)
10121007

10131008
const newParams = new URLSearchParams(location.search)
@@ -1099,7 +1094,6 @@ export default function EnvTriggerView({ filteredAppIds, isVirtualEnv }: AppGrou
10991094
closeCIModal()
11001095
setErrorCode(response.code)
11011096
setInvalidateCache(false)
1102-
preventBodyScroll(false)
11031097
getWorkflowStatusData(workflows)
11041098
}
11051099
})
@@ -1192,7 +1186,6 @@ export default function EnvTriggerView({ filteredAppIds, isVirtualEnv }: AppGrou
11921186
setIsBranchChangeLoading(false)
11931187
setCDLoading(false)
11941188
setCILoading(false)
1195-
preventBodyScroll(true)
11961189
return
11971190
}
11981191

@@ -1212,7 +1205,6 @@ export default function EnvTriggerView({ filteredAppIds, isVirtualEnv }: AppGrou
12121205
updateResponseListData([..._responseList, ...skippedResources])
12131206
setCDLoading(false)
12141207
setCILoading(false)
1215-
preventBodyScroll(true)
12161208
})
12171209
.catch((error) => {
12181210
showError(error)
@@ -1271,22 +1263,20 @@ export default function EnvTriggerView({ filteredAppIds, isVirtualEnv }: AppGrou
12711263

12721264
const closeCIModal = (): void => {
12731265
abortControllerRef.current.abort()
1274-
preventBodyScroll(false)
12751266
setShowMaterialRegexModal(false)
12761267
setRuntimeParams({})
12771268
setRuntimeParamsErrorState({})
12781269
history.push(url)
12791270
}
12801271

12811272
const closeCDModal = (e: React.MouseEvent): void => {
1282-
e.stopPropagation()
1273+
e?.stopPropagation()
12831274
abortControllerRef.current.abort()
12841275
setCDLoading(false)
12851276
history.push({
12861277
search: '',
12871278
})
12881279
getWorkflowStatusData(workflows)
1289-
preventBodyScroll(false)
12901280
}
12911281

12921282
const closeApprovalModal = (e: React.MouseEvent): void => {
@@ -1295,7 +1285,6 @@ export default function EnvTriggerView({ filteredAppIds, isVirtualEnv }: AppGrou
12951285
search: '',
12961286
})
12971287
getWorkflowStatusData(workflows)
1298-
preventBodyScroll(false)
12991288
}
13001289

13011290
const onClickWebhookTimeStamp = () => {
@@ -1371,7 +1360,6 @@ export default function EnvTriggerView({ filteredAppIds, isVirtualEnv }: AppGrou
13711360
setIsBranchChangeLoading(false)
13721361
setShowBulkSourceChangeModal(false)
13731362
setResponseList([])
1374-
preventBodyScroll(false)
13751363
}
13761364

13771365
const handleCloseChangeImageSource = () => {
@@ -1639,7 +1627,6 @@ export default function EnvTriggerView({ filteredAppIds, isVirtualEnv }: AppGrou
16391627
setCDLoading(false)
16401628
setCILoading(false)
16411629
setIsBulkTriggerLoading(false)
1642-
preventBodyScroll(false)
16431630
getWorkflowStatusData(workflows)
16441631
})
16451632
} else {
@@ -2242,7 +2229,7 @@ export default function EnvTriggerView({ filteredAppIds, isVirtualEnv }: AppGrou
22422229
const material = node?.[materialType] || []
22432230

22442231
return (
2245-
<VisibleModal className="" parentClassName="dc__overflow-hidden" close={closeCDModal}>
2232+
<VisibleModal parentClassName="dc__overflow-hidden" close={closeCDModal}>
22462233
<div
22472234
className={`modal-body--cd-material h-100 contains-diff-view flexbox-col ${
22482235
material.length > 0 ? '' : 'no-material'

0 commit comments

Comments
 (0)