Skip to content

Commit 434444c

Browse files
authored
feat: add fe member list cache (#3607)
1 parent 455e445 commit 434444c

File tree

2 files changed

+112
-77
lines changed

2 files changed

+112
-77
lines changed

frontend/src/modules/member/pages/member-list-page.vue

Lines changed: 110 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -102,131 +102,164 @@ import LfContributorAdd from '@/modules/contributor/components/edit/contributor-
102102
import allMembers from '@/modules/member/config/saved-views/views/all-members';
103103
import LfIcon from '@/ui-kit/icon/Icon.vue';
104104
import LfButton from '@/ui-kit/button/Button.vue';
105+
import { useQuery, useQueryClient } from '@tanstack/vue-query';
106+
import { TanstackKey } from '@/shared/types/tanstack';
105107
import { memberFilters, memberSearchFilter } from '../config/filters/main';
106108
import { memberSavedViews, memberStaticViews } from '../config/saved-views/main';
107109
108110
const memberStore = useMemberStore();
109-
const { getMemberCustomAttributes, fetchMembers } = memberStore;
110-
const { filters, customAttributesFilter, savedFilterBody } = storeToRefs(memberStore);
111+
const { filters, customAttributesFilter } = storeToRefs(memberStore);
111112
112113
const lsSegmentsStore = useLfSegmentsStore();
113114
const { selectedProjectGroup } = storeToRefs(lsSegmentsStore);
114115
115-
const membersCount = ref(0);
116-
const membersToMergeCount = ref(0);
117116
const memberCreate = ref(false);
118117
119118
const { listByPlatform } = mapGetters('integration');
120119
121120
const { hasPermission } = usePermissions();
122121
123-
const memberFilter = ref<LfFilter | null>(null);
122+
const memberFilter = ref<InstanceType<typeof LfFilter> | null>(null);
124123
125124
const hasIntegrations = computed(() => !!Object.keys(listByPlatform.value || {}).length);
126125
126+
const queryClient = useQueryClient();
127+
127128
const pagination = ref({
128129
page: 1,
129130
perPage: 20,
130131
});
131132
133+
// Reactive state for query parameters
134+
const queryParams = ref({
135+
search: '',
136+
filter: {},
137+
offset: 0,
138+
limit: 20,
139+
orderBy: 'activityCount_DESC',
140+
});
141+
132142
filters.value = { ...allMembers.config };
133143
134-
const fetchMembersToMergeCount = () => {
135-
MemberService.fetchMergeSuggestions(0, 0, {
136-
countOnly: true,
137-
})
138-
.then(({ count }: any) => {
139-
membersToMergeCount.value = count;
140-
});
141-
};
144+
// Create a computed query key for members
145+
const membersQueryKey = computed(() => [
146+
TanstackKey.MEMBERS_LIST,
147+
selectedProjectGroup.value?.id,
148+
queryParams.value,
149+
]);
142150
143-
const loading = ref(true);
144-
const tableLoading = ref(true);
151+
// Query for members list with caching
152+
const {
153+
data: membersData,
154+
isLoading: membersLoading,
155+
isFetching: membersFetching,
156+
} = useQuery({
157+
queryKey: membersQueryKey,
158+
queryFn: () => MemberService.listMembers({
159+
search: queryParams.value.search,
160+
filter: queryParams.value.filter,
161+
offset: queryParams.value.offset,
162+
limit: queryParams.value.limit,
163+
orderBy: queryParams.value.orderBy,
164+
}),
165+
enabled: !!selectedProjectGroup.value?.id,
166+
});
145167
146-
const showLoading = (filter: any, body: any): boolean => {
147-
const saved: any = { ...savedFilterBody.value };
148-
delete saved.offset;
149-
delete saved.limit;
150-
delete saved.orderBy;
151-
const compare = {
152-
...body,
153-
filter,
154-
};
155-
return JSON.stringify(saved) !== JSON.stringify(compare);
156-
};
168+
// Create a computed query key for merge suggestions
169+
const mergeSuggestionsQueryKey = computed(() => [
170+
TanstackKey.MEMBER_MERGE_SUGGESTIONS_COUNT,
171+
selectedProjectGroup.value?.id,
172+
]);
173+
174+
// Query for merge suggestions count with caching
175+
const {
176+
data: mergeSuggestionsData,
177+
} = useQuery({
178+
queryKey: mergeSuggestionsQueryKey,
179+
queryFn: () => MemberService.fetchMergeSuggestions(0, 0, { countOnly: true }),
180+
enabled: !!selectedProjectGroup.value?.id,
181+
});
182+
183+
// Watch for members data changes and update the store
184+
watch(membersData, (newData) => {
185+
if (newData) {
186+
// Update the Pinia store with the new data
187+
memberStore.members = newData.rows || [];
188+
memberStore.totalMembers = newData.count || 0;
189+
memberStore.savedFilterBody = {
190+
search: queryParams.value.search,
191+
filter: queryParams.value.filter,
192+
offset: queryParams.value.offset,
193+
limit: queryParams.value.limit,
194+
orderBy: queryParams.value.orderBy,
195+
};
196+
}
197+
}, { immediate: true });
198+
199+
// Computed properties derived from queries
200+
const membersCount = computed(() => membersData.value?.count || 0);
201+
const membersToMergeCount = computed(() => mergeSuggestionsData.value?.count || 0);
202+
const loading = computed(() => membersLoading.value);
203+
const tableLoading = computed(() => membersFetching.value);
157204
158205
const fetch = ({
159206
search, filter, orderBy, body,
160207
}: FilterQuery) => {
161-
if (!loading.value) {
162-
loading.value = showLoading(filter, body);
163-
}
208+
// Update query parameters
209+
queryParams.value = {
210+
search: search || '',
211+
filter: filter || {},
212+
offset: 0,
213+
limit: pagination.value.perPage,
214+
orderBy: orderBy || 'activityCount_DESC',
215+
...body,
216+
};
164217
165218
pagination.value.page = 1;
166-
fetchMembers({
167-
body: {
168-
...body,
169-
search,
170-
filter,
171-
offset: 0,
172-
limit: pagination.value.perPage,
173-
orderBy,
174-
},
175-
}).then((result) => {
176-
if (result && result.count !== undefined) {
177-
membersCount.value = result.count;
178-
}
179-
}).finally(() => {
180-
tableLoading.value = false;
181-
loading.value = false;
182-
});
183219
};
220+
184221
const onPaginationChange = ({
185222
page, perPage,
186-
}: FilterQuery) => {
187-
tableLoading.value = true;
188-
fetchMembers({
189-
reload: true,
190-
body: {
191-
offset: (page - 1) * perPage || 0,
192-
limit: perPage || 20,
193-
},
194-
}).finally(() => {
195-
tableLoading.value = false;
196-
});
223+
}: { page: number; perPage: number }) => {
224+
// Update only pagination parameters
225+
queryParams.value = {
226+
...queryParams.value,
227+
offset: (page - 1) * perPage || 0,
228+
limit: perPage || 20,
229+
};
230+
231+
pagination.value.page = page;
232+
pagination.value.perPage = perPage;
197233
};
198234
199235
watch(
200236
selectedProjectGroup,
201237
(newProjectGroup, oldProjectGroup) => {
202238
if (newProjectGroup?.id !== oldProjectGroup?.id) {
203239
pagination.value.page = 1;
204-
loading.value = true;
205-
tableLoading.value = true;
206-
207-
fetchMembers({
208-
reload: true,
209-
body: {
210-
offset: 0,
211-
limit: pagination.value.perPage,
212-
},
213-
}).then((result) => {
214-
if (result && result.count !== undefined) {
215-
membersCount.value = result.count;
216-
}
217-
}).finally(() => {
218-
tableLoading.value = false;
219-
loading.value = false;
220-
});
221240
222-
fetchMembersToMergeCount();
241+
// Reset query params for new project group
242+
queryParams.value = {
243+
search: '',
244+
filter: {},
245+
offset: 0,
246+
limit: pagination.value.perPage,
247+
orderBy: 'activityCount_DESC',
248+
};
249+
250+
// Invalidate all related caches
251+
queryClient.invalidateQueries({
252+
queryKey: [TanstackKey.MEMBERS_LIST],
253+
});
254+
queryClient.invalidateQueries({
255+
queryKey: [TanstackKey.MEMBER_MERGE_SUGGESTIONS_COUNT],
256+
});
223257
}
224258
},
225259
);
226260
227261
onMounted(() => {
228-
fetchMembersToMergeCount();
229-
getMemberCustomAttributes();
262+
memberStore.getMemberCustomAttributes();
230263
(window as any).analytics.page('Members');
231264
});
232265
</script>

frontend/src/shared/types/tanstack.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,6 @@ export enum TanstackKey {
33
ADMIN_COLLECTIONS = 'admin-collections',
44
ADMIN_INSIGHTS_PROJECTS = 'admin-insights-projects',
55
ADMIN_SUB_PROJECTS = 'admin-sub-projects',
6+
MEMBERS_LIST= 'members-list',
7+
MEMBER_MERGE_SUGGESTIONS_COUNT = 'member-merge-suggestions-count',
68
}

0 commit comments

Comments
 (0)