Files
speckle-server/packages/frontend-2/components/settings/server/user/ChangeRoleDialog.vue
T
andrewwallacespeckle d6754d6c80 fix(fe2): Align dialogs with the designs (#2895)
* Updates to Dialogs

* Updates to dialogs
2024-09-09 13:46:53 +01:00

131 lines
3.8 KiB
Vue

<template>
<LayoutDialog v-model:open="isOpen" max-width="xs" :buttons="dialogButtons">
<template #header>Change role</template>
<div class="flex flex-col gap-6 text-sm text-foreground">
<p>
Are you sure you want to
<strong>change the role of</strong>
the selected user?
</p>
<div v-if="user && newRole && oldRole" class="flex flex-col gap-3">
<div class="flex items-center gap-2">
<UserAvatar :user="user" />
{{ user.name }}
</div>
<div class="flex gap-2 items-center">
<span class="capitalize">{{ getRoleLabel(oldRole) }}</span>
<ArrowLongRightIcon class="h-6 w-6" />
<strong class="capitalize">{{ getRoleLabel(newRole) }}</strong>
</div>
</div>
<div
v-if="user && newRole === Roles.Server.Admin"
class="flex gap-2 items-center bg-danger-lighter dark:bg-danger border-danger-darker dark:border-danger-lighter border rounded-lg p-2"
>
<ExclamationTriangleIcon
class="h-8 w-8 mt-0.5 text-danger-darker dark:text-danger-lighter"
/>
<div>
<p>Make sure you trust {{ user.name }}!</p>
<p>An admin on the server has access to every resource.</p>
</div>
</div>
</div>
</LayoutDialog>
</template>
<script setup lang="ts">
import { computed } from 'vue'
import { LayoutDialog, type LayoutDialogButton } from '@speckle/ui-components'
import type { UserItem } from '~~/lib/server-management/helpers/types'
import { Roles } from '@speckle/shared'
import type { ServerRoles } from '@speckle/shared'
import { ArrowLongRightIcon, ExclamationTriangleIcon } from '@heroicons/vue/20/solid'
import { getRoleLabel } from '~~/lib/server-management/helpers/utils'
import { changeRoleMutation } from '~~/lib/server-management/graphql/mutations'
import { useGlobalToast, ToastNotificationType } from '~~/lib/common/composables/toast'
import { useMutation } from '@vue/apollo-composable'
import {
convertThrowIntoFetchResult,
getCacheId,
getFirstErrorMessage
} from '~~/lib/common/helpers/graphql'
const emit = defineEmits<{
(e: 'update:open', val: boolean): void
}>()
const props = defineProps<{
open: boolean
user: UserItem | null
oldRole: ServerRoles | undefined
newRole: ServerRoles | undefined
}>()
const { triggerNotification } = useGlobalToast()
const { mutate: mutateChangeRole } = useMutation(changeRoleMutation)
const isOpen = computed({
get: () => props.open,
set: (newVal) => emit('update:open', newVal)
})
const changeUserRoleConfirmed = async () => {
if (!props.user || !props.newRole) {
return
}
const userId = props.user?.id
const newRoleVal = props.newRole
const result = await mutateChangeRole(
{
userRoleInput: { id: userId, role: newRoleVal }
},
{
update: (cache, { data }) => {
if (data?.userRoleChange) {
cache.modify({
id: getCacheId('AdminUserListItem', userId),
fields: {
role: () => newRoleVal
}
})
}
}
}
).catch(convertThrowIntoFetchResult)
if (result?.data?.userRoleChange) {
triggerNotification({
type: ToastNotificationType.Success,
title: 'User role updated',
description: 'The user role has been updated'
})
emit('update:open', false)
} else {
const errorMessage = getFirstErrorMessage(result?.errors)
triggerNotification({
type: ToastNotificationType.Danger,
title: 'Failed to update role',
description: errorMessage
})
}
emit('update:open', false)
}
const dialogButtons = computed((): LayoutDialogButton[] => [
{
text: 'Change role',
props: { color: 'danger' },
onClick: changeUserRoleConfirmed
},
{
text: 'Cancel',
props: { color: 'outline' },
onClick: () => emit('update:open', false)
}
])
</script>