mirror of https://github.com/buster-so/buster.git
invite modal update
This commit is contained in:
parent
f99f2bddab
commit
898562b965
|
@ -11,6 +11,7 @@ import { useInviteModalStore } from '@/context/BusterAppLayout';
|
|||
import { InvitePeopleModal } from '@/components/features/modal/InvitePeopleModal';
|
||||
import { useMemoizedFn } from '@/hooks';
|
||||
import { Button } from '@/components/ui/buttons';
|
||||
import { Plus } from '@/components/ui/icons';
|
||||
|
||||
export default function Page() {
|
||||
const userOrganization = useUserConfigContextSelector((x) => x.userOrganizations);
|
||||
|
@ -43,7 +44,9 @@ export default function Page() {
|
|||
setSearchText={handleSearchChange}
|
||||
/>
|
||||
|
||||
<Button onClick={() => onToggleInviteModal(true)}>Invite people</Button>
|
||||
<Button prefix={<Plus />} onClick={() => onToggleInviteModal(true)}>
|
||||
Invite people
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -67,7 +67,7 @@ export const LoginForm: React.FC<{}> = ({}) => {
|
|||
} catch (error: any) {
|
||||
errorFallback(error);
|
||||
}
|
||||
setLoading('google');
|
||||
setLoading(null);
|
||||
});
|
||||
|
||||
const onSignInWithGithub = useMemoizedFn(async () => {
|
||||
|
@ -78,7 +78,7 @@ export const LoginForm: React.FC<{}> = ({}) => {
|
|||
} catch (error: any) {
|
||||
errorFallback(error);
|
||||
}
|
||||
setLoading('github');
|
||||
setLoading(null);
|
||||
});
|
||||
|
||||
const onSignInWithAzure = useMemoizedFn(async () => {
|
||||
|
@ -182,6 +182,10 @@ const LoginOptions: React.FC<{
|
|||
Object.keys(Cookies.get()).forEach((cookieName) => {
|
||||
Cookies.remove(cookieName);
|
||||
});
|
||||
|
||||
//also clear local storage
|
||||
localStorage.clear();
|
||||
sessionStorage.clear();
|
||||
});
|
||||
|
||||
const onSubmitClickPreflight = useMemoizedFn(async (d: { email: string; password: string }) => {
|
||||
|
|
|
@ -5,6 +5,7 @@ import { InputTagInput } from '@/components/ui/inputs/InputTagInput';
|
|||
import { useInviteUser } from '@/api/buster_rest/users';
|
||||
import { validate } from 'email-validator';
|
||||
import { useBusterNotifications } from '@/context/BusterNotifications';
|
||||
import uniq from 'lodash/uniq';
|
||||
|
||||
export const InvitePeopleModal: React.FC<{
|
||||
open: boolean;
|
||||
|
@ -12,10 +13,12 @@ export const InvitePeopleModal: React.FC<{
|
|||
}> = React.memo(({ open, onClose }) => {
|
||||
const [emails, setEmails] = React.useState<string[]>([]);
|
||||
const { mutateAsync: inviteUsers, isPending: inviting } = useInviteUser();
|
||||
const [inputText, setInputText] = React.useState<string>('');
|
||||
const { openErrorMessage } = useBusterNotifications();
|
||||
|
||||
const handleInvite = useMemoizedFn(async () => {
|
||||
await inviteUsers({ emails });
|
||||
const allEmails = uniq([...emails, inputText].filter((email) => !!email && validate(email)));
|
||||
await inviteUsers({ emails: allEmails });
|
||||
onClose();
|
||||
});
|
||||
|
||||
|
@ -26,22 +29,27 @@ export const InvitePeopleModal: React.FC<{
|
|||
};
|
||||
}, []);
|
||||
|
||||
const isInputTextValidEmail = useMemo(() => {
|
||||
return validate(inputText);
|
||||
}, [inputText]);
|
||||
|
||||
const memoizedFooter = useMemo(() => {
|
||||
return {
|
||||
primaryButton: {
|
||||
text: 'Send invites',
|
||||
onClick: handleInvite,
|
||||
loading: inviting,
|
||||
disabled: emails.length === 0
|
||||
disabled: inputText.length ? !isInputTextValidEmail : emails.length === 0
|
||||
}
|
||||
};
|
||||
}, [inviting, emails.length]);
|
||||
}, [inviting, isInputTextValidEmail, emails.length, inputText.length]);
|
||||
|
||||
return (
|
||||
<AppModal open={open} onClose={onClose} header={memoizedHeader} footer={memoizedFooter}>
|
||||
<div className="flex flex-col">
|
||||
<InputTagInput
|
||||
tags={emails}
|
||||
onChangeText={setInputText}
|
||||
onTagAdd={(v) => {
|
||||
if (validate(v)) {
|
||||
setEmails([...emails, v]);
|
||||
|
|
|
@ -11,6 +11,7 @@ export interface TagInputProps extends VariantProps<typeof inputVariants> {
|
|||
tags: string[];
|
||||
onTagAdd?: (tag: string) => void;
|
||||
onTagRemove?: (index: number) => void;
|
||||
onChangeText?: (text: string) => void;
|
||||
placeholder?: string;
|
||||
disabled?: boolean;
|
||||
maxTags?: number;
|
||||
|
@ -26,6 +27,7 @@ const InputTagInput = React.forwardRef<HTMLInputElement, TagInputProps>(
|
|||
tags = [],
|
||||
onTagAdd,
|
||||
onTagRemove,
|
||||
onChangeText,
|
||||
placeholder,
|
||||
disabled = false,
|
||||
maxTags,
|
||||
|
@ -72,6 +74,7 @@ const InputTagInput = React.forwardRef<HTMLInputElement, TagInputProps>(
|
|||
} else {
|
||||
setInputValue(value);
|
||||
}
|
||||
onChangeText?.(value);
|
||||
});
|
||||
|
||||
// Focus the container when clicked
|
||||
|
|
Loading…
Reference in New Issue