diff --git a/packages/nc-gui/components/project/InviteProjectCollabSection.vue b/packages/nc-gui/components/project/InviteProjectCollabSection.vue index 35f85c8a05..dd67518176 100644 --- a/packages/nc-gui/components/project/InviteProjectCollabSection.vue +++ b/packages/nc-gui/components/project/InviteProjectCollabSection.vue @@ -9,6 +9,65 @@ const inviteData = reactive({ roles: ProjectRoles.VIEWER, }) +const focusRef = ref() +const isDivFocused = ref(false) +const divRef = ref() + +const emailValidation = reactive({ + isError: false, + message: '', +}) + +const validateEmail = (email: string): boolean => { + const regEx = /^[^\s@]+@[^\s@]+\.[^\s@]+$/ + return regEx.test(email) +} + +// all user input emails are stored here +const emailBadges = ref>([]) +watch(inviteData, (newVal) => { + if (newVal.email.includes(',')) { + if (inviteData.email.length < 1) { + emailValidation.isError = true + emailValidation.message = 'email should not be empty' + return + } + if (!validateEmail(inviteData.email.trim())) { + emailValidation.isError = true + emailValidation.message = 'invalid email' + return + } + // if email is already enterd we just ignore the input + // no error is thrown + if (emailBadges.value.includes(newVal.email.split(',')[0])) { + inviteData.email = '' + return + } + const emailToAdd = newVal.email.split(',')[0].trim() + emailBadges.value.push(emailToAdd) + inviteData.email = '' + } + if (newVal.email.length < 1 && emailValidation.isError) { + emailValidation.isError = false + } +}) + +const handleEnter = () => { + if (inviteData.email.length < 1) { + emailValidation.isError = true + emailValidation.message = 'email should not be empty' + return + } + if (!validateEmail(inviteData.email.trim())) { + emailValidation.isError = true + emailValidation.message = 'invalid email' + return + } + inviteData.email += ',' + emailValidation.isError = false + emailValidation.message = '' +} + const { dashboardUrl } = useDashboard() const { inviteUser } = useManageUsers() @@ -36,6 +95,7 @@ const inviteCollaborator = async () => { if (usersData.value) { message.success('Invitation sent successfully') inviteData.email = '' + emailBadges.value = [] emit('invited') } } catch (e: any) { @@ -76,11 +136,25 @@ const copyUrl = async () => { // Copied shareable base url to clipboard! message.success(t('msg.success.shareableURLCopied')) + inviteData.email = '' + emailBadges.value = [] } catch (e: any) { message.error(e.message) } $e('c:shared-base:copy-url') } + +const focusOnDiv = () => { + focusRef.value?.focus() + isDivFocused.value = true +} + +// remove one email per backspace +onKeyStroke('Backspace', () => { + if (isDivFocused.value && inviteData.email.length < 1) { + emailBadges.value.pop() + } +})