Browse Source

fix(nc-gui): show only available audit types

pull/8836/head
Ramesh Mane 1 week ago
parent
commit
af7407d98f
  1. 106
      packages/nc-gui/components/workspace/AuditLogs.vue
  2. 47
      packages/nocodb-sdk/src/lib/globals.ts

106
packages/nc-gui/components/workspace/AuditLogs.vue

@ -1,12 +1,28 @@
<script setup lang="ts">
import { Empty } from 'ant-design-vue'
import type { AuditType, WorkspaceUserType } from 'nocodb-sdk'
import { timeAgo, AuditOperationTypes, AuditOperationSubTypes } from 'nocodb-sdk'
import {
timeAgo,
AuditOperationTypes,
AuditOperationSubTypes,
auditOperationTypeLabels,
auditOperationSubTypeLabels,
} from 'nocodb-sdk'
interface Props {
workspaceId?: string
}
const allowedAuditOperationTypes = [AuditOperationTypes.DATA, AuditOperationTypes.TABLE, AuditOperationTypes.TABLE_COLUMN]
const allowedAuditOperationSubTypes = [
AuditOperationSubTypes.CREATE,
AuditOperationSubTypes.UPDATE,
AuditOperationSubTypes.DELETE,
AuditOperationSubTypes.INSERT,
AuditOperationSubTypes.LINK_RECORD,
AuditOperationSubTypes.UNLINK_RECORD,
]
const props = defineProps<Props>()
const workspaceStore = useWorkspace()
@ -52,6 +68,43 @@ const auditDropdowns = ref({
user: false,
})
const auditTypeOptions = computed(() => {
return Object.values(AuditOperationTypes)
.filter((type) => allowedAuditOperationTypes.includes(type as AuditOperationTypes))
.map((type) => ({
label: auditOperationTypeLabels[type],
value: type,
}))
})
const auditSubTypeOptions = computed(() => {
return Object.values(AuditOperationSubTypes)
.filter((subType) => {
if (
auditLogsQuery.value.type === AuditOperationTypes.TABLE ||
auditLogsQuery.value.type === AuditOperationTypes.TABLE_COLUMN
) {
return [AuditOperationSubTypes.CREATE, AuditOperationSubTypes.UPDATE, AuditOperationSubTypes.DELETE].includes(subType)
}
if (auditLogsQuery.value.type === AuditOperationTypes.DATA) {
return [
AuditOperationSubTypes.UPDATE,
AuditOperationSubTypes.DELETE,
AuditOperationSubTypes.INSERT,
AuditOperationSubTypes.LINK_RECORD,
AuditOperationSubTypes.UNLINK_RECORD,
].includes(subType)
}
return allowedAuditOperationSubTypes.includes(subType)
})
.map((subType) => ({
label: auditOperationSubTypeLabels[subType],
value: subType,
}))
})
async function loadAudits(page = currentPage.value, limit = currentLimit.value) {
try {
if (!props.workspaceId) return
@ -124,11 +177,13 @@ onMounted(async () => {
</template>
</a-input>
</form>
<div class="flex items-stretch border-1 border-gray-200 rounded-lg overflow-hidden">
<div class="flex items-stretch border-1 border-gray-200 rounded-lg overflow-hidden h-8">
<NcDropdown v-model:visible="auditDropdowns.type">
<NcButton type="secondary" size="small" class="!border-none !rounded-none">
<div class="!w-[106px] flex items-center justify-between gap-2">
<div class="max-w-[120px] truncate text-sm !leading-5">Type: {{ auditLogsQuery.type || 'All' }}</div>
<div class="max-w-[120px] truncate text-sm !leading-5">
Type: {{ auditOperationTypeLabels[auditLogsQuery.type] || 'All' }}
</div>
<GeneralIcon icon="arrowDown" class="flex-none h-4 w-4" />
</div>
</NcButton>
@ -139,6 +194,7 @@ onMounted(async () => {
@click="
() => {
auditDropdowns.type = false
loadAudits()
}
"
@ -151,17 +207,22 @@ onMounted(async () => {
</NcMenuItem>
<NcDivider />
<NcMenuItem
v-for="type in AuditOperationTypes"
:key="type"
v-for="type in auditTypeOptions"
:key="type.value"
class="!children:w-full"
@click="auditLogsQuery.type = type"
@click="
() => {
auditLogsQuery.type = type.value
auditLogsQuery.subType = undefined
}
"
>
<div class="w-full flex items-center justify-between gap-3">
<div class="flex-1 flex items-center gap-2 max-w-[calc(100%_-_28px)]">
{{ type }}
{{ type.label }}
</div>
<GeneralIcon v-if="auditLogsQuery.type === type" icon="check" class="flex-none text-primary w-4 h-4" />
<GeneralIcon v-if="auditLogsQuery.type === type.value" icon="check" class="flex-none text-primary w-4 h-4" />
</div>
</NcMenuItem>
</NcMenu>
@ -170,7 +231,10 @@ onMounted(async () => {
<NcDropdown v-model:visible="auditDropdowns.subType" placement="bottomRight">
<NcButton type="secondary" size="small" class="!border-none !rounded-none">
<div class="!w-[146px] flex items-center justify-between gap-2">
<div class="truncate text-sm !leading-5">Sub-Type: {{ auditLogsQuery.subType || 'All' }}</div>
<div class="truncate text-sm !leading-5">
Sub-Type:
{{ auditLogsQuery.subType ? auditOperationSubTypeLabels[auditLogsQuery.subType] : 'All' }}
</div>
<GeneralIcon icon="arrowDown" class="flex-none h-4 w-4" />
</div>
</NcButton>
@ -193,17 +257,21 @@ onMounted(async () => {
</NcMenuItem>
<NcDivider />
<NcMenuItem
v-for="subType in AuditOperationSubTypes"
:key="subType"
v-for="subType in auditSubTypeOptions"
:key="subType.value"
class="!children:w-full"
@click="auditLogsQuery.subType = subType"
@click="auditLogsQuery.subType = subType.value"
>
<div class="w-full flex items-center justify-between gap-3">
<div class="flex-1 flex items-center gap-2 max-w-[calc(100%_-_28px)]">
{{ subType }}
{{ subType.label }}
</div>
<GeneralIcon v-if="auditLogsQuery.subType === subType" icon="check" class="flex-none text-primary w-4 h-4" />
<GeneralIcon
v-if="auditLogsQuery.subType === subType.value"
icon="check"
class="flex-none text-primary w-4 h-4"
/>
</div>
</NcMenuItem>
</NcMenu>
@ -415,20 +483,20 @@ onMounted(async () => {
</template>
</div>
<div class="td cell-type">
<div class="truncate">
<div class="truncate bg-gray-200 px-3 py-1 rounded-lg">
<NcTooltip class="truncate" placement="bottom" show-on-truncate-only>
<template #title> {{ audit.op_type }}</template>
<template #title> {{ auditOperationTypeLabels[audit.op_type] }}</template>
<span class="truncate"> {{ audit.op_type }} </span>
<span class="truncate"> {{ auditOperationTypeLabels[audit.op_type] }} </span>
</NcTooltip>
</div>
</div>
<div class="td cell-sub-type">
<div class="truncate">
<NcTooltip class="truncate" placement="bottom" show-on-truncate-only>
<template #title> {{ audit.op_sub_type }}</template>
<template #title> {{ auditOperationSubTypeLabels[audit.op_sub_type] }}</template>
<span class="truncate"> {{ audit.op_sub_type }} </span>
<span class="truncate"> {{ auditOperationSubTypeLabels[audit.op_sub_type] }} </span>
</NcTooltip>
</div>
</div>

47
packages/nocodb-sdk/src/lib/globals.ts

@ -44,16 +44,32 @@ export enum AuditOperationTypes {
ORG_USER = 'ORG_USER',
}
export const auditOperationTypeLabels = {
[AuditOperationTypes.COMMENT]: 'Comment',
[AuditOperationTypes.DATA]: 'Data',
[AuditOperationTypes.PROJECT]: 'Project',
[AuditOperationTypes.VIRTUAL_RELATION]: 'Virtual Relation',
[AuditOperationTypes.RELATION]: 'Relation',
[AuditOperationTypes.TABLE_VIEW]: 'Table View',
[AuditOperationTypes.TABLE]: 'Table',
[AuditOperationTypes.VIEW]: 'View',
[AuditOperationTypes.META]: 'Meta',
[AuditOperationTypes.WEBHOOKS]: 'Webhooks',
[AuditOperationTypes.AUTHENTICATION]: 'Authentication',
[AuditOperationTypes.TABLE_COLUMN]: 'Table Column',
[AuditOperationTypes.ORG_USER]: 'Org User',
};
export enum AuditOperationSubTypes {
UPDATE = 'UPDATE',
INSERT = 'INSERT',
CREATE = 'CREATE',
UPDATE = 'UPDATE',
DELETE = 'DELETE',
BULK_INSERT = 'BULK_INSERT',
BULK_UPDATE = 'BULK_UPDATE',
BULK_DELETE = 'BULK_DELETE',
LINK_RECORD = 'LINK_RECORD',
UNLINK_RECORD = 'UNLINK_RECORD',
DELETE = 'DELETE',
CREATE = 'CREATE',
RENAME = 'RENAME',
IMPORT_FROM_ZIP = 'IMPORT_FROM_ZIP',
EXPORT_TO_FS = 'EXPORT_TO_FS',
@ -69,6 +85,31 @@ export enum AuditOperationSubTypes {
RESEND_INVITE = 'RESEND_INVITE',
}
export const auditOperationSubTypeLabels = {
[AuditOperationSubTypes.UPDATE]: 'Update',
[AuditOperationSubTypes.INSERT]: 'Insert',
[AuditOperationSubTypes.DELETE]: 'Delete',
[AuditOperationSubTypes.BULK_INSERT]: 'Bulk Insert',
[AuditOperationSubTypes.BULK_UPDATE]: 'Bulk Update',
[AuditOperationSubTypes.BULK_DELETE]: 'Bulk Delete',
[AuditOperationSubTypes.LINK_RECORD]: 'Link Record',
[AuditOperationSubTypes.UNLINK_RECORD]: 'Unlink Record',
[AuditOperationSubTypes.CREATE]: 'Create',
[AuditOperationSubTypes.RENAME]: 'Rename',
[AuditOperationSubTypes.IMPORT_FROM_ZIP]: 'Import From Zip',
[AuditOperationSubTypes.EXPORT_TO_FS]: 'Export To FS',
[AuditOperationSubTypes.EXPORT_TO_ZIP]: 'Export To Zip',
[AuditOperationSubTypes.SIGNIN]: 'Signin',
[AuditOperationSubTypes.SIGNUP]: 'Signup',
[AuditOperationSubTypes.PASSWORD_RESET]: 'Password Reset',
[AuditOperationSubTypes.PASSWORD_FORGOT]: 'Password Forgot',
[AuditOperationSubTypes.PASSWORD_CHANGE]: 'Password Change',
[AuditOperationSubTypes.EMAIL_VERIFICATION]: 'Email Verification',
[AuditOperationSubTypes.ROLES_MANAGEMENT]: 'Roles Management',
[AuditOperationSubTypes.INVITE]: 'Invite',
[AuditOperationSubTypes.RESEND_INVITE]: 'Resend Invite',
};
export enum PluginCategory {
STORAGE = 'Storage',
EMAIL = 'Email',

Loading…
Cancel
Save