mirror of
https://github.com/makeplane/plane.git
synced 2025-12-25 16:19:43 +01:00
[WEB-2774]fix:reordering favorites and favorite folders (#6119)
* fixed re order for favorites * fixed lint errors * added reorder * fixed reorder inside folder * fixed lint issues * memoized reorder * removed unnecessary comments * seprated duplicate logic to a common file * removed code comments * fixed favorite remove while reorder inside folder * fixed folder remove while reorder inside folder * fixed-reorder issue * added last child to drop handled * fixed orderby function * removed unncessasary comments
This commit is contained in:
@@ -34,7 +34,6 @@ type Props = {
|
||||
favorite: IFavorite;
|
||||
handleRemoveFromFavorites: (favorite: IFavorite) => void;
|
||||
handleRemoveFromFavoritesFolder: (favoriteId: string) => void;
|
||||
handleReorder: (favoriteId: string, sequence: number) => void;
|
||||
handleDrop: (self: DropTargetRecord,source: ElementDragPayload, location: DragLocationHistory) => void;
|
||||
};
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ import { usePlatformOS } from "@/hooks/use-platform-os";
|
||||
// plane web components
|
||||
import { FavoriteFolder } from "./favorite-folder";
|
||||
import { FavoriteRoot } from "./favorite-items";
|
||||
import { getDestinationStateSequence, getInstructionFromPayload, TargetData } from "./favorites.helpers";
|
||||
import { getInstructionFromPayload, TargetData } from "./favorites.helpers";
|
||||
import { NewFavoriteFolder } from "./new-fav-folder";
|
||||
|
||||
export const SidebarFavoritesMenu = observer(() => {
|
||||
@@ -94,22 +94,20 @@ export const SidebarFavoritesMenu = observer(() => {
|
||||
handleMoveToFolder(sourceData.id, parentId);
|
||||
}
|
||||
//handle remove from folder if dropped outside of the folder
|
||||
if (parentId && sourceData.isChild) {
|
||||
if (parentId && parentId !== sourceData.parentId && sourceData.isChild) {
|
||||
handleRemoveFromFavoritesFolder(sourceData.id);
|
||||
}
|
||||
|
||||
// handle reordering at root level
|
||||
if (droppedFavId) {
|
||||
if (instruction != "make-child") {
|
||||
const destinationSequence = getDestinationStateSequence(groupedFavorites, droppedFavId, instruction);
|
||||
handleReorder(sourceData.id, destinationSequence || 0);
|
||||
handleReorder(sourceData.id, droppedFavId, instruction);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
//handling reordering for favorites
|
||||
if (droppedFavId) {
|
||||
const destinationSequence = getDestinationStateSequence(groupedFavorites, droppedFavId, instruction);
|
||||
handleReorder(sourceData.id, destinationSequence || 0);
|
||||
handleReorder(sourceData.id, droppedFavId, instruction);
|
||||
}
|
||||
|
||||
// handle removal from folder if dropped outside a folder
|
||||
@@ -147,10 +145,8 @@ export const SidebarFavoritesMenu = observer(() => {
|
||||
};
|
||||
|
||||
const handleReorder = useCallback(
|
||||
(favoriteId: string, sequence: number) => {
|
||||
reOrderFavorite(workspaceSlug.toString(), favoriteId, {
|
||||
sequence: sequence,
|
||||
}).catch(() => {
|
||||
(favoriteId: string, droppedFavId: string, edge: string | undefined) => {
|
||||
reOrderFavorite(workspaceSlug.toString(), favoriteId, droppedFavId, edge).catch(() => {
|
||||
setToast({
|
||||
type: TOAST_TYPE.ERROR,
|
||||
title: "Error!",
|
||||
@@ -271,7 +267,6 @@ export const SidebarFavoritesMenu = observer(() => {
|
||||
isLastChild={index === length - 1}
|
||||
handleRemoveFromFavorites={handleRemoveFromFavorites}
|
||||
handleRemoveFromFavoritesFolder={handleRemoveFromFavoritesFolder}
|
||||
handleReorder={handleReorder}
|
||||
handleDrop={handleDrop}
|
||||
/>
|
||||
) : (
|
||||
|
||||
@@ -9,47 +9,6 @@ export type TargetData = {
|
||||
isChild: boolean;
|
||||
}
|
||||
|
||||
export const getDestinationStateSequence = (
|
||||
favoriteMap: Record<string, IFavorite>,
|
||||
destinationId: string,
|
||||
edge: string | undefined
|
||||
) => {
|
||||
const defaultSequence = 65535;
|
||||
if (!edge) return defaultSequence;
|
||||
|
||||
|
||||
const favoriteIds = orderBy(Object.values(favoriteMap), "sequence", "desc")
|
||||
.filter((fav: IFavorite) => !fav.parent)
|
||||
.map((fav: IFavorite) => fav.id);
|
||||
const destinationStateIndex = favoriteIds.findIndex((id) => id === destinationId);
|
||||
const destinationStateSequence = favoriteMap[destinationId]?.sequence || undefined;
|
||||
|
||||
if (!destinationStateSequence) return defaultSequence;
|
||||
|
||||
|
||||
let resultSequence = defaultSequence;
|
||||
if (edge === "reorder-above") {
|
||||
const prevStateSequence = favoriteMap[favoriteIds[destinationStateIndex - 1]]?.sequence || undefined;
|
||||
|
||||
if (prevStateSequence === undefined) {
|
||||
resultSequence = destinationStateSequence + defaultSequence;
|
||||
}else {
|
||||
resultSequence = (destinationStateSequence + prevStateSequence) / 2
|
||||
}
|
||||
} else if (edge === "reorder-below") {
|
||||
const nextStateSequence = favoriteMap[favoriteIds[destinationStateIndex + 1]]?.sequence || undefined;
|
||||
|
||||
if (nextStateSequence === undefined) {
|
||||
resultSequence = destinationStateSequence - defaultSequence;
|
||||
} else {
|
||||
resultSequence = (destinationStateSequence + nextStateSequence) / 2;
|
||||
}
|
||||
}
|
||||
resultSequence = Math.round(resultSequence)
|
||||
|
||||
return resultSequence;
|
||||
};
|
||||
|
||||
/**
|
||||
* extracts the Payload and translates the instruction for the current dropTarget based on drag and drop payload
|
||||
* @param dropTarget dropTarget for which the instruction is required
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { uniqBy } from "lodash";
|
||||
import { orderBy, result, uniqBy } from "lodash";
|
||||
import set from "lodash/set";
|
||||
import { action, observable, makeObservable, runInAction, computed } from "mobx";
|
||||
import { v4 as uuidv4 } from "uuid";
|
||||
@@ -28,7 +28,12 @@ export interface IFavoriteStore {
|
||||
getGroupedFavorites: (workspaceSlug: string, favoriteId: string) => Promise<IFavorite[]>;
|
||||
moveFavoriteToFolder: (workspaceSlug: string, favoriteId: string, data: Partial<IFavorite>) => Promise<void>;
|
||||
removeFavoriteEntity: (workspaceSlug: string, entityId: string) => Promise<void>;
|
||||
reOrderFavorite: (workspaceSlug: string, favoriteId: string, data: Partial<IFavorite>) => Promise<void>;
|
||||
reOrderFavorite: (
|
||||
workspaceSlug: string,
|
||||
favoriteId: string,
|
||||
destinationId: string,
|
||||
edge: string | undefined
|
||||
) => Promise<void>;
|
||||
removeFromFavoriteFolder: (workspaceSlug: string, favoriteId: string) => Promise<void>;
|
||||
removeFavoriteFromStore: (entity_identifier: string) => void;
|
||||
}
|
||||
@@ -190,14 +195,37 @@ export class FavoriteStore implements IFavoriteStore {
|
||||
}
|
||||
};
|
||||
|
||||
reOrderFavorite = async (workspaceSlug: string, favoriteId: string, data: Partial<IFavorite>) => {
|
||||
reOrderFavorite = async (
|
||||
workspaceSlug: string,
|
||||
favoriteId: string,
|
||||
destinationId: string,
|
||||
edge: string | undefined
|
||||
) => {
|
||||
const initialSequence = this.favoriteMap[favoriteId].sequence;
|
||||
try {
|
||||
let resultSequence = 10000;
|
||||
if (edge) {
|
||||
const sortedIds = orderBy(Object.values(this.favoriteMap), "sequence", "desc").map((fav: IFavorite) => fav.id);
|
||||
const destinationSequence = this.favoriteMap[destinationId]?.sequence || undefined;
|
||||
if (destinationSequence) {
|
||||
const destinationIndex = sortedIds.findIndex((id) => id === destinationId);
|
||||
if (edge === "reorder-above") {
|
||||
const prevSequence = this.favoriteMap[sortedIds[destinationIndex - 1]]?.sequence || undefined;
|
||||
if (prevSequence) {
|
||||
resultSequence = (destinationSequence + prevSequence) / 2;
|
||||
} else {
|
||||
resultSequence = destinationSequence + resultSequence;
|
||||
}
|
||||
} else {
|
||||
resultSequence = destinationSequence - resultSequence;
|
||||
}
|
||||
}
|
||||
}
|
||||
runInAction(() => {
|
||||
set(this.favoriteMap, [favoriteId, "sequence"], data.sequence);
|
||||
set(this.favoriteMap, [favoriteId, "sequence"], resultSequence);
|
||||
});
|
||||
|
||||
await this.favoriteService.updateFavorite(workspaceSlug, favoriteId, data);
|
||||
await this.favoriteService.updateFavorite(workspaceSlug, favoriteId, { sequence: resultSequence });
|
||||
} catch (error) {
|
||||
console.error("Failed to move favorite folder");
|
||||
runInAction(() => {
|
||||
@@ -214,8 +242,7 @@ export class FavoriteStore implements IFavoriteStore {
|
||||
//remove parent
|
||||
set(this.favoriteMap, [favoriteId, "parent"], null);
|
||||
});
|
||||
await this.favoriteService.updateFavorite(workspaceSlug, favoriteId, { parent: null});
|
||||
|
||||
await this.favoriteService.updateFavorite(workspaceSlug, favoriteId, { parent: null });
|
||||
} catch (error) {
|
||||
console.error("Failed to move favorite");
|
||||
runInAction(() => {
|
||||
|
||||
Reference in New Issue
Block a user