Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -93,12 +93,12 @@ export const FavoriteFolder: React.FC<Props> = (props) => {
const element = elementRef.current;

if (!element) return;
const initialData = { type: "PARENT", id: favorite.id };
const initialData = { type: "PARENT", id: favorite.id, is_folder: favorite.is_folder };

return combine(
draggable({
element,
// getInitialData: () => initialData,
getInitialData: () => initialData,
onDragStart: () => setIsDragging(true),
onDrop: (data) => {
setIsDraggedOver(false);
Expand All @@ -109,7 +109,7 @@ export const FavoriteFolder: React.FC<Props> = (props) => {
const edge = extractClosestEdge(destinationData) || undefined;
const payload = {
id: favorite.id,
sequence: getDestinationStateSequence(favoriteMap, destinationData.id as string, edge),
sequence: Math.round(getDestinationStateSequence(favoriteMap, destinationData.id as string, edge) || 0),
};

handleOnDropFolder(payload);
Expand All @@ -127,7 +127,7 @@ export const FavoriteFolder: React.FC<Props> = (props) => {
onDragEnter: (args) => {
setIsDragging(true);
setIsDraggedOver(true);
setClosestEdge(extractClosestEdge(args.self.data));
args.source.data.is_folder && setClosestEdge(extractClosestEdge(args.self.data));
},
onDragLeave: () => {
setIsDragging(false);
Expand All @@ -142,7 +142,7 @@ export const FavoriteFolder: React.FC<Props> = (props) => {
setIsDraggedOver(false);
const sourceId = source?.data?.id as string | undefined;
const destinationId = self?.data?.id as string | undefined;

if (source.data.is_folder) return;
if (sourceId === destinationId) return;
if (!sourceId || !destinationId) return;
if (favoriteMap[sourceId].parent === destinationId) return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ export const FavoriteItem = observer(
{getIcon()}

{!sidebarCollapsed && (
<Link href={getLink()} className="text-sm leading-5 font-medium flex-1">
<Link href={getLink()} className="text-sm leading-5 font-medium flex-1 truncate">
{favorite.entity_data ? favorite.entity_data.name : favorite.name}
</Link>
)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import React, { useEffect, useRef, useState } from "react";
import { combine } from "@atlaskit/pragmatic-drag-and-drop/combine";
import { dropTargetForElements } from "@atlaskit/pragmatic-drag-and-drop/element/adapter";
import { orderBy } from "lodash";
import { orderBy, uniqBy } from "lodash";
import { observer } from "mobx-react";
import { useParams } from "next/navigation";
import { ChevronRight, FolderPlus } from "lucide-react";
Expand Down Expand Up @@ -131,7 +131,7 @@ export const SidebarFavoritesMenu = observer(() => {
)}
>
<span onClick={() => toggleFavoriteMenu(!isFavoriteMenuOpen)} className="flex-1 text-start">
MY FAVORITES
YOUR FAVORITES
</span>
<span className="flex gap-2 flex-shrink-0 opacity-0 pointer-events-none group-hover/workspace-button:opacity-100 group-hover/workspace-button:pointer-events-auto rounded p-0.5 ">
<FolderPlus
Expand Down Expand Up @@ -168,7 +168,7 @@ export const SidebarFavoritesMenu = observer(() => {
static
>
{createNewFolder && <NewFavoriteFolder setCreateNewFolder={setCreateNewFolder} actionType="create" />}
{orderBy(Object.values(favoriteMap), "sequence", "desc")
{uniqBy(orderBy(Object.values(favoriteMap), "sequence", "desc"), "id")
.filter((fav) => !fav.parent)
.map((fav, index) => (
<Tooltip
Expand Down
1 change: 1 addition & 0 deletions web/core/store/cycle.store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -551,6 +551,7 @@ export class CycleStore implements ICycleStore {
deleteCycle = async (workspaceSlug: string, projectId: string, cycleId: string) =>
await this.cycleService.deleteCycle(workspaceSlug, projectId, cycleId).then(() => {
runInAction(() => {
this.rootStore.favorite.removeFavoriteFromStore(cycleId);
delete this.cycleMap[cycleId];
delete this.activeCycleIdMap[cycleId];
});
Expand Down
122 changes: 99 additions & 23 deletions web/core/store/favorite.store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ export interface IFavoriteStore {
removeFavoriteEntity: (workspaceSlug: string, entityId: string) => Promise<void>;
moveFavoriteFolder: (workspaceSlug: string, favoriteId: string, data: Partial<IFavorite>) => Promise<void>;
removeFromFavoriteFolder: (workspaceSlug: string, favoriteId: string, data: Partial<IFavorite>) => Promise<void>;
removeFavoriteFromStore: (entity_identifier: string) => void;
}

export class FavoriteStore implements IFavoriteStore {
Expand Down Expand Up @@ -124,14 +125,19 @@ export class FavoriteStore implements IFavoriteStore {
* @returns Promise<IFavorite>
*/
updateFavorite = async (workspaceSlug: string, favoriteId: string, data: Partial<IFavorite>) => {
const initialState = this.favoriteMap[favoriteId];
try {
const response = await this.favoriteService.updateFavorite(workspaceSlug, favoriteId, data);
runInAction(() => {
set(this.favoriteMap, [response.id], response);
set(this.favoriteMap, [favoriteId], { ...this.favoriteMap[favoriteId], ...data });
});
const response = await this.favoriteService.updateFavorite(workspaceSlug, favoriteId, data);

return response;
} catch (error) {
console.error("Failed to update favorite from favorite store");
runInAction(() => {
set(this.favoriteMap, [favoriteId], initialState);
});
throw error;
}
};
Expand All @@ -144,15 +150,15 @@ export class FavoriteStore implements IFavoriteStore {
* @returns Promise<void>
*/
moveFavorite = async (workspaceSlug: string, favoriteId: string, data: Partial<IFavorite>) => {
const oldParent = this.favoriteMap[favoriteId].parent;
const favorite = this.favoriteMap[favoriteId];
try {
const response = await this.favoriteService.updateFavorite(workspaceSlug, favoriteId, data);
runInAction(() => {
// add the favorite to the new parent
if (!data.parent) return;
set(this.favoriteMap, [data.parent, "children"], [response, ...this.favoriteMap[data.parent].children]);
set(this.favoriteMap, [data.parent, "children"], [favorite, ...this.favoriteMap[data.parent].children]);

// remove the favorite from the old parent
const oldParent = this.favoriteMap[favoriteId].parent;
if (oldParent) {
set(
this.favoriteMap,
Expand All @@ -164,8 +170,32 @@ export class FavoriteStore implements IFavoriteStore {
// 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;
// remove the favorite from the new parent
set(
this.favoriteMap,
[data.parent, "children"],
this.favoriteMap[data.parent].children.filter((child) => child.id !== favoriteId)
);

// add the favorite back to the old parent
if (oldParent) {
set(
this.favoriteMap,
[oldParent, "children"],
[...this.favoriteMap[oldParent].children, this.favoriteMap[favoriteId]]
);
}

// revert the parent
set(this.favoriteMap, [favoriteId, "parent"], oldParent);
});
throw error;
}
};
Expand All @@ -176,24 +206,21 @@ export class FavoriteStore implements IFavoriteStore {
runInAction(() => {
set(this.favoriteMap, [favoriteId, "sequence"], data.sequence);
});
console.log(JSON.parse(JSON.stringify(this.favoriteMap)), "getDestinationStateSequence");

await this.favoriteService.updateFavorite(workspaceSlug, favoriteId, data);
} catch (error) {
console.error("Failed to move favorite folder");
runInAction(() => {
set(this.favoriteMap, [favoriteId, "sequence"], initialSequence);
console.error("Failed to move favorite folder");
throw error;
});
}
};

removeFromFavoriteFolder = async (workspaceSlug: string, favoriteId: string, data: Partial<IFavorite>) => {
const parent = this.favoriteMap[favoriteId].parent;
try {
await this.favoriteService.updateFavorite(workspaceSlug, favoriteId, data);
runInAction(() => {
const parent = this.favoriteMap[favoriteId].parent;

//remove parent
set(this.favoriteMap, [favoriteId, "parent"], null);

Expand All @@ -206,8 +233,20 @@ export class FavoriteStore implements IFavoriteStore {
);
}
});
await this.favoriteService.updateFavorite(workspaceSlug, favoriteId, data);
} catch (error) {
console.error("Failed to move favorite");
runInAction(() => {
set(this.favoriteMap, [favoriteId, "parent"], parent);
if (parent) {
set(
this.favoriteMap,
[parent, "children"],
[...this.favoriteMap[parent].children, this.favoriteMap[favoriteId]]
);
}
throw error;
});
throw error;
}
};
Expand Down Expand Up @@ -236,35 +275,43 @@ export class FavoriteStore implements IFavoriteStore {
* @returns Promise<void>
*/
deleteFavorite = async (workspaceSlug: string, favoriteId: string) => {
const parent = this.favoriteMap[favoriteId].parent;
const children = this.favoriteMap[favoriteId].children;
const entity_identifier = this.favoriteMap[favoriteId].entity_identifier;
const initialState = this.favoriteMap[favoriteId];

try {
await this.favoriteService.deleteFavorite(workspaceSlug, favoriteId);
runInAction(() => {
const parent = this.favoriteMap[favoriteId].parent;
const children = this.favoriteMap[favoriteId].children;
const entity_identifier = this.favoriteMap[favoriteId].entity_identifier;
entity_identifier &&
this.removeFavoriteEntityFromStore(entity_identifier, this.favoriteMap[favoriteId].entity_type);
if (parent) {
set(
this.favoriteMap,
[parent, "children"],
this.favoriteMap[parent].children.filter((child) => child.id !== favoriteId)
);
}
delete this.favoriteMap[favoriteId];
entity_identifier && delete this.entityMap[entity_identifier];
this.favoriteIds = this.favoriteIds.filter((id) => id !== favoriteId);
});
await this.favoriteService.deleteFavorite(workspaceSlug, favoriteId);
runInAction(() => {
entity_identifier && this.removeFavoriteEntityFromStore(entity_identifier, initialState.entity_type);
if (children) {
children.forEach((child) => {
console.log(child.entity_type);
if (!child.entity_identifier) return;
this.removeFavoriteEntityFromStore(child.entity_identifier, child.entity_type);
});
}
delete this.favoriteMap[favoriteId];
entity_identifier && delete this.entityMap[entity_identifier];

this.favoriteIds = this.favoriteIds.filter((id) => id !== favoriteId);
});
} catch (error) {
console.error("Failed to delete favorite from favorite store");
console.error("Failed to delete favorite from favorite store", error);
runInAction(() => {
if (parent) set(this.favoriteMap, [parent, "children"], [...this.favoriteMap[parent].children, initialState]);
set(this.favoriteMap, [favoriteId], initialState);
entity_identifier && set(this.entityMap, [entity_identifier], initialState);
this.favoriteIds = [favoriteId, ...this.favoriteIds];
});
throw error;
}
};
Expand All @@ -276,14 +323,42 @@ export class FavoriteStore implements IFavoriteStore {
* @returns Promise<void>
*/
removeFavoriteEntity = async (workspaceSlug: string, entityId: string) => {
const initialState = this.entityMap[entityId];
try {
const favoriteId = this.entityMap[entityId].id;
await this.deleteFavorite(workspaceSlug, favoriteId);
runInAction(() => {
delete this.entityMap[entityId];
});
await this.deleteFavorite(workspaceSlug, favoriteId);
} catch (error) {
console.error("Failed to remove favorite entity from favorite store", error);
runInAction(() => {
set(this.entityMap, [entityId], initialState);
});
throw error;
}
};

removeFavoriteFromStore = (entity_identifier: string) => {
try {
const favoriteId = this.entityMap[entity_identifier].id;
const favorite = this.favoriteMap[favoriteId];
const parent = favorite.parent;

runInAction(() => {
if (parent) {
set(
this.favoriteMap,
[parent, "children"],
this.favoriteMap[parent].children.filter((child) => child.id !== favoriteId)
);
}
delete this.favoriteMap[favoriteId];
delete this.entityMap[entity_identifier];
this.favoriteIds = this.favoriteIds.filter((id) => id !== favoriteId);
});
} catch (error) {
console.error("Failed to remove favorite entity from favorite store");
console.error("Failed to remove favorite from favorite store", error);
throw error;
}
};
Expand All @@ -294,6 +369,7 @@ export class FavoriteStore implements IFavoriteStore {
* @returns Promise<IFavorite[]>
*/
getGroupedFavorites = async (workspaceSlug: string, favoriteId: string) => {
if (!favoriteId) return [];
try {
const response = await this.favoriteService.getGroupedFavorites(workspaceSlug, favoriteId);
runInAction(() => {
Expand Down
1 change: 1 addition & 0 deletions web/core/store/module.store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -405,6 +405,7 @@ export class ModulesStore implements IModuleStore {
await this.moduleService.deleteModule(workspaceSlug, projectId, moduleId).then(() => {
runInAction(() => {
delete this.moduleMap[moduleId];
this.rootStore.favorite.removeFavoriteFromStore(moduleId);
});
});
};
Expand Down
1 change: 1 addition & 0 deletions web/core/store/project-view.store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,7 @@ export class ProjectViewStore implements IProjectViewStore {
await this.viewService.deleteView(workspaceSlug, projectId, viewId).then(() => {
runInAction(() => {
delete this.viewMap[viewId];
this.rootStore.favorite.removeFavoriteFromStore(viewId);
});
});
};
Expand Down
1 change: 1 addition & 0 deletions web/core/store/project/project.store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -401,6 +401,7 @@ export class ProjectStore implements IProjectStore {
await this.projectService.deleteProject(workspaceSlug, projectId);
runInAction(() => {
delete this.projectMap[projectId];
this.rootStore.favorite.removeFavoriteFromStore(projectId);
});
} catch (error) {
console.log("Failed to delete project from project store");
Expand Down