feat: services table with dnd
This commit is contained in:
@ -11,7 +11,8 @@ import useDealsAndStatusesDnd from "@/app/deals/hooks/useDealsAndStatusesDnd";
|
||||
import FunnelDnd from "@/components/dnd/FunnelDnd/FunnelDnd";
|
||||
import useIsMobile from "@/hooks/utils/useIsMobile";
|
||||
import { DealSchema, StatusSchema } from "@/lib/client";
|
||||
import { sortByLexorank } from "@/utils/lexorank";
|
||||
|
||||
import { sortByLexorank } from "@/utils/lexorank/sort";
|
||||
|
||||
const Funnel: FC = () => {
|
||||
const { selectedBoard } = useBoardsContext();
|
||||
|
||||
@ -8,7 +8,8 @@ import useGetNewRank from "@/app/deals/hooks/useGetNewRank";
|
||||
import { getStatusId, isStatusId } from "@/app/deals/utils/statusId";
|
||||
import useIsMobile from "@/hooks/utils/useIsMobile";
|
||||
import { DealSchema, StatusSchema } from "@/lib/client";
|
||||
import { sortByLexorank } from "@/utils/lexorank";
|
||||
|
||||
import { sortByLexorank } from "@/utils/lexorank/sort";
|
||||
|
||||
type ReturnType = {
|
||||
sortedStatuses: StatusSchema[];
|
||||
|
||||
@ -1,7 +1,8 @@
|
||||
import { LexoRank } from "lexorank";
|
||||
import { useStatusesContext } from "@/app/deals/contexts/StatusesContext";
|
||||
import { DealSchema } from "@/lib/client";
|
||||
import { getNewLexorank, sortByLexorank } from "@/utils/lexorank";
|
||||
import { sortByLexorank } from "@/utils/lexorank/sort";
|
||||
import { getNewLexorank } from "@/utils/lexorank/generation";
|
||||
|
||||
type NewRankGetters = {
|
||||
getNewRankForSameStatus: (
|
||||
|
||||
@ -1,31 +1,24 @@
|
||||
"use client";
|
||||
|
||||
import { useState } from "react";
|
||||
import { Stack } from "@mantine/core";
|
||||
import ServicesDesktopHeader from "@/app/services/components/desktop/ServicesDesktopHeader/ServicesDesktopHeader";
|
||||
import ServicesMobileHeader from "@/app/services/components/mobile/ServicesMobileHeader/ServicesMobileHeader";
|
||||
import ServicesKitsTable from "@/app/services/components/shared/ServicesKitTable/ServicesKitTable";
|
||||
import ServicesTable from "@/app/services/components/shared/ServicesTable/ServicesTable";
|
||||
import { ServicesTab } from "@/app/services/components/shared/ServiceTabSegmentedControl/ServiceTabSegmentedControl";
|
||||
import { useServicesContext } from "@/app/services/contexts/ServicesContext";
|
||||
import PageBlock from "@/components/layout/PageBlock/PageBlock";
|
||||
import useIsMobile from "@/hooks/utils/useIsMobile";
|
||||
import { ServiceType } from "@/modules/dealModularEditorTabs/FulfillmentBase/shared/types/service";
|
||||
|
||||
const PageBody = () => {
|
||||
const isMobile = useIsMobile();
|
||||
|
||||
const [servicesTab, setServicesTab] = useState<ServicesTab>(
|
||||
ServicesTab.PRODUCT_SERVICE
|
||||
);
|
||||
const { servicesTab, setServicesTab } = useServicesContext();
|
||||
|
||||
const getPageBody = () => {
|
||||
switch (servicesTab) {
|
||||
case ServicesTab.PRODUCT_SERVICE:
|
||||
return (
|
||||
<ServicesTable serviceType={ServiceType.PRODUCT_SERVICE} />
|
||||
);
|
||||
case ServicesTab.DEAL_SERVICE:
|
||||
return <ServicesTable serviceType={ServiceType.DEAL_SERVICE} />;
|
||||
return <ServicesTable />;
|
||||
case ServicesTab.SERVICES_KITS:
|
||||
return <ServicesKitsTable />;
|
||||
default:
|
||||
|
||||
@ -1,28 +1,17 @@
|
||||
"use client";
|
||||
|
||||
import { FC, useMemo, useState } from "react";
|
||||
import { DragDropContext, Draggable } from "@hello-pangea/dnd";
|
||||
import { IconGripVertical } from "@tabler/icons-react";
|
||||
import clsx from "clsx";
|
||||
import { DataTableDraggableRow } from "mantine-datatable";
|
||||
import { Center, TableTd } from "@mantine/core";
|
||||
import { FC, useState } from "react";
|
||||
import InnerServicesTableDndWrapper from "@/app/services/components/shared/ServicesTable/components/InnerServicesTableDndWrapper";
|
||||
import useServicesOuterTableColumns from "@/app/services/components/shared/ServicesTable/hooks/servicesOuterTableColumns";
|
||||
import { GroupedServices } from "@/app/services/components/shared/ServicesTable/types/GroupedServices";
|
||||
import ServicesTableDndWrapper from "@/app/services/components/shared/ServicesTableDndWrapper/ServicesTableDndWrapper";
|
||||
import { useServicesContext } from "@/app/services/contexts/ServicesContext";
|
||||
import { useServicesDndContext } from "@/app/services/contexts/ServicesDndContext";
|
||||
import Droppable from "@/components/dnd-pangea/Droppable/Droppable";
|
||||
import DraggableTableRow from "@/components/dnd-pangea/DraggableTableRow/DraggableTableRow";
|
||||
import BaseTable from "@/components/ui/BaseTable/BaseTable";
|
||||
import { ServiceType } from "@/modules/dealModularEditorTabs/FulfillmentBase/shared/types/service";
|
||||
import classes from "./ServicesTable.module.css";
|
||||
import useIsMobile from "@/hooks/utils/useIsMobile";
|
||||
|
||||
type Props = {
|
||||
serviceType: ServiceType;
|
||||
};
|
||||
|
||||
const ServicesTable: FC<Props> = ({ serviceType }) => {
|
||||
const { servicesList } = useServicesContext();
|
||||
const { onDragEnd, onDragStart } = useServicesDndContext();
|
||||
const ServicesTable: FC = () => {
|
||||
const isMobile = useIsMobile();
|
||||
const { groupedServices } = useServicesContext();
|
||||
|
||||
const [expandedCategoryIds, setExpandedCategoryIds] = useState<number[]>(
|
||||
[]
|
||||
@ -33,46 +22,14 @@ const ServicesTable: FC<Props> = ({ serviceType }) => {
|
||||
setExpandedCategoryIds,
|
||||
});
|
||||
|
||||
const groupedServices: GroupedServices[] = useMemo(() => {
|
||||
const grouped: GroupedServices[] = [];
|
||||
servicesList.services.forEach(service => {
|
||||
if (service.serviceType !== serviceType) return;
|
||||
|
||||
const existingGroup = grouped.find(
|
||||
group => group.category.id === service.category.id
|
||||
);
|
||||
if (existingGroup) {
|
||||
existingGroup.services.push(service);
|
||||
} else {
|
||||
grouped.push({
|
||||
category: service.category,
|
||||
services: [service],
|
||||
});
|
||||
}
|
||||
});
|
||||
return grouped;
|
||||
}, [servicesList.services, serviceType]);
|
||||
|
||||
return (
|
||||
<DragDropContext
|
||||
onDragEnd={onDragEnd}
|
||||
onDragStart={onDragStart}>
|
||||
<ServicesTableDndWrapper>
|
||||
<BaseTable
|
||||
columns={outerColumns}
|
||||
groups={undefined}
|
||||
records={groupedServices}
|
||||
withTableBorder
|
||||
idAccessor={"category.id"}
|
||||
tableWrapper={({ children }) => (
|
||||
<Droppable
|
||||
droppableId={"categories"}
|
||||
// isDropDisabled={
|
||||
// dragState !== ServiceDragState.DRAG_CATEGORY
|
||||
// }
|
||||
>
|
||||
{children}
|
||||
</Droppable>
|
||||
)}
|
||||
rowExpansion={{
|
||||
allowMultiple: true,
|
||||
expanded: {
|
||||
@ -82,47 +39,21 @@ const ServicesTable: FC<Props> = ({ serviceType }) => {
|
||||
content: ({ record }) => (
|
||||
<InnerServicesTableDndWrapper
|
||||
services={record.services}
|
||||
categoryId={record.category.id}
|
||||
/>
|
||||
),
|
||||
}}
|
||||
styles={{ table: { tableLayout: "fixed" } }}
|
||||
rowFactory={({
|
||||
record,
|
||||
index,
|
||||
rowProps,
|
||||
children,
|
||||
expandedElement,
|
||||
}) => (
|
||||
<>
|
||||
<Draggable
|
||||
key={record.category.id}
|
||||
draggableId={`category-${record.category.id.toString()}`}
|
||||
index={index}>
|
||||
{(provided, snapshot) => (
|
||||
<DataTableDraggableRow
|
||||
isDragging={snapshot.isDragging}
|
||||
{...rowProps}
|
||||
className={clsx(
|
||||
rowProps.className,
|
||||
classes["draggable-row"]
|
||||
)}
|
||||
{...provided.draggableProps}>
|
||||
<TableTd>
|
||||
<Center
|
||||
{...provided.dragHandleProps}
|
||||
ref={provided.innerRef}>
|
||||
<IconGripVertical />
|
||||
</Center>
|
||||
</TableTd>
|
||||
{children}
|
||||
</DataTableDraggableRow>
|
||||
)}
|
||||
</Draggable>
|
||||
{expandedElement}
|
||||
</>
|
||||
rowFactory={({ record, children, ...props }) => (
|
||||
<DraggableTableRow
|
||||
draggableId={`category-${record.category.id}`}
|
||||
rowElement={children}
|
||||
{...props}
|
||||
/>
|
||||
)}
|
||||
mx={isMobile ? "xs" : 0}
|
||||
/>
|
||||
</DragDropContext>
|
||||
</ServicesTableDndWrapper>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@ -1,54 +1,35 @@
|
||||
"use client";
|
||||
|
||||
import { FC } from "react";
|
||||
import { Draggable } from "@hello-pangea/dnd";
|
||||
import { IconGripVertical } from "@tabler/icons-react";
|
||||
import clsx from "clsx";
|
||||
import { DataTableDraggableRow } from "mantine-datatable";
|
||||
import { Center, TableTd } from "@mantine/core";
|
||||
import useServicesInnerTableColumns from "@/app/services/components/shared/ServicesTable/hooks/servicesInnerTableColumns";
|
||||
import classes from "@/app/services/components/shared/ServicesTable/ServicesTable.module.css";
|
||||
import DraggableTableRow from "@/components/dnd-pangea/DraggableTableRow/DraggableTableRow";
|
||||
import BaseTable from "@/components/ui/BaseTable/BaseTable";
|
||||
import { ServiceSchema } from "@/lib/client";
|
||||
|
||||
type Props = {
|
||||
services: ServiceSchema[];
|
||||
categoryId: number;
|
||||
};
|
||||
|
||||
const InnerServicesTable: FC<Props> = ({ services }) => {
|
||||
const InnerServicesTable: FC<Props> = ({ services, categoryId }) => {
|
||||
const innerColumns = useServicesInnerTableColumns();
|
||||
|
||||
return (
|
||||
<BaseTable
|
||||
key={categoryId}
|
||||
withTableBorder
|
||||
columns={innerColumns}
|
||||
records={services}
|
||||
verticalSpacing={"md"}
|
||||
groups={undefined}
|
||||
styles={{ table: { width: "100%" } }}
|
||||
rowFactory={({ record, index, rowProps, children }) => (
|
||||
<Draggable
|
||||
key={record.id}
|
||||
rowFactory={({ record, children, ...props }) => (
|
||||
<DraggableTableRow
|
||||
draggableId={`service-${record.id}`}
|
||||
index={index}>
|
||||
{(provided, snapshot) => (
|
||||
<DataTableDraggableRow
|
||||
isDragging={snapshot.isDragging}
|
||||
{...rowProps}
|
||||
className={clsx(
|
||||
rowProps.className,
|
||||
classes["draggable-row"]
|
||||
)}
|
||||
{...provided.draggableProps}>
|
||||
<TableTd>
|
||||
<Center
|
||||
{...provided.dragHandleProps}
|
||||
ref={provided.innerRef}>
|
||||
<IconGripVertical />
|
||||
</Center>
|
||||
</TableTd>
|
||||
{children}
|
||||
</DataTableDraggableRow>
|
||||
)}
|
||||
</Draggable>
|
||||
rowElement={children}
|
||||
disableDndOnMobile
|
||||
{...props}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
);
|
||||
|
||||
@ -1,19 +1,26 @@
|
||||
import { FC } from "react";
|
||||
import InnerServicesTable from "@/app/services/components/shared/ServicesTable/components/InnerServicesTable";
|
||||
import { useServicesDndContext } from "@/app/services/contexts/ServicesDndContext";
|
||||
import ServiceDragState from "@/app/services/enums/DragState";
|
||||
import Droppable from "@/components/dnd-pangea/Droppable/Droppable";
|
||||
import { ServiceSchema } from "@/lib/client";
|
||||
|
||||
type Props = {
|
||||
services: ServiceSchema[];
|
||||
categoryId: number;
|
||||
};
|
||||
|
||||
const InnerServicesTableDndWrapper: FC<Props> = ({ services }) => {
|
||||
const InnerServicesTableDndWrapper: FC<Props> = ({ services, categoryId }) => {
|
||||
const { dragState } = useServicesDndContext();
|
||||
|
||||
return (
|
||||
<Droppable
|
||||
droppableId={"services"}
|
||||
// isDropDisabled={dragState !== ServiceDragState.DRAG_SERVICE}
|
||||
>
|
||||
<InnerServicesTable services={services} />
|
||||
droppableId={`services-${categoryId}`}
|
||||
isDropDisabled={dragState !== ServiceDragState.DRAG_SERVICE}>
|
||||
<InnerServicesTable
|
||||
services={services}
|
||||
categoryId={categoryId}
|
||||
/>
|
||||
</Droppable>
|
||||
);
|
||||
};
|
||||
|
||||
@ -34,30 +34,30 @@ const useServicesInnerTableColumns = () => {
|
||||
return useMemo(
|
||||
() =>
|
||||
[
|
||||
{ accessor: "", hiddenContent: true, width: 0 },
|
||||
{ accessor: "", hiddenContent: true, width: 2 },
|
||||
{
|
||||
accessor: "name",
|
||||
title: "Название",
|
||||
width: 350,
|
||||
width: isMobile ? 70 : 350,
|
||||
},
|
||||
{
|
||||
accessor: "price",
|
||||
title: "Цена",
|
||||
render: service => getPriceRow(service),
|
||||
width: 200,
|
||||
width: isMobile ? 40 : 200,
|
||||
},
|
||||
{
|
||||
accessor: "cost",
|
||||
title: isMobile ? "Себестоим." : "Себестоимость",
|
||||
render: service => `${service.cost?.toLocaleString("ru")}₽`,
|
||||
width: 200,
|
||||
width: isMobile ? 40 : 200,
|
||||
},
|
||||
{
|
||||
accessor: "actions",
|
||||
title: isMobile ? "" : "Действия",
|
||||
sortable: false,
|
||||
textAlign: "center",
|
||||
width: 70,
|
||||
width: "0%",
|
||||
render: service => (
|
||||
<Center>
|
||||
<UpdateDeleteTableActions
|
||||
|
||||
@ -45,7 +45,7 @@ const useServicesOuterTableColumns = ({
|
||||
return useMemo(
|
||||
() =>
|
||||
[
|
||||
{ accessor: "", hiddenContent: true, width: 3 },
|
||||
{ accessor: "", hiddenContent: true, width: isMobile ? 1 : 3 },
|
||||
{
|
||||
accessor: "category.name",
|
||||
title: (
|
||||
@ -58,9 +58,10 @@ const useServicesOuterTableColumns = ({
|
||||
Категория
|
||||
</Group>
|
||||
),
|
||||
noWrap: true,
|
||||
render: ({ category: { id, name } }) => (
|
||||
<Group key={id}>
|
||||
<Group
|
||||
key={id}
|
||||
wrap={"nowrap"}>
|
||||
{expandedCategoryIds.includes(id) ? (
|
||||
<IconChevronUp />
|
||||
) : (
|
||||
@ -69,13 +70,14 @@ const useServicesOuterTableColumns = ({
|
||||
<Text>{name}</Text>
|
||||
</Group>
|
||||
),
|
||||
width: 450,
|
||||
width: isMobile ? 100 : 450,
|
||||
},
|
||||
{
|
||||
accessor: "actions",
|
||||
title: isMobile ? "" : "Действия",
|
||||
sortable: false,
|
||||
textAlign: "center",
|
||||
width: isMobile ? 2 : 50,
|
||||
render: ({ category }) => (
|
||||
<Center>
|
||||
<UpdateDeleteTableActions
|
||||
@ -87,7 +89,6 @@ const useServicesOuterTableColumns = ({
|
||||
/>
|
||||
</Center>
|
||||
),
|
||||
width: 50,
|
||||
},
|
||||
] as DataTableColumn<GroupedServices>[],
|
||||
[expandedCategoryIds, categories]
|
||||
|
||||
@ -0,0 +1,27 @@
|
||||
import { FC, ReactNode } from "react";
|
||||
import { DragDropContext } from "@hello-pangea/dnd";
|
||||
import ServiceDragState from "@/app/services/enums/DragState";
|
||||
import Droppable from "@/components/dnd-pangea/Droppable/Droppable";
|
||||
import { useServicesDndContext } from "@/app/services/contexts/ServicesDndContext";
|
||||
|
||||
type Props = {
|
||||
children: ReactNode;
|
||||
};
|
||||
|
||||
const ServicesTableDndWrapper: FC<Props> = ({ children }) => {
|
||||
const { onDragEnd, onDragStart, dragState } = useServicesDndContext();
|
||||
|
||||
return (
|
||||
<DragDropContext
|
||||
onDragEnd={onDragEnd}
|
||||
onDragStart={onDragStart}>
|
||||
<Droppable
|
||||
droppableId={"categories"}
|
||||
isDropDisabled={dragState !== ServiceDragState.DRAG_CATEGORY}>
|
||||
{children}
|
||||
</Droppable>
|
||||
</DragDropContext>
|
||||
);
|
||||
};
|
||||
|
||||
export default ServicesTableDndWrapper;
|
||||
@ -1,5 +1,9 @@
|
||||
"use client";
|
||||
|
||||
import { Dispatch, SetStateAction, useState } from "react";
|
||||
import { GroupedServices } from "@/app/services/components/shared/ServicesTable/types/GroupedServices";
|
||||
import { ServicesTab } from "@/app/services/components/shared/ServiceTabSegmentedControl/ServiceTabSegmentedControl";
|
||||
import useGroupedServices from "@/app/services/hooks/useGroupedServices";
|
||||
import { ServiceCategorySchema } from "@/lib/client";
|
||||
import makeContext from "@/lib/contextFactory/contextFactory";
|
||||
import {
|
||||
@ -22,6 +26,9 @@ import useServicesList, {
|
||||
} from "@/modules/dealModularEditorTabs/FulfillmentBase/shared/hooks/lists/useServicesList";
|
||||
|
||||
type ServicesContextState = {
|
||||
servicesTab: ServicesTab;
|
||||
setServicesTab: Dispatch<SetStateAction<ServicesTab>>;
|
||||
groupedServices: GroupedServices[];
|
||||
servicesList: ServicesList;
|
||||
servicesCrud: ServicesCrud;
|
||||
servicesKitList: ServicesKitsList;
|
||||
@ -31,6 +38,10 @@ type ServicesContextState = {
|
||||
};
|
||||
|
||||
const useServicesContextState = (): ServicesContextState => {
|
||||
const [servicesTab, setServicesTab] = useState<ServicesTab>(
|
||||
ServicesTab.PRODUCT_SERVICE
|
||||
);
|
||||
|
||||
const servicesList = useServicesList();
|
||||
const servicesCrud = useServicesCrud(servicesList);
|
||||
|
||||
@ -43,7 +54,15 @@ const useServicesContextState = (): ServicesContextState => {
|
||||
categories,
|
||||
});
|
||||
|
||||
const groupedServices = useGroupedServices({
|
||||
services: servicesList.services,
|
||||
servicesTab,
|
||||
});
|
||||
|
||||
return {
|
||||
servicesTab,
|
||||
setServicesTab,
|
||||
groupedServices,
|
||||
servicesList,
|
||||
servicesCrud,
|
||||
servicesKitList,
|
||||
|
||||
@ -2,8 +2,11 @@
|
||||
|
||||
import { Dispatch, SetStateAction, useState } from "react";
|
||||
import type { DragStart, DropResult } from "@hello-pangea/dnd";
|
||||
import { ServicesTab } from "@/app/services/components/shared/ServiceTabSegmentedControl/ServiceTabSegmentedControl";
|
||||
import { useServicesContext } from "@/app/services/contexts/ServicesContext";
|
||||
import ServiceDragState from "@/app/services/enums/DragState";
|
||||
import makeContext from "@/lib/contextFactory/contextFactory";
|
||||
import { getNewDndLexorank } from "@/utils/lexorank/generation";
|
||||
|
||||
type ServicesDndContextState = {
|
||||
onDragStart: (start: DragStart) => void;
|
||||
@ -13,36 +16,107 @@ type ServicesDndContextState = {
|
||||
};
|
||||
|
||||
const useServiceDndContextState = (): ServicesDndContextState => {
|
||||
const {
|
||||
categories,
|
||||
groupedServices,
|
||||
servicesTab,
|
||||
categoriesCrud,
|
||||
servicesCrud,
|
||||
servicesList,
|
||||
} = useServicesContext();
|
||||
|
||||
const [dragState, setDragState] = useState<ServiceDragState>(
|
||||
ServiceDragState.DRAG_ENDED
|
||||
);
|
||||
|
||||
const [value, setValue] = useState<boolean>(false);
|
||||
|
||||
const onDragStart = (start: DragStart) => {
|
||||
setValue(prev => !prev);
|
||||
if (start.draggableId.includes("category")) {
|
||||
setDragState(ServiceDragState.DRAG_CATEGORY);
|
||||
return;
|
||||
}
|
||||
setDragState(ServiceDragState.DRAG_SERVICE);
|
||||
};
|
||||
|
||||
const getCategoriesFromGroupedServices = () => [
|
||||
...new Set(groupedServices.map(grouped => grouped.category)),
|
||||
];
|
||||
|
||||
const onCategoryDrag = (result: DropResult) => {
|
||||
if (
|
||||
!result.draggableId.startsWith("category-") ||
|
||||
result.source.index === result.destination!.index
|
||||
)
|
||||
return;
|
||||
|
||||
const draggingCatId = Number(
|
||||
result.draggableId.replace("category-", "")
|
||||
);
|
||||
|
||||
const rankKey =
|
||||
servicesTab === ServicesTab.DEAL_SERVICE
|
||||
? "dealServiceRank"
|
||||
: "productServiceRank";
|
||||
|
||||
const categories = getCategoriesFromGroupedServices();
|
||||
|
||||
const newLexorank = getNewDndLexorank(
|
||||
result.source.index,
|
||||
result.destination!.index,
|
||||
categories,
|
||||
rankKey
|
||||
);
|
||||
|
||||
categoriesCrud.onUpdate(draggingCatId, {
|
||||
[rankKey]: newLexorank,
|
||||
});
|
||||
};
|
||||
|
||||
const onServiceDrag = (result: DropResult) => {
|
||||
if (!result.draggableId.startsWith("service-") || !result.destination)
|
||||
return;
|
||||
|
||||
const sourceCatId = Number(
|
||||
result.source.droppableId.replace("services-", "")
|
||||
);
|
||||
const targetCatId = Number(
|
||||
result.destination!.droppableId.replace("services-", "")
|
||||
);
|
||||
|
||||
const draggingServiceId = Number(
|
||||
result.draggableId.replace("service-", "")
|
||||
);
|
||||
|
||||
const services = servicesList.services.filter(
|
||||
s => s.category.id === targetCatId && s.serviceType === servicesTab
|
||||
);
|
||||
|
||||
const newLexorank = getNewDndLexorank(
|
||||
result.source.index,
|
||||
result.destination!.index,
|
||||
services,
|
||||
"lexorank"
|
||||
);
|
||||
|
||||
const category =
|
||||
sourceCatId !== targetCatId
|
||||
? categories.find(c => c.id === targetCatId)
|
||||
: null;
|
||||
|
||||
servicesCrud.onUpdate(draggingServiceId, {
|
||||
lexorank: newLexorank,
|
||||
category,
|
||||
});
|
||||
};
|
||||
|
||||
const onDragEnd = (result: DropResult) => {
|
||||
if (!result.destination) return;
|
||||
|
||||
const sourceId = result.source.droppableId;
|
||||
const destinationId = result.destination.droppableId;
|
||||
|
||||
console.log(destinationId);
|
||||
|
||||
// const items = Array.from(records);
|
||||
// const sourceIndex = result.source.index;
|
||||
// const destinationIndex = result.destination.index;
|
||||
// const [reorderedItem] = items.splice(sourceIndex, 1);
|
||||
// items.splice(destinationIndex, 0, reorderedItem);
|
||||
//
|
||||
// setRecords(items);
|
||||
// notifications.show({
|
||||
// title: 'Table reordered',
|
||||
// message: `The company named "${items[sourceIndex].name}" has been moved from position ${sourceIndex + 1} to ${destinationIndex + 1}.`,
|
||||
// color: 'blue',
|
||||
// });
|
||||
if (sourceId === "categories") {
|
||||
onCategoryDrag(result);
|
||||
return;
|
||||
}
|
||||
onServiceDrag(result);
|
||||
};
|
||||
|
||||
return {
|
||||
|
||||
46
src/app/services/hooks/useGroupedServices.ts
Normal file
46
src/app/services/hooks/useGroupedServices.ts
Normal file
@ -0,0 +1,46 @@
|
||||
import { useMemo } from "react";
|
||||
import { GroupedServices } from "@/app/services/components/shared/ServicesTable/types/GroupedServices";
|
||||
import { ServicesTab } from "@/app/services/components/shared/ServiceTabSegmentedControl/ServiceTabSegmentedControl";
|
||||
import { ServiceCategorySchema, ServiceSchema } from "@/lib/client";
|
||||
|
||||
type Props = {
|
||||
services: ServiceSchema[];
|
||||
servicesTab: ServicesTab;
|
||||
};
|
||||
|
||||
const useGroupedServices = ({ services, servicesTab }: Props) => {
|
||||
const sortGroupedServices = (grouped: GroupedServices[]) => {
|
||||
const key: keyof ServiceCategorySchema =
|
||||
servicesTab === ServicesTab.DEAL_SERVICE
|
||||
? "dealServiceRank"
|
||||
: "productServiceRank";
|
||||
|
||||
return grouped.sort((a, b) => {
|
||||
const aRank = a.category[key];
|
||||
const bRank = b.category[key];
|
||||
return aRank < bRank ? -1 : aRank > bRank ? 1 : 0;
|
||||
});
|
||||
};
|
||||
|
||||
return useMemo(() => {
|
||||
const grouped: GroupedServices[] = [];
|
||||
services.forEach(service => {
|
||||
if (service.serviceType !== servicesTab) return;
|
||||
|
||||
const existingGroup = grouped.find(
|
||||
group => group.category.id === service.category.id
|
||||
);
|
||||
if (existingGroup) {
|
||||
existingGroup.services.push(service);
|
||||
} else {
|
||||
grouped.push({
|
||||
category: service.category,
|
||||
services: [service],
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
return sortGroupedServices(grouped);
|
||||
}, [services, servicesTab]);
|
||||
};
|
||||
export default useGroupedServices;
|
||||
Reference in New Issue
Block a user