|
|
@ -1,14 +1,14 @@ |
|
|
|
<script lang="ts" setup> |
|
|
|
<script lang="ts" setup> |
|
|
|
import { OrderedWorkspaceRoles, RoleColors, RoleLabels, WorkspaceUserRoles } from 'nocodb-sdk' |
|
|
|
import { OrderedWorkspaceRoles, WorkspaceUserRoles } from 'nocodb-sdk' |
|
|
|
import { storeToRefs, stringToColour, timeAgo, useWorkspace } from '#imports' |
|
|
|
import { storeToRefs, stringToColour, timeAgo, useWorkspace } from '#imports' |
|
|
|
|
|
|
|
|
|
|
|
const { user } = useGlobal() |
|
|
|
const { workspaceRoles, loadRoles } = useRoles() |
|
|
|
|
|
|
|
|
|
|
|
const workspaceStore = useWorkspace() |
|
|
|
const workspaceStore = useWorkspace() |
|
|
|
|
|
|
|
|
|
|
|
const { removeCollaborator, updateCollaborator: _updateCollaborator } = workspaceStore |
|
|
|
const { removeCollaborator, updateCollaborator: _updateCollaborator } = workspaceStore |
|
|
|
|
|
|
|
|
|
|
|
const { collaborators, workspaceRole } = storeToRefs(workspaceStore) |
|
|
|
const { collaborators } = storeToRefs(workspaceStore) |
|
|
|
const userSearchText = ref('') |
|
|
|
const userSearchText = ref('') |
|
|
|
|
|
|
|
|
|
|
|
const filterCollaborators = computed(() => { |
|
|
|
const filterCollaborators = computed(() => { |
|
|
@ -19,7 +19,8 @@ const filterCollaborators = computed(() => { |
|
|
|
return collaborators.value.filter((collab) => collab.email!.includes(userSearchText.value)) |
|
|
|
return collaborators.value.filter((collab) => collab.email!.includes(userSearchText.value)) |
|
|
|
}) |
|
|
|
}) |
|
|
|
|
|
|
|
|
|
|
|
const updateCollaborator = async (collab) => { |
|
|
|
const updateCollaborator = async (collab: any, roles: WorkspaceUserRoles) => { |
|
|
|
|
|
|
|
collab.roles = roles |
|
|
|
try { |
|
|
|
try { |
|
|
|
await _updateCollaborator(collab.id, collab.roles) |
|
|
|
await _updateCollaborator(collab.id, collab.roles) |
|
|
|
message.success('Successfully updated user role') |
|
|
|
message.success('Successfully updated user role') |
|
|
@ -29,14 +30,21 @@ const updateCollaborator = async (collab) => { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
const accessibleRoles = computed<WorkspaceUserRoles[]>(() => { |
|
|
|
const accessibleRoles = computed<WorkspaceUserRoles[]>(() => { |
|
|
|
const currentRoleIndex = OrderedWorkspaceRoles.findIndex((role) => role === workspaceRole.value) |
|
|
|
const currentRoleIndex = OrderedWorkspaceRoles.findIndex( |
|
|
|
return OrderedWorkspaceRoles.slice(currentRoleIndex + 1) |
|
|
|
(role) => workspaceRoles.value && Object.keys(workspaceRoles.value).includes(role), |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
if (currentRoleIndex === -1) return [] |
|
|
|
|
|
|
|
return OrderedWorkspaceRoles.slice(currentRoleIndex + 1).filter((r) => r) |
|
|
|
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
onMounted(async () => { |
|
|
|
|
|
|
|
await loadRoles() |
|
|
|
}) |
|
|
|
}) |
|
|
|
</script> |
|
|
|
</script> |
|
|
|
|
|
|
|
|
|
|
|
<template> |
|
|
|
<template> |
|
|
|
<div class="nc-collaborator-table-container mt-4 mx-6"> |
|
|
|
<div class="nc-collaborator-table-container mt-4 mx-6"> |
|
|
|
<WorkspaceInviteSection v-if="workspaceRole !== WorkspaceUserRoles.VIEWER" /> |
|
|
|
<WorkspaceInviteSection v-if="workspaceRoles !== WorkspaceUserRoles.VIEWER" /> |
|
|
|
<div class="w-full h-1 border-t-1 border-gray-100 opacity-50 mt-6"></div> |
|
|
|
<div class="w-full h-1 border-t-1 border-gray-100 opacity-50 mt-6"></div> |
|
|
|
<div class="w-full flex flex-row justify-between items-baseline mt-6.5 mb-2 pr-0.25 ml-2"> |
|
|
|
<div class="w-full flex flex-row justify-between items-baseline mt-6.5 mb-2 pr-0.25 ml-2"> |
|
|
|
<div class="text-xl">Collaborators</div> |
|
|
|
<div class="text-xl">Collaborators</div> |
|
|
@ -74,47 +82,17 @@ const accessibleRoles = computed<WorkspaceUserRoles[]>(() => { |
|
|
|
{{ timeAgo(collab.created_at) }} |
|
|
|
{{ timeAgo(collab.created_at) }} |
|
|
|
</td> |
|
|
|
</td> |
|
|
|
<td class="w-1/5 roles"> |
|
|
|
<td class="w-1/5 roles"> |
|
|
|
<div v-if="collab.roles === WorkspaceUserRoles.OWNER" class="nc-collaborator-role-select"> |
|
|
|
<div class="nc-collaborator-role-select"> |
|
|
|
<a-select v-model:value="collab.roles" class="w-30 !rounded px-1" disabled> |
|
|
|
<template v-if="accessibleRoles.includes(collab.roles)"> |
|
|
|
<template #suffixIcon> |
|
|
|
<RolesSelector |
|
|
|
<MdiChevronDown /> |
|
|
|
:role="collab.roles" |
|
|
|
</template> |
|
|
|
:roles="accessibleRoles" |
|
|
|
<a-select-option :value="WorkspaceUserRoles.OWNER"> |
|
|
|
:on-role-change="(role: WorkspaceUserRoles) => updateCollaborator(collab, role)" |
|
|
|
<NcBadge color="purple"> |
|
|
|
/> |
|
|
|
<p class="badge-text">Owner</p> |
|
|
|
|
|
|
|
</NcBadge> |
|
|
|
|
|
|
|
</a-select-option> |
|
|
|
|
|
|
|
</a-select> |
|
|
|
|
|
|
|
</div> |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<div v-else class="nc-collaborator-role-select"> |
|
|
|
|
|
|
|
<NcSelect |
|
|
|
|
|
|
|
v-model:value="collab.roles" |
|
|
|
|
|
|
|
class="w-30 !rounded px-1" |
|
|
|
|
|
|
|
:disabled="collab.id === user?.id || !accessibleRoles.includes(collab.roles)" |
|
|
|
|
|
|
|
@change="updateCollaborator(collab)" |
|
|
|
|
|
|
|
> |
|
|
|
|
|
|
|
<template #suffixIcon> |
|
|
|
|
|
|
|
<MdiChevronDown /> |
|
|
|
|
|
|
|
</template> |
|
|
|
</template> |
|
|
|
<a-select-option v-if="collab.id === user?.id" :value="workspaceRole"> |
|
|
|
<template v-else> |
|
|
|
<NcBadge :color="RoleColors[workspaceRole]"> |
|
|
|
<RolesBadge class="!bg-white" :role="collab.roles" /> |
|
|
|
<p class="badge-text">{{ RoleLabels[workspaceRole] }}</p> |
|
|
|
|
|
|
|
</NcBadge> |
|
|
|
|
|
|
|
</a-select-option> |
|
|
|
|
|
|
|
<a-select-option v-if="!accessibleRoles.includes(collab.roles)" :value="collab.roles"> |
|
|
|
|
|
|
|
<NcBadge :color="RoleColors[collab.roles]"> |
|
|
|
|
|
|
|
<p class="badge-text">{{ RoleLabels[collab.roles] }}</p> |
|
|
|
|
|
|
|
</NcBadge> |
|
|
|
|
|
|
|
</a-select-option> |
|
|
|
|
|
|
|
<template v-for="role of accessibleRoles" :key="`role-option-${role}`"> |
|
|
|
|
|
|
|
<a-select-option v-if="role" :value="role"> |
|
|
|
|
|
|
|
<NcBadge :color="RoleColors[role]"> |
|
|
|
|
|
|
|
<p class="badge-text">{{ RoleLabels[role] }}</p> |
|
|
|
|
|
|
|
</NcBadge> |
|
|
|
|
|
|
|
</a-select-option> |
|
|
|
|
|
|
|
</template> |
|
|
|
</template> |
|
|
|
</NcSelect> |
|
|
|
|
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</td> |
|
|
|
</td> |
|
|
|
<td class="w-1/5"> |
|
|
|
<td class="w-1/5"> |
|
|
|