Browse Source

Nc fix/comments UI (#8711)

* fix: minor fixes

* fix: minor fixes

* fix: minor fixes

* fix: hover on comment

---------

Co-authored-by: DarkPhoenix2704 <anbarasun123@gmail.com>
pull/8714/head
Raju Udava 4 months ago committed by GitHub
parent
commit
5b7c788048
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 12
      packages/nc-gui/components/cell/RichText/LinkOptions.vue
  2. 55
      packages/nc-gui/components/smartsheet/expanded-form/Comments.vue
  3. 5
      packages/nc-gui/components/smartsheet/expanded-form/RichComment.vue
  4. 21
      packages/nc-gui/components/smartsheet/expanded-form/RichTextOptions.vue
  5. 43
      packages/nc-gui/composables/useExpandedFormStore.ts

12
packages/nc-gui/components/cell/RichText/LinkOptions.vue

@ -11,6 +11,7 @@ const emits = defineEmits(['blur'])
interface Props { interface Props {
editor: Editor editor: Editor
isFormField?: boolean isFormField?: boolean
isComment?: boolean
} }
const { editor, isFormField } = toRefs(props) const { editor, isFormField } = toRefs(props)
@ -164,6 +165,9 @@ const openLink = () => {
const onMountLinkOptions = (e) => { const onMountLinkOptions = (e) => {
if (e?.popper?.style) { if (e?.popper?.style) {
if (props.isComment) {
e.popper.style.left = '-10%'
}
e.popper.style.width = '95%' e.popper.style.width = '95%'
} }
} }
@ -233,14 +237,6 @@ const tabIndex = computed(() => {
<MdiDeleteOutline /> <MdiDeleteOutline />
</NcButton> </NcButton>
</NcTooltip> </NcTooltip>
<div class="absolute -bottom-1.5 left-0 right-0 w-full flex flex-row justify-center">
<div
class="flex h-2.5 w-2.5 bg-white border-gray-200 border-r-1 border-b-1 transform rotate-45"
:style="{
boxShadow: '1px 1px 3px rgba(231, 231, 233, 1)',
}"
></div>
</div>
</div> </div>
</div> </div>
</BubbleMenu> </BubbleMenu>

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

@ -13,7 +13,6 @@ const {
audits, audits,
isAuditLoading, isAuditLoading,
saveComment: _saveComment, saveComment: _saveComment,
comment: newComment,
updateComment, updateComment,
} = useExpandedFormStoreOrThrow() } = useExpandedFormStoreOrThrow()
@ -23,6 +22,14 @@ const commentsWrapperEl = ref<HTMLDivElement>()
const commentInputRef = ref<any>() const commentInputRef = ref<any>()
const comment = ref('')
const { copy } = useClipboard()
const route = useRoute()
const { dashboardUrl } = useDashboard()
const editRef = ref<any>() const editRef = ref<any>()
const { user, appInfo } = useGlobal() const { user, appInfo } = useGlobal()
@ -68,10 +75,16 @@ async function onEditComment() {
isCommentMode.value = true isCommentMode.value = true
await updateComment(editComment.value.id!, { const tempCom = {
comment: editComment.value?.comment, ...editCommentValue.value,
}
isEditing.value = false
editCommentValue.value = undefined
await updateComment(tempCom.id!, {
comment: tempCom.comment,
}) })
onStopEdit() loadComments()
} }
function onCancel() { function onCancel() {
@ -116,10 +129,16 @@ function scrollComments() {
} }
} }
const isSaving = ref(false)
const saveComment = async () => { const saveComment = async () => {
if (isSaving.value) return if (!comment.value.trim()) return
while (comment.value.endsWith('<br />') || comment.value.endsWith('\n')) {
if (comment.value.endsWith('<br />')) {
comment.value = comment.value.slice(0, -6)
} else {
comment.value = comment.value.slice(0, -2)
}
}
isCommentMode.value = true isCommentMode.value = true
isSaving.value = true isSaving.value = true
@ -129,7 +148,7 @@ const saveComment = async () => {
...comments.value, ...comments.value,
{ {
id: `temp-${new Date().getTime()}`, id: `temp-${new Date().getTime()}`,
comment: newComment.value, comment: comment.value,
created_at: new Date().toISOString(), created_at: new Date().toISOString(),
created_by: user.value?.id, created_by: user.value?.id,
created_by_email: user.value?.email, created_by_email: user.value?.email,
@ -137,13 +156,16 @@ const saveComment = async () => {
}, },
] ]
const tempCom = comment.value
comment.value = ''
commentInputRef?.value?.setEditorContent('', true) commentInputRef?.value?.setEditorContent('', true)
await nextTick(() => { await nextTick(() => {
scrollComments() scrollComments()
}) })
try { try {
await _saveComment() await _saveComment(tempCom)
await nextTick(() => { await nextTick(() => {
isExpandedFormCommentMode.value = true isExpandedFormCommentMode.value = true
}) })
@ -235,10 +257,8 @@ const createdBy = (
<div v-for="comment of comments" :key="comment.id" :class="`${comment.id}`" class="nc-comment-item"> <div v-for="comment of comments" :key="comment.id" :class="`${comment.id}`" class="nc-comment-item">
<div <div
:class="{ :class="{
'hover:bg-gray-200 bg-[#F9F9FA]': comment.id !== editComment?.id, 'hover:bg-gray-100': editCommentValue?.id !== comment!.id
'bg-gray-200': comment.id === editComment?.id, }"
'!bg-[#E7E7E9]': comment.resolved_by,
}"
class="group gap-3 overflow-hidden px-3 py-2" class="group gap-3 overflow-hidden px-3 py-2"
> >
<div class="flex items-start justify-between"> <div class="flex items-start justify-between">
@ -337,7 +357,7 @@ const createdBy = (
v-model:value="value" v-model:value="value"
autofocus autofocus
:hide-options="false" :hide-options="false"
class="expanded-form-comment-edit-input expanded-form-comment-input !pt-2 !pb-0.5 !pl-2 !m-0 w-full !border-1 !border-gray-200 !rounded-lg !bg-white !text-gray-800 !text-small !leading-18px !max-h-[694px]" class="expanded-form-comment-edit-input cursor-text expanded-form-comment-input !py-2 !px-2 !m-0 w-full !border-1 !border-gray-200 !rounded-lg !bg-white !text-gray-800 !text-small !leading-18px !max-h-[240px]"
data-testid="expanded-form-comment-input" data-testid="expanded-form-comment-input"
sync-value-change sync-value-change
@save="onEditComment" @save="onEditComment"
@ -366,10 +386,10 @@ const createdBy = (
<div v-if="hasEditPermission" class="bg-gray-50 nc-comment-input !rounded-br-2xl gap-2 flex"> <div v-if="hasEditPermission" class="bg-gray-50 nc-comment-input !rounded-br-2xl gap-2 flex">
<SmartsheetExpandedFormRichComment <SmartsheetExpandedFormRichComment
ref="commentInputRef" ref="commentInputRef"
v-model:value="newComment" v-model:value="comment"
:hide-options="false" :hide-options="false"
placeholder="Comment..." placeholder="Comment..."
class="expanded-form-comment-input !m-0 pt-2 w-full !border-t-1 !border-gray-200 !bg-transparent !text-gray-800 !text-small !leading-18px !max-h-[566px]" class="expanded-form-comment-input !py-2 !px-2 cursor-text border-1 rounded-lg w-full bg-transparent !text-gray-800 !text-small !leading-18px !max-h-[240px]"
:autofocus="isExpandedFormCommentMode" :autofocus="isExpandedFormCommentMode"
data-testid="expanded-form-comment-input" data-testid="expanded-form-comment-input"
@focus="isExpandedFormCommentMode = false" @focus="isExpandedFormCommentMode = false"
@ -512,7 +532,8 @@ const createdBy = (
box-shadow: none; box-shadow: none;
&:focus, &:focus,
&:focus-within { &:focus-within {
@apply min-h-16; @apply min-h-16 !bg-white border-brand-500;
box-shadow: 0px 0px 0px 2px rgba(51, 102, 255, 0.24);
} }
&::placeholder { &::placeholder {
@apply !text-gray-400; @apply !text-gray-400;

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

@ -60,6 +60,8 @@ const vModel = useVModel(props, 'value', emits, { defaultValue: '' })
const tiptapExtensions = [ const tiptapExtensions = [
StarterKit.configure({ StarterKit.configure({
heading: false, heading: false,
codeBlock: false,
code: false,
}), }),
Underline, Underline,
Link, Link,
@ -82,6 +84,7 @@ const editor = useEditor({
onFocus: () => { onFocus: () => {
isFocused.value = true isFocused.value = true
emits('focus') emits('focus')
onFocusWrapper()
}, },
onBlur: (e) => { onBlur: (e) => {
if ( if (
@ -122,6 +125,7 @@ const setEditorContent = (contentMd: any, focusEndOfDoc?: boolean) => {
const onFocusWrapper = () => { const onFocusWrapper = () => {
if (!props.readOnly && !keys.shift.value) { if (!props.readOnly && !keys.shift.value) {
editor.value?.chain().focus().run() editor.value?.chain().focus().run()
setEditorContent(vModel.value, true)
} }
} }
@ -236,6 +240,7 @@ defineExpose({
v-if="editor" v-if="editor"
ref="richTextLinkOptionRef" ref="richTextLinkOptionRef"
:editor="editor" :editor="editor"
:is-comment="true"
:is-form-field="true" :is-form-field="true"
@blur="isFocused = false" @blur="isFocused = false"
/> />

21
packages/nc-gui/components/smartsheet/expanded-form/RichTextOptions.vue

@ -67,8 +67,25 @@ const onToggleLink = () => {
} }
const newMentionNode = () => { const newMentionNode = () => {
editor.value?.commands.insertContent('@') if (!editor.value) return
editor.value?.chain().focus().run()
const lastCharacter = editor.value.state.doc.textBetween(
editor.value.state.selection.$from.pos - 1,
editor.value.state.selection.$from.pos,
)
if (lastCharacter === '@') {
editor.value
.chain()
.deleteRange({ from: editor.value.state.selection.$from.pos - 1, to: editor.value.state.selection.$from.pos })
.run()
} else if (lastCharacter !== ' ') {
editor.value?.commands.insertContent(' @')
editor.value?.chain().focus().run()
} else {
editor.value?.commands.insertContent('@')
editor.value?.chain().focus().run()
}
} }
</script> </script>

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

@ -25,8 +25,6 @@ const [useProvideExpandedFormStore, useExpandedFormStore] = useInjectionState((m
const isAuditLoading = ref(false) const isAuditLoading = ref(false)
const comment = ref('')
const commentsDrawer = ref(true) const commentsDrawer = ref(true)
const saveRowAndStay = ref(0) const saveRowAndStay = ref(0)
@ -250,9 +248,12 @@ const [useProvideExpandedFormStore, useExpandedFormStore] = useInjectionState((m
} }
} }
const saveComment = async () => { const saveComment = async (comment: string) => {
try { try {
if (!row.value || !comment.value) return if (!row.value || !comment) {
comments.value = comments.value.filter((c) => !c.id?.startsWith('temp-'))
return
}
const rowId = extractPkFromRow(row.value.row, meta.value.columns as ColumnType[]) const rowId = extractPkFromRow(row.value.row, meta.value.columns as ColumnType[])
@ -261,7 +262,7 @@ const [useProvideExpandedFormStore, useExpandedFormStore] = useInjectionState((m
await $api.utils.commentRow({ await $api.utils.commentRow({
fk_model_id: meta.value?.id as string, fk_model_id: meta.value?.id as string,
row_id: rowId, row_id: rowId,
comment: `${comment.value}`.replace(/(<br \/>)+$/g, ''), comment: `${comment}`.replace(/(<br \/>)+$/g, ''),
}) })
// Increase Comment Count in rowMeta // Increase Comment Count in rowMeta
@ -275,8 +276,6 @@ const [useProvideExpandedFormStore, useExpandedFormStore] = useInjectionState((m
// reloadTrigger?.trigger() // reloadTrigger?.trigger()
await Promise.all([loadComments(), loadAudits()]) await Promise.all([loadComments(), loadAudits()])
comment.value = ''
} catch (e: any) { } catch (e: any) {
comments.value = comments.value.filter((c) => !(c.id ?? '').startsWith('temp-')) comments.value = comments.value.filter((c) => !(c.id ?? '').startsWith('temp-'))
message.error( message.error(
@ -526,7 +525,34 @@ const [useProvideExpandedFormStore, useExpandedFormStore] = useInjectionState((m
} }
const updateComment = async (commentId: string, comment: Partial<CommentType>) => { const updateComment = async (commentId: string, comment: Partial<CommentType>) => {
return await $api.utils.commentUpdate(commentId, comment) const tempEdit = comments.value.find((c) => c.id === commentId)
try {
comments.value = comments.value.map((c) => {
if (c.id === commentId) {
return {
...c,
...comment,
updated_at: new Date().toISOString(),
}
}
return c
})
await $api.utils.commentUpdate(commentId, comment)
} catch (e: any) {
comments.value = comments.value.map((c) => {
if (c.id === commentId) {
return tempEdit
}
return c
})
message.error(
await extractSdkResponseErrorMsg(
e as Error & {
response: any
},
),
)
}
} }
return { return {
@ -540,7 +566,6 @@ const [useProvideExpandedFormStore, useExpandedFormStore] = useInjectionState((m
resolveComment, resolveComment,
isCommentsLoading, isCommentsLoading,
saveComment, saveComment,
comment,
isYou, isYou,
commentsDrawer, commentsDrawer,
row, row,

Loading…
Cancel
Save