profile layer basics

This commit is contained in:
Anton 2023-12-20 20:38:16 +01:00
parent 0e63c794d3
commit 8ced9d39e7
7 changed files with 54 additions and 20 deletions

View File

@ -8,8 +8,8 @@ export const ItemView = ({ children, item }: { children?: React.ReactNode, item?
<div>
{children ?
React.Children.toArray(children).map((child) =>
React.isValidElement<{ item: Item, test: string }>(child) ?
React.cloneElement(child, { item: item, test: "test" }) : ""
React.isValidElement<{ item: Item }>(child) ?
React.cloneElement(child, { item: item }) : ""
) : ""}
</div>
)

View File

@ -85,6 +85,7 @@ export const Layer = (props: LayerProps) => {
<>
{items &&
items.
filter(item => item.text).
filter(item => item.layer?.name === props.name)?.
filter(item =>
filterTags.length == 0 ? item : filterTags.every(tag => getItemTags(item).some(filterTag => filterTag.id === tag.id)))?.
@ -117,7 +118,7 @@ export const Layer = (props: LayerProps) => {
<ItemViewPopup ref={(r) => {
if (!(item.id in leafletRefs))
r && addPopup(item, r as Popup);
}} key={item.id + item.name} item={item} setItemFormPopup={props.setItemFormPopup} >{child}</ItemViewPopup>
}} key={item.id + item.name} itemTitleField={props.itemTitleField} itemAvatarField={props.itemAvatarField} item={item} setItemFormPopup={props.setItemFormPopup} >{child}</ItemViewPopup>
: ""
)
:
@ -125,7 +126,7 @@ export const Layer = (props: LayerProps) => {
<ItemViewPopup key={item.id + item.name} ref={(r) => {
if (!(item.id in leafletRefs))
r && addPopup(item, r as Popup);
}} item={item} setItemFormPopup={props.setItemFormPopup} />
}} item={item} itemTitleField={props.itemTitleField} itemAvatarField={props.itemAvatarField} setItemFormPopup={props.setItemFormPopup} />
</>)
}
<Tooltip offset={[0, -38]} direction='top'>{item.name}</Tooltip>

View File

