Browse Source

refactor(gui): show super admin role in project user list since they have access to all project

Signed-off-by: Pranav C <pranavxc@gmail.com>
pull/4426/head
Pranav C 2 years ago
parent
commit
384bd26684
  1. 138
      packages/nc-gui/components/tabs/auth/UserManagement.vue
  2. 2
      packages/nc-gui/utils/userUtils.ts
  3. 1
      packages/nocodb-sdk/src/index.ts
  4. 0
      packages/nocodb-sdk/src/lib/enums.ts
  5. 2
      packages/nocodb/src/lib/meta/api/apiTokenApis.ts
  6. 2
      packages/nocodb/src/lib/meta/api/ee/orgTokenApis.ts
  7. 2
      packages/nocodb/src/lib/meta/api/orgLicenseApis.ts
  8. 2
      packages/nocodb/src/lib/meta/api/orgTokenApis.ts
  9. 2
      packages/nocodb/src/lib/meta/api/orgUserApis.ts
  10. 2
      packages/nocodb/src/lib/meta/api/projectApis.ts
  11. 2
      packages/nocodb/src/lib/meta/api/projectUserApis.ts
  12. 2
      packages/nocodb/src/lib/meta/api/userApi/initStrategies.ts
  13. 2
      packages/nocodb/src/lib/meta/api/userApi/userApis.ts
  14. 2
      packages/nocodb/src/lib/meta/helpers/ncMetaAclMw.ts
  15. 2
      packages/nocodb/src/lib/utils/projectAcl.ts
  16. 2
      packages/nocodb/src/lib/version-upgrader/ncProjectRolesUpgrader.ts
  17. 2
      packages/nocodb/tests/unit/rest/tests/org.test.ts

138
packages/nc-gui/components/tabs/auth/UserManagement.vue

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

2
packages/nc-gui/utils/userUtils.ts

