Browse Source

fix(nc-gui): update the audits design in expanded form (#8867)

* fix(nc-gui): update the audits design for ce

* fix(nc-gui): ui fix

* fix(nc-gui): left padding
pull/8878/head
Anbarasu 5 months ago committed by GitHub
parent
commit
9109e7adc2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 87
      packages/nc-gui/components/smartsheet/expanded-form/Comments.vue
  2. 38
      packages/nc-gui/components/smartsheet/expanded-form/RichComment.vue
  3. 11
      packages/nc-gui/composables/useExpandedFormStore.ts

87
packages/nc-gui/components/smartsheet/expanded-form/Comments.vue

@ -1,5 +1,5 @@
<script setup lang="ts">
import { type CommentType, ProjectRoles } from 'nocodb-sdk'
import { type AuditType, type CommentType, ProjectRoles } from 'nocodb-sdk'
const props = defineProps<{
loading: boolean
@ -225,6 +225,22 @@ const createdBy = (
}
}
const createdByAudit = (
comment: AuditType & {
created_display_name?: string
},
) => {
if (comment.user === user.value?.email) {
return 'You'
} else if (comment.created_display_name?.trim()) {
return comment.created_display_name || 'Shared source'
} else if (comment.user) {
return comment.user
} else {
return 'Shared source'
}
}
const getUserRole = (email: string) => {
const user = baseUsers.value.find((user) => user.email === email)
if (!user) return ProjectRoles.NO_ACCESS
@ -501,7 +517,12 @@ function handleResetHoverEffect() {
<GeneralLoader size="xlarge" />
</div>
<div v-else ref="commentsWrapperEl" class="flex flex-col h-full py-1 nc-scrollbar-thin !overflow-y-auto">
<div v-else ref="commentsWrapperEl" class="flex flex-col h-full py-1 nc-scrollbar-thin">
<!-- The scrollbar doesn't work when flex-end is used. https://issues.chromium.org/issues/41130651
Hence using a div to fix the issue
https://stackoverflow.com/questions/36130760/use-justify-content-flex-end-and-to-have-vertical-scrollbar
-->
<div class="scroll-fix"></div>
<template v-if="audits.length === 0">
<div class="flex flex-col text-center justify-center h-full">
<div class="text-center text-3xl text-gray-600">
@ -512,25 +533,53 @@ function handleResetHoverEffect() {
</template>
<div v-for="audit of audits" :key="audit.id" class="nc-audit-item">
<div class="group gap-3 overflow-hidden flex items-start p-3">
<GeneralUserIcon size="medium" :email="audit.user" :name="audit.display_name" />
<div class="flex-1 flex flex-col gap-1 max-w-[calc(100%_-_24px)]">
<div class="flex flex-wrap items-center min-h-7">
<NcTooltip class="truncate max-w-42 mr-2" show-on-truncate-only>
<template #title>
{{ audit.display_name?.trim() || audit.user || 'Shared source' }}
</template>
<span class="text-ellipsis break-keep inline whitespace-nowrap overflow-hidden font-bold text-gray-800">
{{ audit.display_name?.trim() || audit.user || 'Shared source' }}
<div class="group gap-3 overflow-hidden px-3 py-2">
<div class="flex items-start justify-between">
<div class="flex items-start gap-3">
<GeneralUserIcon
:email="audit.created_by_email"
:name="audit.created_display_name"
class="mt-0.5"
size="medium"
/>
<div class="flex h-[28px] items-center gap-3">
<NcDropdown placement="topLeft" :trigger="['hover']">
<span class="text-ellipsis text-gray-800 font-medium !text-[13px] max-w-42 overflow-hidden" :style="{}">
{{ createdByAudit(audit) }}
</span>
</NcTooltip>
<div class="text-xs text-gray-400">
{{ timeAgo(audit.created_at) }}
<template #overlay>
<div class="bg-white rounded-lg">
<div class="flex items-center gap-4 py-3 px-2">
<GeneralUserIcon
class="!w-8 !h-8 border-1 border-gray-200 rounded-full"
:name="audit.created_display_name"
:email="audit.created_by_email"
/>
<div class="flex flex-col">
<div class="font-semibold text-gray-800">
{{ createdByAudit(audit) }}
</div>
<div class="text-xs text-gray-600">
{{ audit.created_by_email }}
</div>
<div v-dompurify-html="audit.details" class="text-sm font-medium"></div>
</div>
</div>
<div class="px-3 rounded-b-lg !text-[13px] items-center text-gray-600 flex gap-1 bg-gray-100 py-1.5">
Has <RolesBadge size="sm" :border="false" :role="getUserRole(audit.created_by_email!)" />
role in base
</div>
</div>
</template>
</NcDropdown>
<div class="text-xs text-gray-500">
{{ timeAgo(audit.created_at!) }}
</div>
</div>
</div>
</div>
<div v-dompurify-html="audit.details" class="!text-[13px] text-gray-500 !leading-5 !pl-9"></div>
</div>
</div>
</div>
</div>
@ -549,11 +598,7 @@ function handleResetHoverEffect() {
}
.nc-audit-item {
@apply border-b-1 gap-3 border-gray-200;
}
.nc-audit-item:last-child {
@apply border-b-0;
@apply gap-3;
}
.tab .tab-title {

38
packages/nc-gui/components/smartsheet/expanded-form/RichComment.vue

@ -170,11 +170,17 @@ useEventListener(
const targetEl = e?.relatedTarget as HTMLElement
if (
!targetEl &&
(e.target as HTMLElement)?.closest('.comment-bubble-menu, .nc-comment-save-btn, .tippy-content, .nc-comment-rich-editor')
(e.target as HTMLElement)?.closest(
'.comment-bubble-menu, .nc-comment-save-btn, .nc-mention-list, .mention, .rich-text-bottom-bar, .tippy-content, .nc-comment-rich-editor',
)
)
return
if (!targetEl?.closest('.comment-bubble-menu, .nc-comment-save-btn, .tippy-content, .nc-comment-rich-editor')) {
if (
!targetEl?.closest(
'.comment-bubble-menu, .nc-comment-save-btn, .rich-text-bottom-bar, .mention, .tippy-content, .nc-mention-list, .nc-comment-rich-editor',
)
) {
isFocused.value = false
emits('blur')
@ -189,7 +195,7 @@ onClickOutside(editorDom, (e) => {
if (
!targetEl?.closest(
'.tippy-content, .nc-rich-text-comment, .nc-comment-save-btn, .comment-bubble-menu, .nc-comment-rich-editor',
'.tippy-content, .nc-rich-text-comment, .nc-comment-save-btn, .nc-mention-list, .rich-text-bottom-bar, .mention, .comment-bubble-menu, .nc-comment-rich-editor',
)
) {
isFocused.value = false
@ -216,7 +222,7 @@ const emitSave = (event: KeyboardEvent) => {
const handleEnterDown = (event: KeyboardEvent) => {
const isListsActive =
editor.value?.isActive('bulletList') || editor.value?.isActive('orderedList') || editor.value.isActive('blockquote')
editor.value?.isActive('bulletList') || editor.value?.isActive('orderedList') || editor.value?.isActive('blockquote')
if (isListsActive) {
triggerSaveFromList.value = true
setTimeout(() => {
@ -240,6 +246,12 @@ const handleKeyPress = (event: KeyboardEvent) => {
}
}
const saveComment = (e) => {
e.preventDefault()
e.stopPropagation()
emits('save')
}
defineExpose({
setEditorContent,
})
@ -262,12 +274,6 @@ onMounted(() => {
})
}, 1000)
})
const saveComment = (e) => {
e.preventDefault()
e.stopPropagation()
emits('save')
}
</script>
<template>
@ -297,14 +303,14 @@ const saveComment = (e) => {
ref="editorDom"
:editor="editor"
:class="{
'px-2': !props.readOnly,
'px-[0.25rem]': props.readOnly,
'p-1': !props.readOnly,
'px-[0.25rem] py-1': props.readOnly,
}"
class="flex flex-col nc-comment-rich-editor py-2.125 w-full scrollbar-thin scrollbar-thumb-gray-200 nc-truncate scrollbar-track-transparent"
class="flex flex-col nc-comment-rich-editor w-full scrollbar-thin scrollbar-thumb-gray-200 nc-truncate scrollbar-track-transparent"
@keydown.stop="handleKeyPress"
/>
<div v-if="!hideOptions" class="flex justify-between p-2 items-center">
<div v-if="!hideOptions" class="flex justify-between pt-1 rich-text-bottom-bar items-center">
<LazySmartsheetExpandedFormRichTextOptions :editor="editor" class="!bg-transparent" />
<NcButton
v-e="['a:row-expand:comment:save']"
@ -362,7 +368,7 @@ const saveComment = (e) => {
}
}
.tiptap p.is-editor-empty:first-child::before {
color: #9aa2af;
@apply text-gray-500;
content: attr(data-placeholder);
float: left;
height: 0;
@ -375,7 +381,7 @@ const saveComment = (e) => {
}
p {
@apply !m-0;
@apply !m-0 !leading-5;
}
.ProseMirror-focused {

11
packages/nc-gui/composables/useExpandedFormStore.ts

@ -182,13 +182,22 @@ const [useProvideExpandedFormStore, useExpandedFormStore] = useInjectionState((m
try {
isAuditLoading.value = true
audits.value =
const res =
(
await $api.utils.auditList({
row_id: rowId,
fk_model_id: meta.value.id as string,
})
).list?.reverse?.() || []
audits.value = res.map((audit) => {
const user = baseUsers.value.find((u) => u.email === audit.user)
return {
...audit,
created_display_name: user?.display_name ?? (user?.email ?? '').split('@')[0],
created_by_email: user?.email,
}
})
} catch (e: any) {
message.error(
await extractSdkResponseErrorMsg(

Loading…
Cancel
Save