diff --git a/packages/nc-gui-v2/components.d.ts b/packages/nc-gui-v2/components.d.ts
index 18c354d703..4d8b506ac2 100644
--- a/packages/nc-gui-v2/components.d.ts
+++ b/packages/nc-gui-v2/components.d.ts
@@ -29,10 +29,12 @@ declare module '@vue/runtime-core' {
AMenuDivider: typeof import('ant-design-vue/es')['MenuDivider']
AMenuItem: typeof import('ant-design-vue/es')['MenuItem']
AModal: typeof import('ant-design-vue/es')['Modal']
+ APagination: typeof import('ant-design-vue/es')['Pagination']
ARow: typeof import('ant-design-vue/es')['Row']
ASelect: typeof import('ant-design-vue/es')['Select']
ASelectOption: typeof import('ant-design-vue/es')['SelectOption']
ASkeleton: typeof import('ant-design-vue/es')['Skeleton']
+ ASpin: typeof import('ant-design-vue/es')['Spin']
ASubMenu: typeof import('ant-design-vue/es')['SubMenu']
ATable: typeof import('ant-design-vue/es')['Table']
ATableColumn: typeof import('ant-design-vue/es')['TableColumn']
diff --git a/packages/nc-gui-v2/components/dashboard/settings/AuditTab.vue b/packages/nc-gui-v2/components/dashboard/settings/AuditTab.vue
new file mode 100644
index 0000000000..66f17fcc67
--- /dev/null
+++ b/packages/nc-gui-v2/components/dashboard/settings/AuditTab.vue
@@ -0,0 +1,105 @@
+
+
+
+
+
+
+
+ Reload
+
+
+
+
+
+
+
+
diff --git a/packages/nc-gui-v2/composables/useProject.ts b/packages/nc-gui-v2/composables/useProject.ts
index 9ea67b69f7..1df977267a 100644
--- a/packages/nc-gui-v2/composables/useProject.ts
+++ b/packages/nc-gui-v2/composables/useProject.ts
@@ -1,28 +1,38 @@
import { SqlUiFactory } from 'nocodb-sdk'
import type { ProjectType, TableType } from 'nocodb-sdk'
-import { useNuxtApp } from '#app'
+import { useNuxtApp, useState } from '#app'
+import { USER_PROJECT_ROLES } from '~/lib/constants'
export default () => {
+ const projectRoles = useState>(USER_PROJECT_ROLES, () => ({}))
+
const { $api } = useNuxtApp()
const project = useState('project')
const tables = useState('tables')
+ const loadProjectRoles = async () => {
+ projectRoles.value = {}
+
+ if (project.value.id) {
+ const user = await $api.auth.me({ project_id: project.value.id })
+ projectRoles.value = user.roles
+ }
+ }
const loadTables = async () => {
if (project.value.id) {
const tablesResponse = await $api.dbTable.list(project.value.id)
-
if (tablesResponse.list) tables.value = tablesResponse.list
}
}
const loadProject = async (projectId: string) => {
project.value = await $api.project.read(projectId)
+ await loadProjectRoles()
}
const isMysql = computed(() => ['mysql', 'mysql2'].includes(project.value?.bases?.[0]?.type || ''))
const isPg = computed(() => project.value?.bases?.[0]?.type === 'pg')
-
const sqlUi = computed(() => SqlUiFactory.create({ client: project.value?.bases?.[0]?.type || '' }))
return { project, tables, loadProject, loadTables, isMysql, isPg, sqlUi }
diff --git a/packages/nc-gui-v2/composables/useUIPermission/index.ts b/packages/nc-gui-v2/composables/useUIPermission/index.ts
index ff2cf98b3e..e8fa8e6b5b 100644
--- a/packages/nc-gui-v2/composables/useUIPermission/index.ts
+++ b/packages/nc-gui-v2/composables/useUIPermission/index.ts
@@ -1,14 +1,27 @@
import rolePermissions from './rolePermissions'
+import { useState } from '#app'
+import { USER_PROJECT_ROLES } from '~/lib/constants'
export default () => {
const { $state } = useNuxtApp()
+ const projectRoles = useState>(USER_PROJECT_ROLES, () => ({}))
const isUIAllowed = (permission: keyof typeof rolePermissions[keyof typeof rolePermissions], _skipPreviewAs = false) => {
const user = $state.user
+ let userRoles = user?.value?.roles || {}
+
+ // if string populate key-value paired object
+ if (typeof userRoles === 'string') {
+ userRoles = userRoles.split(',').reduce>((acc, role) => {
+ acc[role] = true
+ return acc
+ }, {})
+ }
+
+ // merge user role and project specific user roles
const roles = {
- ...(user?.value?.roles || {}),
- // todo: load project specific roles
- // ...(state.projectRole || {}),
+ ...userRoles,
+ ...(projectRoles?.value || {}),
}
// todo: handle preview as
@@ -17,6 +30,7 @@ export default () => {
// [state.previewAs]: true
// };
// }
+
return Object.entries(roles).some(([role, hasRole]) => {
return (
hasRole &&
diff --git a/packages/nc-gui-v2/lib/constants.ts b/packages/nc-gui-v2/lib/constants.ts
index fdb8f08d49..21806b0541 100644
--- a/packages/nc-gui-v2/lib/constants.ts
+++ b/packages/nc-gui-v2/lib/constants.ts
@@ -1 +1,2 @@
export const NOCO = 'noco'
+export const USER_PROJECT_ROLES = 'user_project_roles'
diff --git a/packages/nc-gui-v2/utils/dateTimeUtils.ts b/packages/nc-gui-v2/utils/dateTimeUtils.ts
index 0b0d5a5264..e545ee290c 100644
--- a/packages/nc-gui-v2/utils/dateTimeUtils.ts
+++ b/packages/nc-gui-v2/utils/dateTimeUtils.ts
@@ -1,5 +1,14 @@
import dayjs from 'dayjs'
+import relativeTime from 'dayjs/plugin/relativeTime'
+import utc from 'dayjs/plugin/utc'
+dayjs.extend(utc)
+dayjs.extend(relativeTime)
+
+export const timeAgo = (date: any) => {
+ return dayjs.utc(date).fromNow()
+}
+
export const handleTZ = (val: any) => {
if (!val) {
return