Skip to content

Commit b30a645

Browse files
committed
add upload form, change variables to account for files
1 parent 986444c commit b30a645

File tree

4 files changed

+111
-47
lines changed

4 files changed

+111
-47
lines changed

src/assets/fontawesome.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import {
77
faListCheck,
88
faPaperclip,
99
faSquareCheck,
10+
faUpload,
1011
faVial,
1112
faVialCircleCheck,
1213
} from '@fortawesome/free-solid-svg-icons'
@@ -22,9 +23,10 @@ library.add(
2223
faFileLines,
2324
faListCheck,
2425
faMinusSquare,
26+
faPaperclip,
2527
faPlusSquare,
2628
faSquareCheck,
27-
faPaperclip,
29+
faUpload,
2830
faVial,
2931
faVialCircleCheck,
3032
)

src/components/FilesTable/FilesTable.jsx

Lines changed: 16 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,23 @@
11
import React from 'react'
22
import PropTypes from 'prop-types'
3-
import { Table } from 'react-bootstrap'
3+
import { Button, Table } from 'react-bootstrap'
44

5-
const FilesTable = ({addClass, files}) => {
6-
let headers = [{
7-
name: 'File Name',
8-
key: 'file-name'
9-
},
10-
{
11-
name: 'Uploaded By',
12-
key: 'uploaded-by'
13-
},
14-
{
15-
name: 'Size',
16-
key: 'size'
17-
},
18-
{
19-
name: 'Created At',
20-
key: 'created-at'
21-
},
22-
{
23-
name: '',
24-
key: 'buttons'
25-
}]
265

6+
const FilesTable = ({addClass, files, handleDeleteFile}) => {
277
if (files.length === 0) {
288
return (
29-
<h6>You don't have any of these documents yet.</h6>
9+
<h6 className='mt-3'>You do not have this type of document yet.</h6>
3010
)
3111
} else {
3212
return (
3313
<Table striped bordered hover size='sm' className={`${addClass}`}>
3414
<thead>
3515
<tr>
36-
{headers.map((header) => {
37-
return (
38-
<th key={header.key}>
39-
{header.name}
40-
</th>
41-
)
42-
})}
16+
<th>File Name</th>
17+
<th>Uploaded By</th>
18+
<th>Size</th>
19+
<th>Created At</th>
20+
<th> </th>
4321
</tr>
4422
</thead>
4523
<tbody>
@@ -51,7 +29,14 @@ const FilesTable = ({addClass, files}) => {
5129
<td>{uploadedBy}</td>
5230
<td>{contentLength}</td>
5331
<td>{createdAt}</td>
54-
<td><button></button></td>
32+
<td>
33+
{/* TODO: add an X icon here instead of close button, make sure the handleDeleteFile is working */}
34+
<Button
35+
primary
36+
onClick={handleDeleteFile}>
37+
Remove
38+
</Button>
39+
</td>
5540
</tr>
5641
)
5742
})}

src/compounds/ActionsGroup/ActionsGroup.jsx

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import SendMessage from './actions/SendMessage'
66
import ViewFiles from './actions/ViewFiles'
77
import './actions-group.scss'
88

9-
const ActionsGroup = ({ files, handleSendingMessages }) => {
9+
const ActionsGroup = ({ initialFiles, handleSendingMessagesOrFiles }) => {
1010
const [show, setShow] = useState(false)
1111
const [action, setAction] = useState(null)
1212

@@ -22,41 +22,44 @@ const ActionsGroup = ({ files, handleSendingMessages }) => {
2222
return (
2323
<>
2424
<ListGroup className='actions-group'>
25-
{/* TODO(@summercook): return the below once the direction of
26-
https://github.com/scientist-softserv/webstore/issues/156 has been decided */}
25+
{/* TODO(@summercook): return the this and the below commented code
26+
once the direction of https://github.com/scientist-softserv/webstore/issues/156
27+
has been decided */}
2728
{/* <ListGroup.Item action variant='primary' onClick={() => handleShow('SendMessage')}>
2829
<FontAwesomeIcon icon='fa-envelope' />
2930
Send Message
3031
</ListGroup.Item> */}
31-
<ListGroup.Item action variant='primary' onClick={() => handleShow('ViewFiles')} role='presentation'>
32+
<ListGroup.Item
33+
action
34+
variant='primary'
35+
onClick={() => handleShow('ViewFiles')}
36+
role='presentation'
37+
>
3238
<FontAwesomeIcon icon='fa-file-lines' />
3339
View Files
3440
</ListGroup.Item>
3541
</ListGroup>
36-
{/* TODO(@summercook): return the below once the direction of
37-
https://github.com/scientist-softserv/webstore/issues/156 has been decided */}
3842
{/* {(action === 'SendMessage' && show)
3943
&& (
4044
<SendMessage
4145
handleClose={handleClose}
42-
onSubmit={handleSendingMessages}
46+
onSubmit={handleSendingMessagesOrFiles}
4347
/>
4448
)} */}
4549
{(action === 'ViewFiles' && show)
4650
&& (
4751
<ViewFiles
4852
show={show}
4953
handleClose={handleClose}
50-
files={files}
54+
initialFiles={initialFiles}
55+
//onSubmit={handleSendingMessagesOrFiles}
5156
/>
5257
)}
5358
</>
5459
)
5560
}
5661

5762
// ActionsGroup.propTypes = {
58-
// TODO(@summercook): return the below once the direction of
59-
// https://github.com/scientist-softserv/webstore/issues/156 has been decided
6063
//handleSendingMessages: PropTypes.func.isRequired,
6164
// }
6265

src/compounds/ActionsGroup/actions/ViewFiles.jsx

Lines changed: 79 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,21 @@
1-
import React, { useState } from 'react'
1+
import React, { useState, useRef } from 'react'
22
import PropTypes from 'prop-types'
3-
import { Offcanvas, Tab, Tabs } from 'react-bootstrap'
3+
import {
4+
Button,
5+
CloseButton,
6+
Form,
7+
InputGroup,
8+
ListGroup,
9+
Offcanvas,
10+
Tab,
11+
Tabs } from 'react-bootstrap'
12+
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
413
import FilesTable from '../../../components/FilesTable/FilesTable'
14+
import { apiV2CompatibleStrings, convertToBase64 } from '../../../resources/utilityFunctions'
515

6-
const ViewFiles = ({ files, handleClose, show }) => {
16+
const ViewFiles = ({ initialFiles, handleClose, show }) => {
17+
const fileRef = useRef(null)
18+
const [files, setFiles] = useState([])
719
const documentTabs = [
820
{
921
eventKey: 'files',
@@ -22,19 +34,81 @@ const ViewFiles = ({ files, handleClose, show }) => {
2234
status: 'TODO:FILL THIS IN'
2335
},
2436
]
37+
38+
// TODO(summercook): update this method once posting messages is working- may need to use the handleSendingMessagesOrFiles to post
39+
// need to check if we should just a different endpoint to post attachments
40+
const handleSubmit = (event) => {
41+
event.preventDefault()
42+
onSubmit({ files: apiV2CompatibleStrings(files) })
43+
}
44+
45+
const handleAddFile = async (event) => {
46+
event.preventDefault()
47+
try {
48+
// "event.target.files" returns a FileList, which looks like an array but does not respond to array methods
49+
// except "length". we are using the spread syntax to set "files" to be an iterable array
50+
const fileArray = [...event.target.files]
51+
const newBase64Files = await Promise.all(convertToBase64(fileArray))
52+
const newFiles = fileArray.map((file, index) => ({ [file.name]: newBase64Files[index] }))
53+
54+
setFiles([...files, ...newFiles])
55+
fileRef.current.value = ''
56+
} catch (error) {
57+
throw new Error(error)
58+
}
59+
}
60+
61+
const handleDeleteFile = (file) => {
62+
const remainingFiles = files.filter((obj) => obj !== file)
63+
setFiles(remainingFiles)
64+
}
65+
2566
return (
2667
<Offcanvas show={show} onHide={handleClose} placement='end' scroll='true'>
2768
<Offcanvas.Header className='d-flex border-bottom px-3 py-2 bg-light' closeButton>
2869
<Offcanvas.Title>Documents</Offcanvas.Title>
2970
</Offcanvas.Header>
3071
<Offcanvas.Body className='border rounded p-2 m-3'>
72+
<Form>
73+
<h6 className='mt-3'>Upload Additional Documents</h6>
74+
<InputGroup controlId='attachments' className='mb-3'>
75+
<Form.Control
76+
multiple
77+
type='file'
78+
onChange={handleAddFile}
79+
ref={fileRef}
80+
/>
81+
<Button
82+
variant='outline-primary'
83+
onClick={handleSubmit}
84+
type='submit'
85+
>
86+
<FontAwesomeIcon icon='fa-upload' />
87+
</Button>
88+
</InputGroup>
89+
</Form>
90+
<ListGroup variant='flush'>
91+
{files.map((file) => {
92+
const fileName = Object.keys(file)[0]
93+
94+
return (
95+
<ListGroup.Item key={fileName} className='d-flex align-items-center'>
96+
<span>{fileName}</span>
97+
<CloseButton onClick={() => handleDeleteFile(file)} className='ms-auto' />
98+
</ListGroup.Item>
99+
)
100+
})}
101+
</ListGroup>
31102
<Tabs defaultActiveKey="files" id="document-tabs">
32103
{documentTabs && documentTabs.map(tab => {
33104
const { eventKey, title, status } = tab
34-
let filteredFiles = files.filter(f => (status === f.status) || (status === 'Other File' && f.status === null))
105+
let filteredFiles = initialFiles.filter(f => (status === f.status) || (status === 'Other File' && f.status === null))
35106
return (
36107
<Tab eventKey={eventKey} title={title} className='p-2'>
37-
<FilesTable files={filteredFiles} status={status} />
108+
<FilesTable
109+
files={filteredFiles}
110+
status={status}
111+
handleDeleteFile={handleDeleteFile}/>
38112
</Tab>
39113
)
40114
})}

0 commit comments

Comments
 (0)