feat: displaying and sorting groups of deals
This commit is contained in:
@ -1,11 +1,13 @@
|
|||||||
.create-button {
|
.create-button {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
min-height: max-content;
|
min-height: max-content;
|
||||||
|
border: 1px dashed;
|
||||||
@mixin light {
|
@mixin light {
|
||||||
background-color: var(--color-light-white-blue);
|
background-color: var(--color-light-white-blue);
|
||||||
|
border-color: lightblue;
|
||||||
}
|
}
|
||||||
@mixin dark {
|
@mixin dark {
|
||||||
background-color: var(--mantine-color-dark-7);
|
background-color: var(--mantine-color-dark-7);
|
||||||
|
border-color: var(--mantine-color-dark-5);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,11 +1,27 @@
|
|||||||
|
|
||||||
.container {
|
.container {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
|
border: 1px dashed;
|
||||||
@mixin light {
|
@mixin light {
|
||||||
background-color: var(--color-light-white-blue);
|
background-color: var(--color-light-white-blue);
|
||||||
|
border-color: lightblue;
|
||||||
}
|
}
|
||||||
@mixin dark {
|
@mixin dark {
|
||||||
background-color: var(--mantine-color-dark-7);
|
background-color: var(--mantine-color-dark-7);
|
||||||
|
border-color: var(--mantine-color-dark-5);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.container-in-group {
|
||||||
|
padding: 0;
|
||||||
|
border: 1px dashed;
|
||||||
|
@mixin light {
|
||||||
|
background-color: var(--color-light-aqua);
|
||||||
|
border-color: lightblue;
|
||||||
|
}
|
||||||
|
@mixin dark {
|
||||||
|
background-color: var(--mantine-color-dark-6);
|
||||||
|
border-color: var(--mantine-color-dark-5);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -8,9 +8,10 @@ import styles from "./DealCard.module.css";
|
|||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
deal: DealSchema;
|
deal: DealSchema;
|
||||||
|
isInGroup?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
const DealCard = ({ deal }: Props) => {
|
const DealCard = ({ deal, isInGroup = false }: Props) => {
|
||||||
const { selectedProject, modulesSet } = useProjectsContext();
|
const { selectedProject, modulesSet } = useProjectsContext();
|
||||||
const { dealsCrud, refetchDeals } = useDealsContext();
|
const { dealsCrud, refetchDeals } = useDealsContext();
|
||||||
const { openDrawer } = useDrawersContext();
|
const { openDrawer } = useDrawersContext();
|
||||||
@ -31,7 +32,9 @@ const DealCard = ({ deal }: Props) => {
|
|||||||
return (
|
return (
|
||||||
<Card
|
<Card
|
||||||
onClick={onClick}
|
onClick={onClick}
|
||||||
className={styles.container}>
|
className={
|
||||||
|
isInGroup ? styles["container-in-group"] : styles.container
|
||||||
|
}>
|
||||||
<Group
|
<Group
|
||||||
justify={"space-between"}
|
justify={"space-between"}
|
||||||
wrap={"nowrap"}
|
wrap={"nowrap"}
|
||||||
|
|||||||
@ -1,25 +0,0 @@
|
|||||||
import React, { FC, useMemo } from "react";
|
|
||||||
import { Box } from "@mantine/core";
|
|
||||||
import DealCard from "@/app/deals/components/shared/DealCard/DealCard";
|
|
||||||
import SortableItem from "@/components/dnd/SortableItem";
|
|
||||||
import { DealSchema } from "@/lib/client";
|
|
||||||
|
|
||||||
type Props = {
|
|
||||||
deal: DealSchema;
|
|
||||||
};
|
|
||||||
|
|
||||||
const DealContainer: FC<Props> = ({ deal }) => {
|
|
||||||
const dealBody = useMemo(() => <DealCard deal={deal} />, [deal]);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Box>
|
|
||||||
<SortableItem
|
|
||||||
dragHandleStyle={{ cursor: "pointer" }}
|
|
||||||
id={deal.id}
|
|
||||||
renderItem={() => dealBody}
|
|
||||||
/>
|
|
||||||
</Box>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default DealContainer;
|
|
||||||
@ -0,0 +1,12 @@
|
|||||||
|
|
||||||
|
.group-container {
|
||||||
|
border: 1px dashed;
|
||||||
|
@mixin light {
|
||||||
|
background-color: var(--color-light-white-blue);
|
||||||
|
border-color: lightblue;
|
||||||
|
}
|
||||||
|
@mixin dark {
|
||||||
|
background-color: var(--mantine-color-dark-7);
|
||||||
|
border-color: var(--mantine-color-dark-5);
|
||||||
|
}
|
||||||
|
}
|
||||||
30
src/app/deals/components/shared/DealsGroup/DealsGroup.tsx
Normal file
30
src/app/deals/components/shared/DealsGroup/DealsGroup.tsx
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
import { FC } from "react";
|
||||||
|
import { Stack, Text } from "@mantine/core";
|
||||||
|
import DealCard from "@/app/deals/components/shared/DealCard/DealCard";
|
||||||
|
import GroupWithDealsSchema from "@/types/GroupWithDealsSchema";
|
||||||
|
import styles from "./DealsGroup.module.css";
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
group: GroupWithDealsSchema;
|
||||||
|
};
|
||||||
|
|
||||||
|
const DealsGroup: FC<Props> = ({ group }) => {
|
||||||
|
return (
|
||||||
|
<Stack
|
||||||
|
className={styles["group-container"]}
|
||||||
|
gap={"xs"}
|
||||||
|
bdrs={"lg"}
|
||||||
|
p={"xs"}>
|
||||||
|
<Text mx={"xs"}>{group.name}</Text>
|
||||||
|
{group.items.map(deal => (
|
||||||
|
<DealCard
|
||||||
|
deal={deal}
|
||||||
|
isInGroup
|
||||||
|
key={deal.id}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</Stack>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default DealsGroup;
|
||||||
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
import React, { FC, ReactNode } from "react";
|
import React, { FC, ReactNode } from "react";
|
||||||
import DealCard from "@/app/deals/components/shared/DealCard/DealCard";
|
import DealCard from "@/app/deals/components/shared/DealCard/DealCard";
|
||||||
import DealContainer from "@/app/deals/components/shared/DealContainer/DealContainer";
|
import DealsGroup from "@/app/deals/components/shared/DealsGroup/DealsGroup";
|
||||||
import StatusColumnHeader from "@/app/deals/components/shared/StatusColumnHeader/StatusColumnHeader";
|
import StatusColumnHeader from "@/app/deals/components/shared/StatusColumnHeader/StatusColumnHeader";
|
||||||
import StatusColumnWrapper from "@/app/deals/components/shared/StatusColumnWrapper/StatusColumnWrapper";
|
import StatusColumnWrapper from "@/app/deals/components/shared/StatusColumnWrapper/StatusColumnWrapper";
|
||||||
import { useBoardsContext } from "@/app/deals/contexts/BoardsContext";
|
import { useBoardsContext } from "@/app/deals/contexts/BoardsContext";
|
||||||
@ -11,37 +11,36 @@ import useDealsAndStatusesDnd from "@/app/deals/hooks/useDealsAndStatusesDnd";
|
|||||||
import FunnelDnd from "@/components/dnd/FunnelDnd/FunnelDnd";
|
import FunnelDnd from "@/components/dnd/FunnelDnd/FunnelDnd";
|
||||||
import useIsMobile from "@/hooks/utils/useIsMobile";
|
import useIsMobile from "@/hooks/utils/useIsMobile";
|
||||||
import { DealSchema, StatusSchema } from "@/lib/client";
|
import { DealSchema, StatusSchema } from "@/lib/client";
|
||||||
|
import GroupWithDealsSchema from "@/types/GroupWithDealsSchema";
|
||||||
import { sortByLexorank } from "@/utils/lexorank/sort";
|
import { sortByLexorank } from "@/utils/lexorank/sort";
|
||||||
|
|
||||||
const Funnel: FC = () => {
|
const Funnel: FC = () => {
|
||||||
const { selectedBoard } = useBoardsContext();
|
const { selectedBoard } = useBoardsContext();
|
||||||
const { deals } = useDealsContext();
|
const { dealsWithoutGroup, groupsWithDeals } = useDealsContext();
|
||||||
const isMobile = useIsMobile();
|
const isMobile = useIsMobile();
|
||||||
|
|
||||||
const {
|
const { sortedStatuses, handleDragOver, handleDragEnd, swiperRef } =
|
||||||
sortedStatuses,
|
useDealsAndStatusesDnd();
|
||||||
handleDragStart,
|
|
||||||
handleDragOver,
|
|
||||||
handleDragEnd,
|
|
||||||
activeStatus,
|
|
||||||
activeDeal,
|
|
||||||
swiperRef,
|
|
||||||
} = useDealsAndStatusesDnd();
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<FunnelDnd
|
<FunnelDnd<StatusSchema, DealSchema, GroupWithDealsSchema>
|
||||||
containers={sortedStatuses}
|
containers={sortedStatuses}
|
||||||
items={deals}
|
itemsAndGroups={sortByLexorank([
|
||||||
onDragStart={handleDragStart}
|
...dealsWithoutGroup,
|
||||||
|
...groupsWithDeals,
|
||||||
|
])}
|
||||||
onDragOver={handleDragOver}
|
onDragOver={handleDragOver}
|
||||||
onDragEnd={handleDragEnd}
|
onDragEnd={handleDragEnd}
|
||||||
swiperRef={swiperRef}
|
swiperRef={swiperRef}
|
||||||
getContainerId={(status: StatusSchema) => `${status.id}-status`}
|
getItemsByContainer={(status: StatusSchema) =>
|
||||||
getItemsByContainer={(status: StatusSchema, items: DealSchema[]) =>
|
sortByLexorank([
|
||||||
sortByLexorank(
|
...dealsWithoutGroup.filter(
|
||||||
items.filter(deal => deal.status.id === status.id)
|
deal => deal.status.id === status.id
|
||||||
)
|
),
|
||||||
|
...groupsWithDeals.filter(
|
||||||
|
group => group.items[0].status.id === status.id
|
||||||
|
),
|
||||||
|
])
|
||||||
}
|
}
|
||||||
renderContainer={(
|
renderContainer={(
|
||||||
status: StatusSchema,
|
status: StatusSchema,
|
||||||
@ -59,25 +58,28 @@ const Funnel: FC = () => {
|
|||||||
renderContainerHeader={status => (
|
renderContainerHeader={status => (
|
||||||
<StatusColumnHeader
|
<StatusColumnHeader
|
||||||
status={status}
|
status={status}
|
||||||
isDragging={activeStatus?.id === status.id}
|
isDragging={false}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
renderItem={(deal: DealSchema) => (
|
renderItem={(deal: DealSchema) => (
|
||||||
<DealContainer
|
<DealCard
|
||||||
key={deal.id}
|
key={deal.id}
|
||||||
deal={deal}
|
deal={deal}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
activeContainer={activeStatus}
|
renderGroup={(group: GroupWithDealsSchema) => (
|
||||||
activeItem={activeDeal}
|
<DealsGroup
|
||||||
renderItemOverlay={(deal: DealSchema) => <DealCard deal={deal} />}
|
key={`${group.id}group`}
|
||||||
|
group={group}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
renderContainerOverlay={(status: StatusSchema, children) => (
|
renderContainerOverlay={(status: StatusSchema, children) => (
|
||||||
<StatusColumnWrapper
|
<StatusColumnWrapper
|
||||||
status={status}
|
status={status}
|
||||||
renderHeader={() => (
|
renderHeader={() => (
|
||||||
<StatusColumnHeader
|
<StatusColumnHeader
|
||||||
status={status}
|
status={status}
|
||||||
isDragging={activeStatus?.id === status.id}
|
isDragging
|
||||||
/>
|
/>
|
||||||
)}>
|
)}>
|
||||||
{children}
|
{children}
|
||||||
|
|||||||
@ -3,18 +3,24 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import { UseFormReturnType } from "@mantine/form";
|
import { UseFormReturnType } from "@mantine/form";
|
||||||
import { useStatusesContext } from "@/app/deals/contexts/StatusesContext";
|
import { useStatusesContext } from "@/app/deals/contexts/StatusesContext";
|
||||||
|
import useDealsAndGroups from "@/app/deals/hooks/useDealsAndGroups";
|
||||||
import { DealsFiltersForm } from "@/app/deals/hooks/useDealsFilters";
|
import { DealsFiltersForm } from "@/app/deals/hooks/useDealsFilters";
|
||||||
|
import useDealGroupCrud, { GroupsCrud } from "@/hooks/cruds/useDealGroupCrud";
|
||||||
import { DealsCrud, useDealsCrud } from "@/hooks/cruds/useDealsCrud";
|
import { DealsCrud, useDealsCrud } from "@/hooks/cruds/useDealsCrud";
|
||||||
import useDealsList from "@/hooks/lists/useDealsList";
|
import useDealsList from "@/hooks/lists/useDealsList";
|
||||||
import { SortingForm } from "@/hooks/utils/useSorting";
|
import { SortingForm } from "@/hooks/utils/useSorting";
|
||||||
import { DealSchema, PaginationInfoSchema } from "@/lib/client";
|
import { DealSchema, PaginationInfoSchema } from "@/lib/client";
|
||||||
import makeContext from "@/lib/contextFactory/contextFactory";
|
import makeContext from "@/lib/contextFactory/contextFactory";
|
||||||
|
import GroupWithDealsSchema from "@/types/GroupWithDealsSchema";
|
||||||
|
|
||||||
type DealsContextState = {
|
type DealsContextState = {
|
||||||
deals: DealSchema[];
|
deals: DealSchema[];
|
||||||
setDeals: (deals: DealSchema[]) => void;
|
setDeals: (deals: DealSchema[]) => void;
|
||||||
|
dealsWithoutGroup: DealSchema[];
|
||||||
|
groupsWithDeals: GroupWithDealsSchema[];
|
||||||
refetchDeals: () => void;
|
refetchDeals: () => void;
|
||||||
dealsCrud: DealsCrud;
|
dealsCrud: DealsCrud;
|
||||||
|
groupsCrud: GroupsCrud;
|
||||||
paginationInfo?: PaginationInfoSchema;
|
paginationInfo?: PaginationInfoSchema;
|
||||||
page: number;
|
page: number;
|
||||||
setPage: React.Dispatch<React.SetStateAction<number>>;
|
setPage: React.Dispatch<React.SetStateAction<number>>;
|
||||||
@ -48,9 +54,17 @@ const useDealsContextState = ({
|
|||||||
statuses,
|
statuses,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const groupsCrud = useDealGroupCrud();
|
||||||
|
|
||||||
|
const { dealsWithoutGroup, groupsWithDeals } =
|
||||||
|
useDealsAndGroups(dealsListObjects);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...dealsListObjects,
|
...dealsListObjects,
|
||||||
dealsCrud,
|
dealsCrud,
|
||||||
|
groupsCrud,
|
||||||
|
dealsWithoutGroup,
|
||||||
|
groupsWithDeals,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
44
src/app/deals/hooks/useDealsAndGroups.ts
Normal file
44
src/app/deals/hooks/useDealsAndGroups.ts
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
import { useMemo } from "react";
|
||||||
|
import { isNull } from "lodash";
|
||||||
|
import { DealSchema } from "@/lib/client";
|
||||||
|
import GroupWithDealsSchema from "@/types/GroupWithDealsSchema";
|
||||||
|
import { sortByLexorank } from "@/utils/lexorank/sort";
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
deals: DealSchema[];
|
||||||
|
};
|
||||||
|
|
||||||
|
const useDealsAndGroups = ({ deals }: Props) => {
|
||||||
|
const dealsWithoutGroup: DealSchema[] = useMemo(
|
||||||
|
() => deals.filter(d => isNull(d.group)),
|
||||||
|
[deals]
|
||||||
|
);
|
||||||
|
|
||||||
|
const groupsWithDeals: GroupWithDealsSchema[] = useMemo(() => {
|
||||||
|
const groupsWithDealMap = new Map<number, GroupWithDealsSchema>();
|
||||||
|
|
||||||
|
for (const deal of deals) {
|
||||||
|
if (isNull(deal.group)) continue;
|
||||||
|
|
||||||
|
const groupData = groupsWithDealMap.get(deal.group.id);
|
||||||
|
if (groupData) {
|
||||||
|
groupData.items.push(deal);
|
||||||
|
groupsWithDealMap.set(deal.group.id, groupData);
|
||||||
|
} else {
|
||||||
|
groupsWithDealMap.set(deal.group.id, {
|
||||||
|
...deal.group,
|
||||||
|
items: [deal],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return sortByLexorank(groupsWithDealMap.values().toArray());
|
||||||
|
}, [deals]);
|
||||||
|
|
||||||
|
return {
|
||||||
|
dealsWithoutGroup,
|
||||||
|
groupsWithDeals,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export default useDealsAndGroups;
|
||||||
@ -1,32 +1,41 @@
|
|||||||
import { RefObject, useMemo, useRef, useState } from "react";
|
import { RefObject, useMemo, useRef } from "react";
|
||||||
import { DragOverEvent, DragStartEvent, Over } from "@dnd-kit/core";
|
import { DragOverEvent, Over } from "@dnd-kit/core";
|
||||||
import { SwiperRef } from "swiper/swiper-react";
|
import { SwiperRef } from "swiper/swiper-react";
|
||||||
import { useDebouncedCallback } from "@mantine/hooks";
|
import { useDebouncedCallback } from "@mantine/hooks";
|
||||||
import { useDealsContext } from "@/app/deals/contexts/DealsContext";
|
import { useDealsContext } from "@/app/deals/contexts/DealsContext";
|
||||||
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 isItemGroup from "@/app/deals/utils/isItemGroup";
|
||||||
|
import {
|
||||||
|
getContainerId,
|
||||||
|
isContainerId,
|
||||||
|
} from "@/components/dnd/FunnelDnd/utils/columnId";
|
||||||
|
import {
|
||||||
|
getGroupId,
|
||||||
|
isGroupId,
|
||||||
|
} from "@/components/dnd/FunnelDnd/utils/groupId";
|
||||||
import useIsMobile from "@/hooks/utils/useIsMobile";
|
import useIsMobile from "@/hooks/utils/useIsMobile";
|
||||||
import { DealSchema, StatusSchema } from "@/lib/client";
|
import { StatusSchema } from "@/lib/client";
|
||||||
|
|
||||||
import { sortByLexorank } from "@/utils/lexorank/sort";
|
import { sortByLexorank } from "@/utils/lexorank/sort";
|
||||||
|
|
||||||
type ReturnType = {
|
type ReturnType = {
|
||||||
sortedStatuses: StatusSchema[];
|
sortedStatuses: StatusSchema[];
|
||||||
handleDragStart: ({ active }: DragStartEvent) => void;
|
|
||||||
handleDragOver: ({ active, over }: DragOverEvent) => void;
|
handleDragOver: ({ active, over }: DragOverEvent) => void;
|
||||||
handleDragEnd: ({ active, over }: DragOverEvent) => void;
|
handleDragEnd: ({ active, over }: DragOverEvent) => void;
|
||||||
activeStatus: StatusSchema | null;
|
|
||||||
activeDeal: DealSchema | null;
|
|
||||||
swiperRef: RefObject<SwiperRef | null>;
|
swiperRef: RefObject<SwiperRef | null>;
|
||||||
};
|
};
|
||||||
|
|
||||||
const useDealsAndStatusesDnd = (): ReturnType => {
|
const useDealsAndStatusesDnd = (): ReturnType => {
|
||||||
const swiperRef = useRef<SwiperRef>(null);
|
const swiperRef = useRef<SwiperRef>(null);
|
||||||
const [activeDeal, setActiveDeal] = useState<DealSchema | null>(null);
|
|
||||||
const [activeStatus, setActiveStatus] = useState<StatusSchema | null>(null);
|
|
||||||
const { statuses, setStatuses, statusesCrud } = useStatusesContext();
|
const { statuses, setStatuses, statusesCrud } = useStatusesContext();
|
||||||
const { deals, setDeals, dealsCrud } = useDealsContext();
|
const {
|
||||||
|
deals,
|
||||||
|
dealsWithoutGroup,
|
||||||
|
groupsWithDeals,
|
||||||
|
setDeals,
|
||||||
|
dealsCrud,
|
||||||
|
groupsCrud,
|
||||||
|
} = useDealsContext();
|
||||||
const sortedStatuses = useMemo(() => sortByLexorank(statuses), [statuses]);
|
const sortedStatuses = useMemo(() => sortByLexorank(statuses), [statuses]);
|
||||||
const isMobile = useIsMobile();
|
const isMobile = useIsMobile();
|
||||||
|
|
||||||
@ -40,15 +49,29 @@ const useDealsAndStatusesDnd = (): ReturnType => {
|
|||||||
const debouncedSetDeals = useDebouncedCallback(setDeals, 200);
|
const debouncedSetDeals = useDebouncedCallback(setDeals, 200);
|
||||||
|
|
||||||
const getStatusByDealId = (dealId: number) => {
|
const getStatusByDealId = (dealId: number) => {
|
||||||
const deal = deals.find(deal => deal.id === dealId);
|
const deal = dealsWithoutGroup.find(deal => deal.id === dealId);
|
||||||
if (!deal) return;
|
if (!deal) return;
|
||||||
return statuses.find(status => status.id === deal.status.id);
|
return statuses.find(status => status.id === deal.status.id);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const getStatusByGroupId = (groupId: number) => {
|
||||||
|
const group = groupsWithDeals.find(group => group.id === groupId);
|
||||||
|
if (!group || group.items.length === 0) return;
|
||||||
|
return statuses.find(status => status.id === group.items[0].status.id);
|
||||||
|
};
|
||||||
|
|
||||||
const getStatusById = (statusId: number) => {
|
const getStatusById = (statusId: number) => {
|
||||||
return statuses.find(status => status.id === statusId);
|
return statuses.find(status => status.id === statusId);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const getStatusDealsAndGroups = (statusId: number) =>
|
||||||
|
sortByLexorank([
|
||||||
|
...dealsWithoutGroup.filter(d => d.status.id === statusId),
|
||||||
|
...groupsWithDeals.filter(
|
||||||
|
g => g.items.length > 0 && g.items[0].status.id === statusId
|
||||||
|
),
|
||||||
|
]);
|
||||||
|
|
||||||
const swipeSliderDuringDrag = (activeId: number, over: Over) => {
|
const swipeSliderDuringDrag = (activeId: number, over: Over) => {
|
||||||
const activeStatus = getStatusByDealId(activeId);
|
const activeStatus = getStatusByDealId(activeId);
|
||||||
const swiperActiveStatus =
|
const swiperActiveStatus =
|
||||||
@ -58,8 +81,8 @@ const useDealsAndStatusesDnd = (): ReturnType => {
|
|||||||
const activeStatusLexorank = activeStatus?.lexorank;
|
const activeStatusLexorank = activeStatus?.lexorank;
|
||||||
let overStatusLexorank: string | undefined;
|
let overStatusLexorank: string | undefined;
|
||||||
|
|
||||||
if (typeof over.id === "string" && isStatusId(over.id)) {
|
if (typeof over.id === "string" && isContainerId(over.id)) {
|
||||||
const overStatusId = getStatusId(over.id);
|
const overStatusId = getContainerId(over.id);
|
||||||
overStatusLexorank = statuses.find(
|
overStatusLexorank = statuses.find(
|
||||||
s => s.id === overStatusId
|
s => s.id === overStatusId
|
||||||
)?.lexorank;
|
)?.lexorank;
|
||||||
@ -98,11 +121,16 @@ const useDealsAndStatusesDnd = (): ReturnType => {
|
|||||||
swipeSliderDuringDrag(activeId, over);
|
swipeSliderDuringDrag(activeId, over);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof activeId === "string" && isStatusId(activeId)) {
|
if (typeof activeId !== "string") {
|
||||||
|
handleDealDragOver(activeId, over);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isContainerId(activeId)) {
|
||||||
handleColumnDragOver(activeId, over);
|
handleColumnDragOver(activeId, over);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
handleDealDragOver(activeId, over);
|
handleGroupDragOver(activeId, over);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleDealDragOver = (activeId: string | number, over: Over) => {
|
const handleDealDragOver = (activeId: string | number, over: Over) => {
|
||||||
@ -113,6 +141,7 @@ const useDealsAndStatusesDnd = (): ReturnType => {
|
|||||||
const { overStatus, newLexorank } = getDropTarget(
|
const { overStatus, newLexorank } = getDropTarget(
|
||||||
over.id,
|
over.id,
|
||||||
activeDealId,
|
activeDealId,
|
||||||
|
undefined,
|
||||||
activeStatusId
|
activeStatusId
|
||||||
);
|
);
|
||||||
if (!overStatus) return;
|
if (!overStatus) return;
|
||||||
@ -130,14 +159,49 @@ const useDealsAndStatusesDnd = (): ReturnType => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleGroupDragOver = (activeId: string, over: Over) => {
|
||||||
|
const activeGroupId = getGroupId(activeId);
|
||||||
|
const activeStatusId = getStatusByGroupId(activeGroupId)?.id;
|
||||||
|
if (!activeStatusId) return;
|
||||||
|
|
||||||
|
const { overStatus, newLexorank } = getDropTarget(
|
||||||
|
over.id,
|
||||||
|
undefined,
|
||||||
|
activeGroupId,
|
||||||
|
activeStatusId
|
||||||
|
);
|
||||||
|
if (!overStatus) return;
|
||||||
|
|
||||||
|
debouncedSetDeals(
|
||||||
|
deals.map(deal =>
|
||||||
|
deal.group && deal.group.id === activeGroupId
|
||||||
|
? {
|
||||||
|
...deal,
|
||||||
|
status: overStatus,
|
||||||
|
group: {
|
||||||
|
...deal.group,
|
||||||
|
lexorank: newLexorank || deal.group.lexorank,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
: deal
|
||||||
|
)
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
const handleColumnDragOver = (activeId: string, over: Over) => {
|
const handleColumnDragOver = (activeId: string, over: Over) => {
|
||||||
const activeStatusId = getStatusId(activeId);
|
const activeStatusId = getContainerId(activeId);
|
||||||
let overStatusId: number;
|
let overStatusId: number;
|
||||||
|
|
||||||
if (typeof over.id === "string" && isStatusId(over.id)) {
|
if (typeof over.id === "string") {
|
||||||
overStatusId = getStatusId(over.id);
|
if (isContainerId(over.id)) {
|
||||||
|
overStatusId = getContainerId(over.id);
|
||||||
|
} else {
|
||||||
|
const status = getStatusByGroupId(getGroupId(over.id));
|
||||||
|
if (!status) return;
|
||||||
|
overStatusId = status.id;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
const deal = deals.find(deal => deal.id === over.id);
|
const deal = dealsWithoutGroup.find(deal => deal.id === over.id);
|
||||||
if (!deal) return;
|
if (!deal) return;
|
||||||
overStatusId = deal.status.id;
|
overStatusId = deal.status.id;
|
||||||
}
|
}
|
||||||
@ -158,17 +222,44 @@ const useDealsAndStatusesDnd = (): ReturnType => {
|
|||||||
|
|
||||||
const getDropTarget = (
|
const getDropTarget = (
|
||||||
overId: string | number,
|
overId: string | number,
|
||||||
activeDealId: number,
|
activeDealId: number | undefined,
|
||||||
|
activeGroupId: number | undefined,
|
||||||
activeStatusId: number,
|
activeStatusId: number,
|
||||||
isOnDragEnd: boolean = false
|
isOnDragEnd: boolean = false
|
||||||
): { overStatus?: StatusSchema; newLexorank?: string } => {
|
): { overStatus?: StatusSchema; newLexorank?: string } => {
|
||||||
if (typeof overId === "string") {
|
if (typeof overId === "string") {
|
||||||
return {
|
if (isContainerId(overId)) {
|
||||||
overStatus: getStatusById(getStatusId(overId)),
|
return getStatusDropTarget(overId);
|
||||||
newLexorank: undefined,
|
}
|
||||||
};
|
if (isGroupId(overId)) {
|
||||||
|
return getGroupDropTarget(
|
||||||
|
overId,
|
||||||
|
activeGroupId,
|
||||||
|
activeStatusId,
|
||||||
|
isOnDragEnd
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return getDealDropTarget(
|
||||||
|
Number(overId),
|
||||||
|
activeDealId,
|
||||||
|
activeStatusId,
|
||||||
|
isOnDragEnd
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const getStatusDropTarget = (overId: string) => ({
|
||||||
|
overStatus: getStatusById(getContainerId(overId)),
|
||||||
|
newLexorank: undefined,
|
||||||
|
});
|
||||||
|
|
||||||
|
const getDealDropTarget = (
|
||||||
|
overId: number,
|
||||||
|
activeDealId: number | undefined,
|
||||||
|
activeStatusId: number,
|
||||||
|
isOnDragEnd: boolean = false
|
||||||
|
) => {
|
||||||
const overDealId = Number(overId);
|
const overDealId = Number(overId);
|
||||||
const overStatus = getStatusByDealId(overDealId);
|
const overStatus = getStatusByDealId(overDealId);
|
||||||
|
|
||||||
@ -176,51 +267,93 @@ const useDealsAndStatusesDnd = (): ReturnType => {
|
|||||||
return { overStatus: undefined, newLexorank: undefined };
|
return { overStatus: undefined, newLexorank: undefined };
|
||||||
}
|
}
|
||||||
|
|
||||||
const statusDeals = sortByLexorank(
|
const statusItems = getStatusDealsAndGroups(overStatus.id);
|
||||||
deals.filter(deal => deal.status.id === overStatus.id)
|
const overDealIndex = statusItems.findIndex(
|
||||||
|
deal => !isItemGroup(deal) && deal.id === overDealId
|
||||||
);
|
);
|
||||||
const overDealIndex = statusDeals.findIndex(
|
const activeDealIndex = statusItems.findIndex(
|
||||||
deal => deal.id === overDealId
|
deal => !isItemGroup(deal) && deal.id === activeDealId
|
||||||
);
|
);
|
||||||
|
|
||||||
if (activeStatusId === overStatus.id) {
|
if (activeStatusId === overStatus.id) {
|
||||||
const newLexorank = getNewRankForSameStatus(
|
const newLexorank = getNewRankForSameStatus(
|
||||||
statusDeals,
|
statusItems,
|
||||||
overDealIndex,
|
overDealIndex,
|
||||||
activeDealId
|
activeDealIndex
|
||||||
);
|
);
|
||||||
return { overStatus, newLexorank };
|
return { overStatus, newLexorank };
|
||||||
}
|
}
|
||||||
|
|
||||||
const newLexorank = getNewRankForAnotherStatus(
|
const newLexorank = getNewRankForAnotherStatus(
|
||||||
statusDeals,
|
statusItems,
|
||||||
overDealIndex
|
overDealIndex
|
||||||
);
|
);
|
||||||
return { overStatus, newLexorank };
|
return { overStatus, newLexorank };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const getGroupDropTarget = (
|
||||||
|
overId: string,
|
||||||
|
activeGroupId: number | undefined,
|
||||||
|
activeStatusId: number,
|
||||||
|
isOnDragEnd: boolean = false
|
||||||
|
) => {
|
||||||
|
const overGroupId = getGroupId(overId);
|
||||||
|
const overStatus = getStatusByGroupId(overGroupId);
|
||||||
|
|
||||||
|
if (!overStatus || (!isOnDragEnd && activeGroupId === overGroupId)) {
|
||||||
|
return { overStatus: undefined, newLexorank: undefined };
|
||||||
|
}
|
||||||
|
|
||||||
|
const statusItems = getStatusDealsAndGroups(overStatus.id);
|
||||||
|
const overGroupIndex = statusItems.findIndex(
|
||||||
|
group => isItemGroup(group) && group.id === overGroupId
|
||||||
|
);
|
||||||
|
const activeGroupIndex = statusItems.findIndex(
|
||||||
|
group => isItemGroup(group) && group.id === activeGroupId
|
||||||
|
);
|
||||||
|
|
||||||
|
if (activeStatusId === overStatus.id) {
|
||||||
|
const newLexorank = getNewRankForSameStatus(
|
||||||
|
statusItems,
|
||||||
|
overGroupIndex,
|
||||||
|
activeGroupIndex
|
||||||
|
);
|
||||||
|
return { overStatus, newLexorank };
|
||||||
|
}
|
||||||
|
|
||||||
|
const newLexorank = getNewRankForAnotherStatus(
|
||||||
|
statusItems,
|
||||||
|
overGroupIndex
|
||||||
|
);
|
||||||
|
return { overStatus, newLexorank };
|
||||||
|
};
|
||||||
|
|
||||||
const handleDragEnd = ({ active, over }: DragOverEvent) => {
|
const handleDragEnd = ({ active, over }: DragOverEvent) => {
|
||||||
setActiveDeal(null);
|
|
||||||
setActiveStatus(null);
|
|
||||||
if (!over) return;
|
if (!over) return;
|
||||||
|
|
||||||
const activeId: string | number = active.id;
|
const activeId: string | number = active.id;
|
||||||
|
|
||||||
if (typeof activeId === "string" && isStatusId(activeId)) {
|
if (typeof activeId !== "string") {
|
||||||
|
handleDealDragEnd(activeId, over);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (isContainerId(activeId)) {
|
||||||
handleStatusColumnDragEnd(activeId, over);
|
handleStatusColumnDragEnd(activeId, over);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
handleDealDragEnd(activeId, over);
|
handleGroupDragEnd(activeId, over);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleStatusColumnDragEnd = (activeId: string, over: Over) => {
|
const handleStatusColumnDragEnd = (activeId: string, over: Over) => {
|
||||||
const activeStatusId = getStatusId(activeId);
|
const activeStatusId = getContainerId(activeId);
|
||||||
let overStatusId: number;
|
let overStatusId: number;
|
||||||
|
|
||||||
if (typeof over.id === "string" && isStatusId(over.id)) {
|
if (typeof over.id === "string" && isContainerId(over.id)) {
|
||||||
overStatusId = getStatusId(over.id);
|
overStatusId = getContainerId(over.id);
|
||||||
} else {
|
} else {
|
||||||
const deal = deals.find(deal => deal.status.id === over.id);
|
const deal = dealsWithoutGroup.find(
|
||||||
|
deal => deal.status.id === over.id
|
||||||
|
);
|
||||||
if (!deal) return;
|
if (!deal) return;
|
||||||
overStatusId = deal.status.id;
|
overStatusId = deal.status.id;
|
||||||
}
|
}
|
||||||
@ -245,6 +378,7 @@ const useDealsAndStatusesDnd = (): ReturnType => {
|
|||||||
const { overStatus, newLexorank } = getDropTarget(
|
const { overStatus, newLexorank } = getDropTarget(
|
||||||
over.id,
|
over.id,
|
||||||
activeDealId,
|
activeDealId,
|
||||||
|
undefined,
|
||||||
activeStatusId,
|
activeStatusId,
|
||||||
true
|
true
|
||||||
);
|
);
|
||||||
@ -261,30 +395,36 @@ const useDealsAndStatusesDnd = (): ReturnType => {
|
|||||||
dealsCrud.onUpdate(dealId, { statusId, lexorank, name: null });
|
dealsCrud.onUpdate(dealId, { statusId, lexorank, name: null });
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleDragStart = ({ active }: DragStartEvent) => {
|
const handleGroupDragEnd = (activeId: string, over: Over) => {
|
||||||
const activeId = active.id as string | number;
|
const activeGroupId = getGroupId(activeId);
|
||||||
|
const activeStatusId = getStatusByGroupId(activeGroupId)?.id;
|
||||||
|
if (!activeStatusId) return;
|
||||||
|
|
||||||
if (typeof activeId === "string" && isStatusId(activeId)) {
|
const { overStatus, newLexorank } = getDropTarget(
|
||||||
const statusId = getStatusId(activeId);
|
over.id,
|
||||||
setActiveStatus(
|
undefined,
|
||||||
statuses.find(status => status.id === statusId) ?? null
|
activeGroupId,
|
||||||
);
|
activeStatusId,
|
||||||
return;
|
true
|
||||||
}
|
|
||||||
|
|
||||||
setActiveDeal(
|
|
||||||
deals.find(deal => deal.id === (activeId as number)) ?? null
|
|
||||||
);
|
);
|
||||||
|
if (!overStatus) return;
|
||||||
|
|
||||||
|
onGroupDragEnd(activeGroupId, overStatus.id, newLexorank);
|
||||||
|
};
|
||||||
|
|
||||||
|
const onGroupDragEnd = (
|
||||||
|
groupId: number,
|
||||||
|
statusId: number,
|
||||||
|
lexorank?: string
|
||||||
|
) => {
|
||||||
|
groupsCrud.onUpdate(groupId, { statusId, lexorank, name: null });
|
||||||
};
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
swiperRef,
|
swiperRef,
|
||||||
sortedStatuses,
|
sortedStatuses,
|
||||||
handleDragStart,
|
|
||||||
handleDragOver,
|
handleDragOver,
|
||||||
handleDragEnd,
|
handleDragEnd,
|
||||||
activeStatus,
|
|
||||||
activeDeal,
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -1,18 +1,24 @@
|
|||||||
import { LexoRank } from "lexorank";
|
import { LexoRank } from "lexorank";
|
||||||
import { useStatusesContext } from "@/app/deals/contexts/StatusesContext";
|
import { useStatusesContext } from "@/app/deals/contexts/StatusesContext";
|
||||||
import { DealSchema } from "@/lib/client";
|
import {
|
||||||
import { sortByLexorank } from "@/utils/lexorank/sort";
|
BaseDraggable,
|
||||||
|
BaseGroupDraggable,
|
||||||
|
} from "@/components/dnd/types/types";
|
||||||
import { getNewLexorank } from "@/utils/lexorank/generation";
|
import { getNewLexorank } from "@/utils/lexorank/generation";
|
||||||
|
import { sortByLexorank } from "@/utils/lexorank/sort";
|
||||||
|
|
||||||
type NewRankGetters = {
|
type NewRankGetters<
|
||||||
|
TItem extends BaseDraggable,
|
||||||
|
TGroup extends BaseGroupDraggable<TItem>,
|
||||||
|
> = {
|
||||||
getNewRankForSameStatus: (
|
getNewRankForSameStatus: (
|
||||||
statusDeals: DealSchema[],
|
statusItemsAndGroups: (TItem | TGroup)[],
|
||||||
overDealIndex: number,
|
overItemOrGroupIndex: number,
|
||||||
activeDealId: number
|
activeItemOrGroupIndex: number
|
||||||
) => string;
|
) => string;
|
||||||
getNewRankForAnotherStatus: (
|
getNewRankForAnotherStatus: (
|
||||||
statusDeals: DealSchema[],
|
statusItemsAndGroups: (TItem | TGroup)[],
|
||||||
overDealIndex: number
|
overItemOrGroupIndex: number
|
||||||
) => string;
|
) => string;
|
||||||
getNewStatusRank: (
|
getNewStatusRank: (
|
||||||
activeStatusId: number,
|
activeStatusId: number,
|
||||||
@ -20,44 +26,46 @@ type NewRankGetters = {
|
|||||||
) => string | null;
|
) => string | null;
|
||||||
};
|
};
|
||||||
|
|
||||||
const useGetNewRank = (): NewRankGetters => {
|
const useGetNewRank = <
|
||||||
|
TItem extends BaseDraggable,
|
||||||
|
TGroup extends BaseGroupDraggable<TItem>,
|
||||||
|
>(): NewRankGetters<TItem, TGroup> => {
|
||||||
const { statuses } = useStatusesContext();
|
const { statuses } = useStatusesContext();
|
||||||
|
|
||||||
const getNewRankForSameStatus = (
|
const getNewRankForSameStatus = (
|
||||||
statusDeals: DealSchema[],
|
statusItemsAndGroups: (TItem | TGroup)[],
|
||||||
overDealIndex: number,
|
overItemOrGroupIndex: number,
|
||||||
activeDealId: number
|
activeItemOrGroupIndex: number
|
||||||
): string => {
|
): string => {
|
||||||
const activeDealIndex = statusDeals.findIndex(
|
|
||||||
deal => deal.id === activeDealId
|
|
||||||
);
|
|
||||||
const [leftIndex, rightIndex] =
|
const [leftIndex, rightIndex] =
|
||||||
overDealIndex < activeDealIndex
|
overItemOrGroupIndex < activeItemOrGroupIndex
|
||||||
? [overDealIndex - 1, overDealIndex]
|
? [overItemOrGroupIndex - 1, overItemOrGroupIndex]
|
||||||
: [overDealIndex, overDealIndex + 1];
|
: [overItemOrGroupIndex, overItemOrGroupIndex + 1];
|
||||||
|
|
||||||
const leftLexorank =
|
const leftLexorank =
|
||||||
leftIndex >= 0
|
leftIndex >= 0
|
||||||
? LexoRank.parse(statusDeals[leftIndex].lexorank)
|
? LexoRank.parse(statusItemsAndGroups[leftIndex].lexorank)
|
||||||
: null;
|
: null;
|
||||||
const rightLexorank =
|
const rightLexorank =
|
||||||
rightIndex < statusDeals.length
|
rightIndex < statusItemsAndGroups.length
|
||||||
? LexoRank.parse(statusDeals[rightIndex].lexorank)
|
? LexoRank.parse(statusItemsAndGroups[rightIndex].lexorank)
|
||||||
: null;
|
: null;
|
||||||
|
|
||||||
return getNewLexorank(leftLexorank, rightLexorank).toString();
|
return getNewLexorank(leftLexorank, rightLexorank).toString();
|
||||||
};
|
};
|
||||||
|
|
||||||
const getNewRankForAnotherStatus = (
|
const getNewRankForAnotherStatus = (
|
||||||
statusDeals: DealSchema[],
|
statusItemsAndGroups: (TItem | TGroup)[],
|
||||||
overDealIndex: number
|
overItemOrGroupIndex: number
|
||||||
): string => {
|
): string => {
|
||||||
const leftLexorank =
|
const leftLexorank =
|
||||||
overDealIndex > 0
|
overItemOrGroupIndex > 0
|
||||||
? LexoRank.parse(statusDeals[overDealIndex - 1].lexorank)
|
? LexoRank.parse(
|
||||||
|
statusItemsAndGroups[overItemOrGroupIndex - 1].lexorank
|
||||||
|
)
|
||||||
: null;
|
: null;
|
||||||
const rightLexorank = LexoRank.parse(
|
const rightLexorank = LexoRank.parse(
|
||||||
statusDeals[overDealIndex].lexorank
|
statusItemsAndGroups[overItemOrGroupIndex].lexorank
|
||||||
);
|
);
|
||||||
|
|
||||||
return getNewLexorank(leftLexorank, rightLexorank).toString();
|
return getNewLexorank(leftLexorank, rightLexorank).toString();
|
||||||
|
|||||||
15
src/app/deals/utils/isItemGroup.ts
Normal file
15
src/app/deals/utils/isItemGroup.ts
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
import {
|
||||||
|
BaseDraggable,
|
||||||
|
BaseGroupDraggable,
|
||||||
|
} from "@/components/dnd/types/types";
|
||||||
|
|
||||||
|
const isItemGroup = <
|
||||||
|
TItem extends BaseDraggable,
|
||||||
|
TGroup extends BaseGroupDraggable<TItem>,
|
||||||
|
>(
|
||||||
|
item: TItem | TGroup
|
||||||
|
): boolean => {
|
||||||
|
return "items" in item;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default isItemGroup;
|
||||||
@ -1,6 +0,0 @@
|
|||||||
const STATUS_POSTFIX = "-status";
|
|
||||||
|
|
||||||
export const isStatusId = (rawId: string) => rawId.endsWith(STATUS_POSTFIX);
|
|
||||||
|
|
||||||
export const getStatusId = (rawId: string) =>
|
|
||||||
Number(rawId.replace(STATUS_POSTFIX, ""));
|
|
||||||
@ -1,42 +0,0 @@
|
|||||||
import React, { ReactNode } from "react";
|
|
||||||
import { useDroppable } from "@dnd-kit/core";
|
|
||||||
import {
|
|
||||||
SortableContext,
|
|
||||||
verticalListSortingStrategy,
|
|
||||||
} from "@dnd-kit/sortable";
|
|
||||||
import { Stack } from "@mantine/core";
|
|
||||||
import { BaseDraggable } from "@/components/dnd/types/types";
|
|
||||||
|
|
||||||
type Props<TItem> = {
|
|
||||||
id: string;
|
|
||||||
items: TItem[];
|
|
||||||
renderItem: (item: TItem) => ReactNode;
|
|
||||||
children?: ReactNode;
|
|
||||||
};
|
|
||||||
|
|
||||||
const FunnelColumn = <TItem extends BaseDraggable>({
|
|
||||||
id,
|
|
||||||
items,
|
|
||||||
renderItem,
|
|
||||||
children,
|
|
||||||
}: Props<TItem>) => {
|
|
||||||
const { setNodeRef } = useDroppable({ id });
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
{children}
|
|
||||||
<SortableContext
|
|
||||||
id={id}
|
|
||||||
items={items}
|
|
||||||
strategy={verticalListSortingStrategy}>
|
|
||||||
<Stack
|
|
||||||
gap="xs"
|
|
||||||
ref={setNodeRef}>
|
|
||||||
{items.map(renderItem)}
|
|
||||||
</Stack>
|
|
||||||
</SortableContext>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default FunnelColumn;
|
|
||||||
@ -1,6 +1,6 @@
|
|||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import React, { ReactNode, RefObject, useMemo } from "react";
|
import React, { ReactNode, RefObject, useMemo, useState } from "react";
|
||||||
import {
|
import {
|
||||||
DndContext,
|
DndContext,
|
||||||
DragEndEvent,
|
DragEndEvent,
|
||||||
@ -16,17 +16,28 @@ import { Swiper, SwiperRef, SwiperSlide } from "swiper/react";
|
|||||||
import { Box } from "@mantine/core";
|
import { Box } from "@mantine/core";
|
||||||
import CreateStatusButton from "@/app/deals/components/shared/CreateStatusButton/CreateStatusButton";
|
import CreateStatusButton from "@/app/deals/components/shared/CreateStatusButton/CreateStatusButton";
|
||||||
import useDndSensors from "@/app/deals/hooks/useSensors";
|
import useDndSensors from "@/app/deals/hooks/useSensors";
|
||||||
import FunnelColumn from "@/components/dnd/FunnelDnd/FunnelColumn";
|
import FunnelColumn from "@/components/dnd/FunnelDnd/components/FunnelColumn";
|
||||||
import FunnelOverlay from "@/components/dnd/FunnelDnd/FunnelOverlay";
|
import FunnelOverlay from "@/components/dnd/FunnelDnd/components/FunnelOverlay";
|
||||||
import { BaseDraggable } from "@/components/dnd/types/types";
|
import {
|
||||||
|
getContainerId,
|
||||||
|
getDndContainerId,
|
||||||
|
isContainerId,
|
||||||
|
} from "@/components/dnd/FunnelDnd/utils/columnId";
|
||||||
|
import {
|
||||||
|
getGroupId,
|
||||||
|
isGroupId,
|
||||||
|
} from "@/components/dnd/FunnelDnd/utils/groupId";
|
||||||
|
import {
|
||||||
|
BaseDraggable,
|
||||||
|
BaseGroupDraggable,
|
||||||
|
} from "@/components/dnd/types/types";
|
||||||
import useIsMobile from "@/hooks/utils/useIsMobile";
|
import useIsMobile from "@/hooks/utils/useIsMobile";
|
||||||
import SortableItem from "../SortableItem";
|
import SortableItem from "../SortableItem";
|
||||||
import classes from "./FunnelDnd.module.css";
|
import classes from "./FunnelDnd.module.css";
|
||||||
|
|
||||||
type Props<TContainer, TItem> = {
|
type Props<TContainer, TItem, TGroup> = {
|
||||||
containers: TContainer[];
|
containers: TContainer[];
|
||||||
items: TItem[];
|
itemsAndGroups: (TItem | TGroup)[];
|
||||||
onDragStart: (event: DragStartEvent) => void;
|
|
||||||
onDragOver: (event: DragOverEvent) => void;
|
onDragOver: (event: DragOverEvent) => void;
|
||||||
onDragEnd: (event: DragEndEvent) => void;
|
onDragEnd: (event: DragEndEvent) => void;
|
||||||
swiperRef: RefObject<SwiperRef | null>;
|
swiperRef: RefObject<SwiperRef | null>;
|
||||||
@ -42,11 +53,8 @@ type Props<TContainer, TItem> = {
|
|||||||
children: ReactNode
|
children: ReactNode
|
||||||
) => ReactNode;
|
) => ReactNode;
|
||||||
renderItem: (item: TItem) => ReactNode;
|
renderItem: (item: TItem) => ReactNode;
|
||||||
renderItemOverlay: (item: TItem) => ReactNode;
|
renderGroup: (group: TGroup) => ReactNode;
|
||||||
getContainerId: (container: TContainer) => string;
|
getItemsByContainer: (container: TContainer) => (TItem | TGroup)[];
|
||||||
getItemsByContainer: (container: TContainer, items: TItem[]) => TItem[];
|
|
||||||
activeContainer: TContainer | null;
|
|
||||||
activeItem: TItem | null;
|
|
||||||
isCreatingContainerEnabled?: boolean;
|
isCreatingContainerEnabled?: boolean;
|
||||||
disabledColumns?: boolean;
|
disabledColumns?: boolean;
|
||||||
};
|
};
|
||||||
@ -54,10 +62,10 @@ type Props<TContainer, TItem> = {
|
|||||||
const FunnelDnd = <
|
const FunnelDnd = <
|
||||||
TContainer extends BaseDraggable,
|
TContainer extends BaseDraggable,
|
||||||
TItem extends BaseDraggable,
|
TItem extends BaseDraggable,
|
||||||
|
TGroup extends BaseGroupDraggable<TItem>,
|
||||||
>({
|
>({
|
||||||
containers,
|
containers,
|
||||||
items,
|
itemsAndGroups,
|
||||||
onDragStart,
|
|
||||||
onDragOver,
|
onDragOver,
|
||||||
onDragEnd,
|
onDragEnd,
|
||||||
swiperRef,
|
swiperRef,
|
||||||
@ -65,22 +73,25 @@ const FunnelDnd = <
|
|||||||
renderContainerHeader,
|
renderContainerHeader,
|
||||||
renderContainerOverlay,
|
renderContainerOverlay,
|
||||||
renderItem,
|
renderItem,
|
||||||
renderItemOverlay,
|
renderGroup,
|
||||||
getContainerId,
|
|
||||||
getItemsByContainer,
|
getItemsByContainer,
|
||||||
activeContainer,
|
|
||||||
activeItem,
|
|
||||||
isCreatingContainerEnabled = true,
|
isCreatingContainerEnabled = true,
|
||||||
disabledColumns = false,
|
disabledColumns = false,
|
||||||
}: Props<TContainer, TItem>) => {
|
}: Props<TContainer, TItem, TGroup>) => {
|
||||||
const sensors = useDndSensors();
|
const sensors = useDndSensors();
|
||||||
const isMobile = useIsMobile();
|
const isMobile = useIsMobile();
|
||||||
const frequency = useMemo(() => (isMobile ? 1 : undefined), [isMobile]);
|
const frequency = useMemo(() => (isMobile ? 1 : undefined), [isMobile]);
|
||||||
|
|
||||||
|
const [activeItem, setActiveItem] = useState<TItem | null>(null);
|
||||||
|
const [activeContainer, setActiveContainer] = useState<TContainer | null>(
|
||||||
|
null
|
||||||
|
);
|
||||||
|
const [activeGroup, setActiveGroup] = useState<TGroup | null>(null);
|
||||||
|
|
||||||
const renderContainers = () =>
|
const renderContainers = () =>
|
||||||
containers.map((container, index) => {
|
containers.map((container, index) => {
|
||||||
const containerItems = getItemsByContainer(container, items);
|
const containerItems = getItemsByContainer(container);
|
||||||
const containerId = getContainerId(container);
|
const containerId = getDndContainerId(container.id);
|
||||||
return (
|
return (
|
||||||
<SwiperSlide
|
<SwiperSlide
|
||||||
style={{ width: 250 }}
|
style={{ width: 250 }}
|
||||||
@ -94,8 +105,9 @@ const FunnelDnd = <
|
|||||||
container,
|
container,
|
||||||
<FunnelColumn
|
<FunnelColumn
|
||||||
id={containerId}
|
id={containerId}
|
||||||
items={containerItems}
|
itemsAndGroups={containerItems}
|
||||||
renderItem={renderItem}
|
renderItem={renderItem}
|
||||||
|
renderGroup={renderGroup}
|
||||||
/>,
|
/>,
|
||||||
renderDraggable!,
|
renderDraggable!,
|
||||||
index
|
index
|
||||||
@ -156,6 +168,34 @@ const FunnelDnd = <
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const onDragStart = ({ active }: DragStartEvent) => {
|
||||||
|
const activeId = active.id as string | number;
|
||||||
|
|
||||||
|
if (typeof activeId !== "string") {
|
||||||
|
const item = (itemsAndGroups.find(
|
||||||
|
item => !("items" in item) && item.id === activeId
|
||||||
|
) ?? null) as TItem | null;
|
||||||
|
setActiveItem(item);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isContainerId(activeId)) {
|
||||||
|
const contId = getContainerId(activeId);
|
||||||
|
setActiveContainer(
|
||||||
|
containers.find(container => container.id === contId) ?? null
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isGroupId(activeId)) {
|
||||||
|
const groupId = getGroupId(activeId);
|
||||||
|
const group = (itemsAndGroups.find(
|
||||||
|
group => "items" in group && group.id === groupId
|
||||||
|
) ?? null) as TGroup | null;
|
||||||
|
setActiveGroup(group);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<DndContext
|
<DndContext
|
||||||
sensors={sensors}
|
sensors={sensors}
|
||||||
@ -166,30 +206,37 @@ const FunnelDnd = <
|
|||||||
}}
|
}}
|
||||||
onDragStart={onDragStart}
|
onDragStart={onDragStart}
|
||||||
onDragOver={onDragOver}
|
onDragOver={onDragOver}
|
||||||
onDragEnd={onDragEnd}>
|
onDragEnd={state => {
|
||||||
|
setActiveContainer(null);
|
||||||
|
setActiveItem(null);
|
||||||
|
setActiveGroup(null);
|
||||||
|
onDragEnd(state);
|
||||||
|
}}>
|
||||||
<SortableContext
|
<SortableContext
|
||||||
items={containers.map(getContainerId)}
|
items={containers.map(container =>
|
||||||
|
getDndContainerId(container.id)
|
||||||
|
)}
|
||||||
strategy={horizontalListSortingStrategy}>
|
strategy={horizontalListSortingStrategy}>
|
||||||
{renderBody()}
|
{renderBody()}
|
||||||
<FunnelOverlay
|
<FunnelOverlay
|
||||||
activeContainer={activeContainer}
|
activeContainer={activeContainer}
|
||||||
activeItem={activeItem}
|
activeItem={activeItem}
|
||||||
|
activeGroup={activeGroup}
|
||||||
renderContainer={container => {
|
renderContainer={container => {
|
||||||
const containerItems = getItemsByContainer(
|
const containerItems = getItemsByContainer(container);
|
||||||
container,
|
const containerId = getDndContainerId(container.id);
|
||||||
items
|
|
||||||
);
|
|
||||||
const containerId = getContainerId(container);
|
|
||||||
return renderContainerOverlay(
|
return renderContainerOverlay(
|
||||||
container,
|
container,
|
||||||
<FunnelColumn
|
<FunnelColumn
|
||||||
id={containerId}
|
id={containerId}
|
||||||
items={containerItems}
|
itemsAndGroups={containerItems}
|
||||||
renderItem={renderItem}
|
renderItem={renderItem}
|
||||||
|
renderGroup={renderGroup}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
renderItem={renderItemOverlay}
|
renderItem={renderItem}
|
||||||
|
renderGroup={renderGroup}
|
||||||
/>
|
/>
|
||||||
</SortableContext>
|
</SortableContext>
|
||||||
</DndContext>
|
</DndContext>
|
||||||
|
|||||||
76
src/components/dnd/FunnelDnd/components/FunnelColumn.tsx
Normal file
76
src/components/dnd/FunnelDnd/components/FunnelColumn.tsx
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
import React, { ReactNode } from "react";
|
||||||
|
import { useDroppable } from "@dnd-kit/core";
|
||||||
|
import {
|
||||||
|
SortableContext,
|
||||||
|
verticalListSortingStrategy,
|
||||||
|
} from "@dnd-kit/sortable";
|
||||||
|
import { Stack } from "@mantine/core";
|
||||||
|
import { getDndGroupId } from "@/components/dnd/FunnelDnd/utils/groupId";
|
||||||
|
import SortableItem from "@/components/dnd/SortableItem";
|
||||||
|
import {
|
||||||
|
BaseDraggable,
|
||||||
|
BaseGroupDraggable,
|
||||||
|
} from "@/components/dnd/types/types";
|
||||||
|
import isItemGroup from "@/app/deals/utils/isItemGroup";
|
||||||
|
|
||||||
|
type Props<
|
||||||
|
TItem extends BaseDraggable,
|
||||||
|
TGroup extends BaseGroupDraggable<TItem>,
|
||||||
|
> = {
|
||||||
|
id: string;
|
||||||
|
itemsAndGroups: (TItem | TGroup)[];
|
||||||
|
renderItem: (item: TItem) => ReactNode;
|
||||||
|
renderGroup: (group: TGroup) => ReactNode;
|
||||||
|
children?: ReactNode;
|
||||||
|
};
|
||||||
|
|
||||||
|
const FunnelColumn = <
|
||||||
|
TItem extends BaseDraggable,
|
||||||
|
TGroup extends BaseGroupDraggable<TItem>,
|
||||||
|
>({
|
||||||
|
id,
|
||||||
|
itemsAndGroups,
|
||||||
|
renderItem,
|
||||||
|
renderGroup,
|
||||||
|
children,
|
||||||
|
}: Props<TItem, TGroup>) => {
|
||||||
|
const { setNodeRef } = useDroppable({ id });
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{children}
|
||||||
|
<SortableContext
|
||||||
|
id={id}
|
||||||
|
items={itemsAndGroups.map(itemOrGroup =>
|
||||||
|
isItemGroup(itemOrGroup)
|
||||||
|
? getDndGroupId(itemOrGroup.id)
|
||||||
|
: itemOrGroup.id
|
||||||
|
)}
|
||||||
|
strategy={verticalListSortingStrategy}>
|
||||||
|
<Stack
|
||||||
|
gap="xs"
|
||||||
|
ref={setNodeRef}>
|
||||||
|
{itemsAndGroups.map(itemOrGroup =>
|
||||||
|
"items" in itemOrGroup ? (
|
||||||
|
<SortableItem
|
||||||
|
key={`${itemOrGroup.id.toString()}g`}
|
||||||
|
dragHandleStyle={{ cursor: "pointer" }}
|
||||||
|
id={getDndGroupId(itemOrGroup.id)}
|
||||||
|
renderItem={() => renderGroup(itemOrGroup)}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<SortableItem
|
||||||
|
key={itemOrGroup.id}
|
||||||
|
dragHandleStyle={{ cursor: "pointer" }}
|
||||||
|
id={itemOrGroup.id}
|
||||||
|
renderItem={() => renderItem(itemOrGroup)}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
)}
|
||||||
|
</Stack>
|
||||||
|
</SortableContext>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default FunnelColumn;
|
||||||
@ -2,28 +2,32 @@ import React, { ReactNode } from "react";
|
|||||||
import { defaultDropAnimation, DragOverlay } from "@dnd-kit/core";
|
import { defaultDropAnimation, DragOverlay } from "@dnd-kit/core";
|
||||||
import styles from "@/components/dnd/FunnelDnd/FunnelDnd.module.css";
|
import styles from "@/components/dnd/FunnelDnd/FunnelDnd.module.css";
|
||||||
|
|
||||||
type Props<TContainer, TItem> = {
|
type Props<TContainer, TItem, TGroup> = {
|
||||||
activeContainer: TContainer | null;
|
activeContainer: TContainer | null;
|
||||||
activeItem: TItem | null;
|
activeItem: TItem | null;
|
||||||
|
activeGroup: TGroup | null;
|
||||||
renderContainer: (container: TContainer) => ReactNode;
|
renderContainer: (container: TContainer) => ReactNode;
|
||||||
renderItem: (item: TItem) => ReactNode;
|
renderItem: (item: TItem) => ReactNode;
|
||||||
|
renderGroup: (group: TGroup) => ReactNode;
|
||||||
};
|
};
|
||||||
|
|
||||||
const FunnelOverlay = <TContainer, TItem>({
|
const FunnelOverlay = <TContainer, TItem, TGroup>({
|
||||||
activeContainer,
|
activeContainer,
|
||||||
activeItem,
|
activeItem,
|
||||||
|
activeGroup,
|
||||||
renderContainer,
|
renderContainer,
|
||||||
renderItem,
|
renderItem,
|
||||||
}: Props<TContainer, TItem>) => {
|
renderGroup,
|
||||||
|
}: Props<TContainer, TItem, TGroup>) => {
|
||||||
|
const renderOverlay = () => {
|
||||||
|
if (activeItem) return renderItem(activeItem);
|
||||||
|
if (activeContainer) return renderContainer(activeContainer);
|
||||||
|
if (activeGroup) return renderGroup(activeGroup);
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<DragOverlay dropAnimation={defaultDropAnimation}>
|
<DragOverlay dropAnimation={defaultDropAnimation}>
|
||||||
<div className={styles.overlay}>
|
<div className={styles.overlay}>{renderOverlay()}</div>
|
||||||
{activeItem
|
|
||||||
? renderItem(activeItem)
|
|
||||||
: activeContainer
|
|
||||||
? renderContainer(activeContainer)
|
|
||||||
: null}
|
|
||||||
</div>
|
|
||||||
</DragOverlay>
|
</DragOverlay>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
9
src/components/dnd/FunnelDnd/utils/columnId.ts
Normal file
9
src/components/dnd/FunnelDnd/utils/columnId.ts
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
const CONTAINER_POSTFIX = "-con";
|
||||||
|
|
||||||
|
export const isContainerId = (rawId: string) => rawId.endsWith(CONTAINER_POSTFIX);
|
||||||
|
|
||||||
|
export const getContainerId = (rawId: string) =>
|
||||||
|
Number(rawId.replace(CONTAINER_POSTFIX, ""));
|
||||||
|
|
||||||
|
export const getDndContainerId = (id: number) =>
|
||||||
|
`${id}${CONTAINER_POSTFIX}`;
|
||||||
8
src/components/dnd/FunnelDnd/utils/groupId.ts
Normal file
8
src/components/dnd/FunnelDnd/utils/groupId.ts
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
const GROUP_POSTFIX = "-gr";
|
||||||
|
|
||||||
|
export const isGroupId = (rawId: string) => rawId.endsWith(GROUP_POSTFIX);
|
||||||
|
|
||||||
|
export const getGroupId = (rawId: string) =>
|
||||||
|
Number(rawId.replace(GROUP_POSTFIX, ""));
|
||||||
|
|
||||||
|
export const getDndGroupId = (id: number) => `${id}${GROUP_POSTFIX}`;
|
||||||
@ -1,3 +1,8 @@
|
|||||||
export type BaseDraggable = {
|
export type BaseDraggable = {
|
||||||
id: number;
|
id: number;
|
||||||
|
lexorank: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type BaseGroupDraggable<TItem extends BaseDraggable> = BaseDraggable & {
|
||||||
|
items: TItem[];
|
||||||
};
|
};
|
||||||
|
|||||||
69
src/hooks/cruds/useDealGroupCrud.tsx
Normal file
69
src/hooks/cruds/useDealGroupCrud.tsx
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
import { useMutation } from "@tanstack/react-query";
|
||||||
|
import { UpdateDealGroupSchema } from "@/lib/client";
|
||||||
|
import {
|
||||||
|
addDealMutation,
|
||||||
|
createDealGroupMutation,
|
||||||
|
removeDealMutation,
|
||||||
|
updateDealGroupMutation,
|
||||||
|
} from "@/lib/client/@tanstack/react-query.gen";
|
||||||
|
|
||||||
|
export type GroupsCrud = {
|
||||||
|
onUpdate: (groupId: number, group: UpdateDealGroupSchema) => void;
|
||||||
|
// onDelete: (group: DealGroupSchema, onSuccess?: () => void) => void;
|
||||||
|
};
|
||||||
|
|
||||||
|
const useDealGroupCrud = (): GroupsCrud => {
|
||||||
|
const updateMutation = useMutation(updateDealGroupMutation());
|
||||||
|
|
||||||
|
const onUpdate = (groupId: number, entity: UpdateDealGroupSchema) => {
|
||||||
|
updateMutation.mutate({
|
||||||
|
path: {
|
||||||
|
pk: groupId,
|
||||||
|
},
|
||||||
|
body: {
|
||||||
|
entity,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const createMutation = useMutation(createDealGroupMutation());
|
||||||
|
|
||||||
|
const onCreate = (draggingDealId: number, hoveredDealId: number) => {
|
||||||
|
createMutation.mutate({
|
||||||
|
body: {
|
||||||
|
draggingDealId,
|
||||||
|
hoveredDealId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const addDealToGroupMutation = useMutation(addDealMutation());
|
||||||
|
|
||||||
|
const onAddDeal = (dealId: number, groupId: number) => {
|
||||||
|
addDealToGroupMutation.mutate({
|
||||||
|
body: {
|
||||||
|
dealId,
|
||||||
|
groupId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const removeDealFromGroupMutation = useMutation(removeDealMutation());
|
||||||
|
|
||||||
|
const onRemoveDeal = (dealId: number) => {
|
||||||
|
removeDealFromGroupMutation.mutate({
|
||||||
|
body: {
|
||||||
|
dealId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
onUpdate,
|
||||||
|
// onCreate,
|
||||||
|
// onAddDeal,
|
||||||
|
// onRemoveDeal,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export default useDealGroupCrud;
|
||||||
@ -9,12 +9,14 @@ import {
|
|||||||
import type { AxiosError } from "axios";
|
import type { AxiosError } from "axios";
|
||||||
import { client as _heyApiClient } from "../client.gen";
|
import { client as _heyApiClient } from "../client.gen";
|
||||||
import {
|
import {
|
||||||
|
addDeal,
|
||||||
addKitToDeal,
|
addKitToDeal,
|
||||||
addKitToDealProduct,
|
addKitToDealProduct,
|
||||||
createBarcodeTemplate,
|
createBarcodeTemplate,
|
||||||
createBoard,
|
createBoard,
|
||||||
createClient,
|
createClient,
|
||||||
createDeal,
|
createDeal,
|
||||||
|
createDealGroup,
|
||||||
createDealProduct,
|
createDealProduct,
|
||||||
createDealProductService,
|
createDealProductService,
|
||||||
createDealService,
|
createDealService,
|
||||||
@ -59,10 +61,12 @@ import {
|
|||||||
getServicesKits,
|
getServicesKits,
|
||||||
getStatuses,
|
getStatuses,
|
||||||
getStatusHistory,
|
getStatusHistory,
|
||||||
|
removeDeal,
|
||||||
updateBarcodeTemplate,
|
updateBarcodeTemplate,
|
||||||
updateBoard,
|
updateBoard,
|
||||||
updateClient,
|
updateClient,
|
||||||
updateDeal,
|
updateDeal,
|
||||||
|
updateDealGroup,
|
||||||
updateDealProduct,
|
updateDealProduct,
|
||||||
updateDealProductService,
|
updateDealProductService,
|
||||||
updateDealService,
|
updateDealService,
|
||||||
@ -76,6 +80,9 @@ import {
|
|||||||
type Options,
|
type Options,
|
||||||
} from "../sdk.gen";
|
} from "../sdk.gen";
|
||||||
import type {
|
import type {
|
||||||
|
AddDealData,
|
||||||
|
AddDealError,
|
||||||
|
AddDealResponse,
|
||||||
AddKitToDealData,
|
AddKitToDealData,
|
||||||
AddKitToDealError,
|
AddKitToDealError,
|
||||||
AddKitToDealProductData,
|
AddKitToDealProductData,
|
||||||
@ -93,6 +100,9 @@ import type {
|
|||||||
CreateClientResponse2,
|
CreateClientResponse2,
|
||||||
CreateDealData,
|
CreateDealData,
|
||||||
CreateDealError,
|
CreateDealError,
|
||||||
|
CreateDealGroupData,
|
||||||
|
CreateDealGroupError,
|
||||||
|
CreateDealGroupResponse2,
|
||||||
CreateDealProductData,
|
CreateDealProductData,
|
||||||
CreateDealProductError,
|
CreateDealProductError,
|
||||||
CreateDealProductResponse2,
|
CreateDealProductResponse2,
|
||||||
@ -194,6 +204,9 @@ import type {
|
|||||||
GetServicesKitsData,
|
GetServicesKitsData,
|
||||||
GetStatusesData,
|
GetStatusesData,
|
||||||
GetStatusHistoryData,
|
GetStatusHistoryData,
|
||||||
|
RemoveDealData,
|
||||||
|
RemoveDealError,
|
||||||
|
RemoveDealResponse,
|
||||||
UpdateBarcodeTemplateData,
|
UpdateBarcodeTemplateData,
|
||||||
UpdateBarcodeTemplateError,
|
UpdateBarcodeTemplateError,
|
||||||
UpdateBarcodeTemplateResponse2,
|
UpdateBarcodeTemplateResponse2,
|
||||||
@ -205,6 +218,9 @@ import type {
|
|||||||
UpdateClientResponse2,
|
UpdateClientResponse2,
|
||||||
UpdateDealData,
|
UpdateDealData,
|
||||||
UpdateDealError,
|
UpdateDealError,
|
||||||
|
UpdateDealGroupData,
|
||||||
|
UpdateDealGroupError,
|
||||||
|
UpdateDealGroupResponse2,
|
||||||
UpdateDealProductData,
|
UpdateDealProductData,
|
||||||
UpdateDealProductError,
|
UpdateDealProductError,
|
||||||
UpdateDealProductResponse2,
|
UpdateDealProductResponse2,
|
||||||
@ -605,6 +621,159 @@ export const updateDealMutation = (
|
|||||||
return mutationOptions;
|
return mutationOptions;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update Group
|
||||||
|
*/
|
||||||
|
export const updateDealGroupMutation = (
|
||||||
|
options?: Partial<Options<UpdateDealGroupData>>
|
||||||
|
): UseMutationOptions<
|
||||||
|
UpdateDealGroupResponse2,
|
||||||
|
AxiosError<UpdateDealGroupError>,
|
||||||
|
Options<UpdateDealGroupData>
|
||||||
|
> => {
|
||||||
|
const mutationOptions: UseMutationOptions<
|
||||||
|
UpdateDealGroupResponse2,
|
||||||
|
AxiosError<UpdateDealGroupError>,
|
||||||
|
Options<UpdateDealGroupData>
|
||||||
|
> = {
|
||||||
|
mutationFn: async localOptions => {
|
||||||
|
const { data } = await updateDealGroup({
|
||||||
|
...options,
|
||||||
|
...localOptions,
|
||||||
|
throwOnError: true,
|
||||||
|
});
|
||||||
|
return data;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
return mutationOptions;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const createDealGroupQueryKey = (
|
||||||
|
options: Options<CreateDealGroupData>
|
||||||
|
) => createQueryKey("createDealGroup", options);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create Group
|
||||||
|
*/
|
||||||
|
export const createDealGroupOptions = (
|
||||||
|
options: Options<CreateDealGroupData>
|
||||||
|
) => {
|
||||||
|
return queryOptions({
|
||||||
|
queryFn: async ({ queryKey, signal }) => {
|
||||||
|
const { data } = await createDealGroup({
|
||||||
|
...options,
|
||||||
|
...queryKey[0],
|
||||||
|
signal,
|
||||||
|
throwOnError: true,
|
||||||
|
});
|
||||||
|
return data;
|
||||||
|
},
|
||||||
|
queryKey: createDealGroupQueryKey(options),
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create Group
|
||||||
|
*/
|
||||||
|
export const createDealGroupMutation = (
|
||||||
|
options?: Partial<Options<CreateDealGroupData>>
|
||||||
|
): UseMutationOptions<
|
||||||
|
CreateDealGroupResponse2,
|
||||||
|
AxiosError<CreateDealGroupError>,
|
||||||
|
Options<CreateDealGroupData>
|
||||||
|
> => {
|
||||||
|
const mutationOptions: UseMutationOptions<
|
||||||
|
CreateDealGroupResponse2,
|
||||||
|
AxiosError<CreateDealGroupError>,
|
||||||
|
Options<CreateDealGroupData>
|
||||||
|
> = {
|
||||||
|
mutationFn: async localOptions => {
|
||||||
|
const { data } = await createDealGroup({
|
||||||
|
...options,
|
||||||
|
...localOptions,
|
||||||
|
throwOnError: true,
|
||||||
|
});
|
||||||
|
return data;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
return mutationOptions;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove Deal
|
||||||
|
*/
|
||||||
|
export const removeDealMutation = (
|
||||||
|
options?: Partial<Options<RemoveDealData>>
|
||||||
|
): UseMutationOptions<
|
||||||
|
RemoveDealResponse,
|
||||||
|
AxiosError<RemoveDealError>,
|
||||||
|
Options<RemoveDealData>
|
||||||
|
> => {
|
||||||
|
const mutationOptions: UseMutationOptions<
|
||||||
|
RemoveDealResponse,
|
||||||
|
AxiosError<RemoveDealError>,
|
||||||
|
Options<RemoveDealData>
|
||||||
|
> = {
|
||||||
|
mutationFn: async localOptions => {
|
||||||
|
const { data } = await removeDeal({
|
||||||
|
...options,
|
||||||
|
...localOptions,
|
||||||
|
throwOnError: true,
|
||||||
|
});
|
||||||
|
return data;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
return mutationOptions;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const addDealQueryKey = (options: Options<AddDealData>) =>
|
||||||
|
createQueryKey("addDeal", options);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add Deal
|
||||||
|
*/
|
||||||
|
export const addDealOptions = (options: Options<AddDealData>) => {
|
||||||
|
return queryOptions({
|
||||||
|
queryFn: async ({ queryKey, signal }) => {
|
||||||
|
const { data } = await addDeal({
|
||||||
|
...options,
|
||||||
|
...queryKey[0],
|
||||||
|
signal,
|
||||||
|
throwOnError: true,
|
||||||
|
});
|
||||||
|
return data;
|
||||||
|
},
|
||||||
|
queryKey: addDealQueryKey(options),
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add Deal
|
||||||
|
*/
|
||||||
|
export const addDealMutation = (
|
||||||
|
options?: Partial<Options<AddDealData>>
|
||||||
|
): UseMutationOptions<
|
||||||
|
AddDealResponse,
|
||||||
|
AxiosError<AddDealError>,
|
||||||
|
Options<AddDealData>
|
||||||
|
> => {
|
||||||
|
const mutationOptions: UseMutationOptions<
|
||||||
|
AddDealResponse,
|
||||||
|
AxiosError<AddDealError>,
|
||||||
|
Options<AddDealData>
|
||||||
|
> = {
|
||||||
|
mutationFn: async localOptions => {
|
||||||
|
const { data } = await addDeal({
|
||||||
|
...options,
|
||||||
|
...localOptions,
|
||||||
|
throwOnError: true,
|
||||||
|
});
|
||||||
|
return data;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
return mutationOptions;
|
||||||
|
};
|
||||||
|
|
||||||
export const getBuiltInModulesQueryKey = (
|
export const getBuiltInModulesQueryKey = (
|
||||||
options?: Options<GetBuiltInModulesData>
|
options?: Options<GetBuiltInModulesData>
|
||||||
) => createQueryKey("getBuiltInModules", options);
|
) => createQueryKey("getBuiltInModules", options);
|
||||||
|
|||||||
@ -3,6 +3,9 @@
|
|||||||
import type { Client, Options as ClientOptions, TDataShape } from "./client";
|
import type { Client, Options as ClientOptions, TDataShape } from "./client";
|
||||||
import { client as _heyApiClient } from "./client.gen";
|
import { client as _heyApiClient } from "./client.gen";
|
||||||
import type {
|
import type {
|
||||||
|
AddDealData,
|
||||||
|
AddDealErrors,
|
||||||
|
AddDealResponses,
|
||||||
AddKitToDealData,
|
AddKitToDealData,
|
||||||
AddKitToDealErrors,
|
AddKitToDealErrors,
|
||||||
AddKitToDealProductData,
|
AddKitToDealProductData,
|
||||||
@ -20,6 +23,9 @@ import type {
|
|||||||
CreateClientResponses,
|
CreateClientResponses,
|
||||||
CreateDealData,
|
CreateDealData,
|
||||||
CreateDealErrors,
|
CreateDealErrors,
|
||||||
|
CreateDealGroupData,
|
||||||
|
CreateDealGroupErrors,
|
||||||
|
CreateDealGroupResponses,
|
||||||
CreateDealProductData,
|
CreateDealProductData,
|
||||||
CreateDealProductErrors,
|
CreateDealProductErrors,
|
||||||
CreateDealProductResponses,
|
CreateDealProductResponses,
|
||||||
@ -144,6 +150,9 @@ import type {
|
|||||||
GetStatusHistoryData,
|
GetStatusHistoryData,
|
||||||
GetStatusHistoryErrors,
|
GetStatusHistoryErrors,
|
||||||
GetStatusHistoryResponses,
|
GetStatusHistoryResponses,
|
||||||
|
RemoveDealData,
|
||||||
|
RemoveDealErrors,
|
||||||
|
RemoveDealResponses,
|
||||||
UpdateBarcodeTemplateData,
|
UpdateBarcodeTemplateData,
|
||||||
UpdateBarcodeTemplateErrors,
|
UpdateBarcodeTemplateErrors,
|
||||||
UpdateBarcodeTemplateResponses,
|
UpdateBarcodeTemplateResponses,
|
||||||
@ -155,6 +164,9 @@ import type {
|
|||||||
UpdateClientResponses,
|
UpdateClientResponses,
|
||||||
UpdateDealData,
|
UpdateDealData,
|
||||||
UpdateDealErrors,
|
UpdateDealErrors,
|
||||||
|
UpdateDealGroupData,
|
||||||
|
UpdateDealGroupErrors,
|
||||||
|
UpdateDealGroupResponses,
|
||||||
UpdateDealProductData,
|
UpdateDealProductData,
|
||||||
UpdateDealProductErrors,
|
UpdateDealProductErrors,
|
||||||
UpdateDealProductResponses,
|
UpdateDealProductResponses,
|
||||||
@ -188,6 +200,8 @@ import type {
|
|||||||
UpdateStatusResponses,
|
UpdateStatusResponses,
|
||||||
} from "./types.gen";
|
} from "./types.gen";
|
||||||
import {
|
import {
|
||||||
|
zAddDealData,
|
||||||
|
zAddDealResponse,
|
||||||
zAddKitToDealData,
|
zAddKitToDealData,
|
||||||
zAddKitToDealProductData,
|
zAddKitToDealProductData,
|
||||||
zAddKitToDealProductResponse,
|
zAddKitToDealProductResponse,
|
||||||
@ -199,6 +213,8 @@ import {
|
|||||||
zCreateClientData,
|
zCreateClientData,
|
||||||
zCreateClientResponse2,
|
zCreateClientResponse2,
|
||||||
zCreateDealData,
|
zCreateDealData,
|
||||||
|
zCreateDealGroupData,
|
||||||
|
zCreateDealGroupResponse2,
|
||||||
zCreateDealProductData,
|
zCreateDealProductData,
|
||||||
zCreateDealProductResponse2,
|
zCreateDealProductResponse2,
|
||||||
zCreateDealProductServiceData,
|
zCreateDealProductServiceData,
|
||||||
@ -288,6 +304,8 @@ import {
|
|||||||
zGetStatusesResponse2,
|
zGetStatusesResponse2,
|
||||||
zGetStatusHistoryData,
|
zGetStatusHistoryData,
|
||||||
zGetStatusHistoryResponse2,
|
zGetStatusHistoryResponse2,
|
||||||
|
zRemoveDealData,
|
||||||
|
zRemoveDealResponse,
|
||||||
zUpdateBarcodeTemplateData,
|
zUpdateBarcodeTemplateData,
|
||||||
zUpdateBarcodeTemplateResponse2,
|
zUpdateBarcodeTemplateResponse2,
|
||||||
zUpdateBoardData,
|
zUpdateBoardData,
|
||||||
@ -295,6 +313,8 @@ import {
|
|||||||
zUpdateClientData,
|
zUpdateClientData,
|
||||||
zUpdateClientResponse2,
|
zUpdateClientResponse2,
|
||||||
zUpdateDealData,
|
zUpdateDealData,
|
||||||
|
zUpdateDealGroupData,
|
||||||
|
zUpdateDealGroupResponse2,
|
||||||
zUpdateDealProductData,
|
zUpdateDealProductData,
|
||||||
zUpdateDealProductResponse2,
|
zUpdateDealProductResponse2,
|
||||||
zUpdateDealProductServiceData,
|
zUpdateDealProductServiceData,
|
||||||
@ -535,6 +555,114 @@ export const updateDeal = <ThrowOnError extends boolean = false>(
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update Group
|
||||||
|
*/
|
||||||
|
export const updateDealGroup = <ThrowOnError extends boolean = false>(
|
||||||
|
options: Options<UpdateDealGroupData, ThrowOnError>
|
||||||
|
) => {
|
||||||
|
return (options.client ?? _heyApiClient).patch<
|
||||||
|
UpdateDealGroupResponses,
|
||||||
|
UpdateDealGroupErrors,
|
||||||
|
ThrowOnError
|
||||||
|
>({
|
||||||
|
requestValidator: async data => {
|
||||||
|
return await zUpdateDealGroupData.parseAsync(data);
|
||||||
|
},
|
||||||
|
responseType: "json",
|
||||||
|
responseValidator: async data => {
|
||||||
|
return await zUpdateDealGroupResponse2.parseAsync(data);
|
||||||
|
},
|
||||||
|
url: "/deal-group/{pk}",
|
||||||
|
...options,
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
...options.headers,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create Group
|
||||||
|
*/
|
||||||
|
export const createDealGroup = <ThrowOnError extends boolean = false>(
|
||||||
|
options: Options<CreateDealGroupData, ThrowOnError>
|
||||||
|
) => {
|
||||||
|
return (options.client ?? _heyApiClient).post<
|
||||||
|
CreateDealGroupResponses,
|
||||||
|
CreateDealGroupErrors,
|
||||||
|
ThrowOnError
|
||||||
|
>({
|
||||||
|
requestValidator: async data => {
|
||||||
|
return await zCreateDealGroupData.parseAsync(data);
|
||||||
|
},
|
||||||
|
responseType: "json",
|
||||||
|
responseValidator: async data => {
|
||||||
|
return await zCreateDealGroupResponse2.parseAsync(data);
|
||||||
|
},
|
||||||
|
url: "/deal-group/",
|
||||||
|
...options,
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
...options.headers,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove Deal
|
||||||
|
*/
|
||||||
|
export const removeDeal = <ThrowOnError extends boolean = false>(
|
||||||
|
options: Options<RemoveDealData, ThrowOnError>
|
||||||
|
) => {
|
||||||
|
return (options.client ?? _heyApiClient).delete<
|
||||||
|
RemoveDealResponses,
|
||||||
|
RemoveDealErrors,
|
||||||
|
ThrowOnError
|
||||||
|
>({
|
||||||
|
requestValidator: async data => {
|
||||||
|
return await zRemoveDealData.parseAsync(data);
|
||||||
|
},
|
||||||
|
responseType: "json",
|
||||||
|
responseValidator: async data => {
|
||||||
|
return await zRemoveDealResponse.parseAsync(data);
|
||||||
|
},
|
||||||
|
url: "/deal-group/deal",
|
||||||
|
...options,
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
...options.headers,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add Deal
|
||||||
|
*/
|
||||||
|
export const addDeal = <ThrowOnError extends boolean = false>(
|
||||||
|
options: Options<AddDealData, ThrowOnError>
|
||||||
|
) => {
|
||||||
|
return (options.client ?? _heyApiClient).post<
|
||||||
|
AddDealResponses,
|
||||||
|
AddDealErrors,
|
||||||
|
ThrowOnError
|
||||||
|
>({
|
||||||
|
requestValidator: async data => {
|
||||||
|
return await zAddDealData.parseAsync(data);
|
||||||
|
},
|
||||||
|
responseType: "json",
|
||||||
|
responseValidator: async data => {
|
||||||
|
return await zAddDealResponse.parseAsync(data);
|
||||||
|
},
|
||||||
|
url: "/deal-group/deal",
|
||||||
|
...options,
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
...options.headers,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get Built In Modules
|
* Get Built In Modules
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -1,5 +1,29 @@
|
|||||||
// This file is auto-generated by @hey-api/openapi-ts
|
// This file is auto-generated by @hey-api/openapi-ts
|
||||||
|
|
||||||
|
/**
|
||||||
|
* AddDealToGroupRequest
|
||||||
|
*/
|
||||||
|
export type AddDealToGroupRequest = {
|
||||||
|
/**
|
||||||
|
* Dealid
|
||||||
|
*/
|
||||||
|
dealId: number;
|
||||||
|
/**
|
||||||
|
* Groupid
|
||||||
|
*/
|
||||||
|
groupId: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* AddDealToGroupResponse
|
||||||
|
*/
|
||||||
|
export type AddDealToGroupResponse = {
|
||||||
|
/**
|
||||||
|
* Message
|
||||||
|
*/
|
||||||
|
message: string;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* BarcodeTemplateAttributeSchema
|
* BarcodeTemplateAttributeSchema
|
||||||
*/
|
*/
|
||||||
@ -347,6 +371,27 @@ export type CreateClientSchema = {
|
|||||||
details: ClientDetailsSchema;
|
details: ClientDetailsSchema;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CreateDealGroupRequest
|
||||||
|
*/
|
||||||
|
export type CreateDealGroupRequest = {
|
||||||
|
/**
|
||||||
|
* Draggingdealid
|
||||||
|
*/
|
||||||
|
draggingDealId: number;
|
||||||
|
/**
|
||||||
|
* Hovereddealid
|
||||||
|
*/
|
||||||
|
hoveredDealId: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CreateDealGroupResponse
|
||||||
|
*/
|
||||||
|
export type CreateDealGroupResponse = {
|
||||||
|
entity: DealGroupSchema;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* CreateDealProductRequest
|
* CreateDealProductRequest
|
||||||
*/
|
*/
|
||||||
@ -832,6 +877,24 @@ export type DealAddKitResponse = {
|
|||||||
message: string;
|
message: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DealGroupSchema
|
||||||
|
*/
|
||||||
|
export type DealGroupSchema = {
|
||||||
|
/**
|
||||||
|
* Id
|
||||||
|
*/
|
||||||
|
id: number;
|
||||||
|
/**
|
||||||
|
* Name
|
||||||
|
*/
|
||||||
|
name?: string | null;
|
||||||
|
/**
|
||||||
|
* Lexorank
|
||||||
|
*/
|
||||||
|
lexorank: string;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* DealProductAddKitRequest
|
* DealProductAddKitRequest
|
||||||
*/
|
*/
|
||||||
@ -887,6 +950,26 @@ export type DealProductSchema = {
|
|||||||
productServices: Array<ProductServiceSchema>;
|
productServices: Array<ProductServiceSchema>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DealRemoveFromGroupRequest
|
||||||
|
*/
|
||||||
|
export type DealRemoveFromGroupRequest = {
|
||||||
|
/**
|
||||||
|
* Dealid
|
||||||
|
*/
|
||||||
|
dealId: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DealRemoveFromGroupResponse
|
||||||
|
*/
|
||||||
|
export type DealRemoveFromGroupResponse = {
|
||||||
|
/**
|
||||||
|
* Message
|
||||||
|
*/
|
||||||
|
message: string;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* DealSchema
|
* DealSchema
|
||||||
*/
|
*/
|
||||||
@ -909,6 +992,7 @@ export type DealSchema = {
|
|||||||
* Createdat
|
* Createdat
|
||||||
*/
|
*/
|
||||||
createdAt: string;
|
createdAt: string;
|
||||||
|
group: DealGroupSchema | null;
|
||||||
/**
|
/**
|
||||||
* Productsquantity
|
* Productsquantity
|
||||||
*/
|
*/
|
||||||
@ -1753,6 +1837,41 @@ export type UpdateClientSchema = {
|
|||||||
details?: ClientDetailsSchema | null;
|
details?: ClientDetailsSchema | null;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* UpdateDealGroupRequest
|
||||||
|
*/
|
||||||
|
export type UpdateDealGroupRequest = {
|
||||||
|
entity: UpdateDealGroupSchema;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* UpdateDealGroupResponse
|
||||||
|
*/
|
||||||
|
export type UpdateDealGroupResponse = {
|
||||||
|
/**
|
||||||
|
* Message
|
||||||
|
*/
|
||||||
|
message: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* UpdateDealGroupSchema
|
||||||
|
*/
|
||||||
|
export type UpdateDealGroupSchema = {
|
||||||
|
/**
|
||||||
|
* Name
|
||||||
|
*/
|
||||||
|
name?: string | null;
|
||||||
|
/**
|
||||||
|
* Lexorank
|
||||||
|
*/
|
||||||
|
lexorank?: string | null;
|
||||||
|
/**
|
||||||
|
* Statusid
|
||||||
|
*/
|
||||||
|
statusId?: number | null;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* UpdateDealProductRequest
|
* UpdateDealProductRequest
|
||||||
*/
|
*/
|
||||||
@ -2466,6 +2585,115 @@ export type UpdateDealResponses = {
|
|||||||
export type UpdateDealResponse2 =
|
export type UpdateDealResponse2 =
|
||||||
UpdateDealResponses[keyof UpdateDealResponses];
|
UpdateDealResponses[keyof UpdateDealResponses];
|
||||||
|
|
||||||
|
export type UpdateDealGroupData = {
|
||||||
|
body: UpdateDealGroupRequest;
|
||||||
|
path: {
|
||||||
|
/**
|
||||||
|
* Pk
|
||||||
|
*/
|
||||||
|
pk: number;
|
||||||
|
};
|
||||||
|
query?: never;
|
||||||
|
url: "/deal-group/{pk}";
|
||||||
|
};
|
||||||
|
|
||||||
|
export type UpdateDealGroupErrors = {
|
||||||
|
/**
|
||||||
|
* Validation Error
|
||||||
|
*/
|
||||||
|
422: HttpValidationError;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type UpdateDealGroupError =
|
||||||
|
UpdateDealGroupErrors[keyof UpdateDealGroupErrors];
|
||||||
|
|
||||||
|
export type UpdateDealGroupResponses = {
|
||||||
|
/**
|
||||||
|
* Successful Response
|
||||||
|
*/
|
||||||
|
200: UpdateDealGroupResponse;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type UpdateDealGroupResponse2 =
|
||||||
|
UpdateDealGroupResponses[keyof UpdateDealGroupResponses];
|
||||||
|
|
||||||
|
export type CreateDealGroupData = {
|
||||||
|
body: CreateDealGroupRequest;
|
||||||
|
path?: never;
|
||||||
|
query?: never;
|
||||||
|
url: "/deal-group/";
|
||||||
|
};
|
||||||
|
|
||||||
|
export type CreateDealGroupErrors = {
|
||||||
|
/**
|
||||||
|
* Validation Error
|
||||||
|
*/
|
||||||
|
422: HttpValidationError;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type CreateDealGroupError =
|
||||||
|
CreateDealGroupErrors[keyof CreateDealGroupErrors];
|
||||||
|
|
||||||
|
export type CreateDealGroupResponses = {
|
||||||
|
/**
|
||||||
|
* Successful Response
|
||||||
|
*/
|
||||||
|
200: CreateDealGroupResponse;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type CreateDealGroupResponse2 =
|
||||||
|
CreateDealGroupResponses[keyof CreateDealGroupResponses];
|
||||||
|
|
||||||
|
export type RemoveDealData = {
|
||||||
|
body: DealRemoveFromGroupRequest;
|
||||||
|
path?: never;
|
||||||
|
query?: never;
|
||||||
|
url: "/deal-group/deal";
|
||||||
|
};
|
||||||
|
|
||||||
|
export type RemoveDealErrors = {
|
||||||
|
/**
|
||||||
|
* Validation Error
|
||||||
|
*/
|
||||||
|
422: HttpValidationError;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type RemoveDealError = RemoveDealErrors[keyof RemoveDealErrors];
|
||||||
|
|
||||||
|
export type RemoveDealResponses = {
|
||||||
|
/**
|
||||||
|
* Successful Response
|
||||||
|
*/
|
||||||
|
200: DealRemoveFromGroupResponse;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type RemoveDealResponse = RemoveDealResponses[keyof RemoveDealResponses];
|
||||||
|
|
||||||
|
export type AddDealData = {
|
||||||
|
body: AddDealToGroupRequest;
|
||||||
|
path?: never;
|
||||||
|
query?: never;
|
||||||
|
url: "/deal-group/deal";
|
||||||
|
};
|
||||||
|
|
||||||
|
export type AddDealErrors = {
|
||||||
|
/**
|
||||||
|
* Validation Error
|
||||||
|
*/
|
||||||
|
422: HttpValidationError;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type AddDealError = AddDealErrors[keyof AddDealErrors];
|
||||||
|
|
||||||
|
export type AddDealResponses = {
|
||||||
|
/**
|
||||||
|
* Successful Response
|
||||||
|
*/
|
||||||
|
200: AddDealToGroupResponse;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type AddDealResponse = AddDealResponses[keyof AddDealResponses];
|
||||||
|
|
||||||
export type GetBuiltInModulesData = {
|
export type GetBuiltInModulesData = {
|
||||||
body?: never;
|
body?: never;
|
||||||
path?: never;
|
path?: never;
|
||||||
|
|||||||
@ -2,6 +2,21 @@
|
|||||||
|
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* AddDealToGroupRequest
|
||||||
|
*/
|
||||||
|
export const zAddDealToGroupRequest = z.object({
|
||||||
|
dealId: z.int(),
|
||||||
|
groupId: z.int(),
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* AddDealToGroupResponse
|
||||||
|
*/
|
||||||
|
export const zAddDealToGroupResponse = z.object({
|
||||||
|
message: z.string(),
|
||||||
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* BarcodeTemplateAttributeSchema
|
* BarcodeTemplateAttributeSchema
|
||||||
*/
|
*/
|
||||||
@ -193,6 +208,30 @@ export const zCreateClientResponse = z.object({
|
|||||||
message: z.string(),
|
message: z.string(),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CreateDealGroupRequest
|
||||||
|
*/
|
||||||
|
export const zCreateDealGroupRequest = z.object({
|
||||||
|
draggingDealId: z.int(),
|
||||||
|
hoveredDealId: z.int(),
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DealGroupSchema
|
||||||
|
*/
|
||||||
|
export const zDealGroupSchema = z.object({
|
||||||
|
id: z.int(),
|
||||||
|
name: z.optional(z.union([z.string(), z.null()])),
|
||||||
|
lexorank: z.string(),
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CreateDealGroupResponse
|
||||||
|
*/
|
||||||
|
export const zCreateDealGroupResponse = z.object({
|
||||||
|
entity: zDealGroupSchema,
|
||||||
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* CreateDealProductSchema
|
* CreateDealProductSchema
|
||||||
*/
|
*/
|
||||||
@ -336,6 +375,7 @@ export const zDealSchema = z.object({
|
|||||||
createdAt: z.iso.datetime({
|
createdAt: z.iso.datetime({
|
||||||
offset: true,
|
offset: true,
|
||||||
}),
|
}),
|
||||||
|
group: z.union([zDealGroupSchema, z.null()]),
|
||||||
productsQuantity: z.optional(z.int()).default(0),
|
productsQuantity: z.optional(z.int()).default(0),
|
||||||
totalPrice: z.optional(z.number()).default(0),
|
totalPrice: z.optional(z.number()).default(0),
|
||||||
client: z.optional(z.union([zClientSchema, z.null()])),
|
client: z.optional(z.union([zClientSchema, z.null()])),
|
||||||
@ -654,6 +694,20 @@ export const zDealProductAddKitResponse = z.object({
|
|||||||
message: z.string(),
|
message: z.string(),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DealRemoveFromGroupRequest
|
||||||
|
*/
|
||||||
|
export const zDealRemoveFromGroupRequest = z.object({
|
||||||
|
dealId: z.int(),
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DealRemoveFromGroupResponse
|
||||||
|
*/
|
||||||
|
export const zDealRemoveFromGroupResponse = z.object({
|
||||||
|
message: z.string(),
|
||||||
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* DeleteBarcodeTemplateResponse
|
* DeleteBarcodeTemplateResponse
|
||||||
*/
|
*/
|
||||||
@ -1034,6 +1088,29 @@ export const zUpdateClientResponse = z.object({
|
|||||||
message: z.string(),
|
message: z.string(),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* UpdateDealGroupSchema
|
||||||
|
*/
|
||||||
|
export const zUpdateDealGroupSchema = z.object({
|
||||||
|
name: z.optional(z.union([z.string(), z.null()])),
|
||||||
|
lexorank: z.optional(z.union([z.string(), z.null()])),
|
||||||
|
statusId: z.optional(z.union([z.int(), z.null()])),
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* UpdateDealGroupRequest
|
||||||
|
*/
|
||||||
|
export const zUpdateDealGroupRequest = z.object({
|
||||||
|
entity: zUpdateDealGroupSchema,
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* UpdateDealGroupResponse
|
||||||
|
*/
|
||||||
|
export const zUpdateDealGroupResponse = z.object({
|
||||||
|
message: z.string(),
|
||||||
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* UpdateDealProductSchema
|
* UpdateDealProductSchema
|
||||||
*/
|
*/
|
||||||
@ -1412,6 +1489,52 @@ export const zUpdateDealData = z.object({
|
|||||||
*/
|
*/
|
||||||
export const zUpdateDealResponse2 = zUpdateDealResponse;
|
export const zUpdateDealResponse2 = zUpdateDealResponse;
|
||||||
|
|
||||||
|
export const zUpdateDealGroupData = z.object({
|
||||||
|
body: zUpdateDealGroupRequest,
|
||||||
|
path: z.object({
|
||||||
|
pk: z.int(),
|
||||||
|
}),
|
||||||
|
query: z.optional(z.never()),
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Successful Response
|
||||||
|
*/
|
||||||
|
export const zUpdateDealGroupResponse2 = zUpdateDealGroupResponse;
|
||||||
|
|
||||||
|
export const zCreateDealGroupData = z.object({
|
||||||
|
body: zCreateDealGroupRequest,
|
||||||
|
path: z.optional(z.never()),
|
||||||
|
query: z.optional(z.never()),
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Successful Response
|
||||||
|
*/
|
||||||
|
export const zCreateDealGroupResponse2 = zCreateDealGroupResponse;
|
||||||
|
|
||||||
|
export const zRemoveDealData = z.object({
|
||||||
|
body: zDealRemoveFromGroupRequest,
|
||||||
|
path: z.optional(z.never()),
|
||||||
|
query: z.optional(z.never()),
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Successful Response
|
||||||
|
*/
|
||||||
|
export const zRemoveDealResponse = zDealRemoveFromGroupResponse;
|
||||||
|
|
||||||
|
export const zAddDealData = z.object({
|
||||||
|
body: zAddDealToGroupRequest,
|
||||||
|
path: z.optional(z.never()),
|
||||||
|
query: z.optional(z.never()),
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Successful Response
|
||||||
|
*/
|
||||||
|
export const zAddDealResponse = zAddDealToGroupResponse;
|
||||||
|
|
||||||
export const zGetBuiltInModulesData = z.object({
|
export const zGetBuiltInModulesData = z.object({
|
||||||
body: z.optional(z.never()),
|
body: z.optional(z.never()),
|
||||||
path: z.optional(z.never()),
|
path: z.optional(z.never()),
|
||||||
|
|||||||
7
src/types/GroupWithDealsSchema.ts
Normal file
7
src/types/GroupWithDealsSchema.ts
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
import { DealGroupSchema, DealSchema } from "@/lib/client";
|
||||||
|
|
||||||
|
type GroupWithDealsSchema = DealGroupSchema & {
|
||||||
|
items: DealSchema[];
|
||||||
|
};
|
||||||
|
|
||||||
|
export default GroupWithDealsSchema;
|
||||||
Reference in New Issue
Block a user