diff --git a/app/components/CopyToClipboard.ts b/app/components/CopyToClipboard.ts index e106d4823..2fcd7b49d 100644 --- a/app/components/CopyToClipboard.ts +++ b/app/components/CopyToClipboard.ts @@ -26,6 +26,9 @@ function CopyToClipboard(props: Props, ref: React.Ref) { if (elem && elem.props && typeof elem.props.onClick === "function") { elem.props.onClick(ev); + } else { + ev.preventDefault(); + ev.stopPropagation(); } }, [children, onCopy, text] diff --git a/app/components/InputSelect.tsx b/app/components/InputSelect.tsx index 1497ab96f..7eefbf947 100644 --- a/app/components/InputSelect.tsx +++ b/app/components/InputSelect.tsx @@ -250,7 +250,7 @@ const InputSelect = (props: Props, ref: React.RefObject) => { const isSelected = select.selectedValue === opt.value; const Icon = isSelected ? CheckmarkIcon : Spacer; return ( - <> + {opt.divider && } ) => {   {labelForOption(opt)} - + ); }) : null} diff --git a/app/components/Sharing/Collection/SharePopover.tsx b/app/components/Sharing/Collection/SharePopover.tsx index 86d00af9d..a9bcfe9bf 100644 --- a/app/components/Sharing/Collection/SharePopover.tsx +++ b/app/components/Sharing/Collection/SharePopover.tsx @@ -143,7 +143,7 @@ function SharePopover({ collection, visible, onRequestClose }: Props) { role: team.defaultUserRole, }, ]); - user = response.users[0]; + user = response[0]; } else { user = users.get(idOrEmail); group = groups.get(idOrEmail); diff --git a/app/components/Sharing/Document/SharePopover.tsx b/app/components/Sharing/Document/SharePopover.tsx index a51a688e0..6f7b97659 100644 --- a/app/components/Sharing/Document/SharePopover.tsx +++ b/app/components/Sharing/Document/SharePopover.tsx @@ -137,7 +137,7 @@ function SharePopover({ role: team.defaultUserRole, }, ]); - user = response.users[0]; + user = response[0]; } else { user = users.get(idOrEmail); } @@ -242,7 +242,7 @@ function SharePopover({ const rightButton = picker ? ( pendingIds.length ? ( - {t("Invite")} + {t("Add")} ) : null ) : ( diff --git a/app/components/Sharing/components/Suggestions.tsx b/app/components/Sharing/components/Suggestions.tsx index 945f35267..f31931769 100644 --- a/app/components/Sharing/components/Suggestions.tsx +++ b/app/components/Sharing/components/Suggestions.tsx @@ -14,6 +14,7 @@ import User from "~/models/User"; import Avatar from "~/components/Avatar"; import { AvatarSize, IAvatar } from "~/components/Avatar/Avatar"; import Empty from "~/components/Empty"; +import Placeholder from "~/components/List/Placeholder"; import useCurrentUser from "~/hooks/useCurrentUser"; import useStores from "~/hooks/useStores"; import useThrottledCallback from "~/hooks/useThrottledCallback"; @@ -51,18 +52,26 @@ export const Suggestions = observer( removePendingId, showGroups, }: Props) => { + const neverRenderedList = React.useRef(false); const { users, groups } = useStores(); const { t } = useTranslation(); const user = useCurrentUser(); const theme = useTheme(); - const fetchUsersByQuery = useThrottledCallback((params) => { - void users.fetchPage({ query: params.query }); + const fetchUsersByQuery = useThrottledCallback( + (params) => { + void users.fetchPage({ query: params.query }); - if (showGroups) { - void groups.fetchPage({ query: params.query }); + if (showGroups) { + void groups.fetchPage({ query: params.query }); + } + }, + 250, + undefined, + { + leading: true, } - }, 250); + ); const getSuggestionForEmail = React.useCallback( (email: string) => ({ @@ -158,6 +167,12 @@ export const Suggestions = observer( (u) => !pendingIds.includes(u.id) ); + if (users.isFetching && isEmpty && neverRenderedList.current) { + return ; + } + + neverRenderedList.current = false; + return ( <> {pending.map((suggestion) => ( diff --git a/app/scenes/Invite.tsx b/app/scenes/Invite.tsx index 1ee352c97..28e1c625e 100644 --- a/app/scenes/Invite.tsx +++ b/app/scenes/Invite.tsx @@ -51,12 +51,12 @@ function Invite({ onSubmit }: Props) { setIsSaving(true); try { - const data = await users.invite( + const response = await users.invite( invites.filter((i) => i.email).map((memo) => ({ ...memo, role })) ); onSubmit(); - if (data.sent.length > 0) { + if (response.length > 0) { toast.success(t("We sent out your invites!")); } else { toast.message(t("Those email addresses are already invited")); diff --git a/app/stores/UsersStore.ts b/app/stores/UsersStore.ts index 497ec3805..87461bdc7 100644 --- a/app/stores/UsersStore.ts +++ b/app/stores/UsersStore.ts @@ -100,15 +100,17 @@ export default class UsersStore extends Store { name: string; role: UserRole; }[] - ) => { + ): Promise => { const res = await client.post(`/users.invite`, { invites, }); invariant(res?.data, "Data should be available"); + + let response: User[] = []; runInAction(`invite`, () => { - res.data.users.forEach(this.add); + response = res.data.users.map(this.add); }); - return res.data; + return response; }; @action