chore(member-invite): early return for pending mutations while copying invite link (#28753)
* chore(member-invite): early return for pending mutations while copying invite link * typo fix * make rabbit happy --------- Co-authored-by: Romit <85230081+romitg2@users.noreply.github.com>
This commit is contained in:
1 parent
dcbb417aec
commit
f3e07c5223
1 file changed
+47
-33
@@ -1,7 +1,7 @@
|
||||
import { useSession } from "next-auth/react";
|
||||
import posthog from "posthog-js";
|
||||
import type { FormEvent } from "react";
|
||||
import { useMemo, useRef, useState } from "react";
|
||||
import { useCallback, useMemo, useRef, useState } from "react";
|
||||
import { Controller, useForm } from "react-hook-form";
|
||||
|
||||
import TeamInviteFromOrg from "~/ee/organizations/components/TeamInviteFromOrg";
|
||||
@@ -89,6 +89,7 @@ export default function MemberInvitationModal(props: MemberInvitationModalProps)
|
||||
const [modalImportMode, setModalInputMode] = useState<ModalMode>(
|
||||
canSeeOrganization ? "ORGANIZATION" : "INDIVIDUAL"
|
||||
);
|
||||
const [isCopying, setIsCopying] = useState(false);
|
||||
|
||||
const createInviteMutation = trpc.viewer.teams.createInvite.useMutation({
|
||||
async onSuccess() {
|
||||
@@ -193,6 +194,48 @@ export default function MemberInvitationModal(props: MemberInvitationModalProps)
|
||||
|
||||
const importRef = useRef<HTMLInputElement | null>(null);
|
||||
|
||||
const handleCopyInviteLink = useCallback(async () => {
|
||||
if (isCopying || createInviteMutation.isPending) return;
|
||||
|
||||
setIsCopying(true);
|
||||
try {
|
||||
// Required for Safari but also works on Chrome
|
||||
// Credits to https://wolfgangrittner.dev/how-to-use-clipboard-api-in-firefox/
|
||||
if (typeof ClipboardItem !== "undefined") {
|
||||
const inviteLinkClipboardItem = new ClipboardItem({
|
||||
//eslint-disable-next-line no-async-promise-executor
|
||||
"text/plain": new Promise((resolve, reject) => {
|
||||
// Instead of doing async work and then writing to clipboard, do async work in clipboard API itself
|
||||
createInviteMutation.mutateAsync({
|
||||
teamId: props.teamId,
|
||||
token: props.token,
|
||||
}).then(({ inviteLink }) => {
|
||||
resolve(new Blob([inviteLink], { type: "text/plain" }));
|
||||
})
|
||||
.catch((err) => {
|
||||
reject(err);
|
||||
});
|
||||
}),
|
||||
});
|
||||
await navigator.clipboard.write([inviteLinkClipboardItem]);
|
||||
showToast(t("invite_link_copied"), "success");
|
||||
} else {
|
||||
// Fallback for browsers that don't support ClipboardItem e.g. Firefox
|
||||
const { inviteLink } = await createInviteMutation.mutateAsync({
|
||||
teamId: props.teamId,
|
||||
token: props.token,
|
||||
});
|
||||
await navigator.clipboard.writeText(inviteLink);
|
||||
showToast(t("invite_link_copied"), "success");
|
||||
}
|
||||
} catch (e) {
|
||||
showToast(t("something_went_wrong_on_our_end"), "error");
|
||||
console.error(e);
|
||||
} finally {
|
||||
setIsCopying(false);
|
||||
}
|
||||
}, [isCopying, createInviteMutation, props.teamId, props.token, t]);
|
||||
|
||||
return (
|
||||
<Dialog
|
||||
name="inviteModal"
|
||||
@@ -412,38 +455,9 @@ export default function MemberInvitationModal(props: MemberInvitationModalProps)
|
||||
type="button"
|
||||
color="minimal"
|
||||
variant="icon"
|
||||
onClick={async function () {
|
||||
try {
|
||||
// Required for Safari but also works on Chrome
|
||||
// Credits to https://wolfgangrittner.dev/how-to-use-clipboard-api-in-firefox/
|
||||
if (typeof ClipboardItem !== "undefined") {
|
||||
const inviteLinkClipbardItem = new ClipboardItem({
|
||||
//eslint-disable-next-line no-async-promise-executor
|
||||
"text/plain": new Promise(async (resolve) => {
|
||||
// Instead of doing async work and then writing to clipboard, do async work in clipboard API itself
|
||||
const { inviteLink } = await createInviteMutation.mutateAsync({
|
||||
teamId: props.teamId,
|
||||
token: props.token,
|
||||
});
|
||||
showToast(t("invite_link_copied"), "success");
|
||||
resolve(new Blob([inviteLink], { type: "text/plain" }));
|
||||
}),
|
||||
});
|
||||
await navigator.clipboard.write([inviteLinkClipbardItem]);
|
||||
} else {
|
||||
// Fallback for browsers that don't support ClipboardItem e.g. Firefox
|
||||
const { inviteLink } = await createInviteMutation.mutateAsync({
|
||||
teamId: props.teamId,
|
||||
token: props.token,
|
||||
});
|
||||
await navigator.clipboard.writeText(inviteLink);
|
||||
showToast(t("invite_link_copied"), "success");
|
||||
}
|
||||
} catch (e) {
|
||||
showToast(t("something_went_wrong_on_our_end"), "error");
|
||||
console.error(e);
|
||||
}
|
||||
}}
|
||||
onClick={handleCopyInviteLink}
|
||||
loading={isCopying || createInviteMutation.isPending}
|
||||
disabled={isCopying || createInviteMutation.isPending}
|
||||
className={classNames("gap-2", props.token && "opacity-50")}
|
||||
StartIcon="link"
|
||||
data-testid="copy-invite-link-button">
|
||||
|
||||
Reference in new issue
Block a user