Browse Source

Merge pull request #5885 from nocodb/fix/5883-show-project-icons-based-role

fix: Show project action icons based project role
pull/5890/head
Raju Udava 1 year ago committed by GitHub
parent
commit
778c06d8f2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 26
      packages/nc-gui/composables/useUIPermission/index.ts
  2. 10
      packages/nc-gui/pages/index/index/index.vue
  3. 10
      packages/nocodb/src/models/ProjectUser.ts

26
packages/nc-gui/composables/useUIPermission/index.ts

@ -24,14 +24,32 @@ export const useUIPermission = createSharedComposable(() => {
const { previewAs } = useGlobal() const { previewAs } = useGlobal()
const { allRoles } = useRoles() const { allRoles } = useRoles()
const isUIAllowed = (permission: Permission | string, skipPreviewAs = false) => { const isUIAllowed = (
permission: Permission | string,
skipPreviewAs = false,
userRoles?: string | Record<string, boolean> | string[],
) => {
if (previewAs.value && !skipPreviewAs) { if (previewAs.value && !skipPreviewAs) {
return hasPermission(previewAs.value, true, permission) return hasPermission(previewAs.value, true, permission)
} }
return Object.entries(allRoles.value).some(([role, hasRole]) => let roles: Record<string, boolean> = {}
hasPermission(role as Role | ProjectRole, hasRole, permission),
) if (!userRoles) {
roles = allRoles.value
} else if (Array.isArray(userRoles) || typeof userRoles === 'string') {
roles = (Array.isArray(userRoles) ? userRoles : userRoles.split(','))
// filter out any empty-string/null/undefined values
.filter(Boolean)
.reduce<Record<string, boolean>>((acc, role) => {
acc[role] = true
return acc
}, {})
} else if (typeof userRoles === 'object') {
roles = userRoles
}
return Object.entries(roles).some(([role, hasRole]) => hasPermission(role as Role | ProjectRole, hasRole, permission))
} }
return { isUIAllowed } return { isUIAllowed }

10
packages/nc-gui/pages/index/index/index.vue

@ -247,9 +247,9 @@ const copyProjectMeta = async () => {
<a-table-column key="title" :title="$t('general.title')" data-index="title"> <a-table-column key="title" :title="$t('general.title')" data-index="title">
<template #default="{ text, record }"> <template #default="{ text, record }">
<div class="flex items-center"> <div class="flex items-center">
<div @click.stop> <div @click.stop class="w-2">
<a-menu class="!border-0 !m-0 !p-0" trigger-sub-menu-action="click"> <a-menu class="!border-0 !m-0 !p-0" trigger-sub-menu-action="click">
<template v-if="isUIAllowed('projectTheme')"> <template v-if="isUIAllowed('projectTheme') || isUIAllowed('projectTheme', true, record.roles)">
<a-sub-menu key="theme" popup-class-name="custom-color"> <a-sub-menu key="theme" popup-class-name="custom-color">
<template #title> <template #title>
<div <div
@ -308,7 +308,7 @@ const copyProjectMeta = async () => {
<div v-if="record.status !== ProjectStatus.JOB" class="flex items-center gap-2"> <div v-if="record.status !== ProjectStatus.JOB" class="flex items-center gap-2">
<component <component
:is="iconMap.edit" :is="iconMap.edit"
v-if="isUIAllowed('projectUpdate', true)" v-if="isUIAllowed('projectUpdate', true) || isUIAllowed('projectUpdate', true, record.roles)"
v-e="['c:project:edit:rename']" v-e="['c:project:edit:rename']"
class="nc-action-btn" class="nc-action-btn"
@click.stop="navigateTo(`/${text}`)" @click.stop="navigateTo(`/${text}`)"
@ -316,14 +316,14 @@ const copyProjectMeta = async () => {
<component <component
:is="iconMap.delete" :is="iconMap.delete"
v-if="isUIAllowed('projectDelete', true)" v-if="isUIAllowed('projectDelete', true) || isUIAllowed('projectDelete', true, record.roles)"
class="nc-action-btn" class="nc-action-btn"
:data-testid="`delete-project-${record.title}`" :data-testid="`delete-project-${record.title}`"
@click.stop="deleteProject(record)" @click.stop="deleteProject(record)"
/> />
<a-dropdown <a-dropdown
v-if="isUIAllowed('duplicateProject', true)" v-if="isUIAllowed('duplicateProject', true) || isUIAllowed('duplicateProject', true, record.roles)"
:trigger="['click']" :trigger="['click']"
overlay-class-name="nc-dropdown-import-menu" overlay-class-name="nc-dropdown-import-menu"
@click.stop @click.stop

10
packages/nocodb/src/models/ProjectUser.ts

@ -236,6 +236,16 @@ export default class ProjectUser {
projectList = await ncMeta projectList = await ncMeta
.knex(MetaTable.PROJECT) .knex(MetaTable.PROJECT)
.select(`${MetaTable.PROJECT}.*`) .select(`${MetaTable.PROJECT}.*`)
.select(`${MetaTable.PROJECT}.title`)
.select(`${MetaTable.PROJECT}.prefix`)
.select(`${MetaTable.PROJECT}.status`)
.select(`${MetaTable.PROJECT}.description`)
.select(`${MetaTable.PROJECT}.meta`)
.select(`${MetaTable.PROJECT}.color`)
.select(`${MetaTable.PROJECT}.is_meta`)
.select(`${MetaTable.PROJECT}.created_at`)
.select(`${MetaTable.PROJECT}.updated_at`)
.select(`${MetaTable.PROJECT_USERS}.roles`)
.innerJoin(MetaTable.PROJECT_USERS, function () { .innerJoin(MetaTable.PROJECT_USERS, function () {
this.on( this.on(
`${MetaTable.PROJECT_USERS}.project_id`, `${MetaTable.PROJECT_USERS}.project_id`,

Loading…
Cancel
Save