From 77a561b58153b4a177df442a1bc7cebe7f5d2301 Mon Sep 17 00:00:00 2001 From: Andrew Bastin Date: Wed, 7 Sep 2022 00:41:08 +0530 Subject: [PATCH] fix: multiple request created on teams (closes #2455) --- .../components/collections/index.vue | 3 ++ .../helpers/backend/GQLClient.ts | 2 ++ .../helpers/teams/TeamCollectionAdapter.ts | 36 +++++++++++++++++++ 3 files changed, 41 insertions(+) diff --git a/packages/hoppscotch-app/components/collections/index.vue b/packages/hoppscotch-app/components/collections/index.vue index 6b49dba8..b71e7d3b 100644 --- a/packages/hoppscotch-app/components/collections/index.vue +++ b/packages/hoppscotch-app/components/collections/index.vue @@ -376,6 +376,9 @@ export default defineComponent({ if (!newValue) this.updateCollectionType("my-collections") }, }, + beforeDestroy() { + this.teamCollectionAdapter.unsubscribeSubscriptions() + }, mounted() { this.subscribeTo(this.teamCollectionAdapter.collections$, (colls) => { this.teamCollectionsNew = cloneDeep(colls) diff --git a/packages/hoppscotch-app/helpers/backend/GQLClient.ts b/packages/hoppscotch-app/helpers/backend/GQLClient.ts index 2bd2c0e6..e3c32837 100644 --- a/packages/hoppscotch-app/helpers/backend/GQLClient.ts +++ b/packages/hoppscotch-app/helpers/backend/GQLClient.ts @@ -208,6 +208,8 @@ export const runGQLQuery = ( }) } +// TODO: The subscription system seems to be firing multiple updates for certain subscriptions. +// Make sure to handle cases if the subscription fires with the same update multiple times export const runGQLSubscription = < DocType, DocVarType, diff --git a/packages/hoppscotch-app/helpers/teams/TeamCollectionAdapter.ts b/packages/hoppscotch-app/helpers/teams/TeamCollectionAdapter.ts index 65abb130..a4b2a338 100644 --- a/packages/hoppscotch-app/helpers/teams/TeamCollectionAdapter.ts +++ b/packages/hoppscotch-app/helpers/teams/TeamCollectionAdapter.ts @@ -181,12 +181,21 @@ function findCollWithReqIDInTree( return null } +type EntityType = "request" | "collection" +type EntityID = `${EntityType}-${string}` + export default class NewTeamCollectionAdapter { collections$: BehaviorSubject // Stream to the list of collections/folders that are being loaded in loadingCollections$: BehaviorSubject + /** + * Stores the entity (collection/request/folder) ids of all the loaded entities. + * Used for preventing duplication of data which definitely is not possible (duplication due to network problems etc.) + */ + private entityIDs: Set + private teamCollectionAdded$: Subscription | null private teamCollectionUpdated$: Subscription | null private teamCollectionRemoved$: Subscription | null @@ -205,6 +214,8 @@ export default class NewTeamCollectionAdapter { this.collections$ = new BehaviorSubject([]) this.loadingCollections$ = new BehaviorSubject([]) + this.entityIDs = new Set() + this.teamCollectionAdded$ = null this.teamCollectionUpdated$ = null this.teamCollectionRemoved$ = null @@ -225,6 +236,8 @@ export default class NewTeamCollectionAdapter { changeTeamID(newTeamID: string | null) { this.teamID = newTeamID this.collections$.next([]) + this.entityIDs.clear() + this.loadingCollections$.next([]) this.unsubscribeSubscriptions() @@ -283,6 +296,9 @@ export default class NewTeamCollectionAdapter { } } + // Add to entity ids set + this.entityIDs.add(`collection-${collection.id}`) + this.collections$.next(tree) } @@ -335,6 +351,11 @@ export default class NewTeamCollectionAdapter { this.loadingCollections$.getValue().filter((x) => x !== "root") ) + // Add all the collections to the entity ids list + totalCollections.forEach((coll) => + this.entityIDs.add(`collection-${coll.id}`) + ) + this.collections$.next(totalCollections) } @@ -363,6 +384,8 @@ export default class NewTeamCollectionAdapter { deleteCollInTree(tree, collectionID) + this.entityIDs.delete(`collection-${collectionID}`) + this.collections$.next(tree) } @@ -372,6 +395,9 @@ export default class NewTeamCollectionAdapter { * @param {TeamRequest} request - The request to add to the tree */ private addRequest(request: TeamRequest) { + // Check if we have it already in the entity tree, if so, we don't need it again + if (this.entityIDs.has(`request-${request.id}`)) return + const tree = this.collections$.value // Check if we have the collection (if not, then not loaded?) @@ -384,6 +410,9 @@ export default class NewTeamCollectionAdapter { // Collection is expanded hence append request coll.requests.push(request) + // Update the Entity IDs list + this.entityIDs.add(`request-${request.id}`) + this.collections$.next(tree) } @@ -421,6 +450,9 @@ export default class NewTeamCollectionAdapter { // Remove the collection remove(coll.requests, (req) => req.id === requestID) + // Remove from entityIDs set + this.entityIDs.delete(`request-${requestID}`) + // Publish new tree this.collections$.next(tree) } @@ -644,6 +676,10 @@ export default class NewTeamCollectionAdapter { collection.children = collections collection.requests = requests + // Add to the entity ids set + collections.forEach((coll) => this.entityIDs.add(`collection-${coll.id}`)) + requests.forEach((req) => this.entityIDs.add(`request-${req.id}`)) + this.loadingCollections$.next( this.loadingCollections$.getValue().filter((x) => x !== collectionID) )