-
Notifications
You must be signed in to change notification settings - Fork 3.6k
[WEB-1986] fix: remove the user favourites when archived a particular entity #5388
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
2de3c38
9203e3d
cf756d9
451e990
dfc5df1
4e23845
696db60
dbd6426
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -18,6 +18,7 @@ export interface IFavoriteStore { | |||||||||||||||||||
| }; | ||||||||||||||||||||
| // computed actions | ||||||||||||||||||||
| existingFolders: string[]; | ||||||||||||||||||||
| groupedFavorites: { [favoriteId: string]: IFavorite }; | ||||||||||||||||||||
| // actions | ||||||||||||||||||||
| fetchFavorite: (workspaceSlug: string) => Promise<IFavorite[]>; | ||||||||||||||||||||
| // CRUD actions | ||||||||||||||||||||
|
|
@@ -57,6 +58,7 @@ export class FavoriteStore implements IFavoriteStore { | |||||||||||||||||||
| favoriteIds: observable, | ||||||||||||||||||||
| //computed | ||||||||||||||||||||
| existingFolders: computed, | ||||||||||||||||||||
| groupedFavorites: computed, | ||||||||||||||||||||
| // action | ||||||||||||||||||||
| fetchFavorite: action, | ||||||||||||||||||||
| // CRUD actions | ||||||||||||||||||||
|
|
@@ -80,6 +82,23 @@ export class FavoriteStore implements IFavoriteStore { | |||||||||||||||||||
| return Object.values(this.favoriteMap).map((fav) => fav.name); | ||||||||||||||||||||
| } | ||||||||||||||||||||
|
|
||||||||||||||||||||
| get groupedFavorites() { | ||||||||||||||||||||
| const data: { [favoriteId: string]: IFavorite } = JSON.parse(JSON.stringify(this.favoriteMap)); | ||||||||||||||||||||
|
|
||||||||||||||||||||
| Object.values(data).forEach((fav) => { | ||||||||||||||||||||
| if (fav.parent && data[fav.parent]) { | ||||||||||||||||||||
| if (data[fav.parent].children) { | ||||||||||||||||||||
| if (!data[fav.parent].children.some((f) => f.id === fav.id)) { | ||||||||||||||||||||
| data[fav.parent].children.push(fav); | ||||||||||||||||||||
| } | ||||||||||||||||||||
| } else { | ||||||||||||||||||||
| data[fav.parent].children = [fav]; | ||||||||||||||||||||
| } | ||||||||||||||||||||
| } | ||||||||||||||||||||
| }); | ||||||||||||||||||||
| return data; | ||||||||||||||||||||
| } | ||||||||||||||||||||
|
Comment on lines
+85
to
+100
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Optimize The computation of get groupedFavorites() {
const data: { [favoriteId: string]: IFavorite } = JSON.parse(JSON.stringify(this.favoriteMap));
const parentMap: { [parentId: string]: IFavorite[] } = {};
Object.values(data).forEach((fav) => {
if (fav.parent) {
if (!parentMap[fav.parent]) {
parentMap[fav.parent] = [];
}
parentMap[fav.parent].push(fav);
}
});
Object.keys(parentMap).forEach((parentId) => {
data[parentId].children = parentMap[parentId];
});
return data;
} |
||||||||||||||||||||
|
|
||||||||||||||||||||
| /** | ||||||||||||||||||||
| * Creates a favorite in the workspace and adds it to the store | ||||||||||||||||||||
| * @param workspaceSlug | ||||||||||||||||||||
|
|
@@ -151,22 +170,8 @@ export class FavoriteStore implements IFavoriteStore { | |||||||||||||||||||
| */ | ||||||||||||||||||||
| moveFavorite = async (workspaceSlug: string, favoriteId: string, data: Partial<IFavorite>) => { | ||||||||||||||||||||
| const oldParent = this.favoriteMap[favoriteId].parent; | ||||||||||||||||||||
| const favorite = this.favoriteMap[favoriteId]; | ||||||||||||||||||||
| try { | ||||||||||||||||||||
| runInAction(() => { | ||||||||||||||||||||
| // add the favorite to the new parent | ||||||||||||||||||||
| if (!data.parent) return; | ||||||||||||||||||||
| set(this.favoriteMap, [data.parent, "children"], [favorite, ...this.favoriteMap[data.parent].children]); | ||||||||||||||||||||
|
|
||||||||||||||||||||
| // remove the favorite from the old parent | ||||||||||||||||||||
| if (oldParent) { | ||||||||||||||||||||
| set( | ||||||||||||||||||||
| this.favoriteMap, | ||||||||||||||||||||
| [oldParent, "children"], | ||||||||||||||||||||
| this.favoriteMap[oldParent].children.filter((child) => child.id !== favoriteId) | ||||||||||||||||||||
| ); | ||||||||||||||||||||
| } | ||||||||||||||||||||
|
|
||||||||||||||||||||
| // add parent of the favorite | ||||||||||||||||||||
| set(this.favoriteMap, [favoriteId, "parent"], data.parent); | ||||||||||||||||||||
| }); | ||||||||||||||||||||
|
|
@@ -177,21 +182,6 @@ export class FavoriteStore implements IFavoriteStore { | |||||||||||||||||||
| // 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); | ||||||||||||||||||||
|
|
@@ -223,28 +213,13 @@ export class FavoriteStore implements IFavoriteStore { | |||||||||||||||||||
| runInAction(() => { | ||||||||||||||||||||
| //remove parent | ||||||||||||||||||||
| set(this.favoriteMap, [favoriteId, "parent"], null); | ||||||||||||||||||||
|
|
||||||||||||||||||||
| //remove children from parent | ||||||||||||||||||||
| if (parent) { | ||||||||||||||||||||
| set( | ||||||||||||||||||||
| this.favoriteMap, | ||||||||||||||||||||
| [parent, "children"], | ||||||||||||||||||||
| this.favoriteMap[parent].children.filter((child) => child.id !== favoriteId) | ||||||||||||||||||||
| ); | ||||||||||||||||||||
| } | ||||||||||||||||||||
| }); | ||||||||||||||||||||
| 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; | ||||||||||||||||||||
|
|
@@ -254,15 +229,26 @@ export class FavoriteStore implements IFavoriteStore { | |||||||||||||||||||
| removeFavoriteEntityFromStore = (entity_identifier: string, entity_type: string) => { | ||||||||||||||||||||
| switch (entity_type) { | ||||||||||||||||||||
| case "view": | ||||||||||||||||||||
| return (this.viewStore.viewMap[entity_identifier].is_favorite = false); | ||||||||||||||||||||
| return ( | ||||||||||||||||||||
| this.viewStore.viewMap[entity_identifier] && (this.viewStore.viewMap[entity_identifier].is_favorite = false) | ||||||||||||||||||||
| ); | ||||||||||||||||||||
| case "module": | ||||||||||||||||||||
| return (this.moduleStore.moduleMap[entity_identifier].is_favorite = false); | ||||||||||||||||||||
| return ( | ||||||||||||||||||||
| this.moduleStore.moduleMap[entity_identifier] && | ||||||||||||||||||||
| (this.moduleStore.moduleMap[entity_identifier].is_favorite = false) | ||||||||||||||||||||
| ); | ||||||||||||||||||||
| case "page": | ||||||||||||||||||||
| return (this.pageStore.data[entity_identifier].is_favorite = false); | ||||||||||||||||||||
| return this.pageStore.data[entity_identifier] && (this.pageStore.data[entity_identifier].is_favorite = false); | ||||||||||||||||||||
| case "cycle": | ||||||||||||||||||||
| return (this.cycleStore.cycleMap[entity_identifier].is_favorite = false); | ||||||||||||||||||||
| return ( | ||||||||||||||||||||
| this.cycleStore.cycleMap[entity_identifier] && | ||||||||||||||||||||
| (this.cycleStore.cycleMap[entity_identifier].is_favorite = false) | ||||||||||||||||||||
| ); | ||||||||||||||||||||
| case "project": | ||||||||||||||||||||
| return (this.projectStore.projectMap[entity_identifier].is_favorite = false); | ||||||||||||||||||||
| return ( | ||||||||||||||||||||
| this.projectStore.projectMap[entity_identifier] && | ||||||||||||||||||||
| (this.projectStore.projectMap[entity_identifier].is_favorite = false) | ||||||||||||||||||||
| ); | ||||||||||||||||||||
|
Comment on lines
+233
to
+251
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Avoid assignment in expressions. Assignments within expressions can be confusing and error-prone. Refactor to separate the assignment from the return statement for clarity. - return (
- this.viewStore.viewMap[entity_identifier] && (this.viewStore.viewMap[entity_identifier].is_favorite = false)
- );
+ if (this.viewStore.viewMap[entity_identifier]) {
+ this.viewStore.viewMap[entity_identifier].is_favorite = false;
+ }
+ return;Apply similar changes to other cases in this switch statement.
ToolsBiome
|
||||||||||||||||||||
| default: | ||||||||||||||||||||
| return; | ||||||||||||||||||||
| } | ||||||||||||||||||||
|
|
@@ -276,29 +262,21 @@ export class FavoriteStore implements IFavoriteStore { | |||||||||||||||||||
| */ | ||||||||||||||||||||
| deleteFavorite = async (workspaceSlug: string, favoriteId: string) => { | ||||||||||||||||||||
| const parent = this.favoriteMap[favoriteId].parent; | ||||||||||||||||||||
| const children = this.favoriteMap[favoriteId].children; | ||||||||||||||||||||
| const children = this.groupedFavorites[favoriteId].children; | ||||||||||||||||||||
| const entity_identifier = this.favoriteMap[favoriteId].entity_identifier; | ||||||||||||||||||||
| const initialState = this.favoriteMap[favoriteId]; | ||||||||||||||||||||
|
|
||||||||||||||||||||
| try { | ||||||||||||||||||||
| await this.favoriteService.deleteFavorite(workspaceSlug, favoriteId); | ||||||||||||||||||||
| runInAction(() => { | ||||||||||||||||||||
| 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); | ||||||||||||||||||||
| }); | ||||||||||||||||||||
|
|
@@ -326,9 +304,6 @@ export class FavoriteStore implements IFavoriteStore { | |||||||||||||||||||
| const initialState = this.entityMap[entityId]; | ||||||||||||||||||||
| try { | ||||||||||||||||||||
| const favoriteId = this.entityMap[entityId].id; | ||||||||||||||||||||
| runInAction(() => { | ||||||||||||||||||||
| delete this.entityMap[entityId]; | ||||||||||||||||||||
| }); | ||||||||||||||||||||
| await this.deleteFavorite(workspaceSlug, favoriteId); | ||||||||||||||||||||
| } catch (error) { | ||||||||||||||||||||
| console.error("Failed to remove favorite entity from favorite store", error); | ||||||||||||||||||||
|
|
@@ -341,19 +316,22 @@ export class FavoriteStore implements IFavoriteStore { | |||||||||||||||||||
|
|
||||||||||||||||||||
| removeFavoriteFromStore = (entity_identifier: string) => { | ||||||||||||||||||||
| try { | ||||||||||||||||||||
| const favoriteId = this.entityMap[entity_identifier].id; | ||||||||||||||||||||
| const favorite = this.favoriteMap[favoriteId]; | ||||||||||||||||||||
| const parent = favorite.parent; | ||||||||||||||||||||
|
|
||||||||||||||||||||
| const favoriteId = this.entityMap[entity_identifier]?.id; | ||||||||||||||||||||
| const oldData = this.favoriteMap[favoriteId]; | ||||||||||||||||||||
| const projectData = Object.values(this.favoriteMap).filter( | ||||||||||||||||||||
| (fav) => fav.project_id === entity_identifier && fav.entity_type !== "project" | ||||||||||||||||||||
| ); | ||||||||||||||||||||
| runInAction(() => { | ||||||||||||||||||||
| if (parent) { | ||||||||||||||||||||
| set( | ||||||||||||||||||||
| this.favoriteMap, | ||||||||||||||||||||
| [parent, "children"], | ||||||||||||||||||||
| this.favoriteMap[parent].children.filter((child) => child.id !== favoriteId) | ||||||||||||||||||||
| ); | ||||||||||||||||||||
| } | ||||||||||||||||||||
| projectData && | ||||||||||||||||||||
| projectData.forEach(async (fav) => { | ||||||||||||||||||||
| this.removeFavoriteFromStore(fav.entity_identifier!); | ||||||||||||||||||||
| this.removeFavoriteEntityFromStore(fav.entity_identifier!, fav.entity_type); | ||||||||||||||||||||
| }); | ||||||||||||||||||||
|
Comment on lines
+325
to
+329
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Use optional chaining for safety. The code can be made safer by using optional chaining to avoid potential runtime errors if - projectData &&
- projectData.forEach(async (fav) => {
+ projectData?.forEach(async (fav) => {Committable suggestion
Suggested change
ToolsBiome
|
||||||||||||||||||||
|
|
||||||||||||||||||||
| if (!favoriteId) return; | ||||||||||||||||||||
| delete this.favoriteMap[favoriteId]; | ||||||||||||||||||||
| this.removeFavoriteEntityFromStore(entity_identifier!, oldData.entity_type); | ||||||||||||||||||||
|
|
||||||||||||||||||||
| delete this.entityMap[entity_identifier]; | ||||||||||||||||||||
| this.favoriteIds = this.favoriteIds.filter((id) => id !== favoriteId); | ||||||||||||||||||||
| }); | ||||||||||||||||||||
|
|
@@ -373,8 +351,6 @@ export class FavoriteStore implements IFavoriteStore { | |||||||||||||||||||
| try { | ||||||||||||||||||||
| const response = await this.favoriteService.getGroupedFavorites(workspaceSlug, favoriteId); | ||||||||||||||||||||
| runInAction(() => { | ||||||||||||||||||||
| // add children to the favorite | ||||||||||||||||||||
| set(this.favoriteMap, [favoriteId, "children"], response); | ||||||||||||||||||||
| // add the favorites to the map | ||||||||||||||||||||
| response.forEach((favorite) => { | ||||||||||||||||||||
| set(this.favoriteMap, [favorite.id], favorite); | ||||||||||||||||||||
|
|
||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ensure
groupedFavoritesaccess is safe.The code assumes that
groupedFavorites[sourceId]exists. Consider adding a check to ensuresourceIdis valid andgroupedFavoritescontains it to prevent runtime errors.Committable suggestion