Skip to content

Commit

Permalink
Fix workspace invitation link state
Browse files Browse the repository at this point in the history
  • Loading branch information
raggesilver committed Dec 27, 2024
1 parent 876f6f6 commit 5d755aa
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 40 deletions.
66 changes: 40 additions & 26 deletions app/components/workspace/member-settings.vue
Original file line number Diff line number Diff line change
Expand Up @@ -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 () => {
Expand All @@ -78,8 +84,6 @@ const onDisableLink = async () => {
</SheetDescription>
</section>

<p>Invitation link: {{ JSON.stringify(invitationLink, null, 2) }}</p>

<section>
<h3 class="font-semibold">Invite Collaborators</h3>
<div class="flex flex-col md:flex-row gap-x-4 gap-y-2">
Expand All @@ -90,10 +94,20 @@ const onDisableLink = async () => {
</p>
<div class="flex flex-col gap-2 flex-1">
<Button @click="onInviteWithLink">
Invite with link <LazyActivityIndicator v-if="isCreatingLink" />
<Icon v-else name="lucide:link" class="ml-1" />
{{ invitationLink === null ? "Invite with link" : "Copy link" }}
<LazyActivityIndicator v-if="isCreatingLink" />
<Icon
v-else-if="invitationLink === null"
name="lucide:link"
class="ml-1"
/>
<Icon v-else name="lucide:clipboard" class="ml-1" />
</Button>
<Button variant="secondary" @click="onDisableLink">
<Button
v-if="invitationLink"
variant="secondary"
@click="onDisableLink"
>
Disable link
<LazyActivityIndicator v-if="isDisablingLink" />
</Button>
Expand Down
18 changes: 5 additions & 13 deletions app/composables/useWorkspaceInvitation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ export const useCreateWorkspaceInvitationLinkMutation = (
}).then((response) => normalizeDates<InvitationLink>(response)),
onSuccess: (result) => {
client.setQueryData(
getWorkspaceInvitationLinkOptions(workspaceId).queryKey,
getWorkspaceInvitationLinkOptions(toValue(workspaceId)).queryKey,
result,
);
},
Expand All @@ -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,
);
}
},
});
};
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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"
}

0 comments on commit 5d755aa

Please sign in to comment.