Files
speckle-server/packages/frontend-2/components/server-management/InviteDialog.vue
T
andrewwallacespeckle 671979e012 Feature - Frontend2 - Server Settings Pages (#1764)
* Add server management menu item

* Server Management Page & Settings Dialog

* escape from the precommits hooks

* Add Delete User Dialog

* Add invitations page

* Add Projects Page

* Pulling in GraphQL Data

* Settings Mutations

* Fix cardinfo type

* GraphQL in Active Users

* Add icons

* Infinite Load on Active Users

* Tidy Ups

* TS fixes

* Add Update button functionality

* Add Delete User

* Projects

* Home Done

* New query

* Delete User

* WIP User Roles

* Overflow fix

* Table Update

* Add Onclick to rows

* Fix bugs

* Fix console error

* Admin Middleware

* Role Update Dialog

* TS Fixes

* Latest updates

* Tidyups

* Tidy Up Nav Menu

* Tidy Up Card

* ChangeUserRoleDialog Tidyup

* Fix bubbling issue on Table

* Design fixes

* fix: speckle server version hydration mismatch

* Remove Dialog bg-white

* Rename Query, Fix Export

* fix: allowing FormSelectBase to reject updates

* feat: cache policies for new admin graph fields

* feat: cache updates so no refetch necessary

* PR Changes

* Fix Projects Page

* Updates to Roles

* Project Delete Mutation

* Add Resend & Delete Invite Mutation

* Fix console warnings

* Disable active user role select

* Linting fixes

* Reorder

* Linting fixes

* Changes from PR

* Fixes from PR

* Ui Fixes

* Update Settings Dialog Cache on Save

* Fix colours

* Delete Invitation Mutation Moved

* Delete Project Logic moved

* Delete Mutation moved to component

* Change User Role mutation moved to Dialog

* Reorder

* WIP - Checkbox Bug

* attempted checkbox fix

* Update Caching

* Rollback tsc

* Update to Resend Button

* Add new buttons

* Use defineModel

* Re-add emits

* Move mutation

* serverInfo cache update fix

* fixed delete invite cache update

* Updates to Project Delete Dialog Caching

* Remove unneeded props

* Fix caching in DeleteUserDialog

* Improved error handling in server info update

* Swap Invite modal to new style

* updated evictObjectFields details

* Update cache on successfull invite

* Add Invite dialog

* Add project Dialog Update

* defineModel

* Remove emits from Add Project and Invites

* Add missing Dialog

* Updates from PR

* Adjust query

* Remove need for items in admin data query

---------

Co-authored-by: Kristaps Fabians Geikins <fabis94@live.com>
2023-09-04 11:57:34 +01:00

143 lines
4.4 KiB
Vue

<template>
<LayoutDialog
v-model:open="isOpen"
max-width="md"
title="Get your colleagues in!"
:buttons="dialogButtons"
>
<form @submit="onSubmit">
<div class="flex flex-col space-y-4 text-foreground">
<p>
Speckle will send a server invite link to the email(-s) below. You can also
add a personal message if you want to. To add multiple e-mails, seperate them
with commas.
</p>
<FormTextInput
:custom-icon="EnvelopeIcon"
name="emailsString"
label="E-mail"
placeholder="example@example.com, example2@example.com"
:rules="[isRequired, isOneOrMultipleEmails]"
:disabled="anyMutationsLoading"
/>
<FormTextArea
name="message"
label="Message"
:disabled="anyMutationsLoading"
:rules="[isStringOfLength({ maxLength: 1024 })]"
placeholder="Write an optional invitation message!"
/>
<div
class="grow flex flex-col space-y-4 sm:space-y-0 sm:flex-row sm:justify-between sm:items-center"
>
<div
class="grow flex flex-col space-y-2 sm:flex-row sm:space-x-2 sm:space-y-0"
>
<FormSelectProjects
v-model="selectedProject"
label="(Optional) Select project to invite to"
class="w-full sm:w-60"
owned-only
show-label
/>
<FormSelectServerRoles
v-if="allowServerRoleSelect"
v-model="serverRole"
label="Select server role"
show-label
:allow-guest="isGuestMode"
:allow-admin="isAdmin"
/>
</div>
</div>
</div>
</form>
</LayoutDialog>
</template>
<script setup lang="ts">
import { EnvelopeIcon } from '@heroicons/vue/24/solid'
import { Optional, Roles, ServerRoles } from '@speckle/shared'
import { useMutationLoading } from '@vue/apollo-composable'
import { useForm } from 'vee-validate'
import { useActiveUser } from '~~/lib/auth/composables/activeUser'
import { FormSelectProjects_ProjectFragment } from '~~/lib/common/generated/gql/graphql'
import {
isRequired,
isOneOrMultipleEmails,
isStringOfLength
} from '~~/lib/common/helpers/validation'
import { useMixpanel } from '~~/lib/core/composables/mp'
import { useServerInfo } from '~~/lib/core/composables/server'
import { useInviteUserToProject } from '~~/lib/projects/composables/projectManagement'
import { useInviteUserToServer } from '~~/lib/server/composables/invites'
const selectedProject = ref(undefined as Optional<FormSelectProjects_ProjectFragment>)
const serverRole = ref<ServerRoles>(Roles.Server.User)
const { handleSubmit } = useForm<{ message?: string; emailsString: string }>()
const { mutate: inviteUserToServer } = useInviteUserToServer()
const inviteUserToProject = useInviteUserToProject()
const anyMutationsLoading = useMutationLoading()
const { isAdmin } = useActiveUser()
const { isGuestMode } = useServerInfo()
const isOpen = defineModel<boolean>('open', { required: true })
const allowServerRoleSelect = computed(() => isAdmin.value || isGuestMode.value)
const mp = useMixpanel()
const onSubmit = handleSubmit(async (values) => {
const emails = values.emailsString.split(',').map((i) => i.trim())
const project = selectedProject.value
const success = project
? await inviteUserToProject(
project.id,
emails.map((email) => ({
email,
serverRole: allowServerRoleSelect.value ? serverRole.value : undefined
}))
)
: await inviteUserToServer(
emails.map((email) => ({
email,
message: values.message,
serverRole: allowServerRoleSelect.value ? serverRole.value : undefined
}))
)
if (success) {
isOpen.value = false
selectedProject.value = undefined
mp.track('Invite Action', {
type: 'server invite',
name: 'send',
multiple: emails.length !== 1,
count: emails.length,
hasProject: !!project,
to: 'email'
})
}
})
const dialogButtons = computed(() => [
{
text: 'Cancel',
props: { color: 'secondary', fullWidth: true },
onClick: () => {
isOpen.value = false
}
},
{
text: 'Send',
props: {
color: 'primary',
fullWidth: true,
outline: true,
submit: true,
disabled: anyMutationsLoading.value
},
onClick: onSubmit
}
])
</script>