route element file uploads
Add short and long PDF paths to elements, keep pdfPath as a short PDF compatibility alias, and route generic file uploads by fileType.
This commit is contained in:
parent
0d5783ba9c
commit
9bbabc7fa6
28 changed files with 686 additions and 214 deletions
|
|
@ -1,4 +1,4 @@
|
|||
import { ref } from 'vue'
|
||||
import { ref, type Ref } from 'vue'
|
||||
import { defineStore } from 'pinia'
|
||||
|
||||
export interface ChildElement {
|
||||
|
|
@ -10,10 +10,14 @@ export interface ChildElement {
|
|||
export interface Element extends ChildElement {
|
||||
iconImageUrl: string | null
|
||||
richText: string
|
||||
shortPdfPath: string | null
|
||||
longPdfPath: string | null
|
||||
pdfPath: string | null
|
||||
youtubeUrl: string | null
|
||||
}
|
||||
|
||||
type ElementFileType = 'iconImage' | 'shortPdf' | 'longPdf'
|
||||
|
||||
interface ElementResponse {
|
||||
element: Element
|
||||
childElements: ChildElement[]
|
||||
|
|
@ -35,6 +39,8 @@ interface ElementPatchInput {
|
|||
description?: string
|
||||
iconImageUrl?: string
|
||||
richText?: string
|
||||
shortPdfPath?: string
|
||||
longPdfPath?: string
|
||||
pdfPath?: string
|
||||
youtubeUrl?: string
|
||||
}
|
||||
|
|
@ -53,7 +59,8 @@ export const useElementsStore = defineStore('elements', () => {
|
|||
const error = ref<string | null>(null)
|
||||
const isSaving = ref(false)
|
||||
const isUploadingIconImage = ref(false)
|
||||
const isUploadingPdf = ref(false)
|
||||
const isUploadingShortPdf = ref(false)
|
||||
const isUploadingLongPdf = ref(false)
|
||||
const saveError = ref<string | null>(null)
|
||||
|
||||
async function fetchElement(elementId: string): Promise<void> {
|
||||
|
|
@ -89,16 +96,35 @@ export const useElementsStore = defineStore('elements', () => {
|
|||
}
|
||||
}
|
||||
|
||||
async function updateElement(elementId: string, input: UpdateElementInput): Promise<boolean> {
|
||||
async function updateElement(
|
||||
elementId: string,
|
||||
input: UpdateElementInput,
|
||||
): Promise<boolean> {
|
||||
return await saveElementPatch(elementId, input, 'Could not save element')
|
||||
}
|
||||
|
||||
async function clearElementIconImage(elementId: string): Promise<boolean> {
|
||||
return await saveElementPatch(elementId, { iconImageUrl: '' }, 'Could not remove icon image')
|
||||
return await saveElementPatch(
|
||||
elementId,
|
||||
{ iconImageUrl: '' },
|
||||
'Could not remove icon image',
|
||||
)
|
||||
}
|
||||
|
||||
async function clearElementPdf(elementId: string): Promise<boolean> {
|
||||
return await saveElementPatch(elementId, { pdfPath: '' }, 'Could not remove PDF')
|
||||
async function clearElementShortPdf(elementId: string): Promise<boolean> {
|
||||
return await saveElementPatch(
|
||||
elementId,
|
||||
{ shortPdfPath: '' },
|
||||
'Could not remove short PDF',
|
||||
)
|
||||
}
|
||||
|
||||
async function clearElementLongPdf(elementId: string): Promise<boolean> {
|
||||
return await saveElementPatch(
|
||||
elementId,
|
||||
{ longPdfPath: '' },
|
||||
'Could not remove long PDF',
|
||||
)
|
||||
}
|
||||
|
||||
async function saveElementPatch(
|
||||
|
|
@ -126,38 +152,64 @@ export const useElementsStore = defineStore('elements', () => {
|
|||
}
|
||||
}
|
||||
|
||||
async function uploadElementIconImage(elementId: string, file: File): Promise<boolean> {
|
||||
saveError.value = null
|
||||
isUploadingIconImage.value = true
|
||||
|
||||
try {
|
||||
const formData = new FormData()
|
||||
formData.append('elementId', elementId)
|
||||
formData.append('iconImage', file)
|
||||
const response = await fetch(ELEMENT_UPDATE_URL, {
|
||||
method: 'POST',
|
||||
headers: { Accept: 'application/json' },
|
||||
credentials: 'include',
|
||||
body: formData,
|
||||
})
|
||||
|
||||
return await handleElementResponse(response, 'Could not upload icon image')
|
||||
} catch {
|
||||
saveError.value = 'Network error - could not upload icon image'
|
||||
return false
|
||||
} finally {
|
||||
isUploadingIconImage.value = false
|
||||
}
|
||||
async function uploadElementIconImage(
|
||||
elementId: string,
|
||||
file: File,
|
||||
): Promise<boolean> {
|
||||
return await uploadElementFile(
|
||||
elementId,
|
||||
file,
|
||||
'iconImage',
|
||||
isUploadingIconImage,
|
||||
'Could not upload icon image',
|
||||
'Network error - could not upload icon image',
|
||||
)
|
||||
}
|
||||
|
||||
async function uploadElementPdf(elementId: string, file: File): Promise<boolean> {
|
||||
async function uploadElementShortPdf(
|
||||
elementId: string,
|
||||
file: File,
|
||||
): Promise<boolean> {
|
||||
return await uploadElementFile(
|
||||
elementId,
|
||||
file,
|
||||
'shortPdf',
|
||||
isUploadingShortPdf,
|
||||
'Could not upload short PDF',
|
||||
'Network error - could not upload short PDF',
|
||||
)
|
||||
}
|
||||
|
||||
async function uploadElementLongPdf(
|
||||
elementId: string,
|
||||
file: File,
|
||||
): Promise<boolean> {
|
||||
return await uploadElementFile(
|
||||
elementId,
|
||||
file,
|
||||
'longPdf',
|
||||
isUploadingLongPdf,
|
||||
'Could not upload long PDF',
|
||||
'Network error - could not upload long PDF',
|
||||
)
|
||||
}
|
||||
|
||||
async function uploadElementFile(
|
||||
elementId: string,
|
||||
file: File,
|
||||
fileType: ElementFileType,
|
||||
isUploadingFile: Ref<boolean>,
|
||||
failureMessage: string,
|
||||
networkErrorMessage: string,
|
||||
): Promise<boolean> {
|
||||
saveError.value = null
|
||||
isUploadingPdf.value = true
|
||||
isUploadingFile.value = true
|
||||
|
||||
try {
|
||||
const formData = new FormData()
|
||||
formData.append('elementId', elementId)
|
||||
formData.append('pdf', file)
|
||||
formData.append('fileType', fileType)
|
||||
formData.append('file', file)
|
||||
const response = await fetch(ELEMENT_UPDATE_URL, {
|
||||
method: 'POST',
|
||||
headers: { Accept: 'application/json' },
|
||||
|
|
@ -165,12 +217,12 @@ export const useElementsStore = defineStore('elements', () => {
|
|||
body: formData,
|
||||
})
|
||||
|
||||
return await handleElementResponse(response, 'Could not upload PDF')
|
||||
return await handleElementResponse(response, failureMessage)
|
||||
} catch {
|
||||
saveError.value = 'Network error - could not upload PDF'
|
||||
saveError.value = networkErrorMessage
|
||||
return false
|
||||
} finally {
|
||||
isUploadingPdf.value = false
|
||||
isUploadingFile.value = false
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -203,7 +255,10 @@ export const useElementsStore = defineStore('elements', () => {
|
|||
return true
|
||||
}
|
||||
|
||||
async function errorMessage(response: Response, fallbackMessage: string): Promise<string> {
|
||||
async function errorMessage(
|
||||
response: Response,
|
||||
fallbackMessage: string,
|
||||
): Promise<string> {
|
||||
try {
|
||||
const data: ErrorResponse = await response.json()
|
||||
return data.error ?? fallbackMessage
|
||||
|
|
@ -219,13 +274,16 @@ export const useElementsStore = defineStore('elements', () => {
|
|||
error,
|
||||
isSaving,
|
||||
isUploadingIconImage,
|
||||
isUploadingPdf,
|
||||
isUploadingShortPdf,
|
||||
isUploadingLongPdf,
|
||||
saveError,
|
||||
fetchElement,
|
||||
updateElement,
|
||||
uploadElementIconImage,
|
||||
uploadElementPdf,
|
||||
uploadElementShortPdf,
|
||||
uploadElementLongPdf,
|
||||
clearElementIconImage,
|
||||
clearElementPdf,
|
||||
clearElementShortPdf,
|
||||
clearElementLongPdf,
|
||||
}
|
||||
})
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue