Browse Source

refactor(gui-v2): update invitation link in UsersModal

pull/3109/head
braks 2 years ago
parent
commit
ca6d1198a0
  1. 8
      packages/nc-gui-v2/components.d.ts
  2. 17
      packages/nc-gui-v2/components/tabs/auth/UserManagement.vue
  3. 42
      packages/nc-gui-v2/components/tabs/auth/user-management/UsersModal.vue
  4. 1
      packages/nc-gui-v2/lib/types.ts

8
packages/nc-gui-v2/components.d.ts vendored

@ -65,8 +65,13 @@ declare module '@vue/runtime-core' {
AUploadDragger: typeof import('ant-design-vue/es')['UploadDragger'] AUploadDragger: typeof import('ant-design-vue/es')['UploadDragger']
CilFullscreen: typeof import('~icons/cil/fullscreen')['default'] CilFullscreen: typeof import('~icons/cil/fullscreen')['default']
CilFullscreenExit: typeof import('~icons/cil/fullscreen-exit')['default'] CilFullscreenExit: typeof import('~icons/cil/fullscreen-exit')['default']
ClaritySuccessLine: typeof import('~icons/clarity/success-line')['default']
EvaEmailOutline: typeof import('~icons/eva/email-outline')['default']
IcBaselineMoreVert: typeof import('~icons/ic/baseline-more-vert')['default']
IcOutlineInsertDriveFile: typeof import('~icons/ic/outline-insert-drive-file')['default'] IcOutlineInsertDriveFile: typeof import('~icons/ic/outline-insert-drive-file')['default']
IcRoundEdit: typeof import('~icons/ic/round-edit')['default']
IcRoundKeyboardArrowDown: typeof import('~icons/ic/round-keyboard-arrow-down')['default'] IcRoundKeyboardArrowDown: typeof import('~icons/ic/round-keyboard-arrow-down')['default']
IcRoundSearch: typeof import('~icons/ic/round-search')['default']
MaterialSymbolsAttachFile: typeof import('~icons/material-symbols/attach-file')['default'] MaterialSymbolsAttachFile: typeof import('~icons/material-symbols/attach-file')['default']
MaterialSymbolsChevronLeftRounded: typeof import('~icons/material-symbols/chevron-left-rounded')['default'] MaterialSymbolsChevronLeftRounded: typeof import('~icons/material-symbols/chevron-left-rounded')['default']
MaterialSymbolsChevronRightRounded: typeof import('~icons/material-symbols/chevron-right-rounded')['default'] MaterialSymbolsChevronRightRounded: typeof import('~icons/material-symbols/chevron-right-rounded')['default']
@ -79,6 +84,7 @@ declare module '@vue/runtime-core' {
MdiAccountCircle: typeof import('~icons/mdi/account-circle')['default'] MdiAccountCircle: typeof import('~icons/mdi/account-circle')['default']
MdiAccountGroup: typeof import('~icons/mdi/account-group')['default'] MdiAccountGroup: typeof import('~icons/mdi/account-group')['default']
MdiAccountIcon: typeof import('~icons/mdi/account-icon')['default'] MdiAccountIcon: typeof import('~icons/mdi/account-icon')['default']
MdiAccountOutline: typeof import('~icons/mdi/account-outline')['default']
MdiAlphaA: typeof import('~icons/mdi/alpha-a')['default'] MdiAlphaA: typeof import('~icons/mdi/alpha-a')['default']
MdiApi: typeof import('~icons/mdi/api')['default'] MdiApi: typeof import('~icons/mdi/api')['default']
MdiArrowExpand: typeof import('~icons/mdi/arrow-expand')['default'] MdiArrowExpand: typeof import('~icons/mdi/arrow-expand')['default']
@ -102,7 +108,9 @@ declare module '@vue/runtime-core' {
MdiDownload: typeof import('~icons/mdi/download')['default'] MdiDownload: typeof import('~icons/mdi/download')['default']
MdiDrag: typeof import('~icons/mdi/drag')['default'] MdiDrag: typeof import('~icons/mdi/drag')['default']
MdiDragVertical: typeof import('~icons/mdi/drag-vertical')['default'] MdiDragVertical: typeof import('~icons/mdi/drag-vertical')['default']
MdiDramaMasks: typeof import('~icons/mdi/drama-masks')['default']
MdiEmail: typeof import('~icons/mdi/email')['default'] MdiEmail: typeof import('~icons/mdi/email')['default']
MdiEmailArrowRightOutline: typeof import('~icons/mdi/email-arrow-right-outline')['default']
MdiExitToApp: typeof import('~icons/mdi/exit-to-app')['default'] MdiExitToApp: typeof import('~icons/mdi/exit-to-app')['default']
MdiEyeOffOutline: typeof import('~icons/mdi/eye-off-outline')['default'] MdiEyeOffOutline: typeof import('~icons/mdi/eye-off-outline')['default']
MdiFlag: typeof import('~icons/mdi/flag')['default'] MdiFlag: typeof import('~icons/mdi/flag')['default']

17
packages/nc-gui-v2/components/tabs/auth/UserManagement.vue

@ -62,6 +62,7 @@ const loadUsers = async (page = currentPage, limit = currentLimit) => {
if (!response.users) return if (!response.users) return
totalRows = response.users.pageInfo.totalRows ?? 0 totalRows = response.users.pageInfo.totalRows ?? 0
users = response.users.list as User[] users = response.users.list as User[]
} catch (e: any) { } catch (e: any) {
message.error(await extractSdkResponseErrorMsg(e)) message.error(await extractSdkResponseErrorMsg(e))
@ -74,7 +75,7 @@ const inviteUser = async (user: User) => {
await api.auth.projectUserAdd(project.value.id, user) await api.auth.projectUserAdd(project.value.id, user)
message.success('Successfully added user to project') message.success('Successfully added user to project')
await loadUsers() await loadUsers()
} catch (e: any) { } catch (e: any) {
message.error(await extractSdkResponseErrorMsg(e)) message.error(await extractSdkResponseErrorMsg(e))
@ -89,7 +90,8 @@ const deleteUser = async () => {
await api.auth.projectUserRemove(project.value.id, selectedUser.id) await api.auth.projectUserRemove(project.value.id, selectedUser.id)
message.success('Successfully deleted user from project') message.success('Successfully deleted user from project')
await loadUsers() await loadUsers()
showUserDeleteModal = false showUserDeleteModal = false
@ -137,7 +139,7 @@ const copyInviteUrl = (user: User) => {
copy(`${dashboardUrl}/signup/${user.invite_token}`) copy(`${dashboardUrl}/signup/${user.invite_token}`)
message.success('Invite url copied to clipboard') message.success('Invite url copied to clipboard')
} }
onMounted(() => { onMounted(() => {
@ -298,12 +300,3 @@ watchDebounced(searchText, () => loadUsers(), { debounce: 300, maxWait: 600 })
</div> </div>
</div> </div>
</template> </template>
<style scoped>
.users-table {
/* equally spaced columns in table */
table-layout: fixed;
width: 100%;
}
</style>

42
packages/nc-gui-v2/components/tabs/auth/user-management/UsersModal.vue

@ -1,14 +1,20 @@
<script setup lang="ts"> <script setup lang="ts">
import { Form, message } from 'ant-design-vue' import { Form, message } from 'ant-design-vue'
import { useClipboard } from '@vueuse/core'
import ShareBase from './ShareBase.vue' import ShareBase from './ShareBase.vue'
import SendIcon from '~icons/material-symbols/send-outline' import {
import CloseIcon from '~icons/material-symbols/close-rounded' computed,
import MidAccountIcon from '~icons/mdi/account-outline' extractSdkResponseErrorMsg,
import ContentCopyIcon from '~icons/mdi/content-copy' isEmail,
import type { User } from '~/lib/types' onMounted,
import { ProjectRole } from '~/lib/enums' projectRoles,
import { extractSdkResponseErrorMsg, isEmail, projectRoleTagColors, projectRoles } from '~/utils' ref,
useClipboard,
useDashboard,
useNuxtApp,
useProject,
} from '#imports'
import type { User } from '~/lib'
import { ProjectRole } from '~/lib'
interface Props { interface Props {
show: boolean show: boolean
@ -22,6 +28,7 @@ interface Users {
} }
const { show, selectedUser } = defineProps<Props>() const { show, selectedUser } = defineProps<Props>()
const emit = defineEmits(['closed', 'reload']) const emit = defineEmits(['closed', 'reload'])
const { project } = useProject() const { project } = useProject()
@ -96,14 +103,13 @@ const saveUser = async () => {
} }
} }
const inviteUrl = $computed(() => const inviteUrl = $computed(() => (usersData.invitationToken ? `${dashboardUrl}/signup/${usersData.invitationToken}` : null))
usersData.invitationToken ? `${dashboardUrl}/user/authentication/signup/${usersData.invitationToken}` : null,
)
const copyUrl = async () => { const copyUrl = async () => {
if (!inviteUrl) return if (!inviteUrl) return
copy(inviteUrl) await copy(inviteUrl)
message.success('Copied shareable base url to clipboard!') message.success('Copied shareable base url to clipboard!')
$e('c:shared-base:copy-url') $e('c:shared-base:copy-url')
@ -124,7 +130,7 @@ const clickInviteMore = () => {
<a-typography-title class="select-none" :level="4"> {{ $t('activity.share') }}: {{ project.title }} </a-typography-title> <a-typography-title class="select-none" :level="4"> {{ $t('activity.share') }}: {{ project.title }} </a-typography-title>
<a-button type="text" class="!rounded-md mr-1 -mt-1.5" @click="emit('closed')"> <a-button type="text" class="!rounded-md mr-1 -mt-1.5" @click="emit('closed')">
<template #icon> <template #icon>
<CloseIcon class="flex mx-auto" /> <MaterialSymbolsCloseRounded class="flex mx-auto" />
</template> </template>
</a-button> </a-button>
</div> </div>
@ -133,7 +139,7 @@ const clickInviteMore = () => {
<template v-if="usersData.invitationToken"> <template v-if="usersData.invitationToken">
<div class="flex flex-col mt-1 border-b-1 pb-5"> <div class="flex flex-col mt-1 border-b-1 pb-5">
<div class="flex flex-row items-center pl-1.5 pb-1 h-[1.1rem]"> <div class="flex flex-row items-center pl-1.5 pb-1 h-[1.1rem]">
<MidAccountIcon /> <MdiAccountOutline />
<div class="text-xs ml-0.5 mt-0.5">Copy Invite Token</div> <div class="text-xs ml-0.5 mt-0.5">Copy Invite Token</div>
</div> </div>
@ -145,7 +151,7 @@ const clickInviteMore = () => {
</div> </div>
<a-button type="text" class="!rounded-md -mt-0.5" @click="copyUrl"> <a-button type="text" class="!rounded-md -mt-0.5" @click="copyUrl">
<template #icon> <template #icon>
<ContentCopyIcon class="flex mx-auto text-green-700 h-[1rem]" /> <MdiContentCopy class="flex mx-auto text-green-700 h-[1rem]" />
</template> </template>
</a-button> </a-button>
</div> </div>
@ -159,7 +165,7 @@ const clickInviteMore = () => {
<div class="flex flex-row justify-start mt-4 ml-2"> <div class="flex flex-row justify-start mt-4 ml-2">
<a-button size="small" outlined @click="clickInviteMore"> <a-button size="small" outlined @click="clickInviteMore">
<div class="flex flex-row justify-center items-center space-x-0.5"> <div class="flex flex-row justify-center items-center space-x-0.5">
<SendIcon class="flex mx-auto text-gray-600 h-[0.8rem]" /> <MaterialSymbolsSendOutline class="flex mx-auto text-gray-600 h-[0.8rem]" />
<div class="text-xs text-gray-600">{{ $t('activity.inviteMore') }}</div> <div class="text-xs text-gray-600">{{ $t('activity.inviteMore') }}</div>
</div> </div>
</a-button> </a-button>
@ -168,7 +174,7 @@ const clickInviteMore = () => {
</template> </template>
<div v-else class="flex flex-col pb-4"> <div v-else class="flex flex-col pb-4">
<div class="flex flex-row items-center pl-2 pb-1 h-[1rem]"> <div class="flex flex-row items-center pl-2 pb-1 h-[1rem]">
<MidAccountIcon /> <MdiAccountOutline />
<div class="text-xs ml-0.5 mt-0.5">{{ selectedUser ? 'Edit User' : 'Invite Team' }}</div> <div class="text-xs ml-0.5 mt-0.5">{{ selectedUser ? 'Edit User' : 'Invite Team' }}</div>
</div> </div>
<div class="border-1 py-3 px-4 rounded-md mt-1"> <div class="border-1 py-3 px-4 rounded-md mt-1">
@ -218,7 +224,7 @@ const clickInviteMore = () => {
<a-button type="primary" html-type="submit"> <a-button type="primary" html-type="submit">
<div v-if="selectedUser">{{ $t('general.save') }}</div> <div v-if="selectedUser">{{ $t('general.save') }}</div>
<div v-else class="flex flex-row justify-center items-center space-x-1.5"> <div v-else class="flex flex-row justify-center items-center space-x-1.5">
<SendIcon class="flex h-[0.8rem]" /> <MaterialSymbolsSendOutline class="flex h-[0.8rem]" />
<div>{{ $t('activity.invite') }}</div> <div>{{ $t('activity.invite') }}</div>
</div> </div>
</a-button> </a-button>

1
packages/nc-gui-v2/lib/types.ts

@ -7,6 +7,7 @@ export interface User {
lastname: string | null lastname: string | null
roles: Roles roles: Roles
invite_token?: string invite_token?: string
project_id?: string
} }
export type Roles = Record<Role, boolean> export type Roles = Record<Role, boolean>

Loading…
Cancel
Save