From 81662df475e32d9c1bbd434c7f3d720bf9a7ec7d Mon Sep 17 00:00:00 2001 From: David Date: Wed, 13 May 2026 23:53:46 +0700 Subject: [PATCH 1/2] fix(stickies): restore full state on failed delete - Add trailing slash to getSticky and deleteSticky API paths, fixing unnecessary 301 redirect - Snapshot workspaceStickies, activeStickyId, and recentStickyId before optimistic delete so all three are restored if the API call fails - Re-throw the error so callers show an error toast instead of success Fixes #9050 --- apps/web/core/services/sticky.service.ts | 4 ++-- apps/web/core/store/sticky/sticky.store.ts | 12 +++++++++--- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/apps/web/core/services/sticky.service.ts b/apps/web/core/services/sticky.service.ts index ff4491e8ed6..f231130a0b8 100644 --- a/apps/web/core/services/sticky.service.ts +++ b/apps/web/core/services/sticky.service.ts @@ -43,7 +43,7 @@ export class StickyService extends APIService { } async getSticky(workspaceSlug: string, id: string) { - return this.get(`/api/workspaces/${workspaceSlug}/stickies/${id}`) + return this.get(`/api/workspaces/${workspaceSlug}/stickies/${id}/`) .then((res) => res?.data) .catch((err) => { throw err?.response?.data; @@ -59,7 +59,7 @@ export class StickyService extends APIService { } async deleteSticky(workspaceSlug: string, id: string) { - return await this.delete(`/api/workspaces/${workspaceSlug}/stickies/${id}`) + return await this.delete(`/api/workspaces/${workspaceSlug}/stickies/${id}/`) .then((res) => res?.data) .catch((err) => { throw err?.response?.data; diff --git a/apps/web/core/store/sticky/sticky.store.ts b/apps/web/core/store/sticky/sticky.store.ts index 09833214505..c02d4ef469f 100644 --- a/apps/web/core/store/sticky/sticky.store.ts +++ b/apps/web/core/store/sticky/sticky.store.ts @@ -205,13 +205,16 @@ export class StickyStore implements IStickyStore { } catch (error) { console.error("Error in updating sticky:", error); this.stickies[id] = sticky; - throw new Error(); + throw error; } }; deleteSticky = async (workspaceSlug: string, id: string) => { const sticky = this.stickies[id]; if (!sticky) return; + const previousWorkspaceStickies = [...(this.workspaceStickies[workspaceSlug] || [])]; + const previousActiveStickyId = this.activeStickyId; + const previousRecentStickyId = this.recentStickyId; try { this.workspaceStickies[workspaceSlug] = this.workspaceStickies[workspaceSlug].filter( (stickyId) => stickyId !== id @@ -220,9 +223,12 @@ export class StickyStore implements IStickyStore { delete this.stickies[id]; this.recentStickyId = this.workspaceStickies[workspaceSlug][0]; await this.stickyService.deleteSticky(workspaceSlug, id); - } catch (e) { - console.log(e); + } catch (error) { this.stickies[id] = sticky; + this.workspaceStickies[workspaceSlug] = previousWorkspaceStickies; + this.activeStickyId = previousActiveStickyId; + this.recentStickyId = previousRecentStickyId; + throw error; } }; From 082dd656c396d889be381f5d4dc5be842c536626 Mon Sep 17 00:00:00 2001 From: David Date: Thu, 14 May 2026 13:50:12 +0700 Subject: [PATCH 2/2] fix(stickies): add guard --- apps/web/core/store/sticky/sticky.store.ts | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/apps/web/core/store/sticky/sticky.store.ts b/apps/web/core/store/sticky/sticky.store.ts index c02d4ef469f..0b873053b03 100644 --- a/apps/web/core/store/sticky/sticky.store.ts +++ b/apps/web/core/store/sticky/sticky.store.ts @@ -212,13 +212,12 @@ export class StickyStore implements IStickyStore { deleteSticky = async (workspaceSlug: string, id: string) => { const sticky = this.stickies[id]; if (!sticky) return; - const previousWorkspaceStickies = [...(this.workspaceStickies[workspaceSlug] || [])]; + const currentWorkspaceStickies = this.workspaceStickies[workspaceSlug] || []; + const previousWorkspaceStickies = [...currentWorkspaceStickies]; const previousActiveStickyId = this.activeStickyId; const previousRecentStickyId = this.recentStickyId; try { - this.workspaceStickies[workspaceSlug] = this.workspaceStickies[workspaceSlug].filter( - (stickyId) => stickyId !== id - ); + this.workspaceStickies[workspaceSlug] = currentWorkspaceStickies.filter((stickyId) => stickyId !== id); if (this.activeStickyId === id) this.activeStickyId = undefined; delete this.stickies[id]; this.recentStickyId = this.workspaceStickies[workspaceSlug][0];