mirror of
https://github.com/utopia-os/utopia-ui.git
synced 2025-12-13 07:46:10 +00:00
fix slow tab switch
This commit is contained in:
parent
8bbdda2873
commit
9ba935a21a
@ -51,6 +51,9 @@ export function ProfileForm({ userType }: { userType: string }) {
|
||||
const getItemTags = useGetItemTags();
|
||||
const items = useItems();
|
||||
|
||||
const [urlParams, setUrlParams] = useState(new URLSearchParams(location.search));
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
item && hasUserPermission("items", "update", item) && setUpdatePermission(true);
|
||||
}, [item])
|
||||
@ -119,8 +122,6 @@ export function ProfileForm({ userType }: { userType: string }) {
|
||||
setTemplate(item.layer?.itemType.template || userType);
|
||||
}, [userType, item])
|
||||
|
||||
let params = new URLSearchParams(window.location.search);
|
||||
|
||||
return (
|
||||
<>
|
||||
<MapOverlayPage backdrop className='tw-mx-4 tw-mt-4 tw-mb-4 tw-overflow-x-hidden tw-w-[calc(100%-32px)] md:tw-w-[calc(50%-32px)] tw-max-w-3xl !tw-left-auto tw-top-0 tw-bottom-0'>
|
||||
@ -138,11 +139,11 @@ export function ProfileForm({ userType }: { userType: string }) {
|
||||
}
|
||||
|
||||
{template == "tabs" &&
|
||||
<TabsForm loading={loading} item={item} state={state} setState={setState} updatePermission={updatePermission} linkItem={(id) => linkItem(id, item, updateItem)} unlinkItem={(id) => unlinkItem(id, item, updateItem)}></TabsForm>
|
||||
<TabsForm loading={loading} item={item} state={state} setState={setState} updatePermission={updatePermission} linkItem={(id) => linkItem(id, item, updateItem)} unlinkItem={(id) => unlinkItem(id, item, updateItem)} setUrlParams={setUrlParams}></TabsForm>
|
||||
}
|
||||
|
||||
<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(state, item, tags, addTag, setLoading, navigate, updateItem, addItem, user, params)} 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>
|
||||
<button className={loading ? " tw-loading tw-btn tw-float-right" : "tw-btn tw-float-right"} onClick={() => onUpdateItem(state, item, tags, addTag, setLoading, navigate, updateItem, addItem, user, urlParams)} 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>
|
||||
|
||||
@ -119,6 +119,9 @@ export function ProfileView({ userType }: { userType: string }) {
|
||||
setTemplate(item.layer?.itemType.template || userType);
|
||||
}, [userType, item])
|
||||
|
||||
const [urlParams, setUrlParams] = useState(new URLSearchParams(location.search));
|
||||
|
||||
|
||||
return (
|
||||
<>
|
||||
{item &&
|
||||
@ -137,7 +140,7 @@ export function ProfileView({ userType }: { userType: string }) {
|
||||
}
|
||||
|
||||
{template == "tabs" &&
|
||||
<TabsView item={item} loading={loading} offers={offers} needs={needs} relations={relations} updatePermission={updatePermission} linkItem={(id) => linkItem(id, item, updateItem)} unlinkItem={(id) => unlinkItem(id, item, updateItem)}/>
|
||||
<TabsView setUrlParams={setUrlParams} item={item} loading={loading} offers={offers} needs={needs} relations={relations} updatePermission={updatePermission} linkItem={(id) => linkItem(id, item, updateItem)} unlinkItem={(id) => unlinkItem(id, item, updateItem)}/>
|
||||
}
|
||||
</>
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { useEffect, useState } from "react"
|
||||
import { useCallback, useEffect, useState } from "react"
|
||||
import { TextAreaInput, TextInput } from "../../Input"
|
||||
import { PopupStartEndInput, TextView } from "../../Map"
|
||||
import { ActionButton } from "../Subcomponents/ActionsButton"
|
||||
@ -7,27 +7,27 @@ import { TagsWidget } from "../Subcomponents/TagsWidget"
|
||||
import { useNavigate } from "react-router-dom"
|
||||
import { useUpdateItem } from "../../Map/hooks/useItems"
|
||||
|
||||
export const TabsForm = ({ item, state, setState, updatePermission, linkItem, unlinkItem, loading }) => {
|
||||
export const TabsForm = ({ item, state, setState, updatePermission, linkItem, unlinkItem, loading, setUrlParams }) => {
|
||||
|
||||
const [activeTab, setActiveTab] = useState<number>(1);
|
||||
const navigate = useNavigate();
|
||||
const updateItem = useUpdateItem();
|
||||
|
||||
const updateActiveTab = (id: number) => {
|
||||
const updateActiveTab = useCallback((id: number) => {
|
||||
setActiveTab(id);
|
||||
|
||||
|
||||
let params = new URLSearchParams(window.location.search);
|
||||
let urlTab = params.get("tab");
|
||||
if (!urlTab?.includes(id.toString()))
|
||||
params.set("tab", `${id ? id : ""}`)
|
||||
navigate(location.pathname + "?" + params.toString());
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
params.set("tab", `${id}`);
|
||||
const newUrl = location.pathname + "?" + params.toString();
|
||||
window.history.pushState({}, '', newUrl);
|
||||
setUrlParams(params);
|
||||
}, [location.pathname]);
|
||||
|
||||
useEffect(() => {
|
||||
let params = new URLSearchParams(location.search);
|
||||
let urlTab = params.get("tab");
|
||||
urlTab ? setActiveTab(Number(urlTab)) : setActiveTab(1);
|
||||
}, [location])
|
||||
setActiveTab(urlTab ? Number(urlTab) : 1);
|
||||
}, [location.search]);
|
||||
|
||||
return (
|
||||
<div role="tablist" className="tw-tabs tw-tabs-lifted tw-mt-3">
|
||||
|
||||
@ -1,101 +1,112 @@
|
||||
import { StartEndView, TextView } from '../../Map';
|
||||
import { TagView } from '../../Templates/TagView';
|
||||
import { LinkedItemsHeaderView } from '../Subcomponents/LinkedItemsHeaderView';
|
||||
import { ActionButton } from '../Subcomponents/ActionsButton';
|
||||
import { useEffect, useRef, useState, useCallback } from 'react';
|
||||
import { useAddFilterTag } from '../../Map/hooks/useFilter';
|
||||
import { Item, Tag } from 'utopia-ui/dist/types';
|
||||
import { useNavigate, useLocation } from 'react-router-dom';
|
||||
import { memo } from 'react';
|
||||
import { StartEndView, TextView } from '../../Map'
|
||||
import { TagView } from '../../Templates/TagView'
|
||||
import { LinkedItemsHeaderView } from '../Subcomponents/LinkedItemsHeaderView'
|
||||
import { ActionButton } from '../Subcomponents/ActionsButton'
|
||||
import { useCallback, useEffect, useRef, useState } from 'react'
|
||||
import { useAddFilterTag } from '../../Map/hooks/useFilter'
|
||||
import { Item, Tag } from 'utopia-ui/dist/types'
|
||||
import { useNavigate } from 'react-router-dom'
|
||||
|
||||
export const TabsView = ({ item, offers, needs, relations, updatePermission, loading, linkItem, unlinkItem }: { item: Item, offers: Array<Tag>, needs: Array<Tag>, relations: Array<Item>, updatePermission: boolean, loading: boolean, linkItem: (id: string) => Promise<void>, unlinkItem: (id: string) => Promise<void> }) => {
|
||||
export const TabsView = ({ item, offers, needs, relations, updatePermission, loading, linkItem, unlinkItem, setUrlParams }: { item: Item, offers: Array<Tag>, needs: Array<Tag>, relations: Array<Item>, updatePermission: boolean, loading: boolean, linkItem: (id: string) => Promise<void>, unlinkItem: (id: string) => Promise<void> , setUrlParams: any}) => {
|
||||
|
||||
const addFilterTag = useAddFilterTag();
|
||||
const [activeTab, setActiveTab] = useState<number>(1);
|
||||
const [activeTab, setActiveTab] = useState<number>();
|
||||
const navigate = useNavigate();
|
||||
const location = useLocation();
|
||||
const tabRef = useRef<HTMLFormElement>(null);
|
||||
|
||||
const [addItemPopupType, setAddItemPopupType] = useState<string>("");
|
||||
|
||||
useEffect(() => {
|
||||
scroll();
|
||||
}, [addItemPopupType]);
|
||||
}, [addItemPopupType])
|
||||
|
||||
const scroll = useCallback(() => {
|
||||
function scroll() {
|
||||
tabRef.current?.scrollIntoView();
|
||||
}, []);
|
||||
}
|
||||
|
||||
const tabRef = useRef<HTMLFormElement>(null);
|
||||
|
||||
const updateActiveTab = useCallback((id: number) => {
|
||||
setActiveTab(id);
|
||||
|
||||
let params = new URLSearchParams(window.location.search);
|
||||
let urlTab = params.get("tab");
|
||||
if (!urlTab?.includes(id.toString())) {
|
||||
params.set("tab", `${id ? id : ""}`);
|
||||
navigate(location.pathname + "?" + params.toString(), { replace: true });
|
||||
}
|
||||
}, [navigate, location.pathname]);
|
||||
params.set("tab", `${id}`);
|
||||
const newUrl = location.pathname + "?" + params.toString();
|
||||
window.history.pushState({}, '', newUrl);
|
||||
setUrlParams(params);
|
||||
}, [location.pathname]);
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
let params = new URLSearchParams(location.search);
|
||||
let urlTab = params.get("tab");
|
||||
urlTab ? setActiveTab(Number(urlTab)) : setActiveTab(1);
|
||||
}, [location]);
|
||||
setActiveTab(urlTab ? Number(urlTab) : 1);
|
||||
}, [location.search]);
|
||||
|
||||
return (
|
||||
<div role="tablist" className="tw-tabs tw-tabs-lifted tw-mt-2 tw-mb-2 tw-px-6">
|
||||
<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="Info" checked={activeTab === 1}
|
||||
aria-label="Info" checked={activeTab == 1 && true}
|
||||
onChange={() => updateActiveTab(1)} />
|
||||
{activeTab === 1 &&
|
||||
<div role="tabpanel"
|
||||
className="tw-tab-content tw-bg-base-100 tw-rounded-box tw-h-[calc(100dvh-280px)] tw-overflow-y-auto fade tw-pt-2 tw-pb-4 tw-mb-4 tw-overflow-x-hidden">
|
||||
{item.layer?.itemType.show_start_end &&
|
||||
<div className='tw-max-w-xs'><StartEndView item={item}></StartEndView></div>
|
||||
}
|
||||
<TextView item={item} />
|
||||
<div className='tw-h-4'></div>
|
||||
<TextView item={item} itemTextField='contact'/>
|
||||
</div>
|
||||
}
|
||||
<div role="tabpanel"
|
||||
className="tw-tab-content tw-bg-base-100 tw-rounded-box tw-h-[calc(100dvh-280px)] tw-overflow-y-auto fade tw-pt-2 tw-pb-4 tw-mb-4 tw-overflow-x-hidden">
|
||||
{item.layer?.itemType.show_start_end &&
|
||||
<div className='tw-max-w-xs'><StartEndView item={item}></StartEndView></div>
|
||||
}
|
||||
<TextView item={item} />
|
||||
<div className='tw-h-4'></div>
|
||||
<TextView item={item} itemTextField='contact'/>
|
||||
</div>
|
||||
|
||||
{item.layer?.itemType.offers_and_needs && <>
|
||||
<input type="radio" name="my_tabs_2" role="tab" className="tw-tab tw-min-w-[10em] [--tab-border-color:var(--fallback-bc,oklch(var(--bc)/0.2))]" aria-label="Offers & Needs" checked={activeTab === 3} onChange={() => updateActiveTab(3)} />
|
||||
{activeTab === 3 &&
|
||||
<div role="tabpanel" className="tw-tab-content tw-bg-base-100 tw-rounded-box tw-h-[calc(100dvh-268px)] tw-overflow-y-auto fade tw-pt-4 tw-pb-1">
|
||||
{item.layer?.itemType.offers_and_needs &&
|
||||
|
||||
<>
|
||||
|
||||
<input type="radio" name="my_tabs_2" role="tab" className="tw-tab tw-min-w-[10em] [--tab-border-color:var(--fallback-bc,oklch(var(--bc)/0.2))]" aria-label="Offers & Needs" checked={activeTab == 3 && true} onChange={() => updateActiveTab(3)} />
|
||||
<div role="tabpanel" className="tw-tab-content tw-bg-base-100 tw-rounded-box tw-h-[calc(100dvh-268px)] tw-overflow-y-auto fade tw-pt-4 tw-pb-1" >
|
||||
<div className='tw-h-full'>
|
||||
<div className='tw-grid tw-grid-cols-1'>
|
||||
{offers.length > 0 &&
|
||||
<div className='tw-col-span-1'>
|
||||
<h3 className='-tw-mb-2'>Offers</h3>
|
||||
<div className='tw-flex tw-flex-wrap tw-mb-4'>
|
||||
{offers.map(o => <TagView key={o?.id} tag={o} onClick={() => addFilterTag(o)} />)}
|
||||
</div>
|
||||
</div>
|
||||
{
|
||||
offers.length > 0 ?
|
||||
<div className='tw-col-span-1'>
|
||||
<h3 className='-tw-mb-2'>Offers</h3>
|
||||
< div className='tw-flex tw-flex-wrap tw-mb-4'>
|
||||
{
|
||||
offers.map(o => <TagView key={o?.id} tag={o} onClick={() => {
|
||||
addFilterTag(o)
|
||||
}} />)
|
||||
}
|
||||
</div>
|
||||
</div> : ""
|
||||
}
|
||||
{needs.length > 0 &&
|
||||
<div className='tw-col-span-1'>
|
||||
<h3 className='-tw-mb-2 tw-col-span-1'>Needs</h3>
|
||||
<div className='tw-flex tw-flex-wrap tw-mb-4'>
|
||||
{needs.map(n => <TagView key={n?.id} tag={n} onClick={() => addFilterTag(n)} />)}
|
||||
</div>
|
||||
</div>
|
||||
{
|
||||
needs.length > 0 ?
|
||||
<div className='tw-col-span-1'>
|
||||
<h3 className='-tw-mb-2 tw-col-span-1'>Needs</h3>
|
||||
< div className='tw-flex tw-flex-wrap tw-mb-4'>
|
||||
{
|
||||
needs.map(n => <TagView key={n?.id} tag={n} onClick={() => addFilterTag(n)} />)
|
||||
}
|
||||
</div>
|
||||
</div> : ""
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</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} onChange={() => updateActiveTab(7)} />
|
||||
{activeTab === 7 &&
|
||||
|
||||
}
|
||||
|
||||
{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-280px)] tw-overflow-y-auto tw-pt-4 tw-pb-1 -tw-mr-4 -tw-mb-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 tw-pb-4'>
|
||||
{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-p-6 tw-mr-4 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'>
|
||||
@ -104,11 +115,12 @@ export const TabsView = ({ item, offers, needs, relations, updatePermission, loa
|
||||
</div>
|
||||
)}
|
||||
{updatePermission && <ActionButton collection="items" item={item} existingRelations={relations} triggerItemSelected={linkItem} colorField={item.layer.itemColorField}></ActionButton>}
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</>}
|
||||
</>
|
||||
}
|
||||
</div>
|
||||
);
|
||||
)
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user