refactor: straightened logic, replaces throttle with mantine debounced

This commit is contained in:
2025-08-05 17:47:39 +04:00
parent c13cc4a0a5
commit abbf782945
7 changed files with 37 additions and 68 deletions

View File

@ -10,7 +10,7 @@ import { Group, ScrollArea } from "@mantine/core";
import DndOverlay from "@/app/deals/components/DndOverlay/DndOverlay"; import DndOverlay from "@/app/deals/components/DndOverlay/DndOverlay";
import StatusColumn from "@/app/deals/components/StatusColumn/StatusColumn"; import StatusColumn from "@/app/deals/components/StatusColumn/StatusColumn";
import { useStatusesContext } from "@/app/deals/contexts/StatusesContext"; import { useStatusesContext } from "@/app/deals/contexts/StatusesContext";
import useDnd from "@/app/deals/hooks/useDnd"; import useDealsAndStatusesDnd from "@/app/deals/hooks/useDealsAndStatusesDnd";
import { SortableItem } from "@/components/SortableDnd/SortableItem"; import { SortableItem } from "@/components/SortableDnd/SortableItem";
import useDndSensors from "../../hooks/useSensors"; import useDndSensors from "../../hooks/useSensors";
@ -33,7 +33,7 @@ const StatusColumnsDnd: FC<Props> = props => {
handleDragEnd, handleDragEnd,
activeStatus, activeStatus,
activeDeal, activeDeal,
} = useDnd(props); } = useDealsAndStatusesDnd(props);
const sensors = useDndSensors(); const sensors = useDndSensors();

View File

