Browse Source

refactor(nc-gui): use enum for role permission keys

pull/3703/head
braks 2 years ago
parent
commit
9a43bfa787
  1. 28
      packages/nc-gui/components/general/PreviewAs.vue
  2. 4
      packages/nc-gui/composables/useGlobal/types.ts
  3. 12
      packages/nc-gui/composables/useUIPermission/index.ts
  4. 40
      packages/nc-gui/composables/useUIPermission/rolePermissions.ts

28
packages/nc-gui/components/general/PreviewAs.vue

@ -1,29 +1,26 @@
<script lang="ts" setup> <script lang="ts" setup>
import { onUnmounted, useEventListener, useGlobal, useState, watch } from '#imports' import { onUnmounted, ref, useEventListener, useGlobal, useI18n, useNuxtApp, watch } from '#imports'
import MdiAccountStar from '~icons/mdi/account-star' import MdiAccountStar from '~icons/mdi/account-star'
import MdiAccountHardHat from '~icons/mdi/account-hard-hat' import MdiAccountHardHat from '~icons/mdi/account-hard-hat'
import MdiAccountEdit from '~icons/mdi/account-edit' import MdiAccountEdit from '~icons/mdi/account-edit'
import MdiEyeOutline from '~icons/mdi/eye-outline' import MdiEyeOutline from '~icons/mdi/eye-outline'
import MdiCommentAccountOutline from '~icons/mdi/comment-account-outline' import MdiCommentAccountOutline from '~icons/mdi/comment-account-outline'
import { ProjectRole } from '~/lib'
const { float } = defineProps<{ float?: boolean }>() const { float } = defineProps<{ float?: boolean }>()
const position = useState('preview-as-position', () => ({
y: `${window.innerHeight - 100}px`,
x: `${window.innerWidth / 2 - 250}px`,
}))
const { $e } = useNuxtApp() const { $e } = useNuxtApp()
const { t } = useI18n() const { t } = useI18n()
const { previewAs } = useGlobal()
const roleList = [ const roleList = [
{ value: 'editor', label: t('objects.roleType.editor') }, { value: ProjectRole.Editor, label: t('objects.roleType.editor') },
{ value: 'commenter', label: t('objects.roleType.commenter') }, { value: ProjectRole.Commenter, label: t('objects.roleType.commenter') },
{ value: 'viewer', label: t('objects.roleType.viewer') }, { value: ProjectRole.Viewer, label: t('objects.roleType.viewer') },
] ]
const { previewAs } = useGlobal()
const roleIcon = { const roleIcon = {
owner: MdiAccountStar, owner: MdiAccountStar,
creator: MdiAccountHardHat, creator: MdiAccountHardHat,
@ -32,6 +29,11 @@ const roleIcon = {
commenter: MdiCommentAccountOutline, commenter: MdiCommentAccountOutline,
} }
const position = ref({
y: `${window.innerHeight - 100}px`,
x: `${window.innerWidth / 2 - 250}px`,
})
const divMove = (e: MouseEvent) => { const divMove = (e: MouseEvent) => {
position.value = { y: `${e.clientY - 10}px`, x: `${e.clientX - 18}px` } position.value = { y: `${e.clientY - 10}px`, x: `${e.clientX - 18}px` }
} }
@ -49,7 +51,7 @@ onUnmounted(() => {
window.removeEventListener('mousemove', divMove, true) window.removeEventListener('mousemove', divMove, true)
}) })
/** reload page on previewas change */ /** reload page on preview-as change */
watch(previewAs, (newRole) => { watch(previewAs, (newRole) => {
$e('a:navdraw:preview', { role: newRole }) $e('a:navdraw:preview', { role: newRole })
window.location.reload() window.location.reload()
@ -63,7 +65,7 @@ watch(previewAs, (newRole) => {
class="floating-reset-btn nc-floating-preview-btn p-4" class="floating-reset-btn nc-floating-preview-btn p-4"
:style="{ top: position.y, left: position.x }" :style="{ top: position.y, left: position.x }"
> >
<MdiDrag style="cursor: move" class="text-white" @mousedown="mouseDown" /> <MdiDrag class="cursor-move text-white" @mousedown="mouseDown" />
<div class="divider" /> <div class="divider" />

4
packages/nc-gui/composables/useGlobal/types.ts

@ -1,7 +1,7 @@
import type { ComputedRef, Ref, ToRefs } from 'vue' import type { ComputedRef, Ref, ToRefs } from 'vue'
import type { WritableComputedRef } from '@vue/reactivity' import type { WritableComputedRef } from '@vue/reactivity'
import type { JwtPayload } from 'jwt-decode' import type { JwtPayload } from 'jwt-decode'
import type { Language, Role, User } from '~/lib' import type { Language, ProjectRole, User } from '~/lib'
import type { useCounter } from '#imports' import type { useCounter } from '#imports'
export interface FeedbackForm { export interface FeedbackForm {
@ -33,7 +33,7 @@ export interface StoredState {
darkMode: boolean darkMode: boolean
feedbackForm: FeedbackForm feedbackForm: FeedbackForm
filterAutoSave: boolean filterAutoSave: boolean
previewAs: Role | null previewAs: ProjectRole | null
includeM2M: boolean includeM2M: boolean
currentVersion: string | null currentVersion: string | null
latestRelease: string | null latestRelease: string | null

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

@ -2,7 +2,7 @@ import { isString } from '@vueuse/core'
import type { Permission } from './rolePermissions' import type { Permission } from './rolePermissions'
import rolePermissions from './rolePermissions' import rolePermissions from './rolePermissions'
import { USER_PROJECT_ROLES, computed, useGlobal, useState } from '#imports' import { USER_PROJECT_ROLES, computed, useGlobal, useState } from '#imports'
import type { Roles } from '~/lib' import type { ProjectRole, Role, Roles } from '~/lib'
export function useUIPermission() { export function useUIPermission() {
const { user, previewAs } = useGlobal() const { user, previewAs } = useGlobal()
@ -27,7 +27,7 @@ export function useUIPermission() {
} }
}) })
const isUIAllowed = (permission: Permission, skipPreviewAs = false) => { const isUIAllowed = (permission: Permission | string, skipPreviewAs = false) => {
let roles = baseRoles.value let roles = baseRoles.value
if (previewAs.value && !skipPreviewAs) { if (previewAs.value && !skipPreviewAs) {
@ -37,9 +37,13 @@ export function useUIPermission() {
} }
return Object.entries(roles).some(([role, hasRole]) => { return Object.entries(roles).some(([role, hasRole]) => {
const rolePermission = rolePermissions[role as keyof typeof rolePermissions] const rolePermission = rolePermissions[role as Role | ProjectRole]
return hasRole && (rolePermission === '*' || rolePermission?.[permission as keyof typeof rolePermission]) return (
hasRole &&
rolePermission &&
((isString(rolePermission) && rolePermission === '*') || rolePermission[permission as keyof typeof rolePermission])
)
}) })
} }

40
packages/nc-gui/composables/useUIPermission/rolePermissions.ts

@ -1,13 +1,24 @@
import { ProjectRole, Role } from '~/lib'
const rolePermissions = { const rolePermissions = {
// general role permissions
/** todo: enable wildcard permission /** todo: enable wildcard permission
* limited permission due to unexpected behaviour in shared base if opened in same window */ * limited permission due to unexpected behaviour in shared base if opened in same window */
super: { [Role.Super]: {
projectTheme: true, projectTheme: true,
}, },
creator: '*', [Role.Admin]: {},
owner: '*', [Role.Guest]: {},
guest: {}, [Role.User]: {
editor: { projectCreate: true,
projectActions: true,
projectSettings: true,
},
// Project role permissions
[ProjectRole.Creator]: '*',
[ProjectRole.Owner]: '*',
[ProjectRole.Editor]: {
smartSheet: true, smartSheet: true,
xcDatatableEditable: true, xcDatatableEditable: true,
column: true, column: true,
@ -25,28 +36,25 @@ const rolePermissions = {
projectSettings: true, projectSettings: true,
newUser: false, newUser: false,
}, },
commenter: { [ProjectRole.Commenter]: {
smartSheet: true, smartSheet: true,
column: true, column: true,
rowComments: true, rowComments: true,
projectSettings: true, projectSettings: true,
}, },
viewer: { [ProjectRole.Viewer]: {
smartSheet: true, smartSheet: true,
column: true, column: true,
projectSettings: true, projectSettings: true,
}, },
user: {
projectCreate: true,
projectActions: true,
projectSettings: true,
},
} as const } as const
type GetKeys<T> = T extends Record<string, boolean> ? keyof T : never type RolePermissions = Omit<typeof rolePermissions, 'creator' | 'owner' | 'guest' | 'admin'>
type GetKeys<T> = T extends Record<string, any> ? keyof T : never
export type Permission<T extends typeof rolePermissions = typeof rolePermissions, K extends keyof T = keyof T> = export type Permission<K extends keyof RolePermissions = keyof RolePermissions> = RolePermissions[K] extends Record<string, any>
| (K extends 'creator' | 'owner' ? T[K] : never | T[K] extends Record<string, boolean> ? GetKeys<T[K]> : never) ? GetKeys<RolePermissions[K]>
| T[K] : never
export default rolePermissions export default rolePermissions

Loading…
Cancel
Save