mirror of
https://github.com/utopia-os/utopia-ui.git
synced 2025-12-12 23:36:00 +00:00
fix(source): select position on index page (#240)
* 3.0.97 * 3.0.98 * 3.0.99 * add select position to item menu on index page * added tooltips to headermenu * optimized toasts while updating item position
This commit is contained in:
parent
a7a50af896
commit
55c39bef88
@ -137,7 +137,8 @@ export function HeaderView({
|
||||
editCallback && (
|
||||
<li>
|
||||
<a
|
||||
className='tw:text-base-content! tw:cursor-pointer'
|
||||
className='tw:text-base-content! tw:tooltip tw:tooltip-right tw:cursor-pointer'
|
||||
data-tip='Edit'
|
||||
onClick={(e) =>
|
||||
item.layer?.customEditLink
|
||||
? navigate(
|
||||
@ -155,7 +156,8 @@ export function HeaderView({
|
||||
setPositionCallback && (
|
||||
<li>
|
||||
<a
|
||||
className='tw:text-base-content! tw:cursor-pointer'
|
||||
className='tw:text-base-content! tw:tooltip tw:tooltip-right tw:cursor-pointer'
|
||||
data-tip='Set position'
|
||||
onClick={setPositionCallback}
|
||||
>
|
||||
<SVG src={TargetDotSVG} className='tw:w-5 tw:h-5' />
|
||||
@ -166,7 +168,11 @@ export function HeaderView({
|
||||
hasUserPermission(api.collectionName!, 'delete', item) &&
|
||||
deleteCallback && (
|
||||
<li>
|
||||
<a className='tw:cursor-pointer tw:text-error!' onClick={openDeleteModal}>
|
||||
<a
|
||||
className='tw:text-error! tw:tooltip tw:tooltip-right tw:cursor-pointer'
|
||||
data-tip='Delete'
|
||||
onClick={openDeleteModal}
|
||||
>
|
||||
{loading ? (
|
||||
<span className='tw:loading tw:loading-spinner tw:loading-sm'></span>
|
||||
) : (
|
||||
|
||||
@ -1,5 +1,13 @@
|
||||
/* eslint-disable @typescript-eslint/no-unsafe-call */
|
||||
export const SelectPosition = ({ setSelectNewItemPosition }: { setSelectNewItemPosition }) => {
|
||||
import type { Item } from '#types/Item'
|
||||
import type { LayerProps } from '#types/LayerProps'
|
||||
|
||||
export const SelectPosition = ({
|
||||
setSelectNewItemPosition,
|
||||
selectNewItemPosition,
|
||||
}: {
|
||||
setSelectNewItemPosition: React.Dispatch<React.SetStateAction<Item | LayerProps | null>>
|
||||
selectNewItemPosition?: Item | LayerProps | null
|
||||
}) => {
|
||||
return (
|
||||
<div className='tw:animate-pulseGrow tw:button tw:z-1000 tw:absolute tw:right-5 tw:top-4 tw:drop-shadow-md'>
|
||||
<label
|
||||
@ -12,7 +20,14 @@ export const SelectPosition = ({ setSelectNewItemPosition }: { setSelectNewItemP
|
||||
</label>
|
||||
<div className='tw:alert tw:bg-base-100 tw:text-base-content'>
|
||||
<div>
|
||||
<span className='tw:text-lg'>Select position on the map!</span>
|
||||
{selectNewItemPosition && 'text' in selectNewItemPosition && (
|
||||
<span className='tw:text-lg'>
|
||||
Select new position of <b>{selectNewItemPosition.name}</b> on the map!
|
||||
</span>
|
||||
)}
|
||||
{selectNewItemPosition && 'menuIcon' in selectNewItemPosition && (
|
||||
<span className='tw:text-lg'>Select position on the map!</span>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -307,7 +307,10 @@ export function UtopiaMapInner({
|
||||
<MapEventListener />
|
||||
<AddButton triggerAction={setSelectNewItemPosition} />
|
||||
{selectNewItemPosition != null && (
|
||||
<SelectPosition setSelectNewItemPosition={setSelectNewItemPosition} />
|
||||
<SelectPosition
|
||||
selectNewItemPosition={selectNewItemPosition}
|
||||
setSelectNewItemPosition={setSelectNewItemPosition}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
|
||||
@ -5,8 +5,7 @@
|
||||
/* eslint-disable @typescript-eslint/prefer-nullish-coalescing */
|
||||
/* eslint-disable @typescript-eslint/await-thenable */
|
||||
/* eslint-disable @typescript-eslint/restrict-plus-operands */
|
||||
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
|
||||
/* eslint-disable @typescript-eslint/no-unsafe-call */
|
||||
|
||||
/* eslint-disable @typescript-eslint/no-non-null-assertion */
|
||||
import { createContext, useContext, useEffect, useState } from 'react'
|
||||
import { toast } from 'react-toastify'
|
||||
@ -87,6 +86,7 @@ function useSelectPositionManager(): {
|
||||
}, [mapClicked])
|
||||
|
||||
const itemUpdateParent = async (updatedItem: Item) => {
|
||||
const toastId = toast.loading('Adding item to ' + markerClicked?.name)
|
||||
if (
|
||||
markerClicked?.layer?.api?.collectionName &&
|
||||
hasUserPermission(markerClicked.layer.api.collectionName, 'update', markerClicked)
|
||||
@ -99,40 +99,57 @@ function useSelectPositionManager(): {
|
||||
position: null,
|
||||
})
|
||||
success = true
|
||||
// eslint-disable-next-line no-catch-all/no-catch-all
|
||||
} catch (error) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
||||
toast.error(error.toString())
|
||||
} catch (error: unknown) {
|
||||
if (error instanceof Error) {
|
||||
toast.update(toastId, { render: error.message, type: 'error' })
|
||||
} else if (typeof error === 'string') {
|
||||
toast.update(toastId, { render: error, type: 'error' })
|
||||
} else {
|
||||
throw error
|
||||
}
|
||||
}
|
||||
if (success) {
|
||||
await updateItem({ ...updatedItem, parent: updatedItem.parent, position: undefined })
|
||||
await linkItem(updatedItem.id)
|
||||
toast.success('Item position updated')
|
||||
toast.update(toastId, {
|
||||
render: 'Item position updated',
|
||||
type: 'success',
|
||||
isLoading: false,
|
||||
})
|
||||
setSelectPosition(null)
|
||||
setMarkerClicked(null)
|
||||
}
|
||||
} else {
|
||||
setSelectPosition(null)
|
||||
toast.error("you don't have permission to add items to " + markerClicked?.name)
|
||||
toast.update(toastId, {
|
||||
render: "you don't have permission to add items to " + markerClicked?.name,
|
||||
type: 'error',
|
||||
isLoading: false,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const itemUpdatePosition = async (updatedItem: Item) => {
|
||||
let success = false
|
||||
const toastId = toast.loading('Updating item position')
|
||||
try {
|
||||
await updatedItem.layer?.api?.updateItem!({
|
||||
id: updatedItem.id,
|
||||
position: updatedItem.position,
|
||||
})
|
||||
success = true
|
||||
// eslint-disable-next-line no-catch-all/no-catch-all
|
||||
} catch (error) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
||||
toast.error(error.toString())
|
||||
} catch (error: unknown) {
|
||||
if (error instanceof Error) {
|
||||
toast.update(toastId, { render: error.message, type: 'error', isLoading: false })
|
||||
} else if (typeof error === 'string') {
|
||||
toast.update(toastId, { render: error, type: 'error', isLoading: false })
|
||||
} else {
|
||||
throw error
|
||||
}
|
||||
}
|
||||
if (success) {
|
||||
updateItem(updatedItem)
|
||||
toast.success('Item position updated')
|
||||
toast.update(toastId, { render: 'Item position updated', type: 'success', isLoading: false })
|
||||
}
|
||||
}
|
||||
|
||||
@ -145,17 +162,22 @@ function useSelectPositionManager(): {
|
||||
const updatedItem = { id: markerClicked.id, relations: newRelations }
|
||||
|
||||
let success = false
|
||||
const toastId = toast.loading('Linking item')
|
||||
try {
|
||||
await markerClicked.layer?.api?.updateItem!(updatedItem)
|
||||
success = true
|
||||
// eslint-disable-next-line no-catch-all/no-catch-all
|
||||
} catch (error) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
||||
toast.error(error.toString())
|
||||
} catch (error: unknown) {
|
||||
if (error instanceof Error) {
|
||||
toast.update(toastId, { render: error.message, type: 'error', isLoading: false })
|
||||
} else if (typeof error === 'string') {
|
||||
toast.update(toastId, { render: error, type: 'error', isLoading: false })
|
||||
} else {
|
||||
throw error
|
||||
}
|
||||
}
|
||||
if (success) {
|
||||
updateItem({ ...markerClicked, relations: newRelations })
|
||||
toast.success('Item linked')
|
||||
toast.update(toastId, { render: 'Item linked', type: 'success', isLoading: false })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
import { useMap } from 'react-leaflet'
|
||||
import { useNavigate } from 'react-router-dom'
|
||||
|
||||
import { useSetSelectPosition } from '#components/Map/hooks/useSelectPosition'
|
||||
import useWindowDimensions from '#components/Map/hooks/useWindowDimension'
|
||||
import { StartEndView, TextView } from '#components/Map/Subcomponents/ItemPopupComponents'
|
||||
import { HeaderView } from '#components/Map/Subcomponents/ItemPopupComponents/HeaderView'
|
||||
@ -21,6 +23,8 @@ export const ItemCard = ({
|
||||
}) => {
|
||||
const navigate = useNavigate()
|
||||
const windowDimensions = useWindowDimensions()
|
||||
const map = useMap()
|
||||
const setSelectPosition = useSetSelectPosition()
|
||||
|
||||
return (
|
||||
<div
|
||||
@ -38,6 +42,11 @@ export const ItemCard = ({
|
||||
item={i}
|
||||
api={i.layer?.api}
|
||||
editCallback={() => navigate('/edit-item/' + i.id)}
|
||||
setPositionCallback={() => {
|
||||
map.closePopup()
|
||||
setSelectPosition(i)
|
||||
navigate('/')
|
||||
}}
|
||||
deleteCallback={() => deleteCallback(i)}
|
||||
></HeaderView>
|
||||
<div className='tw:overflow-y-auto tw:overflow-x-hidden tw:max-h-64 fade'>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user