Skip to content
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

Migrate Create Organisation page to composable TanStack queries #769

41 changes: 10 additions & 31 deletions src/components/CreateOrgs.vue
Original file line number Diff line number Diff line change
Expand Up @@ -206,13 +206,13 @@ import { storeToRefs } from 'pinia';
import _capitalize from 'lodash/capitalize';
import _union from 'lodash/union';
import _without from 'lodash/without';
import { useQuery } from '@tanstack/vue-query';
import { useVuelidate } from '@vuelidate/core';
import { required, requiredIf } from '@vuelidate/validators';
import { useAuthStore } from '@/store/auth';
import { orgFetcher } from '@/helpers/query/orgs';
import useUserClaimsQuery from '@/composables/queries/useUserClaimsQuery';
import useDistrictsQuery from '@/composables/queries/useDistrictsQuery';
import useDistrictSchoolsQuery from '@/composables/queries/useDistrictSchoolsQuery';
import useSchoolClassesQuery from '@/composables/queries/useSchoolClassesQuery';
import useGroupsQuery from '@/composables/queries/useGroupsQuery';

const initialized = ref(false);
const isTestData = ref(false);
Expand Down Expand Up @@ -247,43 +247,26 @@ onMounted(() => {
if (roarfirekit.value.restConfig) initTable();
});

const { isLoading: isLoadingClaims, data: userClaims } = useUserClaimsQuery({
enabled: initialized,
});

const isSuperAdmin = computed(() => Boolean(userClaims.value?.claims?.super_admin));
const adminOrgs = computed(() => userClaims.value?.claims?.minimalAdminOrgs);

const claimsLoaded = computed(() => initialized.value && !isLoadingClaims.value);

const { isLoading: isLoadingDistricts, data: districts } = useDistrictsQuery({
enabled: claimsLoaded,
enabled: initialized,
});

