mirror of
https://github.com/utopia-os/utopia-ui.git
synced 2025-12-13 07:46:10 +00:00
profile layer basics
This commit is contained in:
parent
0e63c794d3
commit
8ced9d39e7
@ -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>
|
||||
)
|
||||
|
||||
@ -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>
|
||||
|
||||
@ -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>
|
||||
:
|
||||
|
||||
@ -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 ?
|
||||
|
||||
|
||||
@ -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>
|
||||
|
||||
|
||||
@ -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>
|
||||
|
||||
@ -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 = {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user