@ -35,12 +35,12 @@ const useProjectsContextState = () => {
project => project.id === selectedProject.id project => project.id === selectedProject.id
) ?? null ) ?? null
); );
} else { return;
}
setSelectedProject(projects[0]); setSelectedProject(projects[0]);
return;
} }
} else {
setSelectedProject(null); setSelectedProject(null);
}
}, [projects]); }, [projects]);
return { return {

View File

@ -1,6 +1,6 @@
import { useMemo, useState } from "react"; import { useMemo, useState } from "react";
import { DragOverEvent, DragStartEvent, Over } from "@dnd-kit/core"; import { DragOverEvent, DragStartEvent, Over } from "@dnd-kit/core";
import { throttle } from "lodash"; import { useDebouncedCallback } from "@mantine/hooks";
import { useStatusesContext } from "@/app/deals/contexts/StatusesContext"; import { useStatusesContext } from "@/app/deals/contexts/StatusesContext";
import useGetNewRank from "@/app/deals/hooks/useGetNewRank"; import useGetNewRank from "@/app/deals/hooks/useGetNewRank";
import { getStatusId, isStatusId } from "@/app/deals/utils/statusId"; import { getStatusId, isStatusId } from "@/app/deals/utils/statusId";
@ -16,7 +16,7 @@ type Props = {
onStatusDragEnd: (statusId: number, lexorank: string) => void; onStatusDragEnd: (statusId: number, lexorank: string) => void;
}; };
const useDnd = (props: Props) => { const useDealsAndStatusesDnd = (props: Props) => {
const [activeDeal, setActiveDeal] = useState<DealSchema | null>(null); const [activeDeal, setActiveDeal] = useState<DealSchema | null>(null);
const [activeStatus, setActiveStatus] = useState<StatusSchema | null>(null); const [activeStatus, setActiveStatus] = useState<StatusSchema | null>(null);
const { statuses, deals, setDeals, setStatuses } = useStatusesContext(); const { statuses, deals, setDeals, setStatuses } = useStatusesContext();
@ -28,14 +28,8 @@ const useDnd = (props: Props) => {
getNewStatusRank, getNewStatusRank,
} = useGetNewRank(); } = useGetNewRank();
const throttledSetStatuses = useMemo( const debouncedSetStatuses = useDebouncedCallback(setStatuses, 200);
() => throttle(setStatuses, 200), const debouncedSetDeals = useDebouncedCallback(setDeals, 200);
[setStatuses]
);
const throttledSetDeals = useMemo(
() => throttle(setDeals, 200),
[setDeals]
);
const getStatusByDealId = (dealId: number) => { const getStatusByDealId = (dealId: number) => {
const deal = deals.find(deal => deal.id === dealId); const deal = deals.find(deal => deal.id === dealId);
@ -49,9 +43,9 @@ const useDnd = (props: Props) => {
if (typeof activeId === "string" && isStatusId(activeId)) { if (typeof activeId === "string" && isStatusId(activeId)) {
handleColumnDragOver(activeId, over); handleColumnDragOver(activeId, over);
} else { return;
handleDealDragOver(activeId, over);
} }
handleDealDragOver(activeId, over);
}; };
const handleDealDragOver = (activeId: string | number, over: Over) => { const handleDealDragOver = (activeId: string | number, over: Over) => {
@ -66,7 +60,7 @@ const useDnd = (props: Props) => {
); );
if (!overStatusId) return; if (!overStatusId) return;
throttledSetDeals(deals => debouncedSetDeals(deals =>
deals.map(deal => deals.map(deal =>
deal.id === activeDealId deal.id === activeDealId
? { ? {
@ -96,7 +90,7 @@ const useDnd = (props: Props) => {
const newRank = getNewStatusRank(activeStatusId, overStatusId); const newRank = getNewStatusRank(activeStatusId, overStatusId);
if (!newRank) return; if (!newRank) return;
throttledSetStatuses(statuses => debouncedSetStatuses(statuses =>
statuses.map(status => statuses.map(status =>
status.id === activeStatusId status.id === activeStatusId
? { ...status, lexorank: newRank } ? { ...status, lexorank: newRank }
@ -132,20 +126,19 @@ const useDnd = (props: Props) => {
deal => deal.id === overDealId deal => deal.id === overDealId
); );
let newLexorank;
if (activeStatusId === overStatusId) { if (activeStatusId === overStatusId) {
newLexorank = getNewRankForSameStatus( const newLexorank = getNewRankForSameStatus(
statusDeals, statusDeals,
overDealIndex, overDealIndex,
activeDealId activeDealId
); );
} else { return { overStatusId, newLexorank };
newLexorank = getNewRankForAnotherStatus( }
const newLexorank = getNewRankForAnotherStatus(
statusDeals, statusDeals,
overDealIndex overDealIndex
); );
}
return { overStatusId, newLexorank }; return { overStatusId, newLexorank };
}; };
@ -158,9 +151,9 @@ const useDnd = (props: Props) => {
if (typeof activeId === "string" && isStatusId(activeId)) { if (typeof activeId === "string" && isStatusId(activeId)) {
handleStatusColumnDragEnd(activeId, over); handleStatusColumnDragEnd(activeId, over);
} else { return;
handleDealDragEnd(activeId, over);
} }
handleDealDragEnd(activeId, over);
}; };
const handleStatusColumnDragEnd = (activeId: string, over: Over) => { const handleStatusColumnDragEnd = (activeId: string, over: Over) => {
@ -207,11 +200,12 @@ const useDnd = (props: Props) => {
setActiveStatus( setActiveStatus(
statuses.find(status => status.id === statusId) ?? null statuses.find(status => status.id === statusId) ?? null
); );
} else { return;
}
setActiveDeal( setActiveDeal(
deals.find(deal => deal.id === (activeId as number)) ?? null deals.find(deal => deal.id === (activeId as number)) ?? null
); );
}
}; };
return { return {
@ -224,4 +218,4 @@ const useDnd = (props: Props) => {
}; };
}; };
export default useDnd; export default useDealsAndStatusesDnd;

View File

@ -1,31 +0,0 @@
import { Anchor, Text, Title } from "@mantine/core";
export function Welcome() {
return (
<>
<Title
ta="center"
mt={100}
className={"font-bold underline"}>
Welcome to Mantine
</Title>
<Text
c="dimmed"
ta="center"
size="lg"
maw={580}
mx="auto"
mt="xl">
This starter Next.js project includes a minimal setup for server
side rendering, if you want to learn more on Mantine + Next.js
integration follow{" "}
<Anchor
href="https://mantine.dev/guides/next/"
size="lg">
this guide
</Anchor>
. To get started edit page.tsx file.
</Text>
</>
);
}

View File

@ -18,7 +18,9 @@ const useBoardsList = ({ projectId }: Props) => {
useEffect(() => { useEffect(() => {
if (projectId === undefined) { if (projectId === undefined) {
setBoards([]); setBoards([]);
} else if (data?.boards) { return;
}
if (data?.boards) {
setBoards(data.boards); setBoards(data.boards);
} }
}, [data?.boards, projectId]); }, [data?.boards, projectId]);

View File

@ -18,7 +18,9 @@ const useDealsList = ({ boardId }: Props) => {
useEffect(() => { useEffect(() => {
if (boardId === undefined) { if (boardId === undefined) {
setDeals([]); setDeals([]);
} else if (data?.deals) { return;
}
if (data?.deals) {
setDeals(data.deals); setDeals(data.deals);
} }
}, [data?.deals, boardId]); }, [data?.deals, boardId]);

View File

@ -18,7 +18,9 @@ const useStatusesList = ({ boardId }: Props) => {
useEffect(() => { useEffect(() => {
if (boardId === undefined) { if (boardId === undefined) {
setStatuses([]); setStatuses([]);
} else if (data?.statuses) { return;
}
if (data?.statuses) {
setStatuses(data.statuses); setStatuses(data.statuses);
} }
}, [data?.statuses, boardId]); }, [data?.statuses, boardId]);