From a8546e4e5f395df64f75f4240d717f469e73d4e1 Mon Sep 17 00:00:00 2001 From: Chuck Driesler Date: Mon, 17 Mar 2025 11:01:06 +0000 Subject: [PATCH] fix(workspaces): make discoverable workspace dismiss sticky (#4189) * fix(workspaces): make discoverable workspace dismiss sticky * Modify cache instead of refetch * Add to new cards --------- Co-authored-by: Mike Tasset --- .../components/projects/DashboardHeader.vue | 27 +--- .../workspace/discoverableWorkspaces/Card.vue | 45 +++--- .../discoverableWorkspaces/Modal.vue | 11 +- .../invite/DiscoverableWorkspaceBanner.vue | 17 +-- .../lib/common/generated/gql/gql.ts | 6 + .../lib/common/generated/gql/graphql.ts | 8 + .../lib/common/helpers/constants.ts | 4 +- .../lib/dashboard/graphql/mutations.ts | 8 + .../composables/discoverableWorkspaces.ts | 139 ++++++++++++------ 9 files changed, 160 insertions(+), 105 deletions(-) diff --git a/packages/frontend-2/components/projects/DashboardHeader.vue b/packages/frontend-2/components/projects/DashboardHeader.vue index f7ca7b0de..2d3913d33 100644 --- a/packages/frontend-2/components/projects/DashboardHeader.vue +++ b/packages/frontend-2/components/projects/DashboardHeader.vue @@ -13,23 +13,20 @@ :invite="invite" /> diff --git a/packages/frontend-2/components/workspace/discoverableWorkspaces/Card.vue b/packages/frontend-2/components/workspace/discoverableWorkspaces/Card.vue index 4b3144eca..653e865ac 100644 --- a/packages/frontend-2/components/workspace/discoverableWorkspaces/Card.vue +++ b/packages/frontend-2/components/workspace/discoverableWorkspaces/Card.vue @@ -12,23 +12,21 @@ {{ workspace.team?.totalCount === 1 ? 'member' : 'members' }}

- - {{ workspace.requestStatus }} - - - Request to join - +
+ + {{ workspace.requestStatus }} + + + Request to join + + Dismiss +
@@ -42,13 +40,18 @@ type WorkspaceWithStatus = LimitedWorkspace & { requestStatus: string | null } -defineProps<{ +const props = defineProps<{ workspace: WorkspaceWithStatus }>() -const { processRequest } = useDiscoverableWorkspaces() +const { requestToJoinWorkspace, dismissDiscoverableWorkspace } = + useDiscoverableWorkspaces() -const onRequest = (workspaceId: string) => { - processRequest(true, workspaceId) +const onRequest = () => { + requestToJoinWorkspace(props.workspace.id) +} + +const onDismiss = () => { + dismissDiscoverableWorkspace(props.workspace.id) } diff --git a/packages/frontend-2/components/workspace/discoverableWorkspaces/Modal.vue b/packages/frontend-2/components/workspace/discoverableWorkspaces/Modal.vue index 6a22dccab..96316972f 100644 --- a/packages/frontend-2/components/workspace/discoverableWorkspaces/Modal.vue +++ b/packages/frontend-2/components/workspace/discoverableWorkspaces/Modal.vue @@ -2,7 +2,11 @@

- Workspaces that match your email domain + {{ + hasDiscoverableWorkspacesOrJoinRequests + ? 'Workspaces that match your email domain' + : 'You have no discoverable workspaces' + }}

('open', { required: true }) diff --git a/packages/frontend-2/components/workspace/invite/DiscoverableWorkspaceBanner.vue b/packages/frontend-2/components/workspace/invite/DiscoverableWorkspaceBanner.vue index 23790662c..ad34dc30d 100644 --- a/packages/frontend-2/components/workspace/invite/DiscoverableWorkspaceBanner.vue +++ b/packages/frontend-2/components/workspace/invite/DiscoverableWorkspaceBanner.vue @@ -17,9 +17,9 @@ const props = defineProps<{ workspace: LimitedWorkspace }>() -const { processRequest } = useDiscoverableWorkspaces() +const { requestToJoinWorkspace, dismissDiscoverableWorkspace } = + useDiscoverableWorkspaces() const mixpanel = useMixpanel() -const { triggerNotification } = useGlobalToast() const invite = computed(() => ({ workspace: { @@ -29,26 +29,17 @@ const invite = computed(() => ({ } })) -const emit = defineEmits<{ - (e: 'dismiss', workspaceId: string): void -}>() - const handleRequest = async (accept: boolean) => { if (accept) { - await processRequest(true, props.workspace.id) - emit('dismiss', props.workspace.id) + await requestToJoinWorkspace(props.workspace.id) } else { - emit('dismiss', props.workspace.id) + await dismissDiscoverableWorkspace(props.workspace.id) mixpanel.track('Workspace Discovery Banner Dismissed', { workspaceId: props.workspace.id, location: 'discovery banner', // eslint-disable-next-line camelcase workspace_id: props.workspace.id }) - triggerNotification({ - title: 'Discoverable workspace dismissed', - type: ToastNotificationType.Info - }) } } diff --git a/packages/frontend-2/lib/common/generated/gql/gql.ts b/packages/frontend-2/lib/common/generated/gql/gql.ts index f78e79b3e..19a0175a4 100644 --- a/packages/frontend-2/lib/common/generated/gql/gql.ts +++ b/packages/frontend-2/lib/common/generated/gql/gql.ts @@ -185,6 +185,7 @@ type Documents = { "\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": typeof types.ProjectModelsSelectorValuesDocument, "\n query MainServerInfoData {\n serverInfo {\n adminContact\n canonicalUrl\n company\n description\n guestModeEnabled\n inviteOnly\n name\n termsOfService\n version\n automateUrl\n configuration {\n isEmailEnabled\n }\n }\n }\n": typeof types.MainServerInfoDataDocument, "\n mutation DashboardRequestToJoinWorkspace($input: WorkspaceRequestToJoinInput!) {\n workspaceMutations {\n requestToJoin(input: $input)\n }\n }\n": typeof types.DashboardRequestToJoinWorkspaceDocument, + "\n mutation DashboardDismissDiscoverableWorkspace($input: WorkspaceDismissInput!) {\n workspaceMutations {\n dismiss(input: $input)\n }\n }\n": typeof types.DashboardDismissDiscoverableWorkspaceDocument, "\n query DashboardProjectsPageQuery {\n activeUser {\n id\n projects(limit: 3) {\n items {\n ...DashboardProjectCard_Project\n }\n }\n ...ProjectsDashboardHeaderProjects_User\n }\n }\n": typeof types.DashboardProjectsPageQueryDocument, "\n query DashboardProjectsPageWorkspaceQuery {\n activeUser {\n id\n ...ProjectsDashboardHeaderWorkspaces_User\n }\n }\n": typeof types.DashboardProjectsPageWorkspaceQueryDocument, "\n mutation DeleteAccessToken($token: String!) {\n apiTokenRevoke(token: $token)\n }\n": typeof types.DeleteAccessTokenDocument, @@ -584,6 +585,7 @@ const documents: Documents = { "\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 canonicalUrl\n company\n description\n guestModeEnabled\n inviteOnly\n name\n termsOfService\n version\n automateUrl\n configuration {\n isEmailEnabled\n }\n }\n }\n": types.MainServerInfoDataDocument, "\n mutation DashboardRequestToJoinWorkspace($input: WorkspaceRequestToJoinInput!) {\n workspaceMutations {\n requestToJoin(input: $input)\n }\n }\n": types.DashboardRequestToJoinWorkspaceDocument, + "\n mutation DashboardDismissDiscoverableWorkspace($input: WorkspaceDismissInput!) {\n workspaceMutations {\n dismiss(input: $input)\n }\n }\n": types.DashboardDismissDiscoverableWorkspaceDocument, "\n query DashboardProjectsPageQuery {\n activeUser {\n id\n projects(limit: 3) {\n items {\n ...DashboardProjectCard_Project\n }\n }\n ...ProjectsDashboardHeaderProjects_User\n }\n }\n": types.DashboardProjectsPageQueryDocument, "\n query DashboardProjectsPageWorkspaceQuery {\n activeUser {\n id\n ...ProjectsDashboardHeaderWorkspaces_User\n }\n }\n": types.DashboardProjectsPageWorkspaceQueryDocument, "\n mutation DeleteAccessToken($token: String!) {\n apiTokenRevoke(token: $token)\n }\n": types.DeleteAccessTokenDocument, @@ -1510,6 +1512,10 @@ export function graphql(source: "\n query MainServerInfoData {\n serverInfo * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. */ export function graphql(source: "\n mutation DashboardRequestToJoinWorkspace($input: WorkspaceRequestToJoinInput!) {\n workspaceMutations {\n requestToJoin(input: $input)\n }\n }\n"): (typeof documents)["\n mutation DashboardRequestToJoinWorkspace($input: WorkspaceRequestToJoinInput!) {\n workspaceMutations {\n requestToJoin(input: $input)\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 mutation DashboardDismissDiscoverableWorkspace($input: WorkspaceDismissInput!) {\n workspaceMutations {\n dismiss(input: $input)\n }\n }\n"): (typeof documents)["\n mutation DashboardDismissDiscoverableWorkspace($input: WorkspaceDismissInput!) {\n workspaceMutations {\n dismiss(input: $input)\n }\n }\n"]; /** * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. */ diff --git a/packages/frontend-2/lib/common/generated/gql/graphql.ts b/packages/frontend-2/lib/common/generated/gql/graphql.ts index b4881d7d0..acf859d23 100644 --- a/packages/frontend-2/lib/common/generated/gql/graphql.ts +++ b/packages/frontend-2/lib/common/generated/gql/graphql.ts @@ -5397,6 +5397,13 @@ export type DashboardRequestToJoinWorkspaceMutationVariables = Exact<{ export type DashboardRequestToJoinWorkspaceMutation = { __typename?: 'Mutation', workspaceMutations: { __typename?: 'WorkspaceMutations', requestToJoin: boolean } }; +export type DashboardDismissDiscoverableWorkspaceMutationVariables = Exact<{ + input: WorkspaceDismissInput; +}>; + + +export type DashboardDismissDiscoverableWorkspaceMutation = { __typename?: 'Mutation', workspaceMutations: { __typename?: 'WorkspaceMutations', dismiss: boolean } }; + export type DashboardProjectsPageQueryQueryVariables = Exact<{ [key: string]: never; }>; @@ -7017,6 +7024,7 @@ export const ServerInfoAllScopesDocument = {"kind":"Document","definitions":[{"k 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"}}]}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"CommonModelSelectorModel"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Model"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}}]} as unknown as DocumentNode; 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":"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"}},{"kind":"Field","name":{"kind":"Name","value":"configuration"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"isEmailEnabled"}}]}}]}}]}}]} as unknown as DocumentNode; export const DashboardRequestToJoinWorkspaceDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"DashboardRequestToJoinWorkspace"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"WorkspaceRequestToJoinInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"workspaceMutations"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"requestToJoin"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}]}]}}]}}]} as unknown as DocumentNode; +export const DashboardDismissDiscoverableWorkspaceDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"DashboardDismissDiscoverableWorkspace"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"WorkspaceDismissInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"workspaceMutations"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"dismiss"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}]}]}}]}}]} as unknown as DocumentNode; export const DashboardProjectsPageQueryDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"DashboardProjectsPageQuery"},"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":"projects"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"limit"},"value":{"kind":"IntValue","value":"3"}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"items"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"DashboardProjectCard_Project"}}]}}]}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"ProjectsDashboardHeaderProjects_User"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"LimitedUserAvatar"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"LimitedUser"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"avatar"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ProjectsInviteBanner"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"PendingStreamCollaborator"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"invitedBy"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"LimitedUserAvatar"}}]}},{"kind":"Field","name":{"kind":"Name","value":"projectId"}},{"kind":"Field","name":{"kind":"Name","value":"projectName"}},{"kind":"Field","name":{"kind":"Name","value":"token"}},{"kind":"Field","name":{"kind":"Name","value":"user"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"DashboardProjectCard_Project"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Project"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"role"}},{"kind":"Field","name":{"kind":"Name","value":"updatedAt"}},{"kind":"Field","name":{"kind":"Name","value":"models"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"totalCount"}}]}},{"kind":"Field","name":{"kind":"Name","value":"team"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"user"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"LimitedUserAvatar"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"workspace"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"logo"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ProjectsDashboardHeaderProjects_User"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"User"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"projectInvites"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"ProjectsInviteBanner"}}]}}]}}]} as unknown as DocumentNode; export const DashboardProjectsPageWorkspaceQueryDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"DashboardProjectsPageWorkspaceQuery"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"activeUser"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"ProjectsDashboardHeaderWorkspaces_User"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"LimitedUserAvatar"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"LimitedUser"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"avatar"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"UseWorkspaceInviteManager_PendingWorkspaceCollaborator"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"PendingWorkspaceCollaborator"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"token"}},{"kind":"Field","name":{"kind":"Name","value":"workspaceId"}},{"kind":"Field","name":{"kind":"Name","value":"workspaceSlug"}},{"kind":"Field","name":{"kind":"Name","value":"user"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"WorkspaceInviteBanner_PendingWorkspaceCollaborator"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"PendingWorkspaceCollaborator"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"invitedBy"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"LimitedUserAvatar"}}]}},{"kind":"Field","name":{"kind":"Name","value":"workspaceId"}},{"kind":"Field","name":{"kind":"Name","value":"workspaceName"}},{"kind":"Field","name":{"kind":"Name","value":"token"}},{"kind":"Field","name":{"kind":"Name","value":"user"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}}]}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"UseWorkspaceInviteManager_PendingWorkspaceCollaborator"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ProjectsDashboardHeaderWorkspaces_User"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"User"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"workspaceInvites"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"WorkspaceInviteBanner_PendingWorkspaceCollaborator"}}]}}]}}]} as unknown as DocumentNode; 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; diff --git a/packages/frontend-2/lib/common/helpers/constants.ts b/packages/frontend-2/lib/common/helpers/constants.ts index 5099e3555..67bba2737 100644 --- a/packages/frontend-2/lib/common/helpers/constants.ts +++ b/packages/frontend-2/lib/common/helpers/constants.ts @@ -4,9 +4,7 @@ export enum CookieKeys { AuthToken = 'authn', Theme = 'theme', - PostAuthRedirect = 'postAuthRedirect', - DismissedDiscoverableWorkspaces = 'dismissedDiscoverableWorkspaces', - DismissedWorkspaceBanner = 'dismissedWorkspaceBanner' + PostAuthRedirect = 'postAuthRedirect' } /** diff --git a/packages/frontend-2/lib/dashboard/graphql/mutations.ts b/packages/frontend-2/lib/dashboard/graphql/mutations.ts index 3e53ecaae..aa90e6b1e 100644 --- a/packages/frontend-2/lib/dashboard/graphql/mutations.ts +++ b/packages/frontend-2/lib/dashboard/graphql/mutations.ts @@ -7,3 +7,11 @@ export const dashboardRequestToJoinWorkspaceMutation = graphql(` } } `) + +export const dashboardDismissDiscoverableWorkspaceMutation = graphql(` + mutation DashboardDismissDiscoverableWorkspace($input: WorkspaceDismissInput!) { + workspaceMutations { + dismiss(input: $input) + } + } +`) diff --git a/packages/frontend-2/lib/workspaces/composables/discoverableWorkspaces.ts b/packages/frontend-2/lib/workspaces/composables/discoverableWorkspaces.ts index 999cd3c53..a5a15f95c 100644 --- a/packages/frontend-2/lib/workspaces/composables/discoverableWorkspaces.ts +++ b/packages/frontend-2/lib/workspaces/composables/discoverableWorkspaces.ts @@ -3,12 +3,17 @@ import { discoverableWorkspacesQuery, discoverableWorkspacesRequestsQuery } from '../graphql/queries' -import { dashboardRequestToJoinWorkspaceMutation } from '~/lib/dashboard/graphql/mutations' +import { + dashboardDismissDiscoverableWorkspaceMutation, + dashboardRequestToJoinWorkspaceMutation +} from '~/lib/dashboard/graphql/mutations' import { graphql } from '~/lib/common/generated/gql' import { useMixpanel } from '~/lib/core/composables/mp' +import type { CacheObjectReference } from '~~/lib/common/helpers/graphql' import { convertThrowIntoFetchResult, - getFirstErrorMessage + getFirstErrorMessage, + getCacheId } from '~~/lib/common/helpers/graphql' graphql(` @@ -60,16 +65,20 @@ export const useDiscoverableWorkspaces = () => { undefined, { enabled: isWorkspacesEnabled } ) - const { - result: requestsResult, - refetch, - loading: joinRequestsLoading - } = useQuery(discoverableWorkspacesRequestsQuery, undefined, { - enabled: isWorkspacesEnabled - }) + const { result: requestsResult, loading: joinRequestsLoading } = useQuery( + discoverableWorkspacesRequestsQuery, + undefined, + { + enabled: isWorkspacesEnabled + } + ) const { mutate: requestToJoin } = useMutation(dashboardRequestToJoinWorkspaceMutation) + const { mutate: dismissWorkspace } = useMutation( + dashboardDismissDiscoverableWorkspaceMutation + ) + const { activeUser } = useActiveUser() const mixpanel = useMixpanel() const { triggerNotification } = useGlobalToast() const apollo = useApolloClient().client @@ -123,40 +132,88 @@ export const useDiscoverableWorkspaces = () => { () => discoverableWorkspacesCount.value + discoverableJoinRequestsCount.value ) - const processRequest = async (accept: boolean, workspaceId: string) => { + const requestToJoinWorkspace = async (workspaceId: string) => { const cache = apollo.cache + const activeUserId = activeUser.value?.id - if (accept) { - const result = await requestToJoin({ - input: { workspaceId } - }).catch(convertThrowIntoFetchResult) + if (!activeUserId) return - if (result?.data) { - cache.evict({ - id: getCacheId('LimitedWorkspace', workspaceId) - }) - refetch() + const result = await requestToJoin({ + input: { workspaceId } + }).catch(convertThrowIntoFetchResult) - mixpanel.track('Workspace Join Request Sent', { - workspaceId, - location: 'onboarding', - // eslint-disable-next-line camelcase - workspace_id: workspaceId - }) + if (result?.data) { + cache.modify({ + id: getCacheId('User', activeUserId), + fields: { + discoverableWorkspaces(existingRefs = [], { readField }) { + return existingRefs.filter( + (ref: CacheObjectReference<'LimitedWorkspace'>) => { + const id = readField('id', ref) + return id !== workspaceId + } + ) + } + } + }) - triggerNotification({ - title: 'Request sent', - description: 'Your request to join the workspace has been sent.', - type: ToastNotificationType.Success - }) - } else { - const errorMessage = getFirstErrorMessage(result?.errors) - triggerNotification({ - title: 'Failed to send request', - description: errorMessage, - type: ToastNotificationType.Danger - }) - } + mixpanel.track('Workspace Join Request Sent', { + workspaceId, + location: 'onboarding', + // eslint-disable-next-line camelcase + workspace_id: workspaceId + }) + + triggerNotification({ + title: 'Request sent', + description: 'Your request to join the workspace has been sent.', + type: ToastNotificationType.Success + }) + } else { + const errorMessage = getFirstErrorMessage(result?.errors) + triggerNotification({ + title: 'Failed to send request', + description: errorMessage, + type: ToastNotificationType.Danger + }) + } + } + + const dismissDiscoverableWorkspace = async (workspaceId: string) => { + const result = await dismissWorkspace({ + input: { workspaceId } + }).catch(convertThrowIntoFetchResult) + const cache = apollo.cache + const activeUserId = activeUser.value?.id + + if (!activeUserId) return + + if (result?.data) { + triggerNotification({ + title: 'Discoverable workspace dismissed', + type: ToastNotificationType.Info + }) + + cache.modify({ + id: getCacheId('User', activeUserId), + fields: { + discoverableWorkspaces(existingRefs = [], { readField }) { + return existingRefs.filter( + (ref: CacheObjectReference<'LimitedWorkspace'>) => { + const id = readField('id', ref) + return id !== workspaceId + } + ) + } + } + }) + } else { + const errorMessage = getFirstErrorMessage(result?.errors) + triggerNotification({ + title: 'Failed to dismiss workspace', + description: errorMessage, + type: ToastNotificationType.Danger + }) } } @@ -172,10 +229,10 @@ export const useDiscoverableWorkspaces = () => { discoverableWorkspacesCount, discoverableWorkspacesAndJoinRequestsCount, discoverableWorkspaces, + dismissDiscoverableWorkspace, workspaceJoinRequests, discoverableWorkspacesAndJoinRequests, - processRequest, - loading, - refetch + requestToJoinWorkspace, + loading } }