@ -1,3 +1,4 @@
import { OrgUserRoles } from 'nocodb-sdk'
import { ProjectRole } from '~/lib/enums'
export const projectRoleTagColors = {
@ -6,6 +7,7 @@ export const projectRoleTagColors = {
[ProjectRole.Editor]: '#c2f5e8',
[ProjectRole.Commenter]: '#ffdaf6',
[ProjectRole.Viewer]: '#ffdce5',
[OrgUserRoles.SUPER_ADMIN]: '#f5d7cb',
}
export const projectRoles = [ProjectRole.Creator, ProjectRole.Editor, ProjectRole.Commenter, ProjectRole.Viewer]

1
packages/nocodb-sdk/src/index.ts

@ -4,6 +4,7 @@ export * from './lib/Api';
export * from './lib/sqlUi';
export * from './lib/globals';
export * from './lib/helperFunctions';
export * from './lib/enums';
export * from './lib/formulaHelpers';
export { default as UITypes, isVirtualCol } from './lib/UITypes';
export { default as CustomAPI } from './lib/CustomAPI';

0
packages/nocodb/src/enums/OrgUserRoles.ts → packages/nocodb-sdk/src/lib/enums.ts

2
packages/nocodb/src/lib/meta/api/apiTokenApis.ts

@ -1,5 +1,5 @@
import { Request, Response, Router } from 'express';
import { OrgUserRoles } from '../../../enums/OrgUserRoles';
import { OrgUserRoles } from 'nocodb-sdk';
import { Tele } from 'nc-help';
import { NcError } from '../helpers/catchError';
import ncMetaAclMw from '../helpers/ncMetaAclMw';

2
packages/nocodb/src/lib/meta/api/ee/orgTokenApis.ts

@ -1,4 +1,4 @@
import { OrgUserRoles } from '../../../../enums/OrgUserRoles';
import { OrgUserRoles } from 'nocodb-sdk';
import ApiToken from '../../../models/ApiToken';
import { PagedResponseImpl } from '../../helpers/PagedResponse';

2
packages/nocodb/src/lib/meta/api/orgLicenseApis.ts

@ -1,5 +1,5 @@
import { Router } from 'express';
import { OrgUserRoles } from '../../../enums/OrgUserRoles';
import { OrgUserRoles } from 'nocodb-sdk';
import { NC_LICENSE_KEY } from '../../constants'
import Store from '../../models/Store';
import { metaApiMetrics } from '../helpers/apiMetrics';

2
packages/nocodb/src/lib/meta/api/orgTokenApis.ts

@ -1,5 +1,5 @@
import { Request, Response, Router } from 'express';
import { OrgUserRoles } from '../../../enums/OrgUserRoles';
import { OrgUserRoles } from 'nocodb-sdk';
import ApiToken from '../../models/ApiToken';
import { Tele } from 'nc-help';
import { metaApiMetrics } from '../helpers/apiMetrics';

2
packages/nocodb/src/lib/meta/api/orgUserApis.ts

@ -6,7 +6,7 @@ import {
} from 'nocodb-sdk';
import { v4 as uuidv4 } from 'uuid';
import validator from 'validator';
import { OrgUserRoles } from '../../../enums/OrgUserRoles';
import { OrgUserRoles } from 'nocodb-sdk';
import { NC_APP_SETTINGS } from '../../constants';
import Audit from '../../models/Audit';
import ProjectUser from '../../models/ProjectUser';

2
packages/nocodb/src/lib/meta/api/projectApis.ts

@ -1,5 +1,5 @@
import { Request, Response } from 'express';
import { OrgUserRoles } from '../../../enums/OrgUserRoles';
import { OrgUserRoles } from 'nocodb-sdk';
import Project from '../../models/Project';
import { ModelTypes, ProjectListType, UITypes } from 'nocodb-sdk';
import DOMPurify from 'isomorphic-dompurify';

2
packages/nocodb/src/lib/meta/api/projectUserApis.ts

@ -1,4 +1,4 @@
import { OrgUserRoles } from '../../../enums/OrgUserRoles';
import { OrgUserRoles } from 'nocodb-sdk';
import { Tele } from 'nc-help';
import ncMetaAclMw from '../helpers/ncMetaAclMw';
import { Router } from 'express';

2
packages/nocodb/src/lib/meta/api/userApi/initStrategies.ts

@ -1,4 +1,4 @@
import { OrgUserRoles } from '../../../../enums/OrgUserRoles';
import { OrgUserRoles } from 'nocodb-sdk';
import User from '../../../models/User';
import ProjectUser from '../../../models/ProjectUser';
import { promisify } from 'util';

2
packages/nocodb/src/lib/meta/api/userApi/userApis.ts

@ -1,6 +1,6 @@
import { Request, Response } from 'express';
import { TableType, validatePassword } from 'nocodb-sdk';
import { OrgUserRoles } from '../../../../enums/OrgUserRoles';
import { OrgUserRoles } from 'nocodb-sdk';
import { NC_APP_SETTINGS } from '../../../constants';
import Store from '../../../models/Store';
import { Tele } from 'nc-help';

2
packages/nocodb/src/lib/meta/helpers/ncMetaAclMw.ts

@ -1,4 +1,4 @@
import { OrgUserRoles } from '../../../enums/OrgUserRoles';
import { OrgUserRoles } from 'nocodb-sdk';
import projectAcl from '../../utils/projectAcl';
import { NextFunction, Request, Response } from 'express';
import catchError, { NcError } from './catchError';

2
packages/nocodb/src/lib/utils/projectAcl.ts

@ -1,4 +1,4 @@
import { OrgUserRoles } from '../../enums/OrgUserRoles';
import { OrgUserRoles } from 'nocodb-sdk';
export default {
owner: {

2
packages/nocodb/src/lib/version-upgrader/ncProjectRolesUpgrader.ts

@ -1,4 +1,4 @@
import { OrgUserRoles } from '../../enums/OrgUserRoles';
import { OrgUserRoles } from 'nocodb-sdk';
import { NC_APP_SETTINGS } from '../constants';
import Store from '../models/Store';
import { MetaTable } from '../utils/globals';

2
packages/nocodb/tests/unit/rest/tests/org.test.ts

@ -1,7 +1,7 @@
import { expect } from 'chai'
import 'mocha'
import request from 'supertest'
import { OrgUserRoles } from '../../../../src/enums/OrgUserRoles'
import { OrgUserRoles } from 'nocodb-sdk'
import init from '../../init'
function authTests() {

Loading…
Cancel
Save