From 835d833a937155aceafface1629f210d30463f29 Mon Sep 17 00:00:00 2001 From: Greg Adams <41639787+greg-adams@users.noreply.github.com> Date: Tue, 17 Sep 2024 13:25:43 -0700 Subject: [PATCH] Bug fix: My Grants showing all grants (#3513) * resolve visible console errors * resolve race condition --- packages/client/src/router/index.js | 25 +++---------------- packages/client/src/store/modules/grants.js | 24 ++++++++++++------ .../client/src/views/GrantDetailsView.spec.js | 4 +-- .../client/src/views/GrantDetailsView.vue | 2 -- 4 files changed, 22 insertions(+), 33 deletions(-) diff --git a/packages/client/src/router/index.js b/packages/client/src/router/index.js index cf666e42d..4f433355d 100644 --- a/packages/client/src/router/index.js +++ b/packages/client/src/router/index.js @@ -67,7 +67,7 @@ export const routes = [ { path: '/grants', name: 'grants', - component: () => import('../views/GrantsView.vue'), + component: () => import('@/views/GrantsView.vue'), meta: { requiresAuth: true, }, @@ -86,27 +86,10 @@ export const routes = [ path: '/my-grants', redirect: { name: 'myGrants', params: { tab: myGrantsTabs[0] } }, }, - { - path: '/my-grants/assigned', - name: 'assigned', - redirect: { name: shareTerminologyEnabled ? 'shared-with-your-team' : undefined }, - meta: { - requiresAuth: true, - }, - }, - { - path: '/my-grants/shared-with-your-team', - name: 'shared-with-your-team', - component: () => import('@/views/MyGrantsView.vue'), - meta: { - requiresAuth: true, - requiresShareTerminologyEnabled: true, - }, - }, { path: '/my-grants/:tab', name: 'myGrants', - component: () => import('../views/MyGrantsView.vue'), + component: () => import('@/views/MyGrantsView.vue'), meta: { tabNames: myGrantsTabs, requiresAuth: true, @@ -166,7 +149,7 @@ export const routes = [ { path: '/my-profile', name: 'myProfile', - component: () => import('../views/MyProfileView.vue'), + component: () => import('@/views/MyProfileView.vue'), meta: { requiresAuth: true, hideLayoutTabs: true, @@ -176,7 +159,7 @@ export const routes = [ }, { path: '/:pathMatch(.*)*', - component: () => import('../views/NotFoundView.vue'), + component: () => import('@/views/NotFoundView.vue'), name: 'notFound', meta: { requiresAuth: true, diff --git a/packages/client/src/store/modules/grants.js b/packages/client/src/store/modules/grants.js index b03153c06..5a98a84f3 100644 --- a/packages/client/src/store/modules/grants.js +++ b/packages/client/src/store/modules/grants.js @@ -21,6 +21,7 @@ function initialState() { totalUpcomingGrants: 0, totalInterestedGrants: 0, currentGrant: {}, + grantsRequestId: 0, searchFormFilters: { costSharing: null, opportunityStatuses: [], @@ -139,7 +140,7 @@ export default { return fetchApi.get(`/api/organizations/${rootGetters['users/selectedAgencyId']}/grants?${query}`) .then((data) => commit('SET_GRANTS', data)); }, - fetchGrantsNext({ commit, rootGetters }, { + fetchGrantsNext({ state, commit, rootGetters }, { currentPage, perPage, orderBy, orderDesc, }) { const pagination = { currentPage, perPage }; @@ -147,8 +148,15 @@ export default { const filters = { ...this.state.grants.searchFormFilters }; const { criteriaQuery, paginationQuery, orderingQuery } = buildGrantsNextQuery({ filters, ordering, pagination }); + // Avoid race conditions for tabs sharing grant fetching + const requestId = state.grantsRequestId + 1; + commit('SET_GRANTS_REQUEST_ID', requestId); return fetchApi.get(`/api/organizations/${rootGetters['users/selectedAgencyId']}/grants/next?${paginationQuery}&${orderingQuery}&${criteriaQuery}`) - .then((data) => commit('SET_GRANTS', data)); + .then((data) => { + if (requestId === state.grantsRequestId) { + commit('SET_GRANTS', data); + } + }); }, // Retrieves grants that the user's team (or any subteam) has interacted with (either by setting status or assigning to a user). // Sorted in descending order by the date on which the interaction occurred (recently interacted with are first). @@ -185,16 +193,15 @@ export default { agencyIds, }); }, - unmarkGrantAsInterested({ rootGetters }, { + async unmarkGrantAsInterested({ rootGetters, commit, dispatch }, { grantId, agencyIds, interestedCode, agencyId, }) { - return fetchApi.deleteRequest(`/api/organizations/${rootGetters['users/selectedAgencyId']}/grants/${grantId}/interested/${agencyId}`, { + await fetchApi.deleteRequest(`/api/organizations/${rootGetters['users/selectedAgencyId']}/grants/${grantId}/interested/${agencyId}`, { agencyIds, interestedCode, }); - }, - fetchInterestedAgencies({ rootGetters }, { grantId }) { - return fetchApi.get(`/api/organizations/${rootGetters['users/selectedAgencyId']}/grants/${grantId}/interested`); + const interestedAgencies = await dispatch('getInterestedAgencies', { grantId }); + commit('UPDATE_GRANT', { grantId, data: { interested_agencies: interestedAgencies } }); }, async markGrantAsInterested({ commit, rootGetters }, { grantId, agencyId, interestedCode }) { const interestedAgencies = await fetchApi.put(`/api/organizations/${rootGetters['users/selectedAgencyId']}/grants/${grantId}/interested/${agencyId}`, { @@ -408,5 +415,8 @@ export default { SET_TABLE_MODE(state, tableMode) { state.tableMode = tableMode; }, + SET_GRANTS_REQUEST_ID(state, id) { + state.grantsRequestId = id; + }, }, }; diff --git a/packages/client/src/views/GrantDetailsView.spec.js b/packages/client/src/views/GrantDetailsView.spec.js index e9c680720..31677c183 100644 --- a/packages/client/src/views/GrantDetailsView.spec.js +++ b/packages/client/src/views/GrantDetailsView.spec.js @@ -1,10 +1,9 @@ -import GrantDetailsView from '@/views/GrantDetailsView.vue'; - import { describe, it, expect, vi, } from 'vitest'; import { shallowMount } from '@vue/test-utils'; import { createStore } from 'vuex'; +import GrantDetailsView from '@/views/GrantDetailsView.vue'; describe('GrantDetailsView', () => { const store = createStore({ @@ -23,7 +22,6 @@ describe('GrantDetailsView', () => { 'grants/markGrantAsViewed': vi.fn(), 'grants/markGrantAsInterested': vi.fn(), 'grants/unmarkGrantAsInterested': vi.fn(), - 'grants/getInterestedAgencies': vi.fn(), 'grants/getGrantAssignedAgencies': vi.fn(), 'grants/assignAgenciesToGrant': vi.fn(), 'grants/unassignAgenciesToGrant': vi.fn(), diff --git a/packages/client/src/views/GrantDetailsView.vue b/packages/client/src/views/GrantDetailsView.vue index 9f7b2ee25..5794936ec 100644 --- a/packages/client/src/views/GrantDetailsView.vue +++ b/packages/client/src/views/GrantDetailsView.vue @@ -378,7 +378,6 @@ export default { markGrantAsViewedAction: 'grants/markGrantAsViewed', markGrantAsInterestedAction: 'grants/markGrantAsInterested', unmarkGrantAsInterestedAction: 'grants/unmarkGrantAsInterested', - getInterestedAgencies: 'grants/getInterestedAgencies', fetchAgencies: 'agencies/fetchAgencies', fetchGrantDetails: 'grants/fetchGrantDetails', }), @@ -421,7 +420,6 @@ export default { agencyIds: [agency.agency_id], interestedCode: agency.interested_code_id, }); - this.currentGrant.interested_agencies = await this.getInterestedAgencies({ grantId: this.currentGrant.grant_id }); const eventName = 'remove team status for grant'; gtagEvent(eventName); datadogRum.addAction(eventName);