@ -9,8 +9,10 @@ import { useHasUserPermission } from "../../hooks/usePermissions";
export function HeaderView({ item, setItemFormPopup }: {
export function HeaderView({ item, title, avatar, setItemFormPopup }: {
item: Item,
title?: string,
avatar?: string,
setItemFormPopup?: React.Dispatch<React.SetStateAction<ItemFormPopupProps | null>>
}) {
@ -25,15 +27,15 @@ export function HeaderView({ item, setItemFormPopup }: {
setLoading(true);
let success = false;
try {
await item.layer?.api?.deleteItem!(item.id)
success = true;
await item.layer?.api?.deleteItem!(item.id)
success = true;
} catch (error) {
toast.error(error.toString());
toast.error(error.toString());
}
if(success) {
if (success) {
removeItem(item);
toast.success("Item deleted");
}
toast.success("Item deleted");
}
setLoading(false);
map.closePopup();
@ -47,11 +49,22 @@ export function HeaderView({ item, setItemFormPopup }: {
setItemFormPopup({ position: new LatLng(item.position.coordinates[1], item.position.coordinates[0]), layer: item.layer!, item: item, setItemFormPopup: setItemFormPopup })
}
console.log(title);
return (
<div className='tw-grid tw-grid-cols-6 tw-pb-2'>
<div className='tw-col-span-5'>
<b className="tw-text-xl tw-font-bold">{item.name}</b>
<div className="tw-flex tw-flex-row">{
avatar ?
<div className="tw-w-10 tw-rounded-full">
<img className="tw-rounded-full" src={avatar} />
</div>
:
""
}
<b className={`tw-text-xl tw-font-bold ${avatar? "tw-ml-2 tw-mt-1" : ""}`}>{title ? title : item.name}</b>
</div>
</div>
<div className='tw-col-span-1'>
{item.layer?.api &&
@ -62,7 +75,7 @@ export function HeaderView({ item, setItemFormPopup }: {
</svg>
</label>
<ul tabIndex={0} className="tw-dropdown-content tw-menu tw-p-2 tw-shadow tw-bg-base-100 tw-rounded-box">
{item.layer.api.updateItem && hasUserPermission(item.layer.api?.collectionName!,"update") && <li>
{item.layer.api.updateItem && hasUserPermission(item.layer.api?.collectionName!, "update") && <li>
<a className="!tw-text-base-content" onClick={openEditPopup}>
<svg xmlns="http://www.w3.org/2000/svg" className="tw-h-5 tw-w-5" viewBox="0 0 20 20" fill="currentColor">
<path d="M13.586 3.586a2 2 0 112.828 2.828l-.793.793-2.828-2.828.793-.793zM11.379 5.793L3 14.172V17h2.828l8.38-8.379-2.83-2.828z" />
@ -70,7 +83,7 @@ export function HeaderView({ item, setItemFormPopup }: {
</a>
</li>}
{item.layer.api.deleteItem && hasUserPermission(item.layer.api?.collectionName!,"delete") && <li>
{item.layer.api.deleteItem && hasUserPermission(item.layer.api?.collectionName!, "delete") && <li>
<a className=' !tw-text-error' onClick={removeItemFromMap}>
{loading ? <span className="tw-loading tw-loading-spinner tw-loading-sm"></span>
:

View File

@ -4,20 +4,36 @@ import { Item } from '../../../types'
import { ItemFormPopupProps } from './ItemFormPopup'
import { HeaderView } from './ItemPopupComponents/HeaderView'
import { TextView } from './ItemPopupComponents/TextView'
import { useAssetApi } from '../../AppShell/hooks/useAssets'
export interface ItemViewPopupProps {
item: Item,
children?: React.ReactNode;
itemTitleField?: string;
itemAvatarField?: string;
setItemFormPopup?: React.Dispatch<React.SetStateAction<ItemFormPopupProps | null>>
}
function getValue(obj, path) {
if(obj){
for (var i=0, path=path.split('.'), len=path.length; i<len; i++){
obj = obj[path[i]];
};
return obj;
}
};
export const ItemViewPopup = React.forwardRef((props: ItemViewPopupProps, ref: any) => {
const assetsApi = useAssetApi();
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} setItemFormPopup={props.setItemFormPopup} />
<HeaderView item={props.item} title={props.itemTitleField && props.item? getValue(props.item,props.itemTitleField) : undefined} avatar={props.itemAvatarField && props.item? assetsApi.url+getValue(props.item,props.itemAvatarField) : undefined} setItemFormPopup={props.setItemFormPopup} />
<div className='tw-overflow-y-auto tw-max-h-72'>
{props.children ?

View File

@ -40,8 +40,8 @@ export function LayerControl() {
:
<div className="tw-card-body hover:tw-bg-slate-300 tw-rounded-2xl tw-p-2 tw-h-10 tw-w-10 tw-transition-all tw-duration-300 hover:tw-cursor-pointer" onClick={() => setOpen(true)}>
<svg version="1.1" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg">
<path id="svg_1" fill="#000" d="m2.75565,11.90727l-1.03852,0.28372c-0.77718,0.38859 -0.77718,1.0138 0,1.4023l7.0156,3.5078c0.77718,0.38859 2.0275,0.38859 2.8047,0l7.0156,-3.5078c0.77718,-0.38859 0.77718,-1.0138 0,-1.4023l-0.63311,-0.48643l-4.67718,2.23624c-1.5452,0.77262 -3.31877,1.58343 -4.86407,0.81081l-5.62302,-2.84434z" />
<path id="svg_2" strokeWidth="2" stroke="#000" fill="none" d="m11.247,4.30851l6.2349,3.0877c0.69083,0.34211 0.69083,0.89295 0,1.2351l-6.2349,3.0877c-0.69083,0.34211 -1.8031,0.34212 -2.494,0l-6.2349,-3.0877c-0.69083,-0.34211 -0.69083,-0.89295 0,-1.2351l6.2349,-3.0877c0.69083,-0.34211 1.8031,-0.34211 2.494,0z" />
<path id="svg_1" fill="currentColor" d="m2.75565,11.90727l-1.03852,0.28372c-0.77718,0.38859 -0.77718,1.0138 0,1.4023l7.0156,3.5078c0.77718,0.38859 2.0275,0.38859 2.8047,0l7.0156,-3.5078c0.77718,-0.38859 0.77718,-1.0138 0,-1.4023l-0.63311,-0.48643l-4.67718,2.23624c-1.5452,0.77262 -3.31877,1.58343 -4.86407,0.81081l-5.62302,-2.84434z" />
<path id="svg_2" strokeWidth="2" stroke="currentColor" fill="none" d="m11.247,4.30851l6.2349,3.0877c0.69083,0.34211 0.69083,0.89295 0,1.2351l-6.2349,3.0877c-0.69083,0.34211 -1.8031,0.34212 -2.494,0l-6.2349,-3.0877c-0.69083,-0.34211 -0.69083,-0.89295 0,-1.2351l6.2349,-3.0877c0.69083,-0.34211 1.8031,-0.34211 2.494,0z" />
</svg>
</div>

View File

@ -13,7 +13,7 @@ export function QuestControl() {
<div className="tw-card tw-bg-base-100 tw-shadow-xl tw-my-2 tw-w-10" onClick={e => e.stopPropagation()}>
<div className="tw-card-body hover:tw-bg-slate-300 tw-rounded-2xl tw-p-2 tw-h-10 tw-w-10 tw-transition-all tw-duration-300 hover:tw-cursor-pointer" onClick={() => setQuestsOpen(true)}>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path d="M192 0c17.7 0 32 14.3 32 32V144H160V32c0-17.7 14.3-32 32-32zM64 64c0-17.7 14.3-32 32-32s32 14.3 32 32v80H64V64zm192 0c0-17.7 14.3-32 32-32s32 14.3 32 32v96c0 17.7-14.3 32-32 32s-32-14.3-32-32V64zm96 64c0-17.7 14.3-32 32-32s32 14.3 32 32v64c0 17.7-14.3 32-32 32s-32-14.3-32-32V128zm-96 88l0-.6c9.4 5.4 20.3 8.6 32 8.6c13.2 0 25.4-4 35.6-10.8c8.7 24.9 32.5 42.8 60.4 42.8c11.7 0 22.6-3.1 32-8.6V256c0 52.3-25.1 98.8-64 128v96c0 17.7-14.3 32-32 32H160c-17.7 0-32-14.3-32-32V401.6c-17.3-7.9-33.2-18.8-46.9-32.5L69.5 357.5C45.5 333.5 32 300.9 32 267V240c0-35.3 28.7-64 64-64h88c22.1 0 40 17.9 40 40s-17.9 40-40 40H128c-8.8 0-16 7.2-16 16s7.2 16 16 16h56c39.8 0 72-32.2 72-72z"/></svg>
<svg xmlns="http://www.w3.org/2000/svg" fill="currentColor" stroke="currentColor" viewBox="0 0 448 512"><path d="M192 0c17.7 0 32 14.3 32 32V144H160V32c0-17.7 14.3-32 32-32zM64 64c0-17.7 14.3-32 32-32s32 14.3 32 32v80H64V64zm192 0c0-17.7 14.3-32 32-32s32 14.3 32 32v96c0 17.7-14.3 32-32 32s-32-14.3-32-32V64zm96 64c0-17.7 14.3-32 32-32s32 14.3 32 32v64c0 17.7-14.3 32-32 32s-32-14.3-32-32V128zm-96 88l0-.6c9.4 5.4 20.3 8.6 32 8.6c13.2 0 25.4-4 35.6-10.8c8.7 24.9 32.5 42.8 60.4 42.8c11.7 0 22.6-3.1 32-8.6V256c0 52.3-25.1 98.8-64 128v96c0 17.7-14.3 32-32 32H160c-17.7 0-32-14.3-32-32V401.6c-17.3-7.9-33.2-18.8-46.9-32.5L69.5 357.5C45.5 333.5 32 300.9 32 267V240c0-35.3 28.7-64 64-64h88c22.1 0 40 17.9 40 40s-17.9 40-40 40H128c-8.8 0-16 7.2-16 16s7.2 16 16 16h56c39.8 0 72-32.2 72-72z"/></svg>
</div>
</div>

View File

@ -21,6 +21,8 @@ export interface LayerProps {
markerShape: string,
markerDefaultColor: string,
api?: ItemsApi<any>,
itemTitleField?: string,
itemAvatarField?: string,
setItemFormPopup?: React.Dispatch<React.SetStateAction<ItemFormPopupProps | null>>,
itemFormPopup?: ItemFormPopupProps | null,
clusterRef?: React.MutableRefObject<any>
@ -67,7 +69,7 @@ export interface ItemsApi<T> {
getItems(): Promise<any>,
createItem?(item : T): Promise<any>,
updateItem?(item : T): Promise<any>,
deleteItem?(id : number | string): Promise<any>,
deleteItem?(id : string): Promise<any>,
collectionName?: string
}
@ -89,10 +91,12 @@ export type UserItem = {
id?: string;
avatar?: string;
role?: string;
color?: string;
first_name: string;
description: string;
email: string;
password?: string;
geoposition?: Geometry
}
export type Permission = {