Skip to content

Commit

Permalink
make upload work from within ui
Browse files Browse the repository at this point in the history
  • Loading branch information
ghackenberg committed Nov 25, 2023
1 parent 6af3ce1 commit 717392d
Show file tree
Hide file tree
Showing 5 changed files with 53 additions and 54 deletions.
15 changes: 1 addition & 14 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,21 +14,8 @@ database.sqlite

*.jwk

# Assets
packages/backend/assets/ldraw

# Models
packages/backend/uploads/*.glb
packages/backend/uploads/*.ldr
packages/backend/uploads/*.mpd

# Images
packages/backend/uploads/*.gif
packages/backend/uploads/*.jpg
packages/backend/uploads/*.png

# Audios
packages/backend/uploads/*.webm
packages/backend/uploads/*

manuscripts/*/*.aux
manuscripts/*/*.bbl
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ export class AttachmentController implements AttachmentREST<string, string, Expr
@UploadedFile() file: Express.Multer.File
): Promise<Attachment> {
await canCreateAttachmentOrFail(this.request.user.userId, productId)
return this.addAttachment(productId, JSON.parse(data), file)
return this.service.addAttachment(productId, JSON.parse(data), file)
}

@Get(':attachmentId')
Expand All @@ -75,7 +75,6 @@ export class AttachmentController implements AttachmentREST<string, string, Expr
@Param('productId') productId: string,
@Param('attachmentId') attachmentId: string
): Promise<StreamableFile> {
await canReadAttachmentOrFail(this.request.user.userId, productId, attachmentId)
const attachment = await this.service.getAttachment(productId, attachmentId)
return new StreamableFile(await this.service.getAttachmentFile(productId, attachmentId), {
type: attachment.type
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ export class AttachmentService implements AttachmentREST<AttachmentAddData, Atta
const created = Date.now()
const updated = created
const userId = this.request.user.userId
const attachment = await Database.get().attachmentRepository.save({ productId, attachmentId, created, updated, userId, ...data })
const attachment = await Database.get().attachmentRepository.save({ productId, attachmentId, userId, created, updated, ...data })
// Update product
const product = await Database.get().productRepository.findOneBy({ productId })
product.updated = attachment.updated
Expand Down
34 changes: 20 additions & 14 deletions packages/frontend/src/scripts/clients/rest/attachment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,23 +9,29 @@ class AttachmentClientImpl implements AttachmentREST<AttachmentAddData, Attachme
async findAttachments(productId: string): Promise<Attachment[]> {
return (await axios.get<Attachment[]>(`/rest/products/${productId}/attachments`, auth)).data
}
async addAttachment(productId: string, data: AttachmentAddData): Promise<Attachment> {
const issue = (await axios.post<Attachment>(`/rest/products/${productId}/attachments`, data, auth)).data
CacheAPI.putAttachment(issue)
return issue
async addAttachment(productId: string, data: AttachmentAddData, file: File): Promise<Attachment> {
const body = new FormData()
body.append('data', JSON.stringify(data))
body.append('file', file)
const attachment = (await axios.post<Attachment>(`/rest/products/${productId}/attachments`, body, auth)).data
CacheAPI.putAttachment(attachment)
return attachment
}
async getAttachment(productId: string, issueId: string): Promise<Attachment> {
return (await axios.get<Attachment>(`/rest/products/${productId}/attachments/${issueId}`, { ...auth })).data
async getAttachment(productId: string, attachmentId: string): Promise<Attachment> {
return (await axios.get<Attachment>(`/rest/products/${productId}/attachments/${attachmentId}`, { ...auth })).data
}
async updateAttachment(productId: string, issueId: string, data: AttachmentUpdateData): Promise<Attachment> {
const issue = (await axios.put<Attachment>(`/rest/products/${productId}/attachments/${issueId}`, data, auth)).data
CacheAPI.putAttachment(issue)
return issue
async updateAttachment(productId: string, attachmentId: string, data: AttachmentUpdateData, file: File): Promise<Attachment> {
const body = new FormData()
body.append('data', JSON.stringify(data))
body.append('file', file)
const attachment = (await axios.put<Attachment>(`/rest/products/${productId}/attachments/${attachmentId}`, body, auth)).data
CacheAPI.putAttachment(attachment)
return attachment
}
async deleteAttachment(productId: string, issueId: string): Promise<Attachment> {
const issue = (await axios.delete<Attachment>(`/rest/products/${productId}/attachments/${issueId}`, auth)).data
CacheAPI.putAttachment(issue)
return issue
async deleteAttachment(productId: string, attachmentId: string): Promise<Attachment> {
const attachment = (await axios.delete<Attachment>(`/rest/products/${productId}/attachments/${attachmentId}`, auth)).data
CacheAPI.putAttachment(attachment)
return attachment
}
}

Expand Down
53 changes: 30 additions & 23 deletions packages/frontend/src/scripts/components/widgets/CommentView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { Object3D } from 'three'

import { Version } from 'productboard-common'

import { AttachmentClient } from '../../clients/rest/attachment'
import { CommentClient } from '../../clients/rest/comment'
import { CommentContext } from '../../contexts/Comment'
import { UserContext } from '../../contexts/User'
Expand Down Expand Up @@ -93,6 +94,7 @@ export const CommentView = (props: { productId: string, issueId: string, comment
const [partsEdit, setPartsEdit] = React.useState(initialPartsEdit)

const [mode, setMode] = React.useState(initialMode)
const [upload, setUpload] = React.useState(false)

// EFFECTS

Expand All @@ -102,7 +104,7 @@ export const CommentView = (props: { productId: string, issueId: string, comment
const text = textEdit || ''
const before = text.substring(0, textRef.current.selectionStart)
const after = text.substring(textRef.current.selectionEnd)
const markdown = `${before && before.charAt(before.length - 1) != '\n' ? '\n' : ''} - [${object.name} @ Version ${version.major}.${version.minor}.${version.patch}](/products/${productId}/versions/${version.versionId}/objects/${computePath(object)})${after && after.charAt(0) != '\n' ? '\n' : ''}`
const markdown = `${before && before.charAt(before.length - 1) != '\n' ? '\n' : ''}- [${object.name} @ Version ${version.major}.${version.minor}.${version.patch}](/products/${productId}/versions/${version.versionId}/objects/${computePath(object)})${after && after.charAt(0) != '\n' ? '\n' : ''}`
setTextEdit(`${before}${markdown}${after}`)
setTimeout(() => {
textRef.current.setSelectionRange(before.length + markdown.length, before.length + markdown.length)
Expand Down Expand Up @@ -155,30 +157,35 @@ export const CommentView = (props: { productId: string, issueId: string, comment
setContextComment(comment)
}

function handlePaste(event: React.ClipboardEvent<HTMLTextAreaElement>) {
if (mode == Mode.EDIT) {
async function handlePaste(event: React.ClipboardEvent<HTMLTextAreaElement>) {
if (mode == Mode.EDIT && !upload) {
for (const index in event.clipboardData.items) {
const item = event.clipboardData.items[index]
if (item.kind == 'file') {
if (item.type == 'image/png') {
const file = item.getAsFile()
const reader = new FileReader()
reader.onload = event => {
console.log('load', event.target.result)
/*
const text = textEdit || ''
const before = text.substring(0, textRef.current.selectionStart)
const after = text.substring(textRef.current.selectionEnd)
const markdown = `${before && before.charAt(before.length - 1) != '\n' ? '\n' : ''}![Pasted image](${event.target.result})${after && after.charAt(0) != '\n' ? '\n' : ''}`
setTextEdit(`${before}${markdown}${after}`)
setTimeout(() => {
textRef.current.setSelectionRange(before.length + markdown.length, before.length + markdown.length)
textRef.current.focus()
}, 0)
*/
}
reader.readAsDataURL(file)
setUpload(true)

