chore(fe2): project page load speed optimization (#1974)
* merging queries for faster load * preload plugin * latest threads/models query optimization
This commit is contained in:
committed by
GitHub
parent
c2085d6b13
commit
86b535d751
@@ -142,19 +142,18 @@ import {
|
||||
CloudArrowDownIcon,
|
||||
ChatBubbleLeftRightIcon
|
||||
} from '@heroicons/vue/24/outline'
|
||||
import { useQuery } from '@vue/apollo-composable'
|
||||
import { Roles } from '@speckle/shared'
|
||||
import type { Optional } from '@speckle/shared'
|
||||
import { useActiveUser } from '~~/lib/auth/composables/activeUser'
|
||||
import { useAuthManager } from '~~/lib/auth/composables/auth'
|
||||
import { loginRoute } from '~~/lib/common/helpers/route'
|
||||
import { useTheme, AppTheme } from '~~/lib/core/composables/theme'
|
||||
import { serverVersionInfoQuery } from '~~/lib/core/graphql/queries'
|
||||
import { useServerInfo } from '~/lib/core/composables/server'
|
||||
|
||||
const { logout } = useAuthManager()
|
||||
const { activeUser, isGuest } = useActiveUser()
|
||||
const { isDarkTheme, setTheme } = useTheme()
|
||||
const { result } = useQuery(serverVersionInfoQuery)
|
||||
const { serverInfo } = useServerInfo()
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
|
||||
@@ -163,7 +162,7 @@ const showProfileEditDialog = ref(false)
|
||||
const token = computed(() => route.query.token as Optional<string>)
|
||||
|
||||
const Icon = computed(() => (isDarkTheme.value ? SunIcon : MoonIcon))
|
||||
const version = computed(() => result.value?.serverInfo.version)
|
||||
const version = computed(() => serverInfo.value?.version)
|
||||
|
||||
const isAdmin = computed(() => activeUser.value?.role === Roles.Server.Admin)
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
v-if="gridOrList === GridListToggleValue.List"
|
||||
:search="finalSearch"
|
||||
:project="project"
|
||||
:project-id="project.id"
|
||||
:source-apps="sourceApps"
|
||||
:contributors="contributors"
|
||||
@update:loading="finalLoading = $event"
|
||||
@@ -14,6 +15,7 @@
|
||||
v-if="gridOrList === GridListToggleValue.Grid"
|
||||
:search="finalSearch"
|
||||
:project="project"
|
||||
:project-id="project.id"
|
||||
:source-apps="sourceApps"
|
||||
:contributors="contributors"
|
||||
@update:loading="finalLoading = $event"
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<template>
|
||||
<ProjectPageLatestItems
|
||||
:count="project.commentThreadCount.totalCount"
|
||||
:count="project?.commentThreadCount.totalCount || 0"
|
||||
:hide-filters="showCommentsIntro"
|
||||
:see-all-url="projectDiscussionsRoute(project.id)"
|
||||
:see-all-url="projectDiscussionsRoute(projectId)"
|
||||
title="Discussions"
|
||||
>
|
||||
<template #default="{ gridOrList }">
|
||||
@@ -31,6 +31,7 @@ import { GridListToggleValue } from '~~/lib/layout/helpers/components'
|
||||
import { useQuery } from '@vue/apollo-composable'
|
||||
import { latestCommentThreadsQuery } from '~~/lib/projects/graphql/queries'
|
||||
import { projectDiscussionsRoute } from '~~/lib/common/helpers/route'
|
||||
import type { Optional } from '@speckle/shared'
|
||||
|
||||
graphql(`
|
||||
fragment ProjectPageLatestItemsComments on Project {
|
||||
@@ -66,14 +67,15 @@ graphql(`
|
||||
`)
|
||||
|
||||
const props = defineProps<{
|
||||
project: ProjectPageLatestItemsCommentsFragment
|
||||
projectId: string
|
||||
project: Optional<ProjectPageLatestItemsCommentsFragment>
|
||||
}>()
|
||||
|
||||
const { result: latestCommentsResult } = useQuery(latestCommentThreadsQuery, () => ({
|
||||
projectId: props.project?.id
|
||||
projectId: props.projectId
|
||||
}))
|
||||
|
||||
const showCommentsIntro = computed(
|
||||
() => props.project.commentThreadCount.totalCount < 1
|
||||
const showCommentsIntro = computed(() =>
|
||||
props.project ? props.project.commentThreadCount.totalCount < 1 : false
|
||||
)
|
||||
</script>
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<template>
|
||||
<ProjectPageLatestItems
|
||||
:count="project.modelCount.totalCount"
|
||||
:count="project?.modelCount.totalCount || 0"
|
||||
:title="title"
|
||||
:see-all-url="allProjectModelsRoute(project.id)"
|
||||
:see-all-url="allProjectModelsRoute(projectId)"
|
||||
hide-heading-bottom-margin
|
||||
>
|
||||
<template #default>
|
||||
@@ -12,6 +12,7 @@
|
||||
v-if="gridOrList === GridListToggleValue.List"
|
||||
:search="debouncedSearch"
|
||||
:project="project"
|
||||
:project-id="projectId"
|
||||
disable-pagination
|
||||
@update:loading="queryLoading = $event"
|
||||
@clear-search=";(search = ''), updateSearchImmediately()"
|
||||
@@ -20,6 +21,7 @@
|
||||
v-if="gridOrList === GridListToggleValue.Grid"
|
||||
:search="debouncedSearch"
|
||||
:project="project"
|
||||
:project-id="projectId"
|
||||
disable-pagination
|
||||
@update:loading="queryLoading = $event"
|
||||
@clear-search=";(search = ''), updateSearchImmediately()"
|
||||
@@ -27,7 +29,7 @@
|
||||
</div>
|
||||
<ProjectPageModelsNewDialog
|
||||
v-model:open="showNewDialog"
|
||||
:project-id="project.id"
|
||||
:project-id="projectId"
|
||||
/>
|
||||
</template>
|
||||
<template #filters>
|
||||
@@ -86,7 +88,7 @@ import { debounce } from 'lodash-es'
|
||||
import { PlusIcon } from '@heroicons/vue/24/solid'
|
||||
import { CubeIcon } from '@heroicons/vue/24/outline'
|
||||
import { allProjectModelsRoute, modelRoute } from '~~/lib/common/helpers/route'
|
||||
import { SpeckleViewer } from '@speckle/shared'
|
||||
import { SpeckleViewer, type Optional } from '@speckle/shared'
|
||||
import { useMixpanel } from '~~/lib/core/composables/mp'
|
||||
|
||||
graphql(`
|
||||
@@ -100,7 +102,8 @@ graphql(`
|
||||
`)
|
||||
|
||||
const props = defineProps<{
|
||||
project: ProjectPageLatestItemsModelsFragment
|
||||
projectId: string
|
||||
project: Optional<ProjectPageLatestItemsModelsFragment>
|
||||
}>()
|
||||
|
||||
const mp = useMixpanel()
|
||||
@@ -121,12 +124,14 @@ const title = ref('Models')
|
||||
|
||||
const gridOrList = useProjectPageItemViewType(title.value)
|
||||
|
||||
const canContribute = computed(() => canModifyModels(props.project))
|
||||
const canContribute = computed(() =>
|
||||
props.project ? canModifyModels(props.project) : false
|
||||
)
|
||||
const allModelsRoute = computed(() => {
|
||||
const resourceIdString = SpeckleViewer.ViewerRoute.resourceBuilder()
|
||||
.addAllModels()
|
||||
.toString()
|
||||
return modelRoute(props.project.id, resourceIdString)
|
||||
return modelRoute(props.projectId, resourceIdString)
|
||||
})
|
||||
|
||||
const updateDebouncedSearch = debounce(() => {
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
>
|
||||
<ProjectCardImportFileArea
|
||||
ref="importArea"
|
||||
:project-id="project.id"
|
||||
:project-id="projectId"
|
||||
:model-name="model.name"
|
||||
class="h-full w-full"
|
||||
/>
|
||||
@@ -69,7 +69,7 @@
|
||||
rounded
|
||||
size="xs"
|
||||
:icon-left="ArrowPathRoundedSquareIcon"
|
||||
:to="modelVersionsRoute(project.id, model.id)"
|
||||
:to="modelVersionsRoute(projectId, model.id)"
|
||||
:class="`transition ${
|
||||
hovered ? 'inline-block opacity-100' : 'sm:hidden sm:opacity-0'
|
||||
}`"
|
||||
@@ -80,7 +80,7 @@
|
||||
v-if="showActions && !isPendingModelFragment(model)"
|
||||
v-model:open="showActionsMenu"
|
||||
:model="model"
|
||||
:project-id="project.id"
|
||||
:project-id="projectId"
|
||||
:can-edit="canEdit"
|
||||
@click.stop.prevent
|
||||
@upload-version="triggerVersionUpload"
|
||||
@@ -103,7 +103,7 @@
|
||||
class="absolute top-0 left-0 p-2"
|
||||
>
|
||||
<ProjectPageModelsCardAutomationStatusRefactor
|
||||
:project-id="project.id"
|
||||
:project-id="projectId"
|
||||
:model-or-version="{
|
||||
...model,
|
||||
automationStatus: model.automationStatus
|
||||
@@ -129,7 +129,7 @@ import { modelRoute, modelVersionsRoute } from '~~/lib/common/helpers/route'
|
||||
import { graphql } from '~~/lib/common/generated/gql'
|
||||
import { canModifyModels } from '~~/lib/projects/helpers/permissions'
|
||||
import { isPendingModelFragment } from '~~/lib/projects/helpers/models'
|
||||
import type { Nullable } from '@speckle/shared'
|
||||
import type { Nullable, Optional } from '@speckle/shared'
|
||||
import { keyboardClick } from '@speckle/ui-components'
|
||||
|
||||
graphql(`
|
||||
@@ -145,8 +145,9 @@ const emit = defineEmits<{
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
projectId: string
|
||||
model: ProjectPageLatestItemsModelItemFragment | PendingFileUploadFragment
|
||||
project: ProjectPageModelsCardProjectFragment
|
||||
project: Optional<ProjectPageModelsCardProjectFragment>
|
||||
showVersions?: boolean
|
||||
showActions?: boolean
|
||||
disableDefaultLink?: boolean
|
||||
@@ -159,7 +160,8 @@ const props = withDefaults(
|
||||
}
|
||||
)
|
||||
|
||||
provide('projectId', props.project.id)
|
||||
// TODO: Get rid of this, its not reactive. Is it even necessary?
|
||||
provide('projectId', props.projectId)
|
||||
|
||||
const importArea = ref(
|
||||
null as Nullable<{
|
||||
@@ -206,7 +208,7 @@ const updatedAt = computed(() => {
|
||||
const finalShowVersions = computed(
|
||||
() => props.showVersions && !isPendingModelFragment(props.model)
|
||||
)
|
||||
const canEdit = computed(() => canModifyModels(props.project))
|
||||
const canEdit = computed(() => (props.project ? canModifyModels(props.project) : false))
|
||||
const versionCount = computed(() => {
|
||||
return isPendingModelFragment(props.model) ? 0 : props.model.versionCount.totalCount
|
||||
})
|
||||
@@ -218,7 +220,7 @@ const pendingVersion = computed(() => {
|
||||
})
|
||||
|
||||
const finalModelUrl = computed(() =>
|
||||
defaultLinkDisabled.value ? undefined : modelRoute(props.project.id, props.model.id)
|
||||
defaultLinkDisabled.value ? undefined : modelRoute(props.projectId, props.model.id)
|
||||
)
|
||||
|
||||
const triggerVersionUpload = () => {
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
v-for="(item, i) in items"
|
||||
:key="item.id"
|
||||
:model="item"
|
||||
:project-id="projectId"
|
||||
:project="project"
|
||||
:show-actions="showActions"
|
||||
:show-versions="showVersions"
|
||||
@@ -17,7 +18,7 @@
|
||||
<FormButtonSecondaryViewAll
|
||||
v-if="showViewAll"
|
||||
class="mt-4"
|
||||
:to="allProjectModelsRoute(project.id)"
|
||||
:to="allProjectModelsRoute(projectId)"
|
||||
/>
|
||||
</template>
|
||||
<template v-else-if="!areQueriesLoading">
|
||||
@@ -26,7 +27,7 @@
|
||||
@clear-search="() => $emit('clear-search')"
|
||||
/>
|
||||
<div v-else>
|
||||
<ProjectCardImportFileArea :project-id="project.id" class="h-36 col-span-4" />
|
||||
<ProjectCardImportFileArea :project-id="projectId" class="h-36 col-span-4" />
|
||||
</div>
|
||||
</template>
|
||||
<InfiniteLoading
|
||||
@@ -46,7 +47,7 @@ import {
|
||||
latestModelsPaginationQuery,
|
||||
latestModelsQuery
|
||||
} from '~~/lib/projects/graphql/queries'
|
||||
import type { Nullable, SourceAppDefinition } from '@speckle/shared'
|
||||
import type { Nullable, Optional, SourceAppDefinition } from '@speckle/shared'
|
||||
import type { InfiniteLoaderState } from '~~/lib/global/helpers/components'
|
||||
import { allProjectModelsRoute } from '~~/lib/common/helpers/route'
|
||||
|
||||
@@ -58,7 +59,8 @@ const emit = defineEmits<{
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
project: ProjectPageLatestItemsModelsFragment
|
||||
projectId: string
|
||||
project: Optional<ProjectPageLatestItemsModelsFragment>
|
||||
search?: string
|
||||
showActions?: boolean
|
||||
showVersions?: boolean
|
||||
@@ -80,7 +82,7 @@ const areQueriesLoading = useQueryLoading()
|
||||
|
||||
const latestModelsQueryVariables = computed(
|
||||
(): ProjectLatestModelsPaginationQueryVariables => ({
|
||||
projectId: props.project.id,
|
||||
projectId: props.projectId,
|
||||
filter: {
|
||||
search: props.search || null,
|
||||
excludeIds: props.excludedIds || null,
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
</div>
|
||||
<FormButtonSecondaryViewAll
|
||||
v-if="showViewAll"
|
||||
:to="allProjectModelsRoute(project.id)"
|
||||
:to="allProjectModelsRoute(projectId)"
|
||||
/>
|
||||
</div>
|
||||
<template v-else-if="!areQueriesLoading">
|
||||
@@ -25,7 +25,7 @@
|
||||
@clear-search="$emit('clear-search')"
|
||||
/>
|
||||
<div v-else>
|
||||
<ProjectCardImportFileArea :project-id="project.id" class="h-36 col-span-4" />
|
||||
<ProjectCardImportFileArea :project-id="projectId" class="h-36 col-span-4" />
|
||||
</div>
|
||||
</template>
|
||||
<InfiniteLoading
|
||||
@@ -35,7 +35,7 @@
|
||||
/>
|
||||
<ProjectPageModelsNewDialog
|
||||
v-model:open="showNewDialog"
|
||||
:project-id="project.id"
|
||||
:project-id="projectId"
|
||||
:parent-model-name="newSubmodelParent || undefined"
|
||||
/>
|
||||
</template>
|
||||
@@ -62,7 +62,8 @@ const emit = defineEmits<{
|
||||
}>()
|
||||
|
||||
const props = defineProps<{
|
||||
project: ProjectPageLatestItemsModelsFragment
|
||||
projectId: string
|
||||
project?: ProjectPageLatestItemsModelsFragment
|
||||
search?: string
|
||||
disablePagination?: boolean
|
||||
sourceApps?: SourceAppDefinition[]
|
||||
@@ -84,11 +85,10 @@ const showNewDialog = computed({
|
||||
|
||||
const evictModelFields = useEvictProjectModelFields()
|
||||
const areQueriesLoading = useQueryLoading()
|
||||
const projectId = computed(() => props.project.id)
|
||||
|
||||
const baseQueryVariables = computed(
|
||||
(): ProjectModelsTreeTopLevelQueryVariables => ({
|
||||
projectId: projectId.value,
|
||||
projectId: props.projectId,
|
||||
filter: {
|
||||
search: props.search || null,
|
||||
sourceApps: props.sourceApps?.length
|
||||
@@ -148,7 +148,9 @@ const topLevelItems = computed(
|
||||
props.disablePagination ? 8 : undefined
|
||||
)
|
||||
)
|
||||
const canContribute = computed(() => canModifyModels(props.project))
|
||||
const canContribute = computed(() =>
|
||||
props.project ? canModifyModels(props.project) : false
|
||||
)
|
||||
const isUsingSearch = computed(() => !!resultVariables.value?.filter?.search)
|
||||
const moreToLoad = computed(
|
||||
() =>
|
||||
@@ -160,7 +162,7 @@ const showViewAll = computed(() => moreToLoad.value && props.disablePagination)
|
||||
|
||||
const onModelUpdated = () => {
|
||||
// Evict model data
|
||||
evictModelFields(props.project.id)
|
||||
evictModelFields(props.projectId)
|
||||
|
||||
// Reset pagination
|
||||
infiniteLoadCacheBuster.value++
|
||||
|
||||
@@ -43,6 +43,7 @@
|
||||
:key="pendingModel.id"
|
||||
:model="pendingModel"
|
||||
:project="project"
|
||||
:project-id="project.id"
|
||||
height="h-52"
|
||||
/>
|
||||
<ProjectPageModelsCard
|
||||
@@ -52,6 +53,7 @@
|
||||
:project="project"
|
||||
:show-versions="false"
|
||||
:show-actions="false"
|
||||
:project-id="project.id"
|
||||
height="h-52"
|
||||
/>
|
||||
<ProjectCardImportFileArea
|
||||
|
||||
@@ -20,9 +20,8 @@
|
||||
</LayoutDialog>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { useQuery } from '@vue/apollo-composable'
|
||||
import { CodeBracketIcon, ChevronRightIcon } from '@heroicons/vue/24/outline'
|
||||
import { profileEditDialogQuery } from '~~/lib/user/graphql/queries'
|
||||
import { useActiveUser } from '~/lib/auth/composables/activeUser'
|
||||
|
||||
type FormButtonColor =
|
||||
| 'default'
|
||||
@@ -42,9 +41,7 @@ const props = defineProps<{
|
||||
open: boolean
|
||||
}>()
|
||||
|
||||
const { result } = useQuery(profileEditDialogQuery)
|
||||
|
||||
const user = computed(() => result.value?.activeUser)
|
||||
const { activeUser: user } = useActiveUser()
|
||||
|
||||
const isOpen = computed({
|
||||
get: () => !!(props.open && user.value),
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
v-if="project"
|
||||
:search="debouncedSearch"
|
||||
:project="project"
|
||||
:project-id="project.id"
|
||||
:excluded-ids="alreadyLoadedModelIds"
|
||||
:show-actions="false"
|
||||
:show-versions="false"
|
||||
|
||||
@@ -8,12 +8,15 @@ export const activeUserQuery = graphql(`
|
||||
activeUser {
|
||||
id
|
||||
email
|
||||
company
|
||||
bio
|
||||
name
|
||||
role
|
||||
avatar
|
||||
isOnboardingFinished
|
||||
createdAt
|
||||
verified
|
||||
notificationPreferences
|
||||
}
|
||||
}
|
||||
`)
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
import type { QueryOptions } from '@apollo/client/core'
|
||||
import { convertThrowIntoFetchResult } from '~/lib/common/helpers/graphql'
|
||||
|
||||
export const useApolloClientIfAvailable = () => {
|
||||
const nuxt = useNuxtApp()
|
||||
const getClient = () => (nuxt.$apollo?.default ? nuxt.$apollo.default : undefined)
|
||||
@@ -13,3 +16,15 @@ export const useApolloClientFromNuxt = () => {
|
||||
|
||||
return client
|
||||
}
|
||||
|
||||
export const usePreloadApolloQueries = () => {
|
||||
const client = useApolloClientFromNuxt()
|
||||
return async (params: { queries: QueryOptions[] }) => {
|
||||
const { queries } = params
|
||||
|
||||
const promises = queries.map((q) =>
|
||||
client.query(q).catch(convertThrowIntoFetchResult)
|
||||
)
|
||||
return await Promise.all(promises)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,7 +62,7 @@ const documents = {
|
||||
"\n fragment ThreadCommentAttachment on Comment {\n text {\n attachments {\n id\n fileName\n fileType\n fileSize\n }\n }\n }\n": types.ThreadCommentAttachmentFragmentDoc,
|
||||
"\n fragment ViewerCommentsListItem on Comment {\n id\n rawText\n archived\n author {\n ...LimitedUserAvatar\n }\n createdAt\n viewedAt\n replies {\n totalCount\n cursor\n items {\n ...ViewerCommentsReplyItem\n }\n }\n replyAuthors(limit: 4) {\n totalCount\n items {\n ...FormUsersSelectItem\n }\n }\n resources {\n resourceId\n resourceType\n }\n }\n": types.ViewerCommentsListItemFragmentDoc,
|
||||
"\n fragment ViewerModelVersionCardItem on Version {\n id\n message\n referencedObject\n sourceApplication\n createdAt\n previewUrl\n authorUser {\n ...LimitedUserAvatar\n }\n }\n": types.ViewerModelVersionCardItemFragmentDoc,
|
||||
"\n query ActiveUserMainMetadata {\n activeUser {\n id\n email\n name\n role\n avatar\n isOnboardingFinished\n createdAt\n verified\n }\n }\n": types.ActiveUserMainMetadataDocument,
|
||||
"\n query ActiveUserMainMetadata {\n activeUser {\n id\n email\n company\n bio\n name\n role\n avatar\n isOnboardingFinished\n createdAt\n verified\n notificationPreferences\n }\n }\n": types.ActiveUserMainMetadataDocument,
|
||||
"\n mutation CreateOnboardingProject {\n projectMutations {\n createForOnboarding {\n ...ProjectPageProject\n ...ProjectDashboardItem\n }\n }\n }\n ": types.CreateOnboardingProjectDocument,
|
||||
"\n mutation FinishOnboarding {\n activeUserMutations {\n finishOnboarding\n }\n }\n": types.FinishOnboardingDocument,
|
||||
"\n mutation RequestVerificationByEmail($email: String!) {\n requestVerificationByEmail(email: $email)\n }\n": types.RequestVerificationByEmailDocument,
|
||||
@@ -75,7 +75,6 @@ const documents = {
|
||||
"\n query ServerInfoAllScopes {\n serverInfo {\n scopes {\n name\n description\n }\n }\n }\n": types.ServerInfoAllScopesDocument,
|
||||
"\n query ProjectModelsSelectorValues($projectId: String!, $cursor: String) {\n project(id: $projectId) {\n id\n models(limit: 100, cursor: $cursor) {\n cursor\n totalCount\n items {\n ...CommonModelSelectorModel\n }\n }\n }\n }\n": types.ProjectModelsSelectorValuesDocument,
|
||||
"\n query MainServerInfoData {\n serverInfo {\n adminContact\n blobSizeLimitBytes\n canonicalUrl\n company\n description\n guestModeEnabled\n inviteOnly\n name\n termsOfService\n version\n automateUrl\n }\n }\n": types.MainServerInfoDataDocument,
|
||||
"\n query ServerVersionInfo {\n serverInfo {\n version\n }\n }\n": types.ServerVersionInfoDocument,
|
||||
"\n mutation DeleteAccessToken($token: String!) {\n apiTokenRevoke(token: $token)\n }\n": types.DeleteAccessTokenDocument,
|
||||
"\n mutation CreateAccessToken($token: ApiTokenCreateInput!) {\n apiTokenCreate(token: $token)\n }\n": types.CreateAccessTokenDocument,
|
||||
"\n mutation DeleteApplication($appId: String!) {\n appDelete(appId: $appId)\n }\n": types.DeleteApplicationDocument,
|
||||
@@ -381,7 +380,7 @@ export function graphql(source: "\n fragment ViewerModelVersionCardItem on Vers
|
||||
/**
|
||||
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
|
||||
*/
|
||||
export function graphql(source: "\n query ActiveUserMainMetadata {\n activeUser {\n id\n email\n name\n role\n avatar\n isOnboardingFinished\n createdAt\n verified\n }\n }\n"): (typeof documents)["\n query ActiveUserMainMetadata {\n activeUser {\n id\n email\n name\n role\n avatar\n isOnboardingFinished\n createdAt\n verified\n }\n }\n"];
|
||||
export function graphql(source: "\n query ActiveUserMainMetadata {\n activeUser {\n id\n email\n company\n bio\n name\n role\n avatar\n isOnboardingFinished\n createdAt\n verified\n notificationPreferences\n }\n }\n"): (typeof documents)["\n query ActiveUserMainMetadata {\n activeUser {\n id\n email\n company\n bio\n name\n role\n avatar\n isOnboardingFinished\n createdAt\n verified\n notificationPreferences\n }\n }\n"];
|
||||
/**
|
||||
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
|
||||
*/
|
||||
@@ -430,10 +429,6 @@ export function graphql(source: "\n query ProjectModelsSelectorValues($projectI
|
||||
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
|
||||
*/
|
||||
export function graphql(source: "\n query MainServerInfoData {\n serverInfo {\n adminContact\n blobSizeLimitBytes\n canonicalUrl\n company\n description\n guestModeEnabled\n inviteOnly\n name\n termsOfService\n version\n automateUrl\n }\n }\n"): (typeof documents)["\n query MainServerInfoData {\n serverInfo {\n adminContact\n blobSizeLimitBytes\n canonicalUrl\n company\n description\n guestModeEnabled\n inviteOnly\n name\n termsOfService\n version\n automateUrl\n }\n }\n"];
|
||||
/**
|
||||
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
|
||||
*/
|
||||
export function graphql(source: "\n query ServerVersionInfo {\n serverInfo {\n version\n }\n }\n"): (typeof documents)["\n query ServerVersionInfo {\n serverInfo {\n version\n }\n }\n"];
|
||||
/**
|
||||
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
|
||||
*/
|
||||
|
||||
@@ -3013,7 +3013,7 @@ export type ViewerModelVersionCardItemFragment = { __typename?: 'Version', id: s
|
||||
export type ActiveUserMainMetadataQueryVariables = Exact<{ [key: string]: never; }>;
|
||||
|
||||
|
||||
export type ActiveUserMainMetadataQuery = { __typename?: 'Query', activeUser?: { __typename?: 'User', id: string, email?: string | null, name: string, role?: string | null, avatar?: string | null, isOnboardingFinished?: boolean | null, createdAt?: string | null, verified?: boolean | null } | null };
|
||||
export type ActiveUserMainMetadataQuery = { __typename?: 'Query', activeUser?: { __typename?: 'User', id: string, email?: string | null, company?: string | null, bio?: string | null, name: string, role?: string | null, avatar?: string | null, isOnboardingFinished?: boolean | null, createdAt?: string | null, verified?: boolean | null, notificationPreferences: {} } | null };
|
||||
|
||||
export type CreateOnboardingProjectMutationVariables = Exact<{ [key: string]: never; }>;
|
||||
|
||||
@@ -3092,11 +3092,6 @@ export type MainServerInfoDataQueryVariables = Exact<{ [key: string]: never; }>;
|
||||
|
||||
export type MainServerInfoDataQuery = { __typename?: 'Query', serverInfo: { __typename?: 'ServerInfo', adminContact?: string | null, blobSizeLimitBytes: number, canonicalUrl?: string | null, company?: string | null, description?: string | null, guestModeEnabled: boolean, inviteOnly?: boolean | null, name: string, termsOfService?: string | null, version?: string | null, automateUrl?: string | null } };
|
||||
|
||||
export type ServerVersionInfoQueryVariables = Exact<{ [key: string]: never; }>;
|
||||
|
||||
|
||||
export type ServerVersionInfoQuery = { __typename?: 'Query', serverInfo: { __typename?: 'ServerInfo', version?: string | null } };
|
||||
|
||||
export type DeleteAccessTokenMutationVariables = Exact<{
|
||||
token: Scalars['String'];
|
||||
}>;
|
||||
@@ -3754,7 +3749,7 @@ export const RegisterPanelServerInviteDocument = {"kind":"Document","definitions
|
||||
export const EmailVerificationBannerStateDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"EmailVerificationBannerState"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"activeUser"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"email"}},{"kind":"Field","name":{"kind":"Name","value":"verified"}},{"kind":"Field","name":{"kind":"Name","value":"hasPendingVerification"}}]}}]}}]} as unknown as DocumentNode<EmailVerificationBannerStateQuery, EmailVerificationBannerStateQueryVariables>;
|
||||
export const RequestVerificationDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"RequestVerification"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"requestVerification"}}]}}]} as unknown as DocumentNode<RequestVerificationMutation, RequestVerificationMutationVariables>;
|
||||
export const OnUserProjectsUpdateDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"subscription","name":{"kind":"Name","value":"OnUserProjectsUpdate"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"userProjectsUpdated"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"type"}},{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"project"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"ProjectDashboardItem"}}]}}]}}]}},...ProjectDashboardItemFragmentDoc.definitions,...ProjectDashboardItemNoModelsFragmentDoc.definitions,...ProjectPageModelsCardProjectFragmentDoc.definitions,...ProjectPageLatestItemsModelItemFragmentDoc.definitions,...PendingFileUploadFragmentDoc.definitions,...ProjectPageModelsCardRenameDialogFragmentDoc.definitions,...ProjectPageModelsCardDeleteDialogFragmentDoc.definitions,...ProjectPageModelsActionsFragmentDoc.definitions,...ModelCardAutomationStatus_ModelFragmentDoc.definitions,...ModelCardAutomationStatus_AutomationsStatusFragmentDoc.definitions]} as unknown as DocumentNode<OnUserProjectsUpdateSubscription, OnUserProjectsUpdateSubscriptionVariables>;
|
||||
export const ActiveUserMainMetadataDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"ActiveUserMainMetadata"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"activeUser"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"email"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"role"}},{"kind":"Field","name":{"kind":"Name","value":"avatar"}},{"kind":"Field","name":{"kind":"Name","value":"isOnboardingFinished"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"verified"}}]}}]}}]} as unknown as DocumentNode<ActiveUserMainMetadataQuery, ActiveUserMainMetadataQueryVariables>;
|
||||
export const ActiveUserMainMetadataDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"ActiveUserMainMetadata"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"activeUser"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"email"}},{"kind":"Field","name":{"kind":"Name","value":"company"}},{"kind":"Field","name":{"kind":"Name","value":"bio"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"role"}},{"kind":"Field","name":{"kind":"Name","value":"avatar"}},{"kind":"Field","name":{"kind":"Name","value":"isOnboardingFinished"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"verified"}},{"kind":"Field","name":{"kind":"Name","value":"notificationPreferences"}}]}}]}}]} as unknown as DocumentNode<ActiveUserMainMetadataQuery, ActiveUserMainMetadataQueryVariables>;
|
||||
export const CreateOnboardingProjectDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"CreateOnboardingProject"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"projectMutations"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"createForOnboarding"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"ProjectPageProject"}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"ProjectDashboardItem"}}]}}]}}]}},...ProjectPageProjectFragmentDoc.definitions,...ProjectPageProjectHeaderFragmentDoc.definitions,...ProjectPageStatsBlockTeamFragmentDoc.definitions,...LimitedUserAvatarFragmentDoc.definitions,...ProjectPageTeamDialogFragmentDoc.definitions,...ProjectPageStatsBlockVersionsFragmentDoc.definitions,...ProjectPageStatsBlockModelsFragmentDoc.definitions,...ProjectPageStatsBlockCommentsFragmentDoc.definitions,...ProjectPageLatestItemsModelsFragmentDoc.definitions,...ProjectPageLatestItemsCommentsFragmentDoc.definitions,...ProjectDashboardItemFragmentDoc.definitions,...ProjectDashboardItemNoModelsFragmentDoc.definitions,...ProjectPageModelsCardProjectFragmentDoc.definitions,...ProjectPageLatestItemsModelItemFragmentDoc.definitions,...PendingFileUploadFragmentDoc.definitions,...ProjectPageModelsCardRenameDialogFragmentDoc.definitions,...ProjectPageModelsCardDeleteDialogFragmentDoc.definitions,...ProjectPageModelsActionsFragmentDoc.definitions,...ModelCardAutomationStatus_ModelFragmentDoc.definitions,...ModelCardAutomationStatus_AutomationsStatusFragmentDoc.definitions]} as unknown as DocumentNode<CreateOnboardingProjectMutation, CreateOnboardingProjectMutationVariables>;
|
||||
export const FinishOnboardingDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"FinishOnboarding"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"activeUserMutations"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"finishOnboarding"}}]}}]}}]} as unknown as DocumentNode<FinishOnboardingMutation, FinishOnboardingMutationVariables>;
|
||||
export const RequestVerificationByEmailDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"RequestVerificationByEmail"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"email"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"requestVerificationByEmail"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"email"},"value":{"kind":"Variable","name":{"kind":"Name","value":"email"}}}]}]}}]} as unknown as DocumentNode<RequestVerificationByEmailMutation, RequestVerificationByEmailMutationVariables>;
|
||||
@@ -3767,7 +3762,6 @@ export const ServerInfoBlobSizeLimitDocument = {"kind":"Document","definitions":
|
||||
export const ServerInfoAllScopesDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"ServerInfoAllScopes"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"serverInfo"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"scopes"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"description"}}]}}]}}]}}]} as unknown as DocumentNode<ServerInfoAllScopesQuery, ServerInfoAllScopesQueryVariables>;
|
||||
export const ProjectModelsSelectorValuesDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"ProjectModelsSelectorValues"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"projectId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"cursor"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"project"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"projectId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"models"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"limit"},"value":{"kind":"IntValue","value":"100"}},{"kind":"Argument","name":{"kind":"Name","value":"cursor"},"value":{"kind":"Variable","name":{"kind":"Name","value":"cursor"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"cursor"}},{"kind":"Field","name":{"kind":"Name","value":"totalCount"}},{"kind":"Field","name":{"kind":"Name","value":"items"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"CommonModelSelectorModel"}}]}}]}}]}}]}},...CommonModelSelectorModelFragmentDoc.definitions]} as unknown as DocumentNode<ProjectModelsSelectorValuesQuery, ProjectModelsSelectorValuesQueryVariables>;
|
||||
export const MainServerInfoDataDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"MainServerInfoData"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"serverInfo"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"adminContact"}},{"kind":"Field","name":{"kind":"Name","value":"blobSizeLimitBytes"}},{"kind":"Field","name":{"kind":"Name","value":"canonicalUrl"}},{"kind":"Field","name":{"kind":"Name","value":"company"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"guestModeEnabled"}},{"kind":"Field","name":{"kind":"Name","value":"inviteOnly"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"termsOfService"}},{"kind":"Field","name":{"kind":"Name","value":"version"}},{"kind":"Field","name":{"kind":"Name","value":"automateUrl"}}]}}]}}]} as unknown as DocumentNode<MainServerInfoDataQuery, MainServerInfoDataQueryVariables>;
|
||||
export const ServerVersionInfoDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"ServerVersionInfo"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"serverInfo"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"version"}}]}}]}}]} as unknown as DocumentNode<ServerVersionInfoQuery, ServerVersionInfoQueryVariables>;
|
||||
export const DeleteAccessTokenDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"DeleteAccessToken"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"token"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"apiTokenRevoke"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"token"},"value":{"kind":"Variable","name":{"kind":"Name","value":"token"}}}]}]}}]} as unknown as DocumentNode<DeleteAccessTokenMutation, DeleteAccessTokenMutationVariables>;
|
||||
export const CreateAccessTokenDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"CreateAccessToken"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"token"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ApiTokenCreateInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"apiTokenCreate"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"token"},"value":{"kind":"Variable","name":{"kind":"Name","value":"token"}}}]}]}}]} as unknown as DocumentNode<CreateAccessTokenMutation, CreateAccessTokenMutationVariables>;
|
||||
export const DeleteApplicationDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"DeleteApplication"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"appId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"appDelete"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"appId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"appId"}}}]}]}}]} as unknown as DocumentNode<DeleteApplicationMutation, DeleteApplicationMutationVariables>;
|
||||
|
||||
@@ -3,7 +3,7 @@ import { nanoid } from 'nanoid'
|
||||
import { graphql } from '~~/lib/common/generated/gql'
|
||||
import type { H3Event } from 'h3'
|
||||
|
||||
const serverInfoQuery = graphql(`
|
||||
export const mainServerInfoDataQuery = graphql(`
|
||||
query MainServerInfoData {
|
||||
serverInfo {
|
||||
adminContact
|
||||
@@ -22,7 +22,7 @@ const serverInfoQuery = graphql(`
|
||||
`)
|
||||
|
||||
export function useServerInfo() {
|
||||
const { result } = useQuery(serverInfoQuery)
|
||||
const { result } = useQuery(mainServerInfoDataQuery)
|
||||
|
||||
const serverInfo = computed(() => result.value?.serverInfo)
|
||||
|
||||
|
||||
@@ -381,9 +381,14 @@ function createLink(params: {
|
||||
// SSR req logging link
|
||||
const loggerLink = new ApolloLink((operation, forward) => {
|
||||
const startTime = Date.now()
|
||||
const name = operation.operationName
|
||||
|
||||
nuxtApp.$logger.debug(
|
||||
{ operation: name },
|
||||
`Apollo operation {operation} started...`
|
||||
)
|
||||
return forward(operation).map((result) => {
|
||||
const elapsed = new Date().getTime() - startTime
|
||||
const name = operation.operationName
|
||||
const success = !!(result.data && !result.errors?.length)
|
||||
|
||||
nuxtApp.$logger.info(
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
import { graphql } from '~~/lib/common/generated/gql'
|
||||
|
||||
export const serverVersionInfoQuery = graphql(`
|
||||
query ServerVersionInfo {
|
||||
serverInfo {
|
||||
version
|
||||
}
|
||||
}
|
||||
`)
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div>
|
||||
<div v-if="project">
|
||||
<template v-if="project">
|
||||
<ProjectsInviteBanner v-if="invite" :invite="invite" :show-stream-name="false" />
|
||||
<!-- Heading text w/ actions -->
|
||||
<ProjectPageHeader :project="project" class="mb-8" />
|
||||
@@ -17,14 +17,15 @@
|
||||
<ProjectPageStatsBlockComments :project="project" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-col space-y-8 sm:space-y-14">
|
||||
<!-- Latest models -->
|
||||
<ProjectPageLatestItemsModels :project="project" />
|
||||
<!-- Latest comments -->
|
||||
<ProjectPageLatestItemsComments :project="project" />
|
||||
<!-- More actions -->
|
||||
<!-- <ProjectPageMoreActions /> -->
|
||||
</div>
|
||||
</template>
|
||||
<!-- No v-if=project to ensure internal queries trigger ASAP -->
|
||||
<div v-show="project" class="flex flex-col space-y-8 sm:space-y-14">
|
||||
<!-- Latest models -->
|
||||
<ProjectPageLatestItemsModels :project="project" :project-id="projectId" />
|
||||
<!-- Latest comments -->
|
||||
<ProjectPageLatestItemsComments :project="project" :project-id="projectId" />
|
||||
<!-- More actions -->
|
||||
<!-- <ProjectPageMoreActions /> -->
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -13,6 +13,14 @@ export default defineNuxtPlugin((ctx) => {
|
||||
path: `${String(name)}: ${path}`
|
||||
}
|
||||
|
||||
logger.debug(
|
||||
{
|
||||
routeName: name,
|
||||
routePath: path
|
||||
},
|
||||
'{routePath} SSR render started...'
|
||||
)
|
||||
|
||||
ctx.hook('app:rendered', () => {
|
||||
const endTime = Date.now() - state.start
|
||||
logger.info(
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
import type { Optional } from '@speckle/shared'
|
||||
import { activeUserQuery } from '~/lib/auth/composables/activeUser'
|
||||
import { usePreloadApolloQueries } from '~/lib/common/composables/graphql'
|
||||
import { mainServerInfoDataQuery } from '~/lib/core/composables/server'
|
||||
import { projectAccessCheckQuery } from '~/lib/projects/graphql/queries'
|
||||
|
||||
/**
|
||||
* Prefetches data for specific routes to avoid the problem of serial API requests
|
||||
* (e.g. in the case of multiple middlewares)
|
||||
*/
|
||||
export default defineNuxtPlugin(async (ctx) => {
|
||||
const logger = useLogger()
|
||||
const route = ctx._route
|
||||
const preload = usePreloadApolloQueries()
|
||||
|
||||
if (!route) {
|
||||
logger.info('No route obj found, skipping data preload...')
|
||||
return
|
||||
}
|
||||
|
||||
const path = route.path
|
||||
const idParam = route.params.id as Optional<string>
|
||||
const promises: Promise<unknown>[] = []
|
||||
|
||||
// Standard/global
|
||||
promises.push(
|
||||
preload({
|
||||
queries: [{ query: activeUserQuery }, { query: mainServerInfoDataQuery }]
|
||||
})
|
||||
)
|
||||
|
||||
// Preload project data
|
||||
if (idParam && path.startsWith('/projects/')) {
|
||||
promises.push(
|
||||
preload({
|
||||
queries: [
|
||||
{
|
||||
query: projectAccessCheckQuery,
|
||||
variables: { id: idParam },
|
||||
context: { skipLoggingErrors: true }
|
||||
}
|
||||
]
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
await Promise.all(promises)
|
||||
})
|
||||
Reference in New Issue
Block a user