Files
speckle-server/packages/frontend-2/components/developer-settings/CreateTokenDialog.vue
T
andrewwallacespeckle 9f4b0c99da Dialog Consistency Task (#1852)
* Fixing up "Manage Project" & "New Project" Dialogs

* Dialog Updates

* Updates from tickets

* Remove sidepanel

* Remove max-height prop from Dialog component

* Updates to Profile Dialog

* Props for Buttons in Dialog. Attachment Dialog

* Remove margin to show issue with dialogs

* Update to stories

* Responsive updates

* Fix overflow on MoveTo

* Use Dialog header prop

* Dialog updates

* Responsive Changes

* Responsive fixes

* Small responsive change

* Fixes

* Type based declaration

* Last fixes

* Small darkmode fixes

* Updated type

* Update

* Updates from PR comments

* Fix storybook issues

* Updates from PR

* Updates from PR

* Changes from Agi

* Turntable mode Toggle

* Fix dialog shadows on scroll

* Fix invite autocomplete

* Changes from PR Comments

* Small styling updates

* Responsive views

* Adjust Danger zones

* Fix typo

* New Webhook Icon. Swap icon prop to slot.

* Adjust Icon weights

* FE2-TASK-27

* FE2-TASK-26

* FE2-TASK-28
2023-11-07 11:18:25 +00:00

130 lines
3.5 KiB
Vue

<template>
<LayoutDialog
v-model:open="isOpen"
max-width="sm"
:buttons="dialogButtons"
prevent-close-on-click-outside
>
<template #header>Create Token</template>
<form @submit="onSubmit">
<div class="flex flex-col gap-6">
<FormTextInput
v-model="name"
label="Name"
help="A name to remember this token by. For example, the name of the script or application you're planning to use it in!"
name="hookName"
:rules="[isRequired]"
show-required
show-label
type="text"
/>
<FormSelectBadges
v-model="scopes"
multiple
name="scopes"
label="Scopes"
placeholder="Choose Scopes"
help="It's good practice to limit the scopes of your token to the absolute minimum. For example, if your application or script will only read and write streams, select just those scopes."
show-required
:rules="[isItemSelected]"
show-label
:items="apiTokenScopes"
mount-menu-on-body
by="id"
/>
</div>
</form>
</LayoutDialog>
</template>
<script setup lang="ts">
import { useMutation } from '@vue/apollo-composable'
import { AllScopes } from '@speckle/shared'
import { LayoutDialog, FormSelectBadges } from '@speckle/ui-components'
import { TokenFormValues } from '~~/lib/developer-settings/helpers/types'
import { createAccessTokenMutation } from '~~/lib/developer-settings/graphql/mutations'
import { isItemSelected, isRequired } from '~~/lib/common/helpers/validation'
import { useForm } from 'vee-validate'
import {
convertThrowIntoFetchResult,
getFirstErrorMessage
} from '~~/lib/common/helpers/graphql'
import { useGlobalToast, ToastNotificationType } from '~~/lib/common/composables/toast'
const emit = defineEmits<{
(e: 'token-created', tokenId: string): void
}>()
const { mutate: createToken } = useMutation(createAccessTokenMutation)
const { triggerNotification } = useGlobalToast()
const { handleSubmit } = useForm<TokenFormValues>()
const isOpen = defineModel<boolean>('open', { required: true })
const name = ref('')
const scopes = ref<typeof apiTokenScopes.value>([])
const apiTokenScopes = computed(() => {
return Object.values(AllScopes).map((value) => ({
id: value,
text: value
}))
})
const onSubmit = handleSubmit(async (tokenFormValues) => {
const result = await createToken({
token: {
name: name.value,
scopes: tokenFormValues.scopes.map((t) => t.id)
}
}).catch(convertThrowIntoFetchResult)
if (result?.data?.apiTokenCreate) {
isOpen.value = false
resetFormFields()
emit('token-created', result.data.apiTokenCreate)
triggerNotification({
type: ToastNotificationType.Success,
title: 'Webhook created',
description: 'The webhook has been successfully created'
})
} else {
const errorMessage = getFirstErrorMessage(result?.errors)
triggerNotification({
type: ToastNotificationType.Danger,
title: 'Failed to create token',
description: errorMessage
})
}
})
const dialogButtons = computed(() => [
{
text: 'Cancel',
props: { color: 'secondary', fullWidth: true, outline: true },
onClick: () => {
isOpen.value = false
}
},
{
text: 'Create',
props: { color: 'primary', fullWidth: true },
onClick: onSubmit
}
])
const resetFormFields = () => {
name.value = ''
scopes.value = []
}
watch(
() => isOpen.value,
(newVal) => {
if (newVal) {
resetFormFields()
}
}
)
</script>