|
|
@ -1,4 +1,5 @@ |
|
|
|
<script setup lang="ts"> |
|
|
|
<script setup lang="ts"> |
|
|
|
|
|
|
|
import { OrgUserRoles } from 'nocodb-sdk' |
|
|
|
import type { RequestParams } from 'nocodb-sdk' |
|
|
|
import type { RequestParams } from 'nocodb-sdk' |
|
|
|
import { |
|
|
|
import { |
|
|
|
extractSdkResponseErrorMsg, |
|
|
|
extractSdkResponseErrorMsg, |
|
|
@ -160,6 +161,10 @@ onBeforeMount(async () => { |
|
|
|
}) |
|
|
|
}) |
|
|
|
|
|
|
|
|
|
|
|
watchDebounced(searchText, () => loadUsers(), { debounce: 300, maxWait: 600 }) |
|
|
|
watchDebounced(searchText, () => loadUsers(), { debounce: 300, maxWait: 600 }) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const isSuperAdmin = (user: { main_roles?: string }) => { |
|
|
|
|
|
|
|
return user.main_roles?.split(',').includes(OrgUserRoles.SUPER_ADMIN) |
|
|
|
|
|
|
|
} |
|
|
|
</script> |
|
|
|
</script> |
|
|
|
|
|
|
|
|
|
|
|
<template> |
|
|
|
<template> |
|
|
@ -246,14 +251,20 @@ watchDebounced(searchText, () => loadUsers(), { debounce: 300, maxWait: 600 }) |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
|
|
|
|
|
|
|
|
<div v-for="(user, index) of users" :key="index" class="flex flex-row items-center border-b-1 py-2 px-2 nc-user-row"> |
|
|
|
<div v-for="(user, index) of users" :key="index" |
|
|
|
|
|
|
|
class="flex flex-row items-center border-b-1 py-2 px-2 nc-user-row"> |
|
|
|
<div class="flex w-4/6 flex-wrap nc-user-email"> |
|
|
|
<div class="flex w-4/6 flex-wrap nc-user-email"> |
|
|
|
{{ user.email }} |
|
|
|
{{ user.email }} |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
|
|
|
|
|
|
|
|
<div class="flex w-1/6 justify-center flex-wrap ml-4"> |
|
|
|
<div class="flex w-1/6 justify-center flex-wrap ml-4"> |
|
|
|
|
|
|
|
<div v-if="isSuperAdmin(user)" class="rounded-full px-2 py-1 nc-user-role" |
|
|
|
|
|
|
|
:style="{ backgroundColor: projectRoleTagColors[OrgUserRoles.SUPER_ADMIN] }" |
|
|
|
|
|
|
|
> |
|
|
|
|
|
|
|
Super Admin |
|
|
|
|
|
|
|
</div> |
|
|
|
<div |
|
|
|
<div |
|
|
|
v-if="user.roles" |
|
|
|
v-else-if="user.roles" |
|
|
|
class="rounded-full px-2 py-1 nc-user-role" |
|
|
|
class="rounded-full px-2 py-1 nc-user-role" |
|
|
|
:style="{ backgroundColor: projectRoleTagColors[user.roles] }" |
|
|
|
:style="{ backgroundColor: projectRoleTagColors[user.roles] }" |
|
|
|
> |
|
|
|
> |
|
|
@ -261,71 +272,74 @@ watchDebounced(searchText, () => loadUsers(), { debounce: 300, maxWait: 600 }) |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
<div class="flex w-1/6 flex-wrap justify-end"> |
|
|
|
<div class="flex w-1/6 flex-wrap justify-end"> |
|
|
|
<a-tooltip v-if="user.project_id" placement="bottom"> |
|
|
|
<template v-if="!isSuperAdmin(user)"> |
|
|
|
<template #title> |
|
|
|
<a-tooltip v-if="user.project_id" placement="bottom"> |
|
|
|
<span>{{ $t('activity.editUser') }}</span> |
|
|
|
<template #title> |
|
|
|
</template> |
|
|
|
<span>{{ $t('activity.editUser') }}</span> |
|
|
|
|
|
|
|
|
|
|
|
<a-button type="text" class="!rounded-md nc-user-edit" @click="onEdit(user)"> |
|
|
|
|
|
|
|
<template #icon> |
|
|
|
|
|
|
|
<IcRoundEdit class="flex mx-auto h-[1rem] text-gray-500" /> |
|
|
|
|
|
|
|
</template> |
|
|
|
</template> |
|
|
|
</a-button> |
|
|
|
|
|
|
|
</a-tooltip> |
|
|
|
<a-button type="text" class="!rounded-md nc-user-edit" @click="onEdit(user)"> |
|
|
|
|
|
|
|
<template #icon> |
|
|
|
<!-- Add user to project --> |
|
|
|
<IcRoundEdit class="flex mx-auto h-[1rem] text-gray-500" /> |
|
|
|
<a-tooltip v-if="!user.project_id" placement="bottom"> |
|
|
|
</template> |
|
|
|
<template #title> |
|
|
|
</a-button> |
|
|
|
<span>{{ $t('activity.addUserToProject') }}</span> |
|
|
|
</a-tooltip> |
|
|
|
</template> |
|
|
|
|
|
|
|
|
|
|
|
<!-- Add user to project --> |
|
|
|
<a-button type="text" class="!rounded-md nc-user-invite" @click="inviteUser(user)"> |
|
|
|
<a-tooltip v-if="!user.project_id" placement="bottom"> |
|
|
|
<template #icon> |
|
|
|
<template #title> |
|
|
|
<MdiPlus class="flex mx-auto h-[1.1rem] text-gray-500" /> |
|
|
|
<span>{{ $t('activity.addUserToProject') }}</span> |
|
|
|
</template> |
|
|
|
</template> |
|
|
|
</a-button> |
|
|
|
|
|
|
|
</a-tooltip> |
|
|
|
<a-button type="text" class="!rounded-md nc-user-invite" @click="inviteUser(user)"> |
|
|
|
|
|
|
|
<template #icon> |
|
|
|
<!-- Remove user from the project --> |
|
|
|
<MdiPlus class="flex mx-auto h-[1.1rem] text-gray-500" /> |
|
|
|
<a-tooltip v-else placement="bottom"> |
|
|
|
</template> |
|
|
|
<template #title> |
|
|
|
</a-button> |
|
|
|
<span>{{ $t('activity.deleteUser') }}</span> |
|
|
|
</a-tooltip> |
|
|
|
</template> |
|
|
|
|
|
|
|
|
|
|
|
<!-- Remove user from the project --> |
|
|
|
<a-button v-e="['c:user:delete']" type="text" class="!rounded-md nc-user-delete" @click="onDelete(user)"> |
|
|
|
<a-tooltip v-else placement="bottom"> |
|
|
|
<template #icon> |
|
|
|
<template #title> |
|
|
|
<MdiDeleteOutline class="flex mx-auto h-[1.1rem] text-gray-500" /> |
|
|
|
<span>{{ $t('activity.deleteUser') }}</span> |
|
|
|
</template> |
|
|
|
</template> |
|
|
|
</a-button> |
|
|
|
|
|
|
|
</a-tooltip> |
|
|
|
<a-button v-e="['c:user:delete']" type="text" class="!rounded-md nc-user-delete" @click="onDelete(user)"> |
|
|
|
|
|
|
|
<template #icon> |
|
|
|
<a-dropdown :trigger="['click']" class="flex" placement="bottomRight" overlay-class-name="nc-dropdown-user-mgmt"> |
|
|
|
<MdiDeleteOutline class="flex mx-auto h-[1.1rem] text-gray-500" /> |
|
|
|
<div class="flex flex-row items-center"> |
|
|
|
</template> |
|
|
|
<a-button type="text" class="!px-0"> |
|
|
|
|
|
|
|
<div class="flex flex-row items-center h-[1.2rem]"> |
|
|
|
|
|
|
|
<IcBaselineMoreVert /> |
|
|
|
|
|
|
|
</div> |
|
|
|
|
|
|
|
</a-button> |
|
|
|
</a-button> |
|
|
|
</div> |
|
|
|
</a-tooltip> |
|
|
|
|
|
|
|
|
|
|
|
<template #overlay> |
|
|
|
<a-dropdown :trigger="['click']" class="flex" placement="bottomRight" |
|
|
|
<a-menu> |
|
|
|
overlay-class-name="nc-dropdown-user-mgmt"> |
|
|
|
<a-menu-item> |
|
|
|
<div class="flex flex-row items-center"> |
|
|
|
<!-- Resend invite Email --> |
|
|
|
<a-button type="text" class="!px-0"> |
|
|
|
<div class="flex flex-row items-center py-3" @click="resendInvite(user)"> |
|
|
|
<div class="flex flex-row items-center h-[1.2rem]"> |
|
|
|
<MdiEmailArrowRightOutline class="flex h-[1rem] text-gray-500" /> |
|
|
|
<IcBaselineMoreVert /> |
|
|
|
<div class="text-xs pl-2">{{ $t('activity.resendInvite') }}</div> |
|
|
|
|
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</a-menu-item> |
|
|
|
</a-button> |
|
|
|
<a-menu-item> |
|
|
|
</div> |
|
|
|
<div class="flex flex-row items-center py-3" @click="copyInviteUrl(user)"> |
|
|
|
|
|
|
|
<MdiContentCopy class="flex h-[1rem] text-gray-500" /> |
|
|
|
<template #overlay> |
|
|
|
<div class="text-xs pl-2">{{ $t('activity.copyInviteURL') }}</div> |
|
|
|
<a-menu> |
|
|
|
</div> |
|
|
|
<a-menu-item> |
|
|
|
</a-menu-item> |
|
|
|
<!-- Resend invite Email --> |
|
|
|
</a-menu> |
|
|
|
<div class="flex flex-row items-center py-3" @click="resendInvite(user)"> |
|
|
|
</template> |
|
|
|
<MdiEmailArrowRightOutline class="flex h-[1rem] text-gray-500" /> |
|
|
|
</a-dropdown> |
|
|
|
<div class="text-xs pl-2">{{ $t('activity.resendInvite') }}</div> |
|
|
|
|
|
|
|
</div> |
|
|
|
|
|
|
|
</a-menu-item> |
|
|
|
|
|
|
|
<a-menu-item> |
|
|
|
|
|
|
|
<div class="flex flex-row items-center py-3" @click="copyInviteUrl(user)"> |
|
|
|
|
|
|
|
<MdiContentCopy class="flex h-[1rem] text-gray-500" /> |
|
|
|
|
|
|
|
<div class="text-xs pl-2">{{ $t('activity.copyInviteURL') }}</div> |
|
|
|
|
|
|
|
</div> |
|
|
|
|
|
|
|
</a-menu-item> |
|
|
|
|
|
|
|
</a-menu> |
|
|
|
|
|
|
|
</template> |
|
|
|
|
|
|
|
</a-dropdown> |
|
|
|
|
|
|
|
</template> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
|
|
|
|
|
|
|
|