From 5d755aab35be20d51b132c96671fe23845776e11 Mon Sep 17 00:00:00 2001 From: Paulo Queiroz <16908491+raggesilver@users.noreply.github.com> Date: Fri, 27 Dec 2024 00:39:13 -0300 Subject: [PATCH] Fix workspace invitation link state --- app/components/workspace/member-settings.vue | 66 ++++++++++++-------- app/composables/useWorkspaceInvitation.ts | 18 ++---- package.json | 2 +- 3 files changed, 46 insertions(+), 40 deletions(-) diff --git a/app/components/workspace/member-settings.vue b/app/components/workspace/member-settings.vue index 951505b..2d52fa4 100644 --- a/app/components/workspace/member-settings.vue +++ b/app/components/workspace/member-settings.vue @@ -6,55 +6,61 @@ const props = defineProps<{ workspace: Workspace; }>(); +const workspaceId = computed(() => props.workspace.id); + const { data: collaborators, isPending, suspense, -} = useWorkspaceCollaborators(() => props.workspace.id); +} = useWorkspaceCollaborators(workspaceId); const { data: invitationLink, isPending: isInvitationLinkPending, suspense: invitationLinkSuspense, -} = useWorkspaceInvitationLink(() => props.workspace.id); +} = useWorkspaceInvitationLink(workspaceId); const { mutateAsync: createInvitationLink, isPending: isCreatingLink } = - useCreateWorkspaceInvitationLinkMutation(() => props.workspace.id); + useCreateWorkspaceInvitationLinkMutation(workspaceId); const { mutateAsync: disableInvitationLink, isPending: isDisablingLink } = - useDeactivateWorkspaceInvitationLinkMutation(() => props.workspace.id); + useDeactivateWorkspaceInvitationLinkMutation(workspaceId); if (import.meta.env.SSR) { await Promise.all([suspense(), invitationLinkSuspense()]); } -const generateAndCopyLink = async (id: string) => { +const generateLink = async (id: string) => { const _url = useRequestURL(); const url = new URL("/api/invitation/accept", _url.origin); url.searchParams.set("token", id); - return navigator.clipboard - .writeText(url.toString()) - .then(() => toast.success("Link copied to clipboard.")) - .catch((err) => { - console.error(err); - toast.error("Failed to copy link to clipboard."); - }); + return url.toString(); }; const onInviteWithLink = async () => { if (isCreatingLink.value) return; - if (invitationLink.value) { - // invitationLink.value.id - await generateAndCopyLink(invitationLink.value.id); - return; - } - - const invitation = await createInvitationLink(); - console.log({ invitation }); - await generateAndCopyLink(invitation.id); + // We need to use ClipboardItem with async content in order for this to work + // in Safari. Otherwise, it will throw an error when we try writing to the + // clipboard after awaiting for a promise. + const item = new ClipboardItem({ + "text/plain": new Promise((resolve) => { + if (invitationLink.value) { + resolve(generateLink(invitationLink.value.id)); + } else { + createInvitationLink() + .then(({ id }) => resolve(generateLink(id))) + .catch(() => toast.error("Failed to create invitation link.")); + } + }), + }); + + await navigator.clipboard + .write([item]) + .then(() => toast.success("Invitation link copied to clipboard.")) + .catch(() => toast.error("Failed to copy invitation link to clipboard.")); }; const onDisableLink = async () => { @@ -78,8 +84,6 @@ const onDisableLink = async () => { -

Invitation link: {{ JSON.stringify(invitationLink, null, 2) }}

-

Invite Collaborators

@@ -90,10 +94,20 @@ const onDisableLink = async () => {

- diff --git a/app/composables/useWorkspaceInvitation.ts b/app/composables/useWorkspaceInvitation.ts index 34bd889..db40bd3 100644 --- a/app/composables/useWorkspaceInvitation.ts +++ b/app/composables/useWorkspaceInvitation.ts @@ -41,7 +41,7 @@ export const useCreateWorkspaceInvitationLinkMutation = ( }).then((response) => normalizeDates(response)), onSuccess: (result) => { client.setQueryData( - getWorkspaceInvitationLinkOptions(workspaceId).queryKey, + getWorkspaceInvitationLinkOptions(toValue(workspaceId)).queryKey, result, ); }, @@ -61,19 +61,11 @@ export const useDeactivateWorkspaceInvitationLinkMutation = ( method: "POST", }, ), - onSuccess: async (result) => { - const activeWorkspaceInvitationLink = client.getQueryData( - getWorkspaceInvitationLinkOptions(workspaceId).queryKey, + onSuccess: async () => { + client.setQueryData( + getWorkspaceInvitationLinkOptions(toValue(workspaceId)).queryKey, + null, ); - - console.log({ result, activeWorkspaceInvitationLink }); - - if (activeWorkspaceInvitationLink?.id === result.id) { - client.setQueryData( - getWorkspaceInvitationLinkOptions(workspaceId).queryKey, - null, - ); - } }, }); }; diff --git a/package.json b/package.json index 017c7fc..051aac4 100644 --- a/package.json +++ b/package.json @@ -77,5 +77,5 @@ "vitest": "^2.1.3", "vue-tsc": "^2.1.6" }, - "packageManager": "pnpm@9.12.3+sha512.cce0f9de9c5a7c95bef944169cc5dfe8741abfb145078c0d508b868056848a87c81e626246cb60967cbd7fd29a6c062ef73ff840d96b3c86c40ac92cf4a813ee" + "packageManager": "pnpm@9.15.0+sha512.76e2379760a4328ec4415815bcd6628dee727af3779aaa4c914e3944156c4299921a89f976381ee107d41f12cfa4b66681ca9c718f0668fa0831ed4c6d8ba56c" }