Skip to content

Commit

Permalink
feat: add onChange function to fileuploader, closes #44
Browse files Browse the repository at this point in the history
  • Loading branch information
olavis committed Aug 30, 2023
1 parent b5527b0 commit b7476d3
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 46 deletions.
12 changes: 0 additions & 12 deletions src/features/AddModelDialog/AddModelDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,6 @@ export const AddModelDialog = ({
cancel,
}: AddModelDialogProps) => {
const [isFileDisplay, setFileDisplay] = useState<boolean>(false)
const files = {
NC: {
name: 'CoarseSand_LargerFlow_1.nc',
size: 1.43,
onDelete: deleteInputFile,
},
}

// Temporary ignore because not implemented yet
// eslint-disable-next-line @typescript-eslint/no-empty-function
function deleteInputFile() {}

function toggleINIFileContent() {
setFileDisplay(!isFileDisplay)
Expand All @@ -41,7 +30,6 @@ export const AddModelDialog = ({
</Styled.Dialog.Header>
<Styled.DialogCustomContent scrollable>
<ModelInputFilesTable
files={files}
fileDisplay={{
isVisible: isFileDisplay,
toggle: toggleINIFileContent,
Expand Down
51 changes: 37 additions & 14 deletions src/features/FileUploader/FileUploader.tsx
Original file line number Diff line number Diff line change
@@ -1,27 +1,50 @@
import { Icon } from '@equinor/eds-core-react'
import { subdirectory_arrow_right as arrowIcon } from '@equinor/eds-icons'
import { ChangeEvent, useRef } from 'react'
import { theme } from '../../tokens/theme'
import { File } from '../ModelInputFilesTable/ModelInputFilesTable'
import { FileUpload, SelectFile } from './FileUploader.styled'

interface FileUploaderProps {
file: File | undefined
INI?: boolean
file?: File
onChange: (e: ChangeEvent<HTMLInputElement>) => void
acceptType: 'NC' | 'INI'
}

export const FileUploader = ({ file, INI }: FileUploaderProps) => {
const text = INI ? 'Select parameter INI file' : 'Select model NC file'
const accept = INI ? '.ini' : '.nc'
export const FileUploader = ({
file,
onChange,
acceptType,
}: FileUploaderProps) => {
const INI = acceptType === 'INI'
const ref = useRef<HTMLInputElement>(null)

function handleClick(e: ChangeEvent<HTMLInputElement>) {
e.preventDefault()
ref.current?.click()
}

return file ? (
<>{file.name}</>
<>{file}</>
) : (
<FileUpload htmlFor="file-upload" className="custom-file-upload">
{INI && (
<Icon fill={theme.light.text.staticIconsTertiary} data={arrowIcon} />
)}
<SelectFile>{text}</SelectFile> {INI && '(optional)'}
<input id="file-upload" required type="file" accept={accept} />
</FileUpload>
<form method="post" encType="multipart/form-data">
<FileUpload htmlFor="file-upload" className="custom-file-upload">
{INI && (
<Icon fill={theme.light.text.staticIconsTertiary} data={arrowIcon} />
)}
<SelectFile onClick={handleClick}>
{INI ? 'Select parameter INI file' : 'Select model NC file'}
</SelectFile>
{INI && '(optional)'}
<input
id="file-upload"
required={!INI}
type="file"
accept={`.${acceptType.toLowerCase()}`}
onChange={onChange}
ref={ref}
name={acceptType}
/>
</FileUpload>
</form>
)
}
73 changes: 53 additions & 20 deletions src/features/ModelInputFilesTable/ModelInputFilesTable.tsx
Original file line number Diff line number Diff line change
@@ -1,53 +1,76 @@
import { Button, Table } from '@equinor/eds-core-react'
import { delete_to_trash as deleteIcon } from '@equinor/eds-icons'
import { ChangeEvent, useState } from 'react'
import IconButton from '../../components/IconButton/IconButton'
import { FileUploader } from '../FileUploader/FileUploader'

// TODO: Temporary type
export type File = { name: string; size: number; onDelete: () => void }

type FileDisplay = { isVisible: boolean; toggle: () => void }

const FileColumn = ({
file,
fileDisplay,
}: {
interface FileColumnProps {
onChange: (e: ChangeEvent<HTMLInputElement>) => void
onDelete: () => void
INI?: true
file?: File
fileDisplay?: FileDisplay
}) => {
const isINI = fileDisplay !== undefined
}

const FileColumn = ({
onChange,
onDelete,
INI,
file,
fileDisplay,
}: FileColumnProps) => {
const DeleteButton = ({ onDelete }: { onDelete: () => void }) => (
<IconButton icon={deleteIcon} title="delete" onClick={onDelete} />
)

function fileSize(size: number) {
if (size < 1024) {
return `${size} bytes`
} else if (size >= 1024 && size < 1048576) {
return `${(size / 1024).toFixed(1)} KB`
} else if (size >= 1048576) {
return `${(size / 1048576).toFixed(1)} MB`
}
}

return (
<Table.Row className={`${isINI ? 'ini' : 'nc'}-file`}>
<Table.Row className={`${INI ? 'ini' : 'nc'}-file`}>
<Table.Cell>
<FileUploader INI={isINI} file={file} />
<FileUploader
onChange={onChange}
file={file}
acceptType={INI ? 'INI' : 'NC'}
/>
</Table.Cell>
<Table.Cell>
{file && isINI && (
{file && INI && (
<Button variant="outlined" onClick={fileDisplay?.toggle}>
{fileDisplay?.isVisible ? 'Hide' : 'Show'}
</Button>
)}
</Table.Cell>
<Table.Cell>{file ? `${file.size} GB` : '-'}</Table.Cell>
<Table.Cell>
{file && <DeleteButton onDelete={file.onDelete} />}
</Table.Cell>
<Table.Cell>{file ? fileSize(file.size) : '-'}</Table.Cell>
<Table.Cell>{file && <DeleteButton onDelete={onDelete} />}</Table.Cell>
</Table.Row>
)
}

export const ModelInputFilesTable = ({
files,
fileDisplay,
}: {
files: { NC?: File; INI?: File }
fileDisplay: FileDisplay
}) => {
const [files, setFiles] = useState<{ NC?: File; INI?: File }>()

function updateFileDisplay(e: ChangeEvent<HTMLInputElement>) {
e.preventDefault()
const file = e.target.value
const type = e.target.name
setFiles({ ...files, [type]: file })
}

return (
<Table>
<Table.Head>
Expand All @@ -59,8 +82,18 @@ export const ModelInputFilesTable = ({
</Table.Row>
</Table.Head>
<Table.Body>
<FileColumn file={files.NC} />
<FileColumn file={files.INI} fileDisplay={fileDisplay} />
<FileColumn
file={files?.NC}
onChange={updateFileDisplay}
onDelete={() => setFiles({ ...files, NC: undefined })}
/>
<FileColumn
INI
file={files?.INI}
onChange={updateFileDisplay}
onDelete={() => setFiles({ ...files, INI: undefined })}
fileDisplay={fileDisplay}
/>
</Table.Body>
</Table>
)
Expand Down

0 comments on commit b7476d3

Please sign in to comment.