const { data: groups } = useQuery({
queryKey: ['groups'],
queryFn: () => orgFetcher('groups', undefined, isSuperAdmin, adminOrgs, ['name', 'id', 'tags']),
keepPreviousData: true,
enabled: claimsLoaded,
staleTime: 5 * 60 * 1000, // 5 minutes
const { data: groups } = useGroupsQuery({
enabled: initialized,
});

const schoolQueryEnabled = computed(() => {
return claimsLoaded.value && state.parentDistrict !== undefined;
return initialized.value && state.parentDistrict !== undefined;
});

const selectedDistrict = computed(() => state.parentDistrict?.id);

const { isFetching: isFetchingSchools, data: schools } = useQuery({
queryKey: ['schools', selectedDistrict],
queryFn: () => orgFetcher('schools', selectedDistrict, isSuperAdmin, adminOrgs, ['name', 'id', 'tags']),
keepPreviousData: true,
const { isFetching: isFetchingSchools, data: schools } = useDistrictSchoolsQuery(selectedDistrict, {
enabled: schoolQueryEnabled,
staleTime: 5 * 60 * 1000, // 5 minutes
});

const classQueryEnabled = computed(() => {
return claimsLoaded.value && state.parentSchool !== undefined;
return initialized.value && state.parentSchool !== undefined;
});

const schoolDropdownEnabled = computed(() => {
Expand All @@ -292,12 +275,8 @@ const schoolDropdownEnabled = computed(() => {

const selectedSchool = computed(() => state.parentSchool?.id);

const { data: classes } = useQuery({
queryKey: ['classes', selectedSchool],
queryFn: () => orgFetcher('classes', selectedSchool, isSuperAdmin, adminOrgs, ['name', 'id', 'tags']),
keepPreviousData: true,
const { data: classes } = useSchoolClassesQuery(selectedSchool, {
enabled: classQueryEnabled,
staleTime: 5 * 60 * 1000, // 5 minutes
});

const rules = {
Expand Down
3 changes: 1 addition & 2 deletions src/components/ListOrgs.vue
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,6 @@ import { storeToRefs } from 'pinia';
import { useToast } from 'primevue/usetoast';
import _get from 'lodash/get';
import _head from 'lodash/head';
import _isEmpty from 'lodash/isEmpty';
import _kebabCase from 'lodash/kebabCase';
import { useAuthStore } from '@/store/auth';
import { orgFetchAll } from '@/helpers/query/orgs';
Expand Down Expand Up @@ -199,7 +198,7 @@ const activeOrgType = computed(() => {
return Object.keys(orgHeaders.value)[activeIndex.value];
});

const claimsLoaded = computed(() => !_isEmpty(userClaims?.value?.claims));
const claimsLoaded = computed(() => !!userClaims?.value?.claims);

const { isLoading: isLoadingDistricts, data: allDistricts } = useDistrictsQuery({
enabled: claimsLoaded,
Expand Down
4 changes: 2 additions & 2 deletions src/composables/queries/useDistrictSchoolsQuery.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { computed, toValue } from 'vue';
import { useQuery } from '@tanstack/vue-query';
import _isEmpty from 'lodash/isEmpty';
import { orgFetcher } from '@/helpers/query/orgs';
import useUserType from '@/composables/useUserType';
import useUserClaimsQuery from '@/composables/queries/useUserClaimsQuery';
import { DISTRICT_SCHOOLS_QUERY_KEY } from '@/constants/queryKeys';
import { FIRESTORE_COLLECTIONS } from '@/constants/firebase';
Expand All @@ -22,8 +23,7 @@ const useDistrictSchoolsQuery = (districtId, queryOptions = undefined) => {
});

// Get admin status and administation orgs.
// @TODO: Replace with useUserType composable once yeatmanlab/roar-dashboard/pull/751 is merged.
const isSuperAdmin = computed(() => Boolean(userClaims.value?.claims?.super_admin));
const { isSuperAdmin } = useUserType(userClaims);
const administrationOrgs = computed(() => userClaims.value?.claims?.minimalAdminOrgs);

// Ensure all necessary data is loaded before enabling the query.
Expand Down
39 changes: 39 additions & 0 deletions src/composables/queries/useGroupsQuery.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { computed, toValue } from 'vue';
import { useQuery } from '@tanstack/vue-query';
import _isEmpty from 'lodash/isEmpty';
import { orgFetcher } from '@/helpers/query/orgs';
import useUserType from '@/composables/useUserType';
import useUserClaimsQuery from '@/composables/queries/useUserClaimsQuery';
import { GROUPS_QUERY_KEY } from '@/constants/queryKeys';
import { FIRESTORE_COLLECTIONS } from '@/constants/firebase';

/**
* Groups query.
*
* @param {Ref<String>} districtId – A Vue ref containing the ID of the district to fetch schools for.
maximilianoertel marked this conversation as resolved.
Show resolved Hide resolved
* @param {QueryOptions|undefined} queryOptions – Optional TanStack query options.
* @returns {UseQueryResult} The TanStack query result.
*/
const useGroupsQuery = (districtId, queryOptions = undefined) => {
// Fetch the user claims.
const { data: userClaims } = useUserClaimsQuery({
enabled: queryOptions?.enabled ?? true,
});

// Get admin status and administation orgs.
const { isSuperAdmin } = useUserType(userClaims);
const administrationOrgs = computed(() => userClaims.value?.claims?.minimalAdminOrgs);

// Ensure all necessary data is loaded before enabling the query.
const claimsLoaded = computed(() => !_isEmpty(userClaims?.value?.claims));
const isQueryEnabled = computed(() => !!toValue(districtId) && claimsLoaded.value && (queryOptions?.enabled ?? true));

return useQuery({
queryKey: [GROUPS_QUERY_KEY],
queryFn: () => orgFetcher(FIRESTORE_COLLECTIONS.GROUPS, undefined, isSuperAdmin, administrationOrgs),
enabled: isQueryEnabled,
...queryOptions,
});
};

export default useGroupsQuery;
41 changes: 41 additions & 0 deletions src/composables/queries/useSchoolClassesQuery.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { computed, toValue } from 'vue';
import { useQuery } from '@tanstack/vue-query';
import _isEmpty from 'lodash/isEmpty';
import { orgFetcher } from '@/helpers/query/orgs';
import useUserType from '@/composables/useUserType';
import useUserClaimsQuery from '@/composables/queries/useUserClaimsQuery';
import { SCHOOL_CLASSES_QUERY_KEY } from '@/constants/queryKeys';
import { FIRESTORE_COLLECTIONS } from '@/constants/firebase';

/**
* School Classes query.
*
* Query designed to fetch the classes of a given school.
*
* @param {Ref<String>} schoolId – A Vue ref containing the ID of the school to fetch classes for.
* @param {QueryOptions|undefined} queryOptions – Optional TanStack query options.
* @returns {UseQueryResult} The TanStack query result.
*/
const useSchoolClassesQuery = (schoolId, queryOptions = undefined) => {
// Fetch the user claims.
const { data: userClaims } = useUserClaimsQuery({
enabled: queryOptions?.enabled ?? true,
});

// Get admin status and administation orgs.
const { isSuperAdmin } = useUserType(userClaims);
const administrationOrgs = computed(() => userClaims.value?.claims?.minimalAdminOrgs);

// Ensure all necessary data is loaded before enabling the query.
const claimsLoaded = computed(() => !_isEmpty(userClaims?.value?.claims));
const isQueryEnabled = computed(() => !!toValue(schoolId) && claimsLoaded.value && (queryOptions?.enabled ?? true));

return useQuery({
queryKey: [SCHOOL_CLASSES_QUERY_KEY, schoolId],
queryFn: () => orgFetcher(FIRESTORE_COLLECTIONS.CLASSES, schoolId, isSuperAdmin, administrationOrgs),
enabled: isQueryEnabled,
...queryOptions,
});
};

export default useSchoolClassesQuery;
2 changes: 2 additions & 0 deletions src/constants/queryKeys.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,5 @@ export const DISTRICT_SCHOOLS_QUERY_KEY = 'district-schools';
export const DSGF_ORGS_QUERY_KEY = 'dsgf-orgs';
export const ADMINITRATION_VARIANTS_QUERY_KEY = 'administration-variants';
export const ORGS_TABLE_QUERY_KEY = 'orgs-table';
export const SCHOOL_CLASSES_QUERY_KEY = 'school-classes';
export const GROUPS_QUERY_KEY = 'groups';