mirror of
https://github.com/utopia-os/utopia-ui.git
synced 2025-12-13 07:46:10 +00:00
owned item basics and item field adjustments
This commit is contained in:
parent
49ab4a9989
commit
a8112ee604
@ -14,9 +14,26 @@ import { useLocation } from 'react-router-dom';
|
||||
import { useAssetApi } from '../AppShell/hooks/useAssets'
|
||||
import { getValue } from '../../Utils/GetValue'
|
||||
|
||||
export const Layer = (props: LayerProps) => {
|
||||
|
||||
const [itemFormPopup, setItemFormPopup] = useState<ItemFormPopupProps | null>(null);
|
||||
export const Layer = ( {
|
||||
data,
|
||||
children,
|
||||
name='places',
|
||||
menuIcon='MapPinIcon',
|
||||
menuText='add new place',
|
||||
menuColor='#2E7D32',
|
||||
markerIcon='circle-solid',
|
||||
markerShape='circle',
|
||||
markerDefaultColor='#777',
|
||||
api,
|
||||
itemTitleField='name',
|
||||
itemTextField='text',
|
||||
itemAvatarField,
|
||||
itemColorField,
|
||||
itemOwnerField,
|
||||
setItemFormPopup,
|
||||
itemFormPopup,
|
||||
clusterRef
|
||||
}: LayerProps) => {
|
||||
|
||||
const filterTags = useFilterTags();
|
||||
|
||||
@ -41,15 +58,15 @@ export const Layer = (props: LayerProps) => {
|
||||
|
||||
useEffect(() => {
|
||||
|
||||
props.data && setItemsData(props);
|
||||
props.api && setItemsApi(props);
|
||||
}, [props.data, props.api])
|
||||
data && setItemsData({data, children, name, menuIcon, menuText, menuColor, markerIcon, markerShape, markerDefaultColor, api, itemTitleField, itemTextField, itemAvatarField, itemColorField, setItemFormPopup, itemFormPopup, clusterRef});
|
||||
api && setItemsApi({data, children, name, menuIcon, menuText, menuColor, markerIcon, markerShape, markerDefaultColor, api, itemTitleField, itemTextField, itemAvatarField, itemColorField, setItemFormPopup, itemFormPopup, clusterRef});
|
||||
}, [data, api])
|
||||
|
||||
useMapEvents({
|
||||
popupopen: (e) => {
|
||||
const item = Object.entries(leafletRefs).find(r => r[1].popup == e.popup)?.[1].item;
|
||||
if (item?.layer?.name == props.name && window.location.pathname.split("/")[2] != item.id) {
|
||||
window.history.pushState({}, "", `/${props.name}/${item.id}`)
|
||||
if (item?.layer?.name == name && window.location.pathname.split("/")[2] != item.id) {
|
||||
window.history.pushState({}, "", `/${name}/${item.id}`)
|
||||
let title = "";
|
||||
if(item.name) title = item.name;
|
||||
else if (item.layer?.itemTitleField) title = getValue(item, item.layer.itemTitleField);
|
||||
@ -63,13 +80,13 @@ export const Layer = (props: LayerProps) => {
|
||||
map.closePopup();
|
||||
}
|
||||
else {
|
||||
if (window.location.pathname.split("/")[1] == props.name) {
|
||||
if (window.location.pathname.split("/")[1] == name) {
|
||||
|
||||
if (window.location.pathname.split("/")[2]) {
|
||||
const id = window.location.pathname.split("/")[2]
|
||||
const marker = leafletRefs[id]?.marker;
|
||||
if (marker && marker != null) {
|
||||
marker !== null && props.clusterRef?.current?.zoomToShowLayer(marker, () => {
|
||||
marker !== null && clusterRef?.current?.zoomToShowLayer(marker, () => {
|
||||
marker.openPopup();
|
||||
});
|
||||
const item = leafletRefs[id]?.item;
|
||||
@ -96,7 +113,7 @@ export const Layer = (props: LayerProps) => {
|
||||
{items &&
|
||||
items.
|
||||
filter(item => item.text).
|
||||
filter(item => item.layer?.name === props.name)?.
|
||||
filter(item => item.layer?.name === name)?.
|
||||
filter(item =>
|
||||
filterTags.length == 0 ? item : filterTags.every(tag => getItemTags(item).some(filterTag => filterTag.id === tag.id)))?.
|
||||
filter(item => {
|
||||
@ -108,13 +125,13 @@ export const Layer = (props: LayerProps) => {
|
||||
map((item: Item) => {
|
||||
const tags = getItemTags(item);
|
||||
|
||||
let color1 = "#666";
|
||||
let color1 = markerDefaultColor;
|
||||
let color2 = "RGBA(35, 31, 32, 0.2)";
|
||||
if (props.itemColorField) color1 = getValue(item, props.itemColorField);
|
||||
if (itemColorField) color1 = getValue(item, itemColorField);
|
||||
else if (tags && tags[0]) {
|
||||
color1 = tags[0].color;
|
||||
}
|
||||
if (tags && tags[0] && props.itemColorField) color2 = tags[0].color;
|
||||
if (tags && tags[0] && itemColorField) color2 = tags[0].color;
|
||||
else if (tags && tags[1]) {
|
||||
color2 = tags[1].color;
|
||||
}
|
||||
@ -122,19 +139,20 @@ export const Layer = (props: LayerProps) => {
|
||||
<Marker ref={(r) => {
|
||||
if (!(item.id in leafletRefs))
|
||||
r && addMarker(item, r);
|
||||
}} icon={MarkerIconFactory(props.markerShape, color1, color2, props.markerIcon)} key={item.id} position={[item.position.coordinates[1], item.position.coordinates[0]]}>
|
||||
}} icon={MarkerIconFactory(markerShape, color1, color2, markerIcon)} key={item.id} position={[item.position.coordinates[1], item.position.coordinates[0]]}>
|
||||
{
|
||||
(props.children && React.Children.toArray(props.children).some(child => React.isValidElement(child) && child.props.__TYPE === "ItemView") ?
|
||||
React.Children.toArray(props.children).map((child) =>
|
||||
(children && React.Children.toArray(children).some(child => React.isValidElement(child) && child.props.__TYPE === "ItemView") ?
|
||||
React.Children.toArray(children).map((child) =>
|
||||
React.isValidElement(child) && child.props.__TYPE === "ItemView" ?
|
||||
<ItemViewPopup ref={(r) => {
|
||||
if (!(item.id in leafletRefs))
|
||||
r && addPopup(item, r as Popup);
|
||||
}} key={item.id + item.name}
|
||||
title={props.itemTitleField && item ? getValue(item, props.itemTitleField) : undefined}
|
||||
avatar={props.itemAvatarField && item ? assetsApi.url + getValue(item, props.itemAvatarField) : undefined}
|
||||
title={itemTitleField && item ? getValue(item, itemTitleField) : undefined}
|
||||
avatar={itemAvatarField && item ? assetsApi.url + getValue(item, itemAvatarField) : undefined}
|
||||
owner={itemOwnerField && item ? getValue(item, itemOwnerField) : undefined}
|
||||
item={item}
|
||||
setItemFormPopup={props.setItemFormPopup}>
|
||||
setItemFormPopup={setItemFormPopup}>
|
||||
{child}
|
||||
</ItemViewPopup>
|
||||
: ""
|
||||
@ -144,29 +162,30 @@ export const Layer = (props: LayerProps) => {
|
||||
<ItemViewPopup key={item.id + item.name} ref={(r) => {
|
||||
if (!(item.id in leafletRefs))
|
||||
r && addPopup(item, r as Popup);
|
||||
}} title={props.itemTitleField && item ? getValue(item, props.itemTitleField) : undefined}
|
||||
avatar={props.itemAvatarField && item ? assetsApi.url + getValue(item, props.itemAvatarField) : undefined}
|
||||
}} title={itemTitleField && item ? getValue(item, itemTitleField) : undefined}
|
||||
avatar={itemAvatarField && item ? assetsApi.url + getValue(item, itemAvatarField) : undefined}
|
||||
owner={itemOwnerField && item ? getValue(item, itemOwnerField) : undefined}
|
||||
item={item}
|
||||
setItemFormPopup={props.setItemFormPopup} />
|
||||
setItemFormPopup={setItemFormPopup} />
|
||||
</>)
|
||||
}
|
||||
<Tooltip offset={[0, -38]} direction='top'>{item.name? item.name : getValue(item, props.itemTitleField)}</Tooltip>
|
||||
<Tooltip offset={[0, -38]} direction='top'>{item.name? item.name : getValue(item, itemTitleField)}</Tooltip>
|
||||
</Marker>
|
||||
);
|
||||
})
|
||||
}
|
||||
{//{props.children}}
|
||||
{//{children}}
|
||||
}
|
||||
{props.itemFormPopup && props.itemFormPopup.layer!.name == props.name &&
|
||||
(props.children && React.Children.toArray(props.children).some(child => React.isValidElement(child) && child.props.__TYPE === "ItemForm") ?
|
||||
React.Children.toArray(props.children).map((child) =>
|
||||
{itemFormPopup && itemFormPopup.layer!.name == name &&
|
||||
(children && React.Children.toArray(children).some(child => React.isValidElement(child) && child.props.__TYPE === "ItemForm") ?
|
||||
React.Children.toArray(children).map((child) =>
|
||||
React.isValidElement(child) && child.props.__TYPE === "ItemForm" ?
|
||||
<ItemFormPopup key={props.setItemFormPopup?.name} position={props.itemFormPopup!.position} layer={props.itemFormPopup!.layer} setItemFormPopup={setItemFormPopup} item={props.itemFormPopup!.item} >{child}</ItemFormPopup>
|
||||
<ItemFormPopup key={setItemFormPopup?.name} position={itemFormPopup!.position} layer={itemFormPopup!.layer} setItemFormPopup={setItemFormPopup} item={itemFormPopup!.item} >{child}</ItemFormPopup>
|
||||
: ""
|
||||
)
|
||||
:
|
||||
<>
|
||||
<ItemFormPopup position={props.itemFormPopup!.position} layer={props.itemFormPopup!.layer} setItemFormPopup={setItemFormPopup} item={props.itemFormPopup!.item} />
|
||||
<ItemFormPopup position={itemFormPopup!.position} layer={itemFormPopup!.layer} setItemFormPopup={setItemFormPopup} item={itemFormPopup!.item} />
|
||||
</>)
|
||||
}
|
||||
</>
|
||||
|
||||
@ -18,7 +18,7 @@ export interface ItemFormPopupProps {
|
||||
layer: LayerProps,
|
||||
item?: Item,
|
||||
children?: React.ReactNode,
|
||||
setItemFormPopup: React.Dispatch<React.SetStateAction<any>>
|
||||
setItemFormPopup?: React.Dispatch<React.SetStateAction<ItemFormPopupProps | null>>
|
||||
}
|
||||
|
||||
export function ItemFormPopup(props: ItemFormPopupProps) {
|
||||
@ -76,23 +76,23 @@ export function ItemFormPopup(props: ItemFormPopupProps) {
|
||||
map.closePopup();
|
||||
}
|
||||
else {
|
||||
|
||||
const uuid = crypto.randomUUID();
|
||||
let success = false;
|
||||
try {
|
||||
await props.layer.api?.createItem!({...formItem, id: crypto.randomUUID() });
|
||||
await props.layer.api?.createItem!({...formItem, id: uuid });
|
||||
success = true;
|
||||
} catch (error) {
|
||||
toast.error(error.toString());
|
||||
}
|
||||
if(success) {
|
||||
addItem({...formItem, id: crypto.randomUUID(), layer: props.layer, user_created: user});
|
||||
addItem({...formItem, id: uuid, layer: props.layer, user_created: user});
|
||||
toast.success("New item created");
|
||||
resetFilterTags();
|
||||
}
|
||||
setSpinner(false);
|
||||
map.closePopup();
|
||||
}
|
||||
props.setItemFormPopup(null);
|
||||
props.setItemFormPopup!(null);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -7,13 +7,16 @@ import { Item } from "../../../../types";
|
||||
import { toast } from "react-toastify";
|
||||
import { useHasUserPermission } from "../../hooks/usePermissions";
|
||||
import { timeAgo } from "../../../../Utils/TimeAgo";
|
||||
import { useAuth } from "../../../Auth";
|
||||
import { useEffect } from "react";
|
||||
|
||||
|
||||
|
||||
export function HeaderView({ item, title, avatar, setItemFormPopup }: {
|
||||
export function HeaderView({ item, title, avatar, owner, setItemFormPopup }: {
|
||||
item: Item,
|
||||
title?: string,
|
||||
avatar?: string,
|
||||
owner?: string,
|
||||
setItemFormPopup?: React.Dispatch<React.SetStateAction<ItemFormPopupProps | null>>
|
||||
}) {
|
||||
|
||||
@ -23,6 +26,9 @@ export function HeaderView({ item, title, avatar, setItemFormPopup }: {
|
||||
const map = useMap();
|
||||
const hasUserPermission = useHasUserPermission();
|
||||
|
||||
const { user } = useAuth();
|
||||
|
||||
|
||||
const removeItemFromMap = async (event: React.MouseEvent<HTMLElement>) => {
|
||||
setLoading(true);
|
||||
let success = false;
|
||||
@ -66,7 +72,9 @@ export function HeaderView({ item, title, avatar, setItemFormPopup }: {
|
||||
</div>
|
||||
</div>
|
||||
<div className='tw-col-span-1'>
|
||||
{(item.layer?.api?.deleteItem || item.layer?.api?.updateItem) && (hasUserPermission(item.layer.api?.collectionName!, "delete") || hasUserPermission(item.layer.api?.collectionName!, "update")) &&
|
||||
{(item.layer?.api?.deleteItem || item.layer?.api?.updateItem)
|
||||
&& ((user && owner === user.id) || owner == undefined)
|
||||
&& (hasUserPermission(item.layer.api?.collectionName!, "delete") || hasUserPermission(item.layer.api?.collectionName!, "update")) &&
|
||||
<div className="tw-dropdown tw-dropdown-bottom">
|
||||
<label tabIndex={0} className="tw-bg-base-100 tw-btn tw-m-1 tw-leading-3 tw-border-none tw-min-h-0 tw-h-6">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" className="tw-h-5 tw-w-5" viewBox="0 0 20 20" fill="currentColor">
|
||||
|
||||
@ -3,9 +3,9 @@ import { Link } from 'react-router-dom'
|
||||
import { getValue } from '../../../../Utils/GetValue'
|
||||
import { Item } from '../../../../types'
|
||||
|
||||
export const PopupButton = ({url, parameter, text, color, item} : {url: string, parameter: string, text: string, color : string, item? : Item}) => {
|
||||
export const PopupButton = ({url, parameterField, text, color = 'oklch(var(--p))', colorField, item} : {url: string, parameterField?: string, text: string, color? : string, colorField?: string, item? : Item}) => {
|
||||
return (
|
||||
<Link to={`${url}/${getValue(item,parameter)}`}><button style={{backgroundColor: getValue(item,color)}} className="tw-btn tw-text-white tw-btn-sm tw-float-right -tw-mt-2">{text}</button></Link>
|
||||
<Link to={`${url}/${parameterField? getValue(item,parameterField):``}`}><button style={{backgroundColor: `${colorField? getValue(item,colorField) : color}`}} className="tw-btn tw-text-white tw-btn-sm tw-float-right -tw-mt-2">{text}</button></Link>
|
||||
|
||||
)
|
||||
}
|
||||
|
||||
@ -14,6 +14,7 @@ export interface ItemViewPopupProps {
|
||||
children?: React.ReactNode;
|
||||
title?: string;
|
||||
avatar?: string;
|
||||
owner?: string,
|
||||
setItemFormPopup?: React.Dispatch<React.SetStateAction<ItemFormPopupProps | null>>
|
||||
}
|
||||
|
||||
@ -25,7 +26,7 @@ export const ItemViewPopup = React.forwardRef((props: ItemViewPopupProps, ref: a
|
||||
return (
|
||||
<LeafletPopup ref={ref} maxHeight={377} minWidth={275} maxWidth={275} autoPanPadding={[20, 80]}>
|
||||
<div className='tw-bg-base-100 tw-text-base-content'>
|
||||
<HeaderView item={props.item} title={props.title} avatar={props.avatar} setItemFormPopup={props.setItemFormPopup} />
|
||||
<HeaderView item={props.item} title={props.title} avatar={props.avatar} owner={props.owner} setItemFormPopup={props.setItemFormPopup} />
|
||||
<div className='tw-overflow-y-auto tw-overflow-x-hidden tw-max-h-64'>
|
||||
{props.children ?
|
||||
|
||||
|
||||
@ -22,10 +22,12 @@ export interface LayerProps {
|
||||
markerDefaultColor: string,
|
||||
api?: ItemsApi<any>,
|
||||
itemTitleField?: string,
|
||||
itemTextField?: string,
|
||||
itemAvatarField?: string,
|
||||
itemColorField?: string,
|
||||
setItemFormPopup?: React.Dispatch<React.SetStateAction<ItemFormPopupProps | null>>,
|
||||
itemFormPopup?: ItemFormPopupProps | null,
|
||||
itemOwnerField?: string,
|
||||
setItemFormPopup?: React.Dispatch<React.SetStateAction<ItemFormPopupProps | null>>,
|
||||
itemFormPopup?: ItemFormPopupProps | null,
|
||||
clusterRef?: React.MutableRefObject<any>
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user