mirror of
https://github.com/utopia-os/utopia-ui.git
synced 2025-12-13 07:46:10 +00:00
relations in item-profile-settings
This commit is contained in:
parent
44f46d60a4
commit
d1638aea31
@ -8,13 +8,14 @@ import { TextInput } from "../Input";
|
||||
import { getValue } from "../../Utils/GetValue";
|
||||
import { useGetItemTags } from "../Map/hooks/useTags";
|
||||
|
||||
export function ActionButton({ item, triggerAddButton, triggerItemSelected, existingRelations, itemType, colorField, collection = "items" }: {
|
||||
export function ActionButton({ item, triggerAddButton, triggerItemSelected, existingRelations, itemType, colorField, collection = "items", customStyle }: {
|
||||
triggerAddButton?: any,
|
||||
triggerItemSelected?: any,
|
||||
existingRelations: Item[],
|
||||
itemType?: string;
|
||||
colorField?: string,
|
||||
collection?: string,
|
||||
customStyle?:string,
|
||||
item: Item
|
||||
}) {
|
||||
const hasUserPermission = useHasUserPermission();
|
||||
@ -32,7 +33,7 @@ export function ActionButton({ item, triggerAddButton, triggerItemSelected, exis
|
||||
return (
|
||||
<>{hasUserPermission(collection, "update", item) &&
|
||||
<>
|
||||
<div className="tw-absolute tw-right-4 tw-bottom-4 tw-flex tw-flex-col" >
|
||||
<div className={`tw-absolute tw-right-4 tw-bottom-4 tw-flex tw-flex-col ${customStyle}`} >
|
||||
{triggerItemSelected && <button tabIndex={0} className="tw-z-500 tw-btn tw-btn-circle tw-shadow" onClick={() => { 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)}`, color: "#fff" }}>
|
||||
<svg className="tw-h-5 tw-w-5" stroke="currentColor" fill="currentColor" strokeWidth="0" viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg"><path d="M326.612 185.391c59.747 59.809 58.927 155.698.36 214.59-.11.12-.24.25-.36.37l-67.2 67.2c-59.27 59.27-155.699 59.262-214.96 0-59.27-59.26-59.27-155.7 0-214.96l37.106-37.106c9.84-9.84 26.786-3.3 27.294 10.606.648 17.722 3.826 35.527 9.69 52.721 1.986 5.822.567 12.262-3.783 16.612l-13.087 13.087c-28.026 28.026-28.905 73.66-1.155 101.96 28.024 28.579 74.086 28.749 102.325.51l67.2-67.19c28.191-28.191 28.073-73.757 0-101.83-3.701-3.694-7.429-6.564-10.341-8.569a16.037 16.037 0 0 1-6.947-12.606c-.396-10.567 3.348-21.456 11.698-29.806l21.054-21.055c5.521-5.521 14.182-6.199 20.584-1.731a152.482 152.482 0 0 1 20.522 17.197zM467.547 44.449c-59.261-59.262-155.69-59.27-214.96 0l-67.2 67.2c-.12.12-.25.25-.36.37-58.566 58.892-59.387 154.781.36 214.59a152.454 152.454 0 0 0 20.521 17.196c6.402 4.468 15.064 3.789 20.584-1.731l21.054-21.055c8.35-8.35 12.094-19.239 11.698-29.806a16.037 16.037 0 0 0-6.947-12.606c-2.912-2.005-6.64-4.875-10.341-8.569-28.073-28.073-28.191-73.639 0-101.83l67.2-67.19c28.239-28.239 74.3-28.069 102.325.51 27.75 28.3 26.872 73.934-1.155 101.96l-13.087 13.087c-4.35 4.35-5.769 10.79-3.783 16.612 5.864 17.194 9.042 34.999 9.69 52.721.509 13.906 17.454 20.446 27.294 10.606l37.106-37.106c59.271-59.259 59.271-155.699.001-214.959z"></path></svg>
|
||||
|
||||
|
||||
@ -114,7 +114,7 @@ export function OverlayItemProfile() {
|
||||
await map.setView(new LatLng(item?.position?.coordinates[1]!, item?.position?.coordinates[0]! + x / 4), undefined);
|
||||
setTimeout(() => {
|
||||
marker.openPopup();
|
||||
}, 300);
|
||||
}, 500);
|
||||
}
|
||||
if (item) {
|
||||
if (item.position) {
|
||||
|
||||
@ -1,4 +1,3 @@
|
||||
import * as React from 'react'
|
||||
import { useItems, useUpdateItem, useAddItem } from '../Map/hooks/useItems'
|
||||
import { useEffect, useState } from 'react';
|
||||
import { getValue } from '../../Utils/GetValue';
|
||||
@ -7,7 +6,7 @@ import { useAuth } from '../Auth';
|
||||
import { TextInput, TextAreaInput } from '../Input';
|
||||
import { ColorPicker } from './ColorPicker';
|
||||
import { hashTagRegex } from '../../Utils/HashTagRegex';
|
||||
import { useAddTag, useTags } from '../Map/hooks/useTags';
|
||||
import { useAddTag, useGetItemTags, useTags } from '../Map/hooks/useTags';
|
||||
import { randomColor } from '../../Utils/RandomColor';
|
||||
import { useLocation, useNavigate } from 'react-router-dom';
|
||||
import { Item, Tag } from '../../types';
|
||||
@ -16,6 +15,10 @@ import { AvatarWidget } from './AvatarWidget';
|
||||
import { encodeTag } from '../../Utils/FormatTags';
|
||||
import { useLayers } from '../Map/hooks/useLayers';
|
||||
import { TagsWidget } from './TagsWidget';
|
||||
import { LinkedItemsHeaderView } from './LinkedItemsHeaderView';
|
||||
import { TextView } from '../Map';
|
||||
import { ActionButton } from './ActionsButton';
|
||||
import { useHasUserPermission } from '../Map/hooks/usePermissions';
|
||||
|
||||
|
||||
|
||||
@ -29,7 +32,9 @@ export function OverlayItemProfileSettings() {
|
||||
const [color, setColor] = useState<string>("");
|
||||
const [offers, setOffers] = useState<Array<Tag>>([]);
|
||||
const [needs, setNeeds] = useState<Array<Tag>>([]);
|
||||
const [relations, setRelations] = useState<Array<Item>>([]);
|
||||
|
||||
const [updatePermission, setUpdatePermission] = useState<boolean>(false);
|
||||
|
||||
|
||||
const [activeTab, setActiveTab] = useState<number>(1);
|
||||
@ -45,10 +50,18 @@ export function OverlayItemProfileSettings() {
|
||||
const tags = useTags();
|
||||
const addTag = useAddTag();
|
||||
const navigate = useNavigate();
|
||||
const hasUserPermission = useHasUserPermission();
|
||||
const getItemTags = useGetItemTags();
|
||||
|
||||
|
||||
|
||||
const items = useItems();
|
||||
const [item, setItem] = useState<Item>({} as Item)
|
||||
|
||||
useEffect(() => {
|
||||
item && item.user_created && hasUserPermission("items", "update", item) && setUpdatePermission(true);
|
||||
}, [item])
|
||||
|
||||
useEffect(() => {
|
||||
const itemId = location.pathname.split("/")[2];
|
||||
|
||||
@ -90,6 +103,7 @@ export function OverlayItemProfileSettings() {
|
||||
setImage(item?.image ? item?.image : "");
|
||||
setOffers([]);
|
||||
setNeeds([]);
|
||||
setRelations([]);
|
||||
item?.offers?.map(o => {
|
||||
const offer = tags.find(t => t.id === o.tags_id);
|
||||
offer && setOffers(current => [...current, offer])
|
||||
@ -98,6 +112,10 @@ export function OverlayItemProfileSettings() {
|
||||
const need = tags.find(t => t.id === o.tags_id);
|
||||
need && setNeeds(current => [...current, need])
|
||||
})
|
||||
item.relations?.map(r => {
|
||||
const item = items.find(i => i.id == r.related_items_id)
|
||||
item && setRelations(current => [...current, item])
|
||||
})
|
||||
|
||||
}, [item])
|
||||
|
||||
@ -203,6 +221,47 @@ export function OverlayItemProfileSettings() {
|
||||
}
|
||||
}
|
||||
|
||||
const linkItem = async (id: string) => {
|
||||
let new_relations = item.relations || [];
|
||||
new_relations?.push({ items_id: item.id, related_items_id: id })
|
||||
const updatedItem = { id: item.id, relations: new_relations }
|
||||
|
||||
let success = false;
|
||||
try {
|
||||
await item?.layer?.api?.updateItem!(updatedItem)
|
||||
success = true;
|
||||
} catch (error) {
|
||||
toast.error(error.toString());
|
||||
}
|
||||
if (success) {
|
||||
updateItem({ ...item, relations: new_relations })
|
||||
toast.success("Item linked");
|
||||
}
|
||||
}
|
||||
|
||||
const unlinkItem = async (id: string) => {
|
||||
console.log(id);
|
||||
|
||||
let new_relations = item.relations?.filter(r => r.related_items_id !== id)
|
||||
console.log(new_relations);
|
||||
|
||||
const updatedItem = { id: item.id, relations: new_relations }
|
||||
|
||||
|
||||
let success = false;
|
||||
try {
|
||||
await item?.layer?.api?.updateItem!(updatedItem)
|
||||
success = true;
|
||||
} catch (error) {
|
||||
toast.error(error.toString());
|
||||
}
|
||||
if (success) {
|
||||
updateItem({ ...item, relations: new_relations })
|
||||
toast.success("Item unlinked");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
return (
|
||||
@ -239,11 +298,34 @@ export function OverlayItemProfileSettings() {
|
||||
</div>
|
||||
</>
|
||||
}
|
||||
{item.layer?.itemType.relations &&
|
||||
<>
|
||||
<input type="radio" name="my_tabs_2" role="tab" className="tw-tab [--tab-border-color:var(--fallback-bc,oklch(var(--bc)/0.2))]" aria-label="Relations" checked={activeTab == 7 && true} onChange={() => updateActiveTab(7)} />
|
||||
<div role="tabpanel" className="tw-tab-content tw-bg-base-100 tw-rounded-box tw-h-[calc(100dvh-332px)] tw-overflow-y-auto tw-pt-4 tw-pb-1 -tw-mx-4 tw-overflow-x-hidden">
|
||||
<div className='tw-h-full'>
|
||||
<div className='tw-grid tw-grid-cols-1 sm:tw-grid-cols-2 md:tw-grid-cols-1 lg:tw-grid-cols-1 xl:tw-grid-cols-1 2xl:tw-grid-cols-2'>
|
||||
{relations && relations.map(i =>
|
||||
|
||||
|
||||
<div key={i.id} className='tw-cursor-pointer tw-card tw-bg-base-200 tw-border-[1px] tw-border-base-300 tw-card-body tw-shadow-xl tw-text-base-content tw-mx-4 tw-p-6 tw-mb-4' onClick={() => navigate('/item/' + i.id)}>
|
||||
<LinkedItemsHeaderView unlinkPermission={updatePermission} item={i} unlinkCallback={unlinkItem} loading={loading} />
|
||||
<div className='tw-overflow-y-auto tw-overflow-x-hidden tw-max-h-64 fade'>
|
||||
<TextView truncate item={i} />
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
{updatePermission && <ActionButton customStyle="!tw-bottom-20" collection="items" item={item} existingRelations={relations} triggerItemSelected={linkItem} colorField={item.layer.itemColorField}></ActionButton>}
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
}
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<div className="tw-mt-4 tw-mb-4"><button className={loading ? " tw-loading tw-btn-disabled tw-btn tw-btn-primary tw-float-right" : "tw-btn tw-btn-primary tw-float-right"} onClick={() => onUpdateItem()}>Update</button></div>
|
||||
<div className="tw-mt-4 tw-mb-4"><button className={loading ? " tw-loading tw-btn tw-float-right" : "tw-btn tw-float-right"} onClick={() => onUpdateItem()} style={true ? { 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)}`, color: "#fff" } : {color: "#fff"}}>Update</button></div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user