2024-02-23 13:40:45 +00:00
|
|
|
import { DragDropContext, Draggable, Droppable, DropResult } from "@hello-pangea/dnd";
|
|
|
|
// ui
|
|
|
|
import { Loader } from "@plane/ui";
|
|
|
|
// components
|
2024-03-18 07:42:10 +00:00
|
|
|
import { ChartDataType, IBlockUpdateData, IGanttBlock } from "components/gantt-chart";
|
2024-02-23 13:40:45 +00:00
|
|
|
import { ModulesSidebarBlock } from "./block";
|
|
|
|
// types
|
|
|
|
|
|
|
|
type Props = {
|
|
|
|
title: string;
|
|
|
|
blockUpdateHandler: (block: any, payload: IBlockUpdateData) => void;
|
2024-03-18 07:42:10 +00:00
|
|
|
getBlockById: (id: string, currentViewData?: ChartDataType | undefined) => IGanttBlock;
|
|
|
|
blockIds: string[];
|
2024-02-23 13:40:45 +00:00
|
|
|
enableReorder: boolean;
|
|
|
|
};
|
|
|
|
|
|
|
|
export const ModuleGanttSidebar: React.FC<Props> = (props) => {
|
2024-03-18 07:42:10 +00:00
|
|
|
const { blockUpdateHandler, blockIds, getBlockById, enableReorder } = props;
|
2024-02-23 13:40:45 +00:00
|
|
|
|
|
|
|
const handleOrderChange = (result: DropResult) => {
|
2024-03-18 07:42:10 +00:00
|
|
|
if (!blockIds) return;
|
2024-02-23 13:40:45 +00:00
|
|
|
|
|
|
|
const { source, destination } = result;
|
|
|
|
|
|
|
|
// return if dropped outside the list
|
|
|
|
if (!destination) return;
|
|
|
|
|
|
|
|
// return if dropped on the same index
|
|
|
|
if (source.index === destination.index) return;
|
|
|
|
|
2024-03-18 07:42:10 +00:00
|
|
|
let updatedSortOrder = getBlockById(blockIds[source.index]).sort_order;
|
2024-02-23 13:40:45 +00:00
|
|
|
|
|
|
|
// update the sort order to the lowest if dropped at the top
|
2024-03-18 07:42:10 +00:00
|
|
|
if (destination.index === 0) updatedSortOrder = getBlockById(blockIds[0]).sort_order - 1000;
|
2024-02-23 13:40:45 +00:00
|
|
|
// update the sort order to the highest if dropped at the bottom
|
2024-03-18 07:42:10 +00:00
|
|
|
else if (destination.index === blockIds.length - 1)
|
|
|
|
updatedSortOrder = getBlockById(blockIds[blockIds.length - 1]).sort_order + 1000;
|
2024-02-23 13:40:45 +00:00
|
|
|
// update the sort order to the average of the two adjacent blocks if dropped in between
|
|
|
|
else {
|
2024-03-18 07:42:10 +00:00
|
|
|
const destinationSortingOrder = getBlockById(blockIds[destination.index]).sort_order;
|
2024-02-23 13:40:45 +00:00
|
|
|
const relativeDestinationSortingOrder =
|
|
|
|
source.index < destination.index
|
2024-03-18 07:42:10 +00:00
|
|
|
? getBlockById(blockIds[destination.index + 1]).sort_order
|
|
|
|
: getBlockById(blockIds[destination.index - 1]).sort_order;
|
2024-02-23 13:40:45 +00:00
|
|
|
|
|
|
|
updatedSortOrder = (destinationSortingOrder + relativeDestinationSortingOrder) / 2;
|
|
|
|
}
|
|
|
|
|
|
|
|
// extract the element from the source index and insert it at the destination index without updating the entire array
|
2024-03-18 07:42:10 +00:00
|
|
|
const removedElement = blockIds.splice(source.index, 1)[0];
|
|
|
|
blockIds.splice(destination.index, 0, removedElement);
|
2024-02-23 13:40:45 +00:00
|
|
|
|
|
|
|
// call the block update handler with the updated sort order, new and old index
|
2024-03-18 07:42:10 +00:00
|
|
|
blockUpdateHandler(getBlockById(removedElement).data, {
|
2024-02-23 13:40:45 +00:00
|
|
|
sort_order: {
|
|
|
|
destinationIndex: destination.index,
|
|
|
|
newSortOrder: updatedSortOrder,
|
|
|
|
sourceIndex: source.index,
|
|
|
|
},
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
return (
|
|
|
|
<DragDropContext onDragEnd={handleOrderChange}>
|
|
|
|
<Droppable droppableId="gantt-sidebar">
|
|
|
|
{(droppableProvided) => (
|
|
|
|
<div className="h-full" ref={droppableProvided.innerRef} {...droppableProvided.droppableProps}>
|
|
|
|
<>
|
2024-03-18 07:42:10 +00:00
|
|
|
{blockIds ? (
|
|
|
|
blockIds.map((blockId, index) => {
|
|
|
|
const block = getBlockById(blockId);
|
|
|
|
return (
|
|
|
|
<Draggable
|
|
|
|
key={`sidebar-block-${block.id}`}
|
|
|
|
draggableId={`sidebar-block-${block.id}`}
|
|
|
|
index={index}
|
|
|
|
isDragDisabled={!enableReorder}
|
|
|
|
>
|
|
|
|
{(provided, snapshot) => (
|
|
|
|
<ModulesSidebarBlock
|
|
|
|
block={block}
|
|
|
|
enableReorder={enableReorder}
|
|
|
|
provided={provided}
|
|
|
|
snapshot={snapshot}
|
|
|
|
/>
|
|
|
|
)}
|
|
|
|
</Draggable>
|
|
|
|
);
|
|
|
|
})
|
2024-02-23 13:40:45 +00:00
|
|
|
) : (
|
|
|
|
<Loader className="space-y-3 pr-2">
|
|
|
|
<Loader.Item height="34px" />
|
|
|
|
<Loader.Item height="34px" />
|
|
|
|
<Loader.Item height="34px" />
|
|
|
|
<Loader.Item height="34px" />
|
|
|
|
</Loader>
|
|
|
|
)}
|
|
|
|
{droppableProvided.placeholder}
|
|
|
|
</>
|
|
|
|
</div>
|
|
|
|
)}
|
|
|
|
</Droppable>
|
|
|
|
</DragDropContext>
|
|
|
|
);
|
|
|
|
};
|