Skip to content
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

fix(Support): improve attachment uploading #284

Merged
merged 1 commit into from
May 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 20 additions & 9 deletions client/src/components/FileUploader/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ const FileUploader: React.FC<FileUploaderProps> = ({

// Uploader State
const [dragActive, setDragActive] = useState(false);
const [files, setFiles] = useState<File[]>([]); // for showing uploads

/**
* Activates the "droppable" area visual state when a file is dragged into the uploader.
Expand All @@ -61,26 +62,31 @@ const FileUploader: React.FC<FileUploaderProps> = ({
e: React.DragEvent | React.ChangeEvent,
src = "select"
) {
let files;
let filesToUpload: FileList | null = null;
if (src === "drag") {
if ((e as React.DragEvent).dataTransfer?.files) {
files = (e as React.DragEvent).dataTransfer.files;
filesToUpload = (e as React.DragEvent).dataTransfer.files;
}
} else {
// @ts-expect-error
if ((e as React.ChangeEvent).target?.files) {
// @ts-expect-error
files = e.target.files;
filesToUpload = e.target.files;
}
}
if (multiple && maxFiles && files.length > maxFiles) {

const newLength = files
? files.length + (filesToUpload ? filesToUpload.length : 0)
: 0;
if (multiple && maxFiles && newLength > maxFiles) {
// too many files
handleGlobalError(
`This uploader accepts a maximum of ${maxFiles} files.`
);
} else if (files.length > 0) {
} else if (filesToUpload && filesToUpload.length > 0) {
// files uploaded
onUpload(files);
setFiles([...files, ...Array.from(filesToUpload)]); // for showing uploads (not actually used for upload)
onUpload(filesToUpload);
}
}

Expand Down Expand Up @@ -159,10 +165,15 @@ const FileUploader: React.FC<FileUploaderProps> = ({
onDrop={handleFileDrop}
/>
)}
{showUploads && multiple && inputReference.current?.files && (
{showUploads && multiple && files && files.length > 0 && (
<div className="flex flex-row justify-start mt-2">
{Array.from(inputReference.current.files).map((file) => (
<Label color="blue" size="tiny" key={crypto.randomUUID()} className="mr-2">
{Array.from(files).map((file) => (
<Label
color="blue"
size="tiny"
key={crypto.randomUUID()}
className="mr-2"
>
{truncateString(file.name, 40)}
</Label>
))}
Expand Down
25 changes: 18 additions & 7 deletions client/src/components/support/CreateTicketFlow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -189,15 +189,15 @@ const CreateTicketFlow: React.FC<CreateTicketFlowProps> = ({ isLoggedIn }) => {
return;
}

await handleAttachmentsUpload(res.data.ticket.uuid, files);
await handleAttachmentsUpload(res.data.ticket.uuid, files, res.data.ticket.guestAccessKey);
} catch (err) {
handleGlobalError(err);
} finally {
setLoading(false);
}
}

async function handleAttachmentsUpload(ticketID: string, files: File[]) {
async function handleAttachmentsUpload(ticketID: string, files: File[], guestAccessKey?: string) {
setLoading(true);
const formData = new FormData();
Array.from(files).forEach((file) => {
Expand All @@ -206,7 +206,7 @@ const CreateTicketFlow: React.FC<CreateTicketFlowProps> = ({ isLoggedIn }) => {

try {
const uploadRes = await axios.post(
`/support/ticket/${ticketID}/attachments`,
`/support/ticket/${ticketID}/attachments${guestAccessKey ? `?accessKey=${guestAccessKey}` : ''}`,
formData,
{
headers: { "Content-Type": "multipart/form-data" },
Expand All @@ -223,9 +223,9 @@ const CreateTicketFlow: React.FC<CreateTicketFlowProps> = ({ isLoggedIn }) => {
}
}

async function saveFilesToState(files: FileList) {
async function saveFilesToState(filesToSet: FileList) {
setLoading(true);
setFiles(Array.from(files));
setFiles([...files, ...Array.from(filesToSet)]);
setLoading(false);
}

Expand Down Expand Up @@ -254,7 +254,7 @@ const CreateTicketFlow: React.FC<CreateTicketFlowProps> = ({ isLoggedIn }) => {
)}
{(!user || !user.uuid) && (
<div className="mb-4">
<p className="font-bold mb-1">Your Contact Info</p>
<p className="font-bold mb-1 text-lg">Your Contact Info</p>
<div className="flex flex-col lg:flex-row w-full">
<div className="w-full mr-8">
<CtlTextInput
Expand Down Expand Up @@ -320,7 +320,11 @@ const CreateTicketFlow: React.FC<CreateTicketFlowProps> = ({ isLoggedIn }) => {
<Divider className="" />
</div>
)}
<p className="font-bold !mb-2">Request Info</p>
<p className="font-bold !mb-0 text-lg">Request Info</p>
<p className="text-gray-500 text-sm !mt-1">
Please only submit one ticket per issue. If you have multiple
issues, please submit a separate ticket for each.
</p>
<div className="!mt-0">
<CtlTextInput
control={control}
Expand Down Expand Up @@ -454,6 +458,13 @@ const CreateTicketFlow: React.FC<CreateTicketFlowProps> = ({ isLoggedIn }) => {
passwords) in your description.
</p>
</Form.Field>
<p className="text-center italic">
<strong>Note:</strong> Please include any relevant ADAPT question
or course ID's in your description. Screenshots and videos of the
issue are also extremely helpful. If your issue is related to a
Conductor project, please include the project ID if possible. This
will help us resolve your issue faster.
</p>
</Form>
<label className="form-field-label">
Attachments (optional) (max 4 files, 100 MB each)
Expand Down
Loading