mirror of
https://github.com/makeplane/plane
synced 2025-08-07 19:59:33 +00:00
[WEB-2774] fix:favorites reorder (#6179)
* fix:favorites reorder * chore: added error handling Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> --------- Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
This commit is contained in:
@@ -27,6 +27,7 @@ import { CustomMenu, Tooltip, DropIndicator, FavoriteFolderIcon, DragHandle } fr
|
||||
import { cn } from "@/helpers/common.helper";
|
||||
// hooks
|
||||
import { useAppTheme } from "@/hooks/store";
|
||||
import { useFavorite } from "@/hooks/store/use-favorite";
|
||||
import { usePlatformOS } from "@/hooks/use-platform-os";
|
||||
// constants
|
||||
import { FavoriteRoot } from "./favorite-items";
|
||||
@@ -45,7 +46,7 @@ export const FavoriteFolder: React.FC<Props> = (props) => {
|
||||
const { favorite, handleRemoveFromFavorites, isLastChild, handleDrop } = props;
|
||||
// store hooks
|
||||
const { sidebarCollapsed: isSidebarCollapsed } = useAppTheme();
|
||||
|
||||
const { getGroupedFavorites } = useFavorite();
|
||||
const { isMobile } = usePlatformOS();
|
||||
const { workspaceSlug } = useParams();
|
||||
// states
|
||||
@@ -58,6 +59,12 @@ export const FavoriteFolder: React.FC<Props> = (props) => {
|
||||
const actionSectionRef = useRef<HTMLDivElement | null>(null);
|
||||
const elementRef = useRef<HTMLDivElement | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
if (favorite.children === undefined && workspaceSlug) {
|
||||
getGroupedFavorites(workspaceSlug.toString(), favorite.id);
|
||||
}
|
||||
}, [favorite.id, favorite.children, workspaceSlug, getGroupedFavorites]);
|
||||
|
||||
useEffect(() => {
|
||||
const element = elementRef.current;
|
||||
|
||||
@@ -123,7 +130,7 @@ export const FavoriteFolder: React.FC<Props> = (props) => {
|
||||
})
|
||||
);
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [isDragging, favorite.id]);
|
||||
}, [isDragging, favorite.id, isLastChild, favorite.id]);
|
||||
|
||||
useOutsideClickDetector(actionSectionRef, () => setIsMenuActive(false));
|
||||
|
||||
|
||||
@@ -131,7 +131,7 @@ export const FavoriteRoot: FC<Props> = observer((props) => {
|
||||
})
|
||||
);
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [elementRef?.current, isDragging]);
|
||||
}, [elementRef?.current, isDragging, isLastChild, favorite.id]);
|
||||
|
||||
useOutsideClickDetector(actionSectionRef, () => setIsMenuActive(false));
|
||||
|
||||
|
||||
@@ -87,33 +87,27 @@ export const SidebarFavoritesMenu = observer(() => {
|
||||
const sourceData = source.data as TargetData;
|
||||
|
||||
if (!sourceData.id) return;
|
||||
|
||||
if (isFolder) {
|
||||
// handle move to a new parent folder if dropped on a folder
|
||||
if (parentId && parentId !== sourceData.parentId) {
|
||||
handleMoveToFolder(sourceData.id, parentId);
|
||||
handleMoveToFolder(sourceData.id, parentId); /**parent id */
|
||||
}
|
||||
//handle remove from folder if dropped outside of the folder
|
||||
if (parentId && parentId !== sourceData.parentId && sourceData.isChild) {
|
||||
handleRemoveFromFavoritesFolder(sourceData.id);
|
||||
}
|
||||
|
||||
// handle reordering at root level
|
||||
if (droppedFavId) {
|
||||
if (instruction != "make-child") {
|
||||
handleReorder(sourceData.id, droppedFavId, instruction);
|
||||
handleReorder(sourceData.id, droppedFavId, instruction); /** sequence */
|
||||
}
|
||||
}
|
||||
} else {
|
||||
//handling reordering for favorites
|
||||
if (droppedFavId) {
|
||||
handleReorder(sourceData.id, droppedFavId, instruction);
|
||||
handleReorder(sourceData.id, droppedFavId, instruction); /** sequence */
|
||||
}
|
||||
}
|
||||
|
||||
// handle removal from folder if dropped outside a folder
|
||||
if (!parentId && sourceData.isChild) {
|
||||
handleRemoveFromFavoritesFolder(sourceData.id);
|
||||
}
|
||||
/**remove if dropped outside and source is a child */
|
||||
if (!parentId && sourceData.isChild) {
|
||||
handleRemoveFromFavoritesFolder(sourceData.id); /**parent null */
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -174,23 +174,14 @@ export class FavoriteStore implements IFavoriteStore {
|
||||
* @returns Promise<void>
|
||||
*/
|
||||
moveFavoriteToFolder = async (workspaceSlug: string, favoriteId: string, data: Partial<IFavorite>) => {
|
||||
const oldParent = this.favoriteMap[favoriteId].parent;
|
||||
try {
|
||||
await this.favoriteService.updateFavorite(workspaceSlug, favoriteId, data);
|
||||
runInAction(() => {
|
||||
// add parent of the favorite
|
||||
set(this.favoriteMap, [favoriteId, "parent"], data.parent);
|
||||
});
|
||||
await this.favoriteService.updateFavorite(workspaceSlug, favoriteId, data);
|
||||
} catch (error) {
|
||||
console.error("Failed to move favorite from favorite store");
|
||||
|
||||
// revert the changes
|
||||
runInAction(() => {
|
||||
if (!data.parent) return;
|
||||
|
||||
// revert the parent
|
||||
set(this.favoriteMap, [favoriteId, "parent"], oldParent);
|
||||
});
|
||||
console.error("Failed to move favorite to folder", error);
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
@@ -201,7 +192,6 @@ export class FavoriteStore implements IFavoriteStore {
|
||||
destinationId: string,
|
||||
edge: string | undefined
|
||||
) => {
|
||||
const initialSequence = this.favoriteMap[favoriteId].sequence;
|
||||
try {
|
||||
let resultSequence = 10000;
|
||||
if (edge) {
|
||||
@@ -221,35 +211,27 @@ export class FavoriteStore implements IFavoriteStore {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
await this.favoriteService.updateFavorite(workspaceSlug, favoriteId, { sequence: resultSequence });
|
||||
|
||||
runInAction(() => {
|
||||
set(this.favoriteMap, [favoriteId, "sequence"], resultSequence);
|
||||
});
|
||||
|
||||
await this.favoriteService.updateFavorite(workspaceSlug, favoriteId, { sequence: resultSequence });
|
||||
} catch (error) {
|
||||
console.error("Failed to move favorite folder");
|
||||
runInAction(() => {
|
||||
set(this.favoriteMap, [favoriteId, "sequence"], initialSequence);
|
||||
throw error;
|
||||
});
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
removeFromFavoriteFolder = async (workspaceSlug: string, favoriteId: string) => {
|
||||
const parent = this.favoriteMap[favoriteId].parent;
|
||||
try {
|
||||
await this.favoriteService.updateFavorite(workspaceSlug, favoriteId, { parent: null });
|
||||
runInAction(() => {
|
||||
//remove parent
|
||||
set(this.favoriteMap, [favoriteId, "parent"], null);
|
||||
});
|
||||
await this.favoriteService.updateFavorite(workspaceSlug, favoriteId, { parent: null });
|
||||
} catch (error) {
|
||||
console.error("Failed to move favorite");
|
||||
runInAction(() => {
|
||||
set(this.favoriteMap, [favoriteId, "parent"], parent);
|
||||
|
||||
throw error;
|
||||
});
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
@@ -384,7 +366,7 @@ export class FavoriteStore implements IFavoriteStore {
|
||||
set(this.favoriteMap, [favorite.id], favorite);
|
||||
this.favoriteIds.push(favorite.id);
|
||||
this.favoriteIds = uniqBy(this.favoriteIds, (id) => id);
|
||||
favorite.entity_identifier && set(this.entityMap, [favorite.entity_identifier], favorite);
|
||||
if (favorite.entity_identifier) set(this.entityMap, [favorite.entity_identifier], favorite);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user