[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:
parent
1953d6fe3a
commit
63bc01f385
4 changed files with 40 additions and 60 deletions
|
|
@ -34,7 +34,6 @@ type Props = {
|
||||||
favorite: IFavorite;
|
favorite: IFavorite;
|
||||||
handleRemoveFromFavorites: (favorite: IFavorite) => void;
|
handleRemoveFromFavorites: (favorite: IFavorite) => void;
|
||||||
handleRemoveFromFavoritesFolder: (favoriteId: string) => void;
|
handleRemoveFromFavoritesFolder: (favoriteId: string) => void;
|
||||||
handleReorder: (favoriteId: string, sequence: number) => void;
|
|
||||||
handleDrop: (self: DropTargetRecord,source: ElementDragPayload, location: DragLocationHistory) => void;
|
handleDrop: (self: DropTargetRecord,source: ElementDragPayload, location: DragLocationHistory) => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ import { usePlatformOS } from "@/hooks/use-platform-os";
|
||||||
// plane web components
|
// plane web components
|
||||||
import { FavoriteFolder } from "./favorite-folder";
|
import { FavoriteFolder } from "./favorite-folder";
|
||||||
import { FavoriteRoot } from "./favorite-items";
|
import { FavoriteRoot } from "./favorite-items";
|
||||||
import { getDestinationStateSequence, getInstructionFromPayload, TargetData } from "./favorites.helpers";
|
import { getInstructionFromPayload, TargetData } from "./favorites.helpers";
|
||||||
import { NewFavoriteFolder } from "./new-fav-folder";
|
import { NewFavoriteFolder } from "./new-fav-folder";
|
||||||
|
|
||||||
export const SidebarFavoritesMenu = observer(() => {
|
export const SidebarFavoritesMenu = observer(() => {
|
||||||
|
|
@ -94,22 +94,20 @@ export const SidebarFavoritesMenu = observer(() => {
|
||||||
handleMoveToFolder(sourceData.id, parentId);
|
handleMoveToFolder(sourceData.id, parentId);
|
||||||
}
|
}
|
||||||
//handle remove from folder if dropped outside of the folder
|
//handle remove from folder if dropped outside of the folder
|
||||||
if (parentId && sourceData.isChild) {
|
if (parentId && parentId !== sourceData.parentId && sourceData.isChild) {
|
||||||
handleRemoveFromFavoritesFolder(sourceData.id);
|
handleRemoveFromFavoritesFolder(sourceData.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
// handle reordering at root level
|
// handle reordering at root level
|
||||||
if (droppedFavId) {
|
if (droppedFavId) {
|
||||||
if (instruction != "make-child") {
|
if (instruction != "make-child") {
|
||||||
const destinationSequence = getDestinationStateSequence(groupedFavorites, droppedFavId, instruction);
|
handleReorder(sourceData.id, droppedFavId, instruction);
|
||||||
handleReorder(sourceData.id, destinationSequence || 0);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
//handling reordering for favorites
|
//handling reordering for favorites
|
||||||
if (droppedFavId) {
|
if (droppedFavId) {
|
||||||
const destinationSequence = getDestinationStateSequence(groupedFavorites, droppedFavId, instruction);
|
handleReorder(sourceData.id, droppedFavId, instruction);
|
||||||
handleReorder(sourceData.id, destinationSequence || 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// handle removal from folder if dropped outside a folder
|
// handle removal from folder if dropped outside a folder
|
||||||
|
|
@ -147,10 +145,8 @@ export const SidebarFavoritesMenu = observer(() => {
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleReorder = useCallback(
|
const handleReorder = useCallback(
|
||||||
(favoriteId: string, sequence: number) => {
|
(favoriteId: string, droppedFavId: string, edge: string | undefined) => {
|
||||||
reOrderFavorite(workspaceSlug.toString(), favoriteId, {
|
reOrderFavorite(workspaceSlug.toString(), favoriteId, droppedFavId, edge).catch(() => {
|
||||||
sequence: sequence,
|
|
||||||
}).catch(() => {
|
|
||||||
setToast({
|
setToast({
|
||||||
type: TOAST_TYPE.ERROR,
|
type: TOAST_TYPE.ERROR,
|
||||||
title: "Error!",
|
title: "Error!",
|
||||||
|
|
@ -271,7 +267,6 @@ export const SidebarFavoritesMenu = observer(() => {
|
||||||
isLastChild={index === length - 1}
|
isLastChild={index === length - 1}
|
||||||
handleRemoveFromFavorites={handleRemoveFromFavorites}
|
handleRemoveFromFavorites={handleRemoveFromFavorites}
|
||||||
handleRemoveFromFavoritesFolder={handleRemoveFromFavoritesFolder}
|
handleRemoveFromFavoritesFolder={handleRemoveFromFavoritesFolder}
|
||||||
handleReorder={handleReorder}
|
|
||||||
handleDrop={handleDrop}
|
handleDrop={handleDrop}
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
|
|
|
||||||
|
|
@ -9,47 +9,6 @@ export type TargetData = {
|
||||||
isChild: boolean;
|
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
|
* 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
|
* @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 set from "lodash/set";
|
||||||
import { action, observable, makeObservable, runInAction, computed } from "mobx";
|
import { action, observable, makeObservable, runInAction, computed } from "mobx";
|
||||||
import { v4 as uuidv4 } from "uuid";
|
import { v4 as uuidv4 } from "uuid";
|
||||||
|
|
@ -28,7 +28,12 @@ export interface IFavoriteStore {
|
||||||
getGroupedFavorites: (workspaceSlug: string, favoriteId: string) => Promise<IFavorite[]>;
|
getGroupedFavorites: (workspaceSlug: string, favoriteId: string) => Promise<IFavorite[]>;
|
||||||
moveFavoriteToFolder: (workspaceSlug: string, favoriteId: string, data: Partial<IFavorite>) => Promise<void>;
|
moveFavoriteToFolder: (workspaceSlug: string, favoriteId: string, data: Partial<IFavorite>) => Promise<void>;
|
||||||
removeFavoriteEntity: (workspaceSlug: string, entityId: string) => 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>;
|
removeFromFavoriteFolder: (workspaceSlug: string, favoriteId: string) => Promise<void>;
|
||||||
removeFavoriteFromStore: (entity_identifier: string) => 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;
|
const initialSequence = this.favoriteMap[favoriteId].sequence;
|
||||||
try {
|
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(() => {
|
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) {
|
} catch (error) {
|
||||||
console.error("Failed to move favorite folder");
|
console.error("Failed to move favorite folder");
|
||||||
runInAction(() => {
|
runInAction(() => {
|
||||||
|
|
@ -214,8 +242,7 @@ export class FavoriteStore implements IFavoriteStore {
|
||||||
//remove parent
|
//remove parent
|
||||||
set(this.favoriteMap, [favoriteId, "parent"], null);
|
set(this.favoriteMap, [favoriteId, "parent"], null);
|
||||||
});
|
});
|
||||||
await this.favoriteService.updateFavorite(workspaceSlug, favoriteId, { parent: null});
|
await this.favoriteService.updateFavorite(workspaceSlug, favoriteId, { parent: null });
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Failed to move favorite");
|
console.error("Failed to move favorite");
|
||||||
runInAction(() => {
|
runInAction(() => {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue