refactor: removing useAsyncData for tanstack query (#5262)

* refactor: most places with useAsyncData replaced with tanstack query

* refactor report list and report view

* refactor organization page to use tanstack query

* fix types

* refactor collection page and include proper loading state

* fix followed projects proper loading state

* fix 404 handling

* fix organization loading and 404 states

* pnpm prepr

* refactor: remove useAsyncData on newsletter button

* refactor: remove useAsyncData on auth globals fetch

* refactor: settings/billing/index.vue to useQuery instead of useAsyncData

* refactor: user page to remove useAsyncData

* pnpm prepr

* fix reports pages

* fix notifications page

* fix billing page cannot read properties of null and prop warnings

* fix refresh causing 404 by removing useBaseFetch and use api-client

* fix stale data after removing organization from project

* pnpm prepr

* fix news erroring in build

* fix: project page loads header only after content

* fix: user page tanstack problems (start on migrating away from useBaseFetch)

* fix: start swapping useBaseFetch usages to api-client

* Revert "fix: start swapping useBaseFetch usages to api-client"

This reverts commit 3df3fab11d535159132b1288dd7cacc38282b553.

* fix: remove debug logging

* fix: lint

---------

Co-authored-by: Calum H. <calum@modrinth.com>
Co-authored-by: Calum H. (IMB11) <contact@cal.engineer>
This commit is contained in:
Truman Gao
2026-03-16 12:10:29 -07:00
committed by GitHub
parent d0c7575a23
commit 681ae5d1d8
53 changed files with 1686 additions and 1079 deletions

View File

@@ -95,6 +95,10 @@ import {
StyledInput,
} from '@modrinth/ui'
import type { AffiliateLink, User } from '@modrinth/utils'
import { useQuery } from '@tanstack/vue-query'
import { computed, ref } from 'vue'
import { useBaseFetch } from '~/composables/fetch.js'
const { handleError } = injectNotificationManager()
@@ -109,11 +113,12 @@ const revokeModal = useTemplateRef<typeof ConfirmModal>('revokeModal')
const {
data: affiliateCodes,
error,
refresh,
} = await useAsyncData(
'AffiliateLinks',
() => useBaseFetch('affiliate', { method: 'GET', internal: true }) as Promise<AffiliateLink[]>,
)
refetch,
} = useQuery({
queryKey: ['affiliate'],
queryFn: () =>
useBaseFetch('affiliate', { method: 'GET', internal: true }) as Promise<AffiliateLink[]>,
})
const filterQuery = ref('')
const creatingLink = ref(false)
@@ -130,16 +135,13 @@ const userIds = computed(() => {
return Array.from(ids)
})
const { data: users } = await useAsyncData(
'admin-affiliates-bulk-users',
() => {
const { data: users } = useQuery({
queryKey: computed(() => ['users-bulk', userIds.value]),
queryFn: () => {
if (userIds.value.length === 0) return Promise.resolve([])
return useBaseFetch(`users?ids=${JSON.stringify(userIds.value)}`) as Promise<User[]>
},
{
watch: [userIds],
},
)
})
const userMap = computed(() => {
if (!users.value) {
@@ -225,7 +227,7 @@ async function createAffiliateCode(data: { sourceName: string; username?: string
internal: true,
})
await refresh()
await refetch()
createModal.value?.close()
} catch (err) {
handleError(err)
@@ -255,7 +257,7 @@ async function confirmRevokeAffiliateCode() {
internal: true,
})
await refresh()
await refetch()
revokeModal.value?.hide()
revokingAffiliateUsername.value = null
revokingAffiliateId.value = null

View File

@@ -339,9 +339,11 @@ import {
} from '@modrinth/ui'
import { capitalizeString } from '@modrinth/utils'
import { DEFAULT_CREDIT_EMAIL_MESSAGE } from '@modrinth/utils/utils.ts'
import { useQuery } from '@tanstack/vue-query'
import dayjs from 'dayjs'
import ModrinthServersIcon from '~/components/ui/servers/ModrinthServersIcon.vue'
import { useBaseFetch } from '~/composables/fetch.js'
const { addNotification } = injectNotificationManager()
const formatPrice = useFormatPrice()
@@ -370,9 +372,10 @@ const messages = defineMessages({
},
})
const { data: user } = await useAsyncData(`user/${route.params.id}`, () =>
useBaseFetch(`user/${route.params.id}`),
)
const { data: user } = useQuery({
queryKey: ['user', route.params.id],
queryFn: () => useBaseFetch(`user/${route.params.id}`),
})
if (!user.value) {
throw createError({
@@ -382,27 +385,25 @@ if (!user.value) {
})
}
let subscriptions, charges, refreshCharges
try {
;[{ data: subscriptions }, { data: charges, refresh: refreshCharges }] = await Promise.all([
useAsyncData(`billing/subscriptions?user_id=${route.params.id}`, () =>
useBaseFetch(`billing/subscriptions?user_id=${user.value.id}`, {
internal: true,
}),
),
useAsyncData(`billing/payments?user_id=${route.params.id}`, () =>
useBaseFetch(`billing/payments?user_id=${user.value.id}`, {
internal: true,
}),
),
])
} catch {
throw createError({
fatal: true,
statusCode: 404,
message: formatMessage(messages.userNotFoundError),
})
}
const { data: subscriptions } = useQuery({
queryKey: computed(() => ['billing', 'subscriptions', user.value?.id]),
queryFn: () =>
useBaseFetch(`billing/subscriptions?user_id=${user.value.id}`, {
internal: true,
}),
enabled: computed(() => !!user.value?.id),
placeholderData: [],
})
const { data: charges, refetch: refreshCharges } = useQuery({
queryKey: computed(() => ['billing', 'payments', user.value?.id]),
queryFn: () =>
useBaseFetch(`billing/payments?user_id=${user.value.id}`, {
internal: true,
}),
enabled: computed(() => !!user.value?.id),
placeholderData: [],
})
const subscriptionCharges = computed(() => {
return subscriptions.value.map((subscription) => {