-
Notifications
You must be signed in to change notification settings - Fork 24
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Updated Document Upload and details #3643
Changes from 4 commits
a350e46
3025986
51a9341
b78bf10
15f7fb8
f75888d
23ccd22
0abe174
01553ed
5c4ee8c
0fb7ad3
2e215f3
dabbb99
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -27,6 +27,7 @@ export interface ModalContent { | |
handleCancel?: Function; | ||
/** Optional function to control behaviour of ok button. Default is to reload the app. */ | ||
handleOk?: Function; | ||
handleOkDisabled?: boolean; | ||
/** Optional text to display on the cancel button. Default is Cancel. */ | ||
cancelButtonText?: string; | ||
/** Optional variant that will override the default variant of warning. */ | ||
|
@@ -98,6 +99,7 @@ export const GenericModal = (props: Omit<BsModalProps, 'onHide'> & ModalProps) = | |
display, | ||
setDisplay, | ||
handleOk, | ||
handleOkDisabled, | ||
handleCancel, | ||
title, | ||
message, | ||
|
@@ -215,12 +217,19 @@ export const GenericModal = (props: Omit<BsModalProps, 'onHide'> & ModalProps) = | |
title="cancel-modal" | ||
variant={cancelButtonVariant ?? 'secondary'} | ||
onClick={close} | ||
test-id="cancel-modal-button" | ||
> | ||
{cancelButtonText} | ||
</Button> | ||
)} | ||
|
||
<Button title="ok-modal" variant={okButtonVariant ?? 'primary'} onClick={ok}> | ||
<Button | ||
title="ok-modal" | ||
variant={okButtonVariant ?? 'primary'} | ||
onClick={ok} | ||
disabled={handleOkDisabled} | ||
test-id="ok-modal-button" | ||
> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same comment re: test-id |
||
{okButtonText ?? 'Ok'} | ||
</Button> | ||
</div> | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,152 @@ | ||
import { ChangeEvent, FunctionComponent, useState } from 'react'; | ||
import styled from 'styled-components'; | ||
|
||
import { SectionField } from '../Section/SectionField'; | ||
|
||
interface IFileDragAndDropProps { | ||
onSelectFile: (file: File | null) => void; | ||
selectedFile: File | null; | ||
validExtensions: string[]; | ||
} | ||
|
||
const FileDragAndDrop: FunctionComponent<React.PropsWithChildren<IFileDragAndDropProps>> = ({ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The test coverage on this isn't great. Unit testing this completely may not be realistic but is there anything we can do here? |
||
onSelectFile, | ||
selectedFile, | ||
validExtensions, | ||
}) => { | ||
const validDocumentExtensions: string = validExtensions.map(x => `.${x}`).join(','); | ||
|
||
const [isDragging, setIsDragging] = useState(false); | ||
|
||
const handleFileInput = (changeEvent: ChangeEvent<HTMLInputElement>) => { | ||
// handle validations | ||
if (changeEvent.target !== null) { | ||
var target = changeEvent.target; | ||
if (target.files !== null) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. target.files?.length !== null & target.files.length >= 1 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. sure, added the check for at least one file |
||
onSelectFile(target.files[0]); | ||
} | ||
} | ||
}; | ||
|
||
const handleDragEnter = (event: React.DragEvent) => { | ||
event.preventDefault(); | ||
event.stopPropagation(); | ||
|
||
setIsDragging(true); | ||
}; | ||
|
||
const handleDragLeave = (event: React.DragEvent) => { | ||
event.preventDefault(); | ||
event.stopPropagation(); | ||
|
||
setIsDragging(false); | ||
}; | ||
|
||
const handleDragOver = (event: React.DragEvent) => { | ||
event.preventDefault(); | ||
event.stopPropagation(); | ||
|
||
setIsDragging(true); | ||
}; | ||
|
||
const handleDrop = (event: React.DragEvent) => { | ||
event.preventDefault(); | ||
event.stopPropagation(); | ||
|
||
let files = [...event.dataTransfer.files]; | ||
|
||
if (files && files.length > 0) { | ||
onSelectFile(files[0]); | ||
event.dataTransfer.clearData(); | ||
} | ||
|
||
setIsDragging(false); | ||
}; | ||
|
||
const shortenString = (text: string, maxlenght: number, terminator: string = '...'): string => { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. maxlenght -> maxLength |
||
if (text.length > maxlenght) { | ||
return text.substring(0, maxlenght - terminator.length) + terminator; | ||
} | ||
|
||
return text; | ||
}; | ||
|
||
return ( | ||
<div> | ||
<DragDropZone | ||
onDrop={handleDrop} | ||
onDragOver={handleDragOver} | ||
onDragEnter={handleDragEnter} | ||
onDragLeave={handleDragLeave} | ||
isDragging={isDragging} | ||
> | ||
<StyledContent> | ||
Drag files here to attach or{' '} | ||
<StyledUploadLabel> | ||
Browse | ||
<StyledFileInput | ||
data-testid="upload-input" | ||
id="uploadInput" | ||
type="file" | ||
name="documentFile" | ||
accept={validDocumentExtensions} | ||
onChange={handleFileInput} | ||
className="" | ||
/> | ||
</StyledUploadLabel> | ||
</StyledContent> | ||
</DragDropZone> | ||
{selectedFile !== null && ( | ||
<StyledSelectedFile> | ||
<SectionField label="File to add" labelWidth="3"> | ||
{shortenString(selectedFile.name || '', 20)} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. maybe could use the OverflowTip component instead? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I checked with ana and this way worked better |
||
</SectionField> | ||
</StyledSelectedFile> | ||
)} | ||
</div> | ||
); | ||
}; | ||
|
||
export default FileDragAndDrop; | ||
|
||
const DragDropZone = styled.div<{ isDragging: boolean }>` | ||
border: 1px solid ${({ theme }) => theme.css.lightVariantColor}; | ||
|
||
border-style: ${({ isDragging }) => (isDragging ? 'solid' : 'dashed')}; | ||
|
||
border: ${props => (props.isDragging ? `1px solid ${props.theme.css.draftColor}` : '')}; | ||
|
||
background-color: ${props => (props.isDragging ? props.theme.css.filterBoxColor : '')}; | ||
|
||
height: 10rem; | ||
line-height: 10rem; | ||
text-align: center; | ||
`; | ||
|
||
const StyledContent = styled.div` | ||
width: 100%; | ||
display: inline-block; | ||
vertical-align: middle; | ||
line-height: normal; | ||
`; | ||
|
||
const StyledUploadLabel = styled.label` | ||
display: inline-block; | ||
color: ${({ theme }) => theme.css.linkColor}; | ||
cursor: pointer; | ||
|
||
&:hover { | ||
color: ${({ theme }) => theme.css.linkHoverColor}; | ||
text-decoration: underline; | ||
} | ||
`; | ||
|
||
const StyledFileInput = styled.input` | ||
display: none; | ||
`; | ||
|
||
const StyledSelectedFile = styled.div` | ||
padding-top: 2rem; | ||
overflow: hide; | ||
word-wrap: break-word; | ||
`; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we already have the title property to get the buttons in tests. not opposed to adding test ids but I believe the right syntax is data-testid="..."
See here: https://testing-library.com/docs/queries/bytestid/