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) }}
-