const file = item.getAsFile()
const attachment = await AttachmentClient.addAttachment(productId, { type: file.type }, file)

const text = textEdit || ''
const before = text.substring(0, textRef.current.selectionStart)
const after = text.substring(textRef.current.selectionEnd)

let markdown: string

if (file.type.startsWith('image/')) {
markdown = `![${file.name}](/rest/products/${productId}/attachments/${attachment.attachmentId}/file)`
} else {
markdown = `- [${file.name}](/rest/products/${productId}/attachments/${attachment.attachmentId}/file)`
}

setTextEdit(`${before}${markdown}${after}`)
setTimeout(() => {
textRef.current.setSelectionRange(before.length + markdown.length, before.length + markdown.length)
textRef.current.focus()
}, 0)

setUpload(false)
}
}
}
Expand Down Expand Up @@ -294,11 +301,11 @@ export const CommentView = (props: { productId: string, issueId: string, comment
<p>
{comment ? (
<>
<strong><ProductUserName userId={userId} productId={productId}/></strong> commented on {formatDateTime(new Date(comment.created))} {action}
<strong><ProductUserName userId={userId} productId={productId}/></strong> commented on {formatDateTime(new Date(comment.created))} {upload ? 'uploading ...' : action}
</>
) : (
<>
<strong>New comment</strong> ({disabled ? 'requires login' : toggle})
<strong>New comment</strong> ({disabled ? 'requires login' : (upload ? 'uploading ...' : toggle)})
</>
)}
</p>
Expand Down

0 comments on commit 717392d

Please sign in to comment.