mirror of
https://github.com/utopia-os/utopia-ui.git
synced 2026-03-01 12:44:17 +00:00
Make gallery upload work; improve typing
This commit is contained in:
parent
6a68300cea
commit
b87a12a1d8
@ -2,6 +2,8 @@ import { describe, it, expect, vi } from 'vitest'
|
||||
|
||||
import { linkItem } from './itemFunctions'
|
||||
|
||||
import type { Item } from '#types/Item'
|
||||
|
||||
const toastErrorMock: (t: string) => void = vi.fn()
|
||||
const toastSuccessMock: (t: string) => void = vi.fn()
|
||||
|
||||
@ -14,8 +16,45 @@ vi.mock('react-toastify', () => ({
|
||||
|
||||
describe('linkItem', () => {
|
||||
const id = 'some-id'
|
||||
let updateApi: () => void = vi.fn()
|
||||
const item = { layer: { api: { updateItem: () => updateApi() } } }
|
||||
let updateApi: (item: Partial<Item>) => Promise<Item> = vi.fn()
|
||||
const item: Item = {
|
||||
layer: {
|
||||
api: {
|
||||
updateItem: (item) => updateApi(item),
|
||||
getItems: vi.fn(),
|
||||
},
|
||||
name: '',
|
||||
menuIcon: '',
|
||||
menuColor: '',
|
||||
menuText: '',
|
||||
markerIcon: {
|
||||
image: '',
|
||||
},
|
||||
markerShape: 'square',
|
||||
markerDefaultColor: '',
|
||||
itemType: {
|
||||
name: 'Test Item Type',
|
||||
show_name_input: true,
|
||||
show_profile_button: false,
|
||||
show_start_end: true,
|
||||
show_start_end_input: true,
|
||||
show_text: true,
|
||||
show_text_input: true,
|
||||
custom_text: 'This is a custom text for the item type.',
|
||||
profileTemplate: [
|
||||
{ collection: 'users', id: null, item: {} },
|
||||
{ collection: 'posts', id: '123', item: {} },
|
||||
],
|
||||
offers_and_needs: true,
|
||||
icon_as_labels: {},
|
||||
relations: true,
|
||||
template: 'default',
|
||||
questlog: false,
|
||||
},
|
||||
},
|
||||
id: '',
|
||||
name: '',
|
||||
}
|
||||
const updateItem = vi.fn()
|
||||
|
||||
beforeEach(() => {
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
/* eslint-disable @typescript-eslint/restrict-template-expressions */
|
||||
/* eslint-disable @typescript-eslint/no-unnecessary-condition */
|
||||
/* eslint-disable @typescript-eslint/no-unsafe-argument */
|
||||
import { useEffect, useState } from 'react'
|
||||
import { useLocation, useNavigate } from 'react-router-dom'
|
||||
import { toast } from 'react-toastify'
|
||||
@ -200,8 +199,8 @@ export function ProfileForm() {
|
||||
state={state}
|
||||
setState={setState}
|
||||
updatePermission={updatePermission}
|
||||
linkItem={(id) => linkItem(id, item, updateItem)}
|
||||
unlinkItem={(id) => unlinkItem(id, item, updateItem)}
|
||||
linkItem={(id: string) => linkItem(id, item, updateItem)}
|
||||
unlinkItem={(id: string) => unlinkItem(id, item, updateItem)}
|
||||
setUrlParams={setUrlParams}
|
||||
></TabsForm>
|
||||
)}
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import { useState } from 'react'
|
||||
import { useDropzone } from 'react-dropzone'
|
||||
|
||||
import { useAppState } from '#components/AppShell/hooks/useAppState'
|
||||
@ -12,7 +13,11 @@ interface Props {
|
||||
export const GalleryForm = ({ state, setState }: Props) => {
|
||||
const appState = useAppState()
|
||||
|
||||
const [isUploading, setUploading] = useState(false)
|
||||
|
||||
const upload = async (acceptedFiles: File[]) => {
|
||||
setUploading(true)
|
||||
|
||||
const assets = await Promise.all(
|
||||
acceptedFiles.map(async (file) => {
|
||||
return appState.assetsApi.upload(file, 'gallery')
|
||||
@ -22,11 +27,13 @@ export const GalleryForm = ({ state, setState }: Props) => {
|
||||
const newGalleryItems = assets.map((asset) => ({
|
||||
directus_files_id: {
|
||||
id: asset.id,
|
||||
width: 600, // TODO determine
|
||||
height: 400, // TODO determine
|
||||
width: 600, // TODO map to ids only
|
||||
height: 400,
|
||||
},
|
||||
}))
|
||||
|
||||
setUploading(false)
|
||||
|
||||
setState((prevState) => ({
|
||||
...prevState,
|
||||
gallery: [...prevState.gallery, ...newGalleryItems],
|
||||
@ -36,6 +43,9 @@ export const GalleryForm = ({ state, setState }: Props) => {
|
||||
const { getRootProps, getInputProps } = useDropzone({
|
||||
// eslint-disable-next-line @typescript-eslint/no-misused-promises
|
||||
onDrop: upload,
|
||||
accept: {
|
||||
'image/jpeg': [],
|
||||
},
|
||||
})
|
||||
|
||||
const images = state.gallery.map((i, j) => ({
|
||||
@ -62,6 +72,8 @@ export const GalleryForm = ({ state, setState }: Props) => {
|
||||
Drop here
|
||||
</div>
|
||||
|
||||
{isUploading && <div className='tw:mt-2 tw:text-gray-500'>Uploading...</div>}
|
||||
|
||||
{images.map((image, index) => (
|
||||
<div key={index} className='tw:mb-2'>
|
||||
<img
|
||||
|
||||
@ -15,6 +15,7 @@ import { encodeTag } from '#utils/FormatTags'
|
||||
import { hashTagRegex } from '#utils/HashTagRegex'
|
||||
import { randomColor } from '#utils/RandomColor'
|
||||
|
||||
import type { FormState } from '#types/FormState'
|
||||
import type { Item } from '#types/Item'
|
||||
|
||||
// eslint-disable-next-line promise/avoid-new
|
||||
@ -77,8 +78,8 @@ export const submitNewItem = async (
|
||||
setAddItemPopupType('')
|
||||
}
|
||||
|
||||
export const linkItem = async (id: string, item, updateItem) => {
|
||||
const newRelations = item.relations || []
|
||||
export const linkItem = async (id: string, item: Item, updateItem) => {
|
||||
const newRelations = item.relations ?? []
|
||||
newRelations?.push({ items_id: item.id, related_items_id: id })
|
||||
const updatedItem = { id: item.id, relations: newRelations }
|
||||
|
||||
@ -96,7 +97,7 @@ export const linkItem = async (id: string, item, updateItem) => {
|
||||
}
|
||||
}
|
||||
|
||||
export const unlinkItem = async (id: string, item, updateItem) => {
|
||||
export const unlinkItem = async (id: string, item: Item, updateItem) => {
|
||||
const newRelations = item.relations?.filter((r) => r.related_items_id !== id)
|
||||
const updatedItem = { id: item.id, relations: newRelations }
|
||||
|
||||
@ -116,7 +117,7 @@ export const unlinkItem = async (id: string, item, updateItem) => {
|
||||
|
||||
export const handleDelete = async (
|
||||
event: React.MouseEvent<HTMLElement>,
|
||||
item,
|
||||
item: Item,
|
||||
setLoading,
|
||||
removeItem,
|
||||
map,
|
||||
@ -144,8 +145,8 @@ export const handleDelete = async (
|
||||
}
|
||||
|
||||
export const onUpdateItem = async (
|
||||
state,
|
||||
item,
|
||||
state: FormState,
|
||||
item: Item,
|
||||
tags,
|
||||
addTag,
|
||||
setLoading,
|
||||
@ -159,19 +160,20 @@ export const onUpdateItem = async (
|
||||
|
||||
const offerUpdates: any[] = []
|
||||
// check for new offers
|
||||
await state.offers?.map((o) => {
|
||||
state.offers?.map((o) => {
|
||||
const existingOffer = item?.offers?.find((t) => t.tags_id === o.id)
|
||||
existingOffer && offerUpdates.push(existingOffer.id)
|
||||
if (!existingOffer && !tags.some((t) => t.id === o.id)) addTag({ ...o, offer_or_need: true })
|
||||
existingOffer && offerUpdates.push(existingOffer.tags_id)
|
||||
if (!existingOffer && !tags.some((t: { id: string }) => t.id === o.id))
|
||||
addTag({ ...o, offer_or_need: true })
|
||||
!existingOffer && offerUpdates.push({ items_id: item?.id, tags_id: o.id })
|
||||
return null
|
||||
})
|
||||
|
||||
const needsUpdates: any[] = []
|
||||
|
||||
await state.needs?.map((n) => {
|
||||
state.needs?.map((n) => {
|
||||
const existingNeed = item?.needs?.find((t) => t.tags_id === n.id)
|
||||
existingNeed && needsUpdates.push(existingNeed.id)
|
||||
existingNeed && needsUpdates.push(existingNeed.tags_id)
|
||||
!existingNeed && needsUpdates.push({ items_id: item?.id, tags_id: n.id })
|
||||
!existingNeed && !tags.some((t) => t.id === n.id) && addTag({ ...n, offer_or_need: true })
|
||||
return null
|
||||
@ -197,6 +199,7 @@ export const onUpdateItem = async (
|
||||
...(state.offers.length > 0 && { offers: offerUpdates }),
|
||||
...(state.needs.length > 0 && { needs: needsUpdates }),
|
||||
...(state.openCollectiveSlug && { openCollectiveSlug: state.openCollectiveSlug }),
|
||||
gallery: state.gallery,
|
||||
}
|
||||
|
||||
const offersState: any[] = []
|
||||
@ -216,7 +219,7 @@ export const onUpdateItem = async (
|
||||
|
||||
setLoading(true)
|
||||
|
||||
await state.text
|
||||
state.text
|
||||
.toLocaleLowerCase()
|
||||
.match(hashTagRegex)
|
||||
?.map((tag) => {
|
||||
@ -234,7 +237,7 @@ export const onUpdateItem = async (
|
||||
await sleep(200)
|
||||
|
||||
if (!item.new) {
|
||||
item?.layer?.api?.updateItem &&
|
||||
await (item?.layer?.api?.updateItem &&
|
||||
toast
|
||||
.promise(item?.layer?.api?.updateItem(changedItem), {
|
||||
pending: 'updating Item ...',
|
||||
@ -251,10 +254,10 @@ export const onUpdateItem = async (
|
||||
setLoading(false)
|
||||
navigate(`/item/${item.id}${params && '?' + params}`)
|
||||
return null
|
||||
})
|
||||
}))
|
||||
} else {
|
||||
item.new = false
|
||||
item.layer?.api?.createItem &&
|
||||
await (item.layer?.api?.createItem &&
|
||||
toast
|
||||
.promise(item.layer?.api?.createItem(changedItem), {
|
||||
pending: 'updating Item ...',
|
||||
@ -280,6 +283,6 @@ export const onUpdateItem = async (
|
||||
setLoading(false)
|
||||
navigate(`/${params && '?' + params}`)
|
||||
return null
|
||||
})
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user