mirror of
https://github.com/utopia-os/utopia-ui.git
synced 2025-12-13 07:46:10 +00:00
Improve typing of items, remove getValue
This commit is contained in:
parent
f5b7b9267f
commit
4316387ecb
@ -1,11 +1,9 @@
|
||||
/* eslint-disable @typescript-eslint/restrict-plus-operands */
|
||||
/* eslint-disable @typescript-eslint/no-unnecessary-condition */
|
||||
/* eslint-disable @typescript-eslint/prefer-optional-chain */
|
||||
import { Children, isValidElement, useEffect, useState } from 'react'
|
||||
import { Marker, Tooltip } from 'react-leaflet'
|
||||
|
||||
import { encodeTag } from '#utils/FormatTags'
|
||||
import { getValue } from '#utils/GetValue'
|
||||
import { hashTagRegex } from '#utils/HashTagRegex'
|
||||
import MarkerIconFactory from '#utils/MarkerIconFactory'
|
||||
import { randomColor } from '#utils/RandomColor'
|
||||
@ -42,17 +40,6 @@ export const Layer = ({
|
||||
markerDefaultColor2 = 'RGBA(35, 31, 32, 0.2)',
|
||||
api,
|
||||
itemType,
|
||||
itemNameField = 'name',
|
||||
itemSubnameField,
|
||||
itemTextField = 'text',
|
||||
itemAvatarField,
|
||||
itemColorField,
|
||||
itemOwnerField,
|
||||
itemLatitudeField = 'position.coordinates.1',
|
||||
itemLongitudeField = 'position.coordinates.0',
|
||||
itemTagsField,
|
||||
itemOffersField,
|
||||
itemNeedsField,
|
||||
onlyOnePerOwner = false,
|
||||
customEditLink,
|
||||
customEditParameter,
|
||||
@ -105,16 +92,8 @@ export const Layer = ({
|
||||
markerDefaultColor2,
|
||||
api,
|
||||
itemType,
|
||||
itemNameField,
|
||||
itemSubnameField,
|
||||
itemTextField,
|
||||
itemAvatarField,
|
||||
itemColorField,
|
||||
itemOwnerField,
|
||||
itemTagsField,
|
||||
itemOffersField,
|
||||
itemNeedsField,
|
||||
onlyOnePerOwner,
|
||||
// Can we just use editCallback for all cases?
|
||||
customEditLink,
|
||||
customEditParameter,
|
||||
// eslint-disable-next-line camelcase
|
||||
@ -122,6 +101,7 @@ export const Layer = ({
|
||||
listed,
|
||||
setItemFormPopup,
|
||||
itemFormPopup,
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
||||
clusterRef,
|
||||
})
|
||||
api &&
|
||||
@ -138,15 +118,6 @@ export const Layer = ({
|
||||
markerDefaultColor2,
|
||||
api,
|
||||
itemType,
|
||||
itemNameField,
|
||||
itemSubnameField,
|
||||
itemTextField,
|
||||
itemAvatarField,
|
||||
itemColorField,
|
||||
itemOwnerField,
|
||||
itemTagsField,
|
||||
itemOffersField,
|
||||
itemNeedsField,
|
||||
onlyOnePerOwner,
|
||||
customEditLink,
|
||||
customEditParameter,
|
||||
@ -155,6 +126,7 @@ export const Layer = ({
|
||||
listed,
|
||||
setItemFormPopup,
|
||||
itemFormPopup,
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
||||
clusterRef,
|
||||
})
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
@ -196,29 +168,19 @@ export const Layer = ({
|
||||
visibleGroupTypes.length === 0,
|
||||
)
|
||||
.map((item: Item) => {
|
||||
if (getValue(item, itemLongitudeField) && getValue(item, itemLatitudeField)) {
|
||||
// eslint-disable-next-line security/detect-object-injection
|
||||
if (getValue(item, itemTextField)) item[itemTextField] = getValue(item, itemTextField)
|
||||
// eslint-disable-next-line security/detect-object-injection
|
||||
else item[itemTextField] = ''
|
||||
|
||||
if (item.position?.coordinates[0] && item.position?.coordinates[1]) {
|
||||
if (item.tags) {
|
||||
// eslint-disable-next-line security/detect-object-injection
|
||||
item[itemTextField] = item[itemTextField] + '\n\n'
|
||||
item.text += '\n\n'
|
||||
item.tags.map((tag) => {
|
||||
// eslint-disable-next-line security/detect-object-injection
|
||||
if (!item[itemTextField].includes(`#${encodeTag(tag)}`)) {
|
||||
// eslint-disable-next-line security/detect-object-injection
|
||||
return (item[itemTextField] = item[itemTextField] + `#${encodeTag(tag)} `)
|
||||
if (!item.text.includes(`#${encodeTag(tag)}`)) {
|
||||
item.text += `#${encodeTag(tag)}`
|
||||
}
|
||||
// eslint-disable-next-line security/detect-object-injection
|
||||
return item[itemTextField]
|
||||
return item.text
|
||||
})
|
||||
}
|
||||
|
||||
if (allTagsLoaded && allItemsLoaded) {
|
||||
// eslint-disable-next-line security/detect-object-injection
|
||||
item[itemTextField].match(hashTagRegex)?.map((tag) => {
|
||||
item.text.match(hashTagRegex)?.map((tag) => {
|
||||
if (
|
||||
!tags.find(
|
||||
(t) => t.name.toLocaleLowerCase() === tag.slice(1).toLocaleLowerCase(),
|
||||
@ -241,19 +203,18 @@ export const Layer = ({
|
||||
|
||||
const itemTags = getItemTags(item)
|
||||
|
||||
const latitude =
|
||||
itemLatitudeField && item ? getValue(item, itemLatitudeField) : undefined
|
||||
const longitude =
|
||||
itemLongitudeField && item ? getValue(item, itemLongitudeField) : undefined
|
||||
const latitude = item.position.coordinates[1]
|
||||
const longitude = item.position.coordinates[0]
|
||||
|
||||
let color1 = markerDefaultColor
|
||||
let color2 = markerDefaultColor2
|
||||
if (itemColorField && getValue(item, itemColorField) != null)
|
||||
color1 = getValue(item, itemColorField)
|
||||
else if (itemTags && itemTags[0]) {
|
||||
if (item.color) {
|
||||
color1 = item.color
|
||||
} else if (itemTags && itemTags[0]) {
|
||||
color1 = itemTags[0].color
|
||||
}
|
||||
if (itemTags && itemTags[0] && itemColorField) color2 = itemTags[0].color
|
||||
// What is happening here?? Why do we depend on itemColorField?
|
||||
if (itemTags && itemTags[0] && item.layer?.hasColor) color2 = itemTags[0].color
|
||||
else if (itemTags && itemTags[1]) {
|
||||
color2 = itemTags[1].color
|
||||
}
|
||||
@ -314,7 +275,7 @@ export const Layer = ({
|
||||
)}
|
||||
|
||||
<Tooltip offset={[0, -38]} direction='top'>
|
||||
{item.name ? item.name : `${getValue(item, itemNameField)}`}
|
||||
{item.name}
|
||||
</Tooltip>
|
||||
</Marker>
|
||||
)
|
||||
|
||||
@ -23,7 +23,6 @@ import { useLeafletRefs } from '#components/Map/hooks/useLeafletRefs'
|
||||
import { useTags } from '#components/Map/hooks/useTags'
|
||||
import useWindowDimensions from '#components/Map/hooks/useWindowDimension'
|
||||
import { decodeTag } from '#utils/FormatTags'
|
||||
import { getValue } from '#utils/GetValue'
|
||||
import MarkerIconFactory from '#utils/MarkerIconFactory'
|
||||
|
||||
import { LocateControl } from './LocateControl'
|
||||
@ -73,8 +72,6 @@ export const SearchControl = () => {
|
||||
searchGeo()
|
||||
setItemsResults(
|
||||
items.filter((item) => {
|
||||
if (item.layer?.itemNameField) item.name = getValue(item, item.layer.itemNameField)
|
||||
if (item.layer?.itemTextField) item.text = getValue(item, item.layer.itemTextField)
|
||||
return (
|
||||
value.length > 2 &&
|
||||
((item.layer?.listed && item.name.toLowerCase().includes(value.toLowerCase())) ||
|
||||
|
||||
@ -15,7 +15,6 @@ import { useNavigate } from 'react-router-dom'
|
||||
import { useAppState } from '#components/AppShell/hooks/useAppState'
|
||||
import { useHasUserPermission } from '#components/Map/hooks/usePermissions'
|
||||
import DialogModal from '#components/Templates/DialogModal'
|
||||
import { getValue } from '#utils/GetValue'
|
||||
|
||||
import type { Item } from '#types/Item'
|
||||
import type { ItemsApi } from '#types/ItemsApi'
|
||||
@ -26,9 +25,6 @@ export function HeaderView({
|
||||
editCallback,
|
||||
deleteCallback,
|
||||
setPositionCallback,
|
||||
itemNameField,
|
||||
itemSubnameField,
|
||||
itemAvatarField,
|
||||
loading,
|
||||
hideMenu = false,
|
||||
big = false,
|
||||
@ -64,22 +60,11 @@ export function HeaderView({
|
||||
}, [item])
|
||||
|
||||
const avatar =
|
||||
itemAvatarField && getValue(item, itemAvatarField)
|
||||
? appState.assetsApi.url +
|
||||
getValue(item, itemAvatarField) +
|
||||
`${big ? '?width=160&heigth=160' : '?width=80&heigth=80'}`
|
||||
: item.layer?.itemAvatarField &&
|
||||
item &&
|
||||
getValue(item, item.layer?.itemAvatarField) &&
|
||||
appState.assetsApi.url +
|
||||
getValue(item, item.layer?.itemAvatarField) +
|
||||
`${big ? '?width=160&heigth=160' : '?width=80&heigth=80'}`
|
||||
const title = itemNameField
|
||||
? getValue(item, itemNameField)
|
||||
: item.layer?.itemNameField && item && getValue(item, item.layer.itemNameField)
|
||||
const subtitle = itemSubnameField
|
||||
? getValue(item, itemSubnameField)
|
||||
: item.layer?.itemSubnameField && item && getValue(item, item.layer.itemSubnameField)
|
||||
appState.assetsApi.url +
|
||||
item.avatar +
|
||||
`${big ? '?width=160&heigth=160' : '?width=80&heigth=80'}`
|
||||
const title = item.name
|
||||
const subtitle = item.subname
|
||||
|
||||
const [address] = useState<string>('')
|
||||
|
||||
@ -168,7 +153,7 @@ export function HeaderView({
|
||||
onClick={(e) =>
|
||||
item.layer?.customEditLink
|
||||
? navigate(
|
||||
`${item.layer.customEditLink}${item.layer.customEditParameter ? `/${getValue(item, item.layer.customEditParameter)}${params && '?' + params}` : ''} `,
|
||||
`${item.layer.customEditLink}${item.layer.customEditParameter ? `/${item.id}${params && '?' + params}` : ''} `,
|
||||
)
|
||||
: editCallback(e)
|
||||
}
|
||||
|
||||
@ -3,7 +3,6 @@
|
||||
import { Link } from 'react-router-dom'
|
||||
|
||||
import { useGetItemTags } from '#components/Map/hooks/useTags'
|
||||
import { getValue } from '#utils/GetValue'
|
||||
|
||||
import type { Item } from '#types/Item'
|
||||
|
||||
@ -11,23 +10,21 @@ export const PopupButton = ({
|
||||
url,
|
||||
parameterField,
|
||||
text,
|
||||
colorField,
|
||||
item,
|
||||
}: {
|
||||
url: string
|
||||
parameterField?: string
|
||||
text: string
|
||||
colorField?: string
|
||||
item?: Item
|
||||
}) => {
|
||||
const params = new URLSearchParams(window.location.search)
|
||||
const getItemTags = useGetItemTags()
|
||||
|
||||
return (
|
||||
<Link to={`${url}/${parameterField ? getValue(item, parameterField) : ''}?${params}`}>
|
||||
<Link to={`${url}/${parameterField ? item?.id : ''}?${params}`}>
|
||||
<button
|
||||
style={{
|
||||
backgroundColor: `${colorField && getValue(item, colorField) ? getValue(item, colorField) : item && getItemTags(item) && getItemTags(item)[0] && getItemTags(item)[0].color ? getItemTags(item)[0].color : item?.layer?.markerDefaultColor ? item?.layer?.markerDefaultColor : '#000'}`,
|
||||
backgroundColor: `${item?.color || (item && getItemTags(item) && getItemTags(item)[0] && getItemTags(item)[0].color) ? getItemTags(item)[0].color : (item?.layer?.markerDefaultColor ?? '#000')}`,
|
||||
}}
|
||||
className='tw-btn tw-text-white tw-btn-sm tw-float-right tw-mt-1'
|
||||
>
|
||||
|
||||
@ -12,41 +12,38 @@ import remarkBreaks from 'remark-breaks'
|
||||
import { useAddFilterTag } from '#components/Map/hooks/useFilter'
|
||||
import { useTags } from '#components/Map/hooks/useTags'
|
||||
import { decodeTag } from '#utils/FormatTags'
|
||||
import { getValue } from '#utils/GetValue'
|
||||
import { hashTagRegex } from '#utils/HashTagRegex'
|
||||
import { fixUrls, mailRegex } from '#utils/ReplaceURLs'
|
||||
|
||||
import type { Item } from '#types/Item'
|
||||
import type { Tag } from '#types/Tag'
|
||||
|
||||
export const TextView = ({
|
||||
item,
|
||||
itemId,
|
||||
text,
|
||||
truncate = false,
|
||||
itemTextField,
|
||||
rawText,
|
||||
}: {
|
||||
item?: Item
|
||||
itemId: string
|
||||
text?: string
|
||||
truncate?: boolean
|
||||
itemTextField?: string
|
||||
rawText?: string
|
||||
}) => {
|
||||
const tags = useTags()
|
||||
const addFilterTag = useAddFilterTag()
|
||||
|
||||
let text = ''
|
||||
let innerText = ''
|
||||
let replacedText = ''
|
||||
|
||||
if (rawText) {
|
||||
text = replacedText = rawText
|
||||
} else if (itemTextField && item) {
|
||||
text = getValue(item, itemTextField)
|
||||
} else {
|
||||
text = item?.layer?.itemTextField && item ? getValue(item, item.layer.itemTextField) : ''
|
||||
innerText = replacedText = rawText
|
||||
} else if (text) {
|
||||
innerText = text
|
||||
}
|
||||
|
||||
if (item && text && truncate) text = truncateText(removeMarkdownKeepLinksAndParagraphs(text), 100)
|
||||
if (innerText && truncate)
|
||||
innerText = truncateText(removeMarkdownKeepLinksAndParagraphs(innerText), 100)
|
||||
|
||||
if (item && text) replacedText = fixUrls(text)
|
||||
if (innerText) replacedText = fixUrls(innerText)
|
||||
|
||||
if (replacedText) {
|
||||
replacedText = replacedText.replace(/(?<!\]?\()https?:\/\/[^\s)]+(?!\))/g, (url) => {
|
||||
@ -114,16 +111,16 @@ export const TextView = ({
|
||||
const CustomHashTagLink = ({
|
||||
children,
|
||||
tag,
|
||||
item,
|
||||
itemId,
|
||||
}: {
|
||||
children: string
|
||||
tag: Tag
|
||||
item?: Item
|
||||
itemId: string
|
||||
}) => {
|
||||
return (
|
||||
<a
|
||||
style={{ color: tag ? tag.color : '#faa', fontWeight: 'bold', cursor: 'pointer' }}
|
||||
key={tag ? tag.name + item?.id : item?.id}
|
||||
key={tag ? tag.name + itemId : itemId}
|
||||
onClick={(e) => {
|
||||
e.stopPropagation()
|
||||
addFilterTag(tag)
|
||||
@ -173,7 +170,7 @@ export const TextView = ({
|
||||
)
|
||||
if (tag)
|
||||
return (
|
||||
<CustomHashTagLink tag={tag} item={item}>
|
||||
<CustomHashTagLink tag={tag} itemId={itemId}>
|
||||
{children}
|
||||
</CustomHashTagLink>
|
||||
)
|
||||
|
||||
@ -105,7 +105,7 @@ export const ItemViewPopup = forwardRef((props: ItemViewPopupProps, ref: any) =>
|
||||
: '',
|
||||
)
|
||||
) : (
|
||||
<TextView item={props.item} />
|
||||
<TextView text={props.item.text} itemId={props.item.id} />
|
||||
)}
|
||||
</div>
|
||||
<div className='tw-flex -tw-mb-1 tw-flex-row tw-mr-2 tw-mt-1'>
|
||||
|
||||
@ -15,7 +15,6 @@ import { toast } from 'react-toastify'
|
||||
import './UtopiaMap.css'
|
||||
|
||||
import { containsUUID } from '#utils/ContainsUUID'
|
||||
import { getValue } from '#utils/GetValue'
|
||||
|
||||
import { useClusterRef, useSetClusterRef } from './hooks/useClusterRef'
|
||||
import { useAddVisibleLayer } from './hooks/useFilter'
|
||||
@ -75,9 +74,10 @@ export function UtopiaMapInner({
|
||||
setTimeout(() => {
|
||||
toast(
|
||||
<>
|
||||
<TextView rawText={'## Do you like this Map?'} />
|
||||
<TextView itemId='' rawText={'## Do you like this Map?'} />
|
||||
<div>
|
||||
<TextView
|
||||
itemId=''
|
||||
rawText={'Support us building free opensource maps and help us grow 🌱☀️'}
|
||||
/>
|
||||
<PopupButton url={'https://opencollective.com/utopia-project'} text={'Donate'} />
|
||||
@ -120,7 +120,6 @@ export function UtopiaMapInner({
|
||||
}
|
||||
let title = ''
|
||||
if (item?.name) title = item.name
|
||||
else if (item?.layer?.itemNameField) title = getValue(item, item.layer.itemNameField)
|
||||
document.title = `${document.title.split('-')[0]} - ${title}`
|
||||
}
|
||||
},
|
||||
@ -142,8 +141,6 @@ export function UtopiaMapInner({
|
||||
})
|
||||
let title = ''
|
||||
if (ref.item.name) title = ref.item.name
|
||||
else if (ref.item.layer?.itemNameField)
|
||||
title = getValue(ref.item.name, ref.item.layer.itemNameField)
|
||||
document.title = `${document.title.split('-')[0]} - ${title}`
|
||||
document
|
||||
.querySelector('meta[property="og:title"]')
|
||||
|
||||
@ -63,7 +63,7 @@ function useSelectPositionManager(): {
|
||||
if ('menuIcon' in selectPosition) {
|
||||
mapClicked &&
|
||||
mapClicked.setItemFormPopup({
|
||||
layer: selectPosition as LayerProps,
|
||||
layer: selectPosition,
|
||||
position: mapClicked.position,
|
||||
})
|
||||
setSelectPosition(null)
|
||||
|
||||
@ -5,12 +5,8 @@
|
||||
/* eslint-disable @typescript-eslint/prefer-optional-chain */
|
||||
/* eslint-disable @typescript-eslint/no-non-null-assertion */
|
||||
/* eslint-disable @typescript-eslint/no-unnecessary-condition */
|
||||
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
||||
/* eslint-disable @typescript-eslint/no-unsafe-call */
|
||||
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
|
||||
import { useCallback, useReducer, createContext, useContext, useState } from 'react'
|
||||
|
||||
import { getValue } from '#utils/GetValue'
|
||||
import { hashTagRegex } from '#utils/HashTagRegex'
|
||||
|
||||
import type { Item } from '#types/Item'
|
||||
@ -96,8 +92,7 @@ function useTagsManager(initialTags: Tag[]): {
|
||||
|
||||
const getItemTags = useCallback(
|
||||
(item: Item) => {
|
||||
const text =
|
||||
item.layer?.itemTextField && item ? getValue(item, item.layer.itemTextField) : undefined
|
||||
const text = item.text
|
||||
const itemTagStrings = text?.match(hashTagRegex)
|
||||
const itemTags: Tag[] = []
|
||||
itemTagStrings?.map((tag) => {
|
||||
@ -108,18 +103,15 @@ function useTagsManager(initialTags: Tag[]): {
|
||||
}
|
||||
return null
|
||||
})
|
||||
item.layer?.itemOffersField &&
|
||||
getValue(item, item.layer.itemOffersField)?.map((o) => {
|
||||
const offer = tags.find((t) => t.id === o.tags_id)
|
||||
offer && itemTags.push(offer)
|
||||
return null
|
||||
})
|
||||
item.layer?.itemNeedsField &&
|
||||
getValue(item, item.layer.itemNeedsField)?.map((n) => {
|
||||
const need = tags.find((t) => t.id === n.tags_id)
|
||||
need && itemTags.push(need)
|
||||
return null
|
||||
})
|
||||
// Could be refactored as it occurs in multiple places
|
||||
item.offers?.forEach((o) => {
|
||||
const offer = tags.find((t) => t.id === o.tags_id)
|
||||
offer && itemTags.push(offer)
|
||||
})
|
||||
item.needs?.forEach((n) => {
|
||||
const need = tags.find((t) => t.id === n.tags_id)
|
||||
need && itemTags.push(need)
|
||||
})
|
||||
|
||||
return itemTags
|
||||
},
|
||||
|
||||
@ -1,8 +1,5 @@
|
||||
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
|
||||
/* eslint-disable @typescript-eslint/no-unsafe-call */
|
||||
/* eslint-disable @typescript-eslint/restrict-template-expressions */
|
||||
/* eslint-disable @typescript-eslint/no-unnecessary-condition */
|
||||
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
||||
/* eslint-disable @typescript-eslint/no-unsafe-argument */
|
||||
import { useEffect, useState } from 'react'
|
||||
import { useLocation, useNavigate } from 'react-router-dom'
|
||||
@ -14,7 +11,6 @@ import { useLayers } from '#components/Map/hooks/useLayers'
|
||||
import { useHasUserPermission } from '#components/Map/hooks/usePermissions'
|
||||
import { useAddTag, useGetItemTags, useTags } from '#components/Map/hooks/useTags'
|
||||
import { MapOverlayPage } from '#components/Templates'
|
||||
import { getValue } from '#utils/GetValue'
|
||||
|
||||
import { linkItem, onUpdateItem, unlinkItem } from './itemFunctions'
|
||||
import { FormHeader } from './Subcomponents/FormHeader'
|
||||
@ -23,11 +19,12 @@ import { OnepagerForm } from './Templates/OnepagerForm'
|
||||
import { SimpleForm } from './Templates/SimpleForm'
|
||||
import { TabsForm } from './Templates/TabsForm'
|
||||
|
||||
import type { FormState } from '#types/FormState'
|
||||
import type { Item } from '#types/Item'
|
||||
import type { Tag } from '#types/Tag'
|
||||
|
||||
export function ProfileForm() {
|
||||
const [state, setState] = useState({
|
||||
const [state, setState] = useState<FormState>({
|
||||
color: '',
|
||||
id: '',
|
||||
group_type: 'wuerdekompass',
|
||||
@ -91,11 +88,9 @@ export function ProfileForm() {
|
||||
|
||||
useEffect(() => {
|
||||
const newColor =
|
||||
item.layer?.itemColorField && getValue(item, item.layer.itemColorField)
|
||||
? getValue(item, item.layer.itemColorField)
|
||||
: getItemTags(item) && getItemTags(item)[0]?.color
|
||||
? getItemTags(item)[0].color
|
||||
: item.layer?.markerDefaultColor
|
||||
(item.color ?? (getItemTags(item) && getItemTags(item)[0]?.color))
|
||||
? getItemTags(item)[0].color
|
||||
: item.layer?.markerDefaultColor
|
||||
|
||||
const offers = (item.offers ?? []).reduce((acc: Tag[], o) => {
|
||||
const offer = tags.find((t) => t.id === o.tags_id)
|
||||
@ -116,7 +111,7 @@ export function ProfileForm() {
|
||||
}, [])
|
||||
|
||||
setState({
|
||||
color: newColor,
|
||||
color: newColor ?? '',
|
||||
id: item?.id ?? '',
|
||||
group_type: item?.group_type ?? '',
|
||||
status: item?.status ?? '',
|
||||
@ -127,7 +122,8 @@ export function ProfileForm() {
|
||||
telephone: item?.telephone ?? '',
|
||||
next_appointment: item?.next_appointment ?? '',
|
||||
image: item?.image ?? '',
|
||||
marker_icon: item?.marker_icon ?? '',
|
||||
// Do we actually mean marker_icon here?
|
||||
marker_icon: item?.markerIcon ?? '',
|
||||
offers,
|
||||
needs,
|
||||
relations,
|
||||
@ -140,7 +136,7 @@ export function ProfileForm() {
|
||||
const [template, setTemplate] = useState<string>('')
|
||||
|
||||
useEffect(() => {
|
||||
setTemplate(item.layer?.itemType.template || appState.userType)
|
||||
setTemplate(item.layer?.itemType.template ?? appState.userType)
|
||||
}, [appState.userType, item])
|
||||
|
||||
return (
|
||||
@ -198,7 +194,8 @@ export function ProfileForm() {
|
||||
className={loading ? ' tw-loading tw-btn tw-float-right' : 'tw-btn tw-float-right'}
|
||||
type='submit'
|
||||
style={{
|
||||
backgroundColor: `${item.layer?.itemColorField && getValue(item, item.layer?.itemColorField) ? getValue(item, item.layer?.itemColorField) : getItemTags(item) && getItemTags(item)[0] && getItemTags(item)[0].color ? getItemTags(item)[0].color : item?.layer?.markerDefaultColor}`,
|
||||
// We could refactor this, it is used several times at different locations
|
||||
backgroundColor: `${(item.color ?? (getItemTags(item) && getItemTags(item)[0] && getItemTags(item)[0].color)) ? getItemTags(item)[0].color : item?.layer?.markerDefaultColor}`,
|
||||
color: '#fff',
|
||||
}}
|
||||
>
|
||||
|
||||
@ -1,10 +1,10 @@
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
||||
/* eslint-disable @typescript-eslint/await-thenable */
|
||||
|
||||
/* eslint-disable @typescript-eslint/no-non-null-assertion */
|
||||
/* eslint-disable @typescript-eslint/no-non-null-asserted-optional-chain */
|
||||
/* eslint-disable @typescript-eslint/no-unsafe-argument */
|
||||
/* eslint-disable @typescript-eslint/no-floating-promises */
|
||||
|
||||
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
|
||||
/* eslint-disable @typescript-eslint/no-unsafe-call */
|
||||
import { LatLng } from 'leaflet'
|
||||
@ -21,7 +21,6 @@ import { useSelectPosition, useSetSelectPosition } from '#components/Map/hooks/u
|
||||
import { useTags } from '#components/Map/hooks/useTags'
|
||||
import { HeaderView } from '#components/Map/Subcomponents/ItemPopupComponents/HeaderView'
|
||||
import { MapOverlayPage } from '#components/Templates'
|
||||
import { getValue } from '#utils/GetValue'
|
||||
|
||||
import { handleDelete, linkItem, unlinkItem } from './itemFunctions'
|
||||
import { FlexView } from './Templates/FlexView'
|
||||
@ -32,6 +31,7 @@ import { TabsView } from './Templates/TabsView'
|
||||
import type { Item } from '#types/Item'
|
||||
import type { ItemsApi } from '#types/ItemsApi'
|
||||
import type { Tag } from '#types/Tag'
|
||||
import type { Marker } from 'leaflet'
|
||||
|
||||
export function ProfileView({ attestationApi }: { attestationApi?: ItemsApi<any> }) {
|
||||
const [item, setItem] = useState<Item>()
|
||||
@ -88,30 +88,25 @@ export function ProfileView({ attestationApi }: { attestationApi?: ItemsApi<any>
|
||||
setNeeds([])
|
||||
setRelations([])
|
||||
|
||||
item?.layer?.itemOffersField &&
|
||||
getValue(item, item.layer.itemOffersField)?.map((o) => {
|
||||
const tag = tags.find((t) => t.id === o.tags_id)
|
||||
tag && setOffers((current) => [...current, tag])
|
||||
return null
|
||||
})
|
||||
item?.layer?.itemNeedsField &&
|
||||
getValue(item, item.layer.itemNeedsField)?.map((n) => {
|
||||
const tag = tags.find((t) => t.id === n.tags_id)
|
||||
tag && setNeeds((current) => [...current, tag])
|
||||
return null
|
||||
})
|
||||
item?.relations?.map((r) => {
|
||||
item?.offers?.forEach((o) => {
|
||||
const tag = tags.find((t) => t.id === o.tags_id)
|
||||
tag && setOffers((current) => [...current, tag])
|
||||
})
|
||||
item?.needs?.forEach((n) => {
|
||||
const tag = tags.find((t) => t.id === n.tags_id)
|
||||
tag && setNeeds((current) => [...current, tag])
|
||||
})
|
||||
item?.relations?.forEach((r) => {
|
||||
const item = items.find((i) => i.id === r.related_items_id)
|
||||
item && setRelations((current) => [...current, item])
|
||||
return null
|
||||
})
|
||||
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [item, items])
|
||||
|
||||
useEffect(() => {
|
||||
const setMap = async (marker, x) => {
|
||||
await map.setView(
|
||||
const setMap = (marker: Marker, x: number) => {
|
||||
map.setView(
|
||||
new LatLng(item?.position?.coordinates[1]!, item?.position?.coordinates[0]! + x / 4),
|
||||
undefined,
|
||||
)
|
||||
@ -164,7 +159,7 @@ export function ProfileView({ attestationApi }: { attestationApi?: ItemsApi<any>
|
||||
}, [selectPosition])
|
||||
|
||||
useEffect(() => {
|
||||
setTemplate(item?.layer?.itemType.template || appState.userType)
|
||||
setTemplate(item?.layer?.itemType.template ?? appState.userType)
|
||||
}, [appState.userType, item])
|
||||
|
||||
return (
|
||||
|
||||
@ -10,7 +10,6 @@ import { useHasUserPermission } from '#components/Map/hooks/usePermissions'
|
||||
import { useGetItemTags } from '#components/Map/hooks/useTags'
|
||||
import { HeaderView } from '#components/Map/Subcomponents/ItemPopupComponents/HeaderView'
|
||||
import DialogModal from '#components/Templates/DialogModal'
|
||||
import { getValue } from '#utils/GetValue'
|
||||
|
||||
import type { Item } from '#types/Item'
|
||||
|
||||
@ -20,7 +19,6 @@ export function ActionButton({
|
||||
triggerItemSelected,
|
||||
existingRelations,
|
||||
itemType,
|
||||
colorField,
|
||||
collection = 'items',
|
||||
customStyle,
|
||||
}: {
|
||||
@ -28,7 +26,6 @@ export function ActionButton({
|
||||
triggerItemSelected?: any
|
||||
existingRelations: Item[]
|
||||
itemType?: string
|
||||
colorField?: string
|
||||
collection?: string
|
||||
customStyle?: string
|
||||
item: Item
|
||||
@ -58,7 +55,7 @@ export function ActionButton({
|
||||
setModalOpen(true)
|
||||
}}
|
||||
style={{
|
||||
backgroundColor: `${colorField && getValue(item, colorField) ? getValue(item, colorField) : getItemTags(item) && getItemTags(item)[0] && getItemTags(item)[0].color ? getItemTags(item)[0].color : item.layer?.markerDefaultColor}`,
|
||||
backgroundColor: `${(item.color ?? (getItemTags(item) && getItemTags(item)[0] && getItemTags(item)[0].color)) ? getItemTags(item)[0].color : item.layer?.markerDefaultColor}`,
|
||||
color: '#fff',
|
||||
}}
|
||||
>
|
||||
@ -82,7 +79,7 @@ export function ActionButton({
|
||||
triggerAddButton()
|
||||
}}
|
||||
style={{
|
||||
backgroundColor: `${colorField && getValue(item, colorField) ? getValue(item, colorField) : getItemTags(item) && getItemTags(item)[0] && getItemTags(item)[0].color ? getItemTags(item)[0].color : item.layer?.markerDefaultColor}`,
|
||||
backgroundColor: `${(item.color ?? (getItemTags(item) && getItemTags(item)[0] && getItemTags(item)[0].color)) ? getItemTags(item)[0].color : item.layer?.markerDefaultColor}`,
|
||||
color: '#fff',
|
||||
}}
|
||||
>
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/* eslint-disable @typescript-eslint/no-unnecessary-condition */
|
||||
/* eslint-disable @typescript-eslint/restrict-template-expressions */
|
||||
|
||||
/* eslint-disable @typescript-eslint/no-unsafe-return */
|
||||
/* eslint-disable @typescript-eslint/restrict-plus-operands */
|
||||
import { useEffect, useState } from 'react'
|
||||
|
||||
@ -4,46 +4,29 @@
|
||||
/* eslint-disable @typescript-eslint/no-unsafe-call */
|
||||
/* eslint-disable @typescript-eslint/restrict-plus-operands */
|
||||
/* eslint-disable @typescript-eslint/no-unnecessary-condition */
|
||||
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
||||
|
||||
import { useEffect } from 'react'
|
||||
|
||||
import { useAppState } from '#components/AppShell/hooks/useAppState'
|
||||
import { getValue } from '#utils/GetValue'
|
||||
|
||||
import type { Item } from '#types/Item'
|
||||
|
||||
export function LinkedItemsHeaderView({
|
||||
item,
|
||||
unlinkCallback,
|
||||
itemNameField,
|
||||
itemAvatarField,
|
||||
loading,
|
||||
unlinkPermission,
|
||||
itemSubnameField,
|
||||
}: {
|
||||
item: Item
|
||||
unlinkCallback?: any
|
||||
itemNameField?: string
|
||||
itemAvatarField?: string
|
||||
itemSubnameField?: string
|
||||
loading?: boolean
|
||||
unlinkPermission: boolean
|
||||
}) {
|
||||
const appState = useAppState()
|
||||
|
||||
const avatar =
|
||||
itemAvatarField && getValue(item, itemAvatarField)
|
||||
? appState.assetsApi.url + getValue(item, itemAvatarField)
|
||||
: item.layer?.itemAvatarField &&
|
||||
item &&
|
||||
getValue(item, item.layer?.itemAvatarField) &&
|
||||
appState.assetsApi.url + getValue(item, item.layer?.itemAvatarField)
|
||||
const title = itemNameField
|
||||
? getValue(item, itemNameField)
|
||||
: item.layer?.itemNameField && item && getValue(item, item.layer.itemNameField)
|
||||
const subtitle = itemSubnameField
|
||||
? getValue(item, itemSubnameField)
|
||||
: item.layer?.itemSubnameField && item && getValue(item, item.layer.itemSubnameField)
|
||||
const avatar = appState.assetsApi.url + item.avatar
|
||||
const title = item.name
|
||||
const subtitle = item.subname
|
||||
|
||||
useEffect(() => {}, [item])
|
||||
|
||||
|
||||
@ -5,7 +5,6 @@
|
||||
import { useEffect, useState } from 'react'
|
||||
|
||||
import { TextAreaInput } from '#components/Input'
|
||||
import { getValue } from '#utils/GetValue'
|
||||
|
||||
import { MarkdownHint } from './MarkdownHint'
|
||||
|
||||
@ -14,6 +13,7 @@ import type { FormState } from '#types/FormState'
|
||||
export const ProfileTextForm = ({
|
||||
state,
|
||||
setState,
|
||||
// Is this really used?
|
||||
dataField,
|
||||
heading,
|
||||
size,
|
||||
@ -49,7 +49,8 @@ export const ProfileTextForm = ({
|
||||
</div>
|
||||
<TextAreaInput
|
||||
placeholder={'...'}
|
||||
defaultValue={getValue(state, field)}
|
||||
// eslint-disable-next-line security/detect-object-injection
|
||||
defaultValue={state[field]}
|
||||
updateFormValue={(v) =>
|
||||
setState((prevState) => ({
|
||||
...prevState,
|
||||
|
||||
@ -1,6 +1,4 @@
|
||||
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
||||
import { TextView } from '#components/Map'
|
||||
import { getValue } from '#utils/GetValue'
|
||||
|
||||
import type { Item } from '#types/Item'
|
||||
|
||||
@ -17,11 +15,11 @@ export const ProfileTextView = ({
|
||||
}) => {
|
||||
return (
|
||||
<div className='tw-my-10 tw-mt-2 tw-px-6'>
|
||||
{!(getValue(item, dataField) === '' && hideWhenEmpty) && (
|
||||
{!(item.data === '' && hideWhenEmpty) && (
|
||||
<h2 className='tw-text-lg tw-font-semibold'>{heading}</h2>
|
||||
)}
|
||||
<div className='tw-mt-2 tw-text-sm'>
|
||||
<TextView rawText={dataField ? getValue(item, dataField) : getValue(item, 'text')} />
|
||||
<TextView itemId={item.id} rawText={dataField ? item.data : item.text} />
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
|
||||
@ -1,7 +1,5 @@
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
||||
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
|
||||
/* eslint-disable @typescript-eslint/no-unsafe-call */
|
||||
|
||||
import { ContactInfoForm } from '#components/Profile/Subcomponents/ContactInfoForm'
|
||||
import { GroupSubheaderForm } from '#components/Profile/Subcomponents/GroupSubheaderForm'
|
||||
|
||||
@ -1,6 +1,4 @@
|
||||
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
||||
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
|
||||
/* eslint-disable @typescript-eslint/no-unsafe-call */
|
||||
|
||||
import { ContactInfoView } from '#components/Profile/Subcomponents/ContactInfoView'
|
||||
import { GalleryView } from '#components/Profile/Subcomponents/GalleryView'
|
||||
@ -9,6 +7,7 @@ import { ProfileStartEndView } from '#components/Profile/Subcomponents/ProfileSt
|
||||
import { ProfileTextView } from '#components/Profile/Subcomponents/ProfileTextView'
|
||||
|
||||
import type { Item } from '#types/Item'
|
||||
import type { Key } from 'react'
|
||||
|
||||
const componentMap = {
|
||||
groupSubheaders: GroupSubHeaderView,
|
||||
@ -24,14 +23,17 @@ export const FlexView = ({ item }: { item: Item }) => {
|
||||
console.log(item)
|
||||
return (
|
||||
<div className='tw-h-full tw-overflow-y-auto fade'>
|
||||
{item.layer?.itemType.profileTemplate.map((templateItem) => {
|
||||
const TemplateComponent = componentMap[templateItem.collection]
|
||||
return TemplateComponent ? (
|
||||
<TemplateComponent key={templateItem.id} item={item} {...templateItem.item} />
|
||||
) : (
|
||||
<div key={templateItem.id}>Component not found</div>
|
||||
)
|
||||
})}
|
||||
{item.layer?.itemType.profileTemplate.map(
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
(templateItem: { collection: string | number; id: Key | null | undefined; item: any }) => {
|
||||
const TemplateComponent = componentMap[templateItem.collection]
|
||||
return TemplateComponent ? (
|
||||
<TemplateComponent key={templateItem.id} item={item} {...templateItem.item} />
|
||||
) : (
|
||||
<div key={templateItem.id}>Component not found</div>
|
||||
)
|
||||
},
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@ -1,4 +1,3 @@
|
||||
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
||||
/* eslint-disable @typescript-eslint/restrict-template-expressions */
|
||||
import { TextView } from '#components/Map'
|
||||
import { ContactInfoView } from '#components/Profile/Subcomponents/ContactInfoView'
|
||||
@ -16,14 +15,14 @@ export const OnepagerView = ({ item }: { item: Item }) => {
|
||||
{item.user_created?.first_name && <ContactInfoView heading='Du hast Fragen?' item={item} />}
|
||||
{/* Description Section */}
|
||||
<div className='tw-my-10 tw-mt-2 tw-px-6 tw-text-sm '>
|
||||
<TextView rawText={item.text || 'Keine Beschreibung vorhanden'} />
|
||||
<TextView itemId={item.id} rawText={item.text || 'Keine Beschreibung vorhanden'} />
|
||||
</div>
|
||||
{/* Next Appointment Section */}
|
||||
{item.next_appointment && (
|
||||
<div className='tw-my-10 tw-px-6'>
|
||||
<h2 className='tw-text-lg tw-font-semibold'>Nächste Termine</h2>
|
||||
<div className='tw-mt-2 tw-text-sm'>
|
||||
<TextView rawText={item.next_appointment} />
|
||||
<TextView itemId={item.id} rawText={item.next_appointment} />
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
@ -5,7 +5,7 @@ import type { Item } from '#types/Item'
|
||||
export const SimpleView = ({ item }: { item: Item }) => {
|
||||
return (
|
||||
<div className='tw-mt-8 tw-h-full tw-overflow-y-auto fade tw-px-6'>
|
||||
<TextView item={item} />
|
||||
<TextView text={item.text} itemId={item.id} />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@ -197,7 +197,7 @@ export const TabsForm = ({
|
||||
loading={loading}
|
||||
/>
|
||||
<div className='tw-overflow-y-auto tw-overflow-x-hidden tw-max-h-64 fade'>
|
||||
<TextView truncate item={i} />
|
||||
<TextView truncate itemId={item.id} />
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
@ -208,7 +208,6 @@ export const TabsForm = ({
|
||||
item={item}
|
||||
existingRelations={state.relations}
|
||||
triggerItemSelected={(id) => linkItem(id, item, updateItem)}
|
||||
colorField={item.layer.itemColorField}
|
||||
></ActionButton>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@ -108,9 +108,9 @@ export const TabsView = ({
|
||||
<StartEndView item={item}></StartEndView>
|
||||
</div>
|
||||
)}
|
||||
<TextView item={item} />
|
||||
<TextView text={item.text} itemId={item.id} />
|
||||
<div className='tw-h-4'></div>
|
||||
<TextView item={item} itemTextField='contact' />
|
||||
<TextView text={item.contact} itemId={item.id} />
|
||||
</div>
|
||||
{item.layer?.itemType.questlog && (
|
||||
<>
|
||||
@ -267,7 +267,7 @@ export const TabsView = ({
|
||||
loading={loading}
|
||||
/>
|
||||
<div className='tw-overflow-y-auto tw-overflow-x-hidden tw-max-h-64 fade'>
|
||||
<TextView truncate item={i} />
|
||||
<TextView truncate text={i.text} itemId={item.id} />
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
@ -277,7 +277,6 @@ export const TabsView = ({
|
||||
item={item}
|
||||
existingRelations={relations}
|
||||
triggerItemSelected={linkItem}
|
||||
colorField={item.layer.itemColorField}
|
||||
></ActionButton>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@ -2,14 +2,12 @@
|
||||
/* eslint-disable @typescript-eslint/no-unsafe-call */
|
||||
/* eslint-disable @typescript-eslint/no-unsafe-return */
|
||||
/* eslint-disable @typescript-eslint/restrict-template-expressions */
|
||||
/* eslint-disable @typescript-eslint/restrict-plus-operands */
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
import { useNavigate } from 'react-router-dom'
|
||||
|
||||
import { StartEndView, TextView } from '#components/Map'
|
||||
import useWindowDimensions from '#components/Map/hooks/useWindowDimension'
|
||||
import { HeaderView } from '#components/Map/Subcomponents/ItemPopupComponents/HeaderView'
|
||||
import { getValue } from '#utils/GetValue'
|
||||
|
||||
import { DateUserInfo } from './DateUserInfo'
|
||||
|
||||
@ -19,13 +17,11 @@ export const ItemCard = ({
|
||||
i,
|
||||
loading,
|
||||
url,
|
||||
parameterField,
|
||||
deleteCallback,
|
||||
}: {
|
||||
i: Item
|
||||
loading: boolean
|
||||
url: string
|
||||
parameterField: string
|
||||
deleteCallback: any
|
||||
}) => {
|
||||
const navigate = useNavigate()
|
||||
@ -35,27 +31,23 @@ export const ItemCard = ({
|
||||
<div
|
||||
className='tw-cursor-pointer tw-card tw-border-[1px] tw-border-base-300 tw-card-body tw-shadow-xl tw-bg-base-100 tw-text-base-content tw-p-4 tw-mb-4 tw-h-fit'
|
||||
onClick={() => {
|
||||
// We could have an onClick callback instead
|
||||
const params = new URLSearchParams(window.location.search)
|
||||
if (windowDimensions.width < 786 && i.position)
|
||||
navigate('/' + getValue(i, parameterField) + `${params ? `?${params}` : ''}`)
|
||||
else navigate(url + getValue(i, parameterField) + `${params ? `?${params}` : ''}`)
|
||||
navigate('/' + i.id + `${params ? `?${params}` : ''}`)
|
||||
else navigate(url + i.id + `${params ? `?${params}` : ''}`)
|
||||
}}
|
||||
>
|
||||
<HeaderView
|
||||
loading={loading}
|
||||
item={i}
|
||||
api={i.layer?.api}
|
||||
itemAvatarField={i.layer?.itemAvatarField}
|
||||
itemNameField={i.layer?.itemNameField}
|
||||
itemSubnameField={i.layer?.itemSubnameField}
|
||||
editCallback={() => navigate('/edit-item/' + i.id)}
|
||||
deleteCallback={() => deleteCallback(i)}
|
||||
></HeaderView>
|
||||
<div className='tw-overflow-y-auto tw-overflow-x-hidden tw-max-h-64 fade'>
|
||||
{i.layer?.itemType.show_start_end && <StartEndView item={i}></StartEndView>}
|
||||
{i.layer?.itemType.show_text && (
|
||||
<TextView truncate item={i} itemTextField={i.layer.itemTextField} />
|
||||
)}
|
||||
{i.layer?.itemType.show_text && <TextView truncate text={i.text} itemId={i.id} />}
|
||||
</div>
|
||||
<DateUserInfo item={i}></DateUserInfo>
|
||||
</div>
|
||||
|
||||
@ -8,7 +8,6 @@ import { useNavigate } from 'react-router-dom'
|
||||
|
||||
import { useItems } from '#components/Map/hooks/useItems'
|
||||
import { useTags } from '#components/Map/hooks/useTags'
|
||||
import { getValue } from '#utils/GetValue'
|
||||
|
||||
import { MapOverlayPage } from './MapOverlayPage'
|
||||
import { TagView } from './TagView'
|
||||
@ -42,21 +41,16 @@ export const MarketView = () => {
|
||||
useEffect(() => {
|
||||
setOffers([])
|
||||
setNeeds([])
|
||||
items.map((i) => {
|
||||
i.layer?.itemOffersField &&
|
||||
getValue(i, i.layer.itemOffersField)?.map((o) => {
|
||||
const tag = tags.find((t) => t.id === o.tags_id)
|
||||
tag && setOffers((current) => [...current, tag])
|
||||
return null
|
||||
})
|
||||
i.layer?.itemNeedsField &&
|
||||
getValue(i, i.layer.itemNeedsField)?.map((n) => {
|
||||
const tag = tags.find((t) => t.id === n.tags_id)
|
||||
tag && setNeeds((current) => [...current, tag])
|
||||
return null
|
||||
})
|
||||
return null
|
||||
})
|
||||
for (const item of items) {
|
||||
item.offers?.forEach((o) => {
|
||||
const tag = tags.find((t) => t.id === o.tags_id)
|
||||
tag && setOffers((current) => [...current, tag])
|
||||
})
|
||||
item.needs?.forEach((n) => {
|
||||
const tag = tags.find((t) => t.id === n.tags_id)
|
||||
tag && setNeeds((current) => [...current, tag])
|
||||
})
|
||||
}
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(offers)
|
||||
|
||||
|
||||
@ -30,12 +30,10 @@ import type { Item } from '#types/Item'
|
||||
export const OverlayItemsIndexPage = ({
|
||||
url,
|
||||
layerName,
|
||||
parameterField,
|
||||
plusButton = true,
|
||||
}: {
|
||||
layerName: string
|
||||
url: string
|
||||
parameterField: string
|
||||
plusButton?: boolean
|
||||
}) => {
|
||||
const [loading, setLoading] = useState<boolean>(false)
|
||||
@ -165,7 +163,6 @@ export const OverlayItemsIndexPage = ({
|
||||
i={i}
|
||||
loading={loading}
|
||||
url={url}
|
||||
parameterField={parameterField}
|
||||
deleteCallback={() => deleteItem(i)}
|
||||
/>
|
||||
</div>
|
||||
|
||||
@ -1,17 +0,0 @@
|
||||
import type { Item } from '#types/Item'
|
||||
|
||||
function getNestedValue(obj: Object, path: string) {
|
||||
re
|
||||
}
|
||||
|
||||
export function getValue(obj: Item | undefined, path: string): Item | string | undefined {
|
||||
if (!obj || typeof path !== 'string') return undefined
|
||||
|
||||
const pathArray = path.split('.') // Use a different variable for the split path
|
||||
for (let i = 0, len = pathArray.length; i < len; i++) {
|
||||
if (!obj) return undefined // Check if obj is falsy at each step
|
||||
// eslint-disable-next-line security/detect-object-injection
|
||||
obj = obj[pathArray[i]] as Item // Dive one level deeper
|
||||
}
|
||||
return obj // Return the final value
|
||||
}
|
||||
2
src/types/FormState.d.ts
vendored
2
src/types/FormState.d.ts
vendored
@ -17,4 +17,6 @@ export interface FormState {
|
||||
offers: Tag[]
|
||||
needs: Tag[]
|
||||
relations: Item[]
|
||||
start: string
|
||||
end: string
|
||||
}
|
||||
|
||||
22
src/types/Item.d.ts
vendored
22
src/types/Item.d.ts
vendored
@ -1,13 +1,19 @@
|
||||
import type { ItemsApi } from './ItemsApi'
|
||||
import type { ItemType } from './ItemType'
|
||||
import type { LayerProps } from './LayerProps'
|
||||
import type { Relation } from './Relation'
|
||||
import type { UserItem } from './UserItem'
|
||||
import type { Point } from 'geojson'
|
||||
|
||||
interface Special_Find_Name {
|
||||
tags_id: string
|
||||
}
|
||||
|
||||
export interface Item {
|
||||
id: string
|
||||
name: string
|
||||
text: string
|
||||
data?: string
|
||||
position?: Point
|
||||
date_created?: string
|
||||
date_updated?: string | null
|
||||
@ -24,7 +30,21 @@ export interface Item {
|
||||
slug?: string
|
||||
user_created?: UserItem
|
||||
image?: string
|
||||
group_type: string
|
||||
group_type?: string
|
||||
offers?: Special_Find_Name[]
|
||||
needs?: Special_Find_Name[]
|
||||
status?: string
|
||||
color?: string
|
||||
markerIcon?: string
|
||||
avatar?: string
|
||||
new?: boolean
|
||||
contact?: string
|
||||
telephone?: string
|
||||
next_appointment?: string
|
||||
type?: ItemType
|
||||
|
||||
// {
|
||||
// coordinates: [number, number]
|
||||
/* constructor(
|
||||
id: string,
|
||||
name: string,
|
||||
|
||||
12
src/types/ItemType.d.ts
vendored
12
src/types/ItemType.d.ts
vendored
@ -1,5 +1,15 @@
|
||||
import type { Key } from 'react'
|
||||
|
||||
export interface ItemType {
|
||||
name: string
|
||||
show_start_end: boolean
|
||||
show_text: boolean
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
[key: string]: any
|
||||
profileTemplate: { collection: string | number; id: Key | null | undefined; item: any }[]
|
||||
offers_and_needs: boolean
|
||||
icon_as_labels: unknown
|
||||
relations: boolean
|
||||
template: string
|
||||
show_start_end_input: boolean
|
||||
questlog: boolean
|
||||
}
|
||||
|
||||
19
src/types/LayerProps.d.ts
vendored
19
src/types/LayerProps.d.ts
vendored
@ -17,18 +17,13 @@ export interface LayerProps {
|
||||
markerDefaultColor2?: string
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
api?: ItemsApi<any>
|
||||
itemType: ItemType
|
||||
itemNameField?: string
|
||||
itemSubnameField?: string
|
||||
itemTextField?: string
|
||||
itemAvatarField?: string
|
||||
itemColorField?: string
|
||||
itemOwnerField?: string
|
||||
itemTagsField?: string
|
||||
itemLatitudeField?: string
|
||||
itemLongitudeField?: string
|
||||
itemOffersField?: string
|
||||
itemNeedsField?: string
|
||||
itemType: ItemType // How does this relate to Item type defined in Item.d.ts?
|
||||
// TODO Conditionally type items with .avatar etc.?
|
||||
hasAvatar?: boolean
|
||||
hasColor?: boolean
|
||||
hasTags?: boolean
|
||||
hasOffers?: boolean
|
||||
hasNeeds?: boolean
|
||||
onlyOnePerOwner?: boolean
|
||||
customEditLink?: string
|
||||
customEditParameter?: string
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user