Files
speckle-server/packages/frontend-2/lib/user/composables/projectUpdates.ts
T
Kristaps Fabians Geikins 596312ab0e feat(frontend): personal project limit disclaimers & prompts (#4822)
* ProjectsAdd wrapper

* WorkspaceMoveProject wrapper added

* move wrapper finalized

* passing through location

* more cleanup

* model add wrapper

* permissions cleanup

* add invite wrapper

* vue-tippy bugfix

* ViewerLimitsDialog prep

* upgrade limit alert prep

* limit alerts

* movemanager fix

* new add flow

* slug update fix

* add model flow

* invites?

* some extra fixes

* move unmount fix?

* more fixes

* vue-tsc update

* style: remove h-32 for smaller screens

* vue-tsc parser fix

* prep for new viewer limits dialog

* updated viewer dialogs

* comment variant cleanup

* CR comments

---------

Co-authored-by: michalspeckle <michal@speckle.systems>
2025-05-28 12:12:18 +03:00

89 lines
2.7 KiB
TypeScript

import { useApolloClient, useSubscription } from '@vue/apollo-composable'
import { graphql } from '~/lib/common/generated/gql'
import { UserProjectsUpdatedMessageType } from '~/lib/common/generated/gql/graphql'
import { getCacheId, modifyObjectField } from '~/lib/common/helpers/graphql'
import { ToastNotificationType, useGlobalToast } from '~/lib/common/composables/toast'
import { projectRoute } from '~/lib/common/helpers/route'
export function useUserProjectsUpdatedTracking() {
const apollo = useApolloClient().client
const { triggerNotification } = useGlobalToast()
const { activeUser } = useActiveUser()
const { onResult: onUserProjectsUpdate } = useSubscription(
graphql(`
subscription OnUserProjectsUpdate {
userProjectsUpdated {
type
id
project {
...ProjectDashboardItem
workspaceId
}
}
}
`)
)
onUserProjectsUpdate((res) => {
const activeUserId = activeUser.value?.id
const event = res.data?.userProjectsUpdated
if (!event) return
if (!activeUserId) return
const isNewProject = event.type === UserProjectsUpdatedMessageType.Added
const incomingProject = event.project
const cache = apollo.cache
if (isNewProject && incomingProject) {
// Add to User.projects where possible
modifyObjectField(
cache,
getCacheId('User', activeUserId),
'projects',
({ helpers: { ref, createUpdatedValue }, variables }) => {
if (incomingProject.workspaceId && variables.filter?.personalOnly) {
return // skip, not a personal project
}
if (
variables.filter?.workspaceId &&
variables.filter?.workspaceId !== incomingProject.workspaceId
) {
return // skip, not in the workspace
}
return createUpdatedValue(({ update }) => {
update('items', (items) => [
ref('Project', incomingProject.id),
...(items || [])
])
update('totalCount', (count) => count + 1)
})
},
{ autoEvictFiltered: true }
)
}
if (!isNewProject) {
// Evict old project from cache entirely to remove it from all searches
cache.evict({
id: getCacheId('Project', event.id)
})
}
// Emit toast notification
triggerNotification({
type: ToastNotificationType.Info,
title: isNewProject ? 'New project added' : 'A project has been removed',
cta:
isNewProject && incomingProject
? {
url: projectRoute(incomingProject.id),
title: 'View project'
}
: undefined
})
})
}