diff --git a/src-web/components/Sidebar.tsx b/src-web/components/Sidebar.tsx index cf8a7d68..0cb807ba 100644 --- a/src-web/components/Sidebar.tsx +++ b/src-web/components/Sidebar.tsx @@ -1,8 +1,5 @@ import classnames from 'classnames'; -import type { Identifier } from 'dnd-core'; -import type { CSSProperties } from 'react'; -import React, { useCallback, useEffect, useRef, useState } from 'react'; -import type { XYCoord } from 'react-dnd'; +import React, { memo, useCallback, useEffect, useMemo, useRef, useState } from 'react'; import { DndProvider, useDrag, useDrop } from 'react-dnd'; import { HTML5Backend } from 'react-dnd-html5-backend'; import { useActiveRequest } from '../hooks/useActiveRequest'; @@ -49,11 +46,6 @@ export function Container({ className }: Props) { const activeRequest = useActiveRequest(); const createRequest = useCreateRequest({ navigateAfter: true }); const { appearance, toggleAppearance } = useTheme(); - const [items, setItems] = useState(requests.map((r) => ({ request: r, left: 0, top: 0 }))); - - useEffect(() => { - setItems(requests.map((r) => ({ request: r, left: 0, top: 0 }))); - }, [requests.length]); const moveState = useRef<{ move: (e: MouseEvent) => void; up: () => void } | null>(null); const unsub = () => { @@ -63,11 +55,11 @@ export function Container({ className }: Props) { } }; - const handleResizeReset = () => { + const handleResizeReset = useCallback(() => { width.set(INITIAL_WIDTH); - }; + }, []); - const handleResizeStart = (e: React.MouseEvent) => { + const handleResizeStart = useCallback((e: React.MouseEvent) => { unsub(); const mouseStartX = e.clientX; const startWidth = width.value; @@ -84,23 +76,14 @@ export function Container({ className }: Props) { document.documentElement.addEventListener('mousemove', moveState.current.move); document.documentElement.addEventListener('mouseup', moveState.current.up); setIsRisizing(true); - }; - - const sidebarWidth = sidebarRef.current?.clientWidth ?? 0; - const handleMove = useCallback((dragIndex: number, hoverIndex: number) => { - setItems((oldItems) => { - const newItems = [...oldItems]; - const b = newItems[hoverIndex]!; - newItems[hoverIndex] = newItems[dragIndex]!; - newItems[dragIndex] = b; - return newItems; - }); }, []); + const sidebarStyles = useMemo(() => ({ width: width.value }), [width.value]); + console.log('RENDER SIDEBAR'); return (
- {items.map(({ request, left, top }, i) => ( - - ))} + ({ request: r, left: 0, top: 0 }))); + + useEffect(() => { + setItems(requests.map((r) => ({ request: r, left: 0, top: 0 }))); + }, [requests.length]); + + const handleMove = useCallback((id: string, hoverId: string) => { + setItems((oldItems) => { + const dragIndex = oldItems.findIndex((i) => i.request.id === id); + const index = oldItems.findIndex((i) => i.request.id === hoverId); + const newItems = [...oldItems]; + const b = newItems[index]!; + newItems[index] = newItems[dragIndex]!; + newItems[dragIndex] = b; + return newItems; + }); + }, []); + + return ( + <> + {items.map(({ request }) => ( + + ))} + + ); +} + +type SidebarItemProps = { request: HttpRequest; sidebarWidth: number; active?: boolean; - isDragging?: boolean; -} +}; -function SidebarItem({ request, active, sidebarWidth, isDragging }: SidebarItemProps) { +function SidebarItem({ request, active, sidebarWidth }: SidebarItemProps) { const deleteRequest = useDeleteRequest(request); const updateRequest = useUpdateRequest(request); const [editing, setEditing] = useState(false); - const handleSubmitNameEdit = async (el: HTMLInputElement) => { + const handleSubmitNameEdit = useCallback(async (el: HTMLInputElement) => { await updateRequest.mutate({ name: el.value }); setEditing(false); - }; + }, []); - const handleFocus = (el: HTMLInputElement | null) => { + const handleFocus = useCallback((el: HTMLInputElement | null) => { el?.focus(); el?.select(); - }; + }, []); + + const itemStyles = useMemo(() => ({ width: sidebarWidth }), [sidebarWidth]); return ( -
  • +