多维表格
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

235 lines
6.2 KiB

import type { ColumnType, CommentType, TableType } from 'nocodb-sdk'
const [useProvideRowComments, useRowComments] = useInjectionState((meta: Ref<TableType>, row: Ref<Row>) => {
const isCommentsLoading = ref(false)
const { isUIAllowed } = useRoles()
const { $e, $state, $api } = useNuxtApp()
const comments = ref<
Array<
CommentType & {
created_display_name: string
resolved_display_name?: string
}
>
>([])
const basesStore = useBases()
const { basesUser } = storeToRefs(basesStore)
const baseUsers = computed(() => (meta.value.base_id ? basesUser.value.get(meta.value.base_id) || [] : []))
const loadComments = async (_rowId?: string, ignoreLoadingIndicator = true) => {
if (!isUIAllowed('commentList') || (!row.value && !_rowId)) return
const rowId = _rowId ?? extractPkFromRow(row.value.row, meta.value.columns as ColumnType[])
if (!rowId) return
try {
if (!ignoreLoadingIndicator) isCommentsLoading.value = true
const res = ((
await $api.utils.commentList({
row_id: rowId,
fk_model_id: meta.value.id as string,
})
).list || []) as Array<
CommentType & {
created_display_name: string
}
>
comments.value = res.map((comment) => {
const user = baseUsers.value.find((u) => u.id === comment.created_by)
const resolvedUser = comment.resolved_by ? baseUsers.value.find((u) => u.id === comment.resolved_by) : null
return {
...comment,
created_display_name: user?.display_name ?? (user?.email ?? '').split('@')[0],
resolved_display_name: resolvedUser ? resolvedUser.display_name ?? resolvedUser.email.split('@')[0] : undefined,
}
})
} catch (e: unknown) {
message.error(
await extractSdkResponseErrorMsg(
e as Error & {
response: any
},
),
)
} finally {
if (!ignoreLoadingIndicator) isCommentsLoading.value = false
}
}
const deleteComment = async (commentId: string) => {
if (!isUIAllowed('commentDelete')) return
const tempC = comments.value.find((c) => c.id === commentId)
if (!tempC) return
try {
comments.value = comments.value.filter((c) => c.id !== commentId)
await $api.utils.commentDelete(commentId)
// update comment count in rowMeta
Object.assign(row.value, {
...row.value,
rowMeta: {
...row.value.rowMeta,
commentCount: (row.value.rowMeta.commentCount ?? 1) - 1,
},
})
} catch (e: unknown) {
message.error(
await extractSdkResponseErrorMsg(
e as Error & {
response: any
},
),
)
comments.value = [...comments.value, tempC]
}
}
const resolveComment = async (commentId: string) => {
if (!isUIAllowed('commentResolve')) return
const tempC = comments.value.find((c) => c.id === commentId)
if (!tempC) return
try {
comments.value = comments.value.map((c) => {
if (c.id === commentId) {
return {
...c,
resolved_by: tempC.resolved_by ? undefined : $state.user?.value?.id,
resolved_by_email: tempC.resolved_by ? undefined : $state.user?.value?.email,
resolved_display_name: tempC.resolved_by
? undefined
: $state.user?.value?.display_name ?? $state.user?.value?.email.split('@')[0],
}
}
return c
})
await $api.utils.commentResolve(commentId, {})
} catch (e: unknown) {
comments.value = comments.value.map((c) => {
if (c.id === commentId) {
return tempC
}
return c
})
message.error(
await extractSdkResponseErrorMsg(
e as Error & {
response: any
},
),
)
}
}
const saveComment = async (comment: string) => {
try {
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[])
if (!rowId) return
await $api.utils.commentRow({
fk_model_id: meta.value?.id as string,
row_id: rowId,
comment: `${comment}`.replace(/(<br \/>)+$/g, ''),
})
// Increase Comment Count in rowMeta
Object.assign(row.value, {
rowMeta: {
...row.value.rowMeta,
commentCount: (row.value.rowMeta.commentCount ?? 0) + 1,
},
})
// reloadTrigger?.trigger()
await loadComments()
} catch (e: any) {
comments.value = comments.value.filter((c) => !(c.id ?? '').startsWith('temp-'))
message.error(
await extractSdkResponseErrorMsg(
e as Error & {
response: any
},
),
)
}
$e('a:row-expand:comment')
}
const updateComment = async (commentId: string, comment: Partial<CommentType>) => {
const tempEdit = comments.value.find((c) => c.id === commentId)
if (!tempEdit) return
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
},
),
)
}
}
const primaryKey = computed(() => {
return extractPkFromRow(row.value.row, meta.value.columns as ColumnType[])
})
return {
comments,
loadComments,
saveComment,
updateComment,
resolveComment,
deleteComment,
isCommentsLoading,
primaryKey,
}
})
export { useProvideRowComments }
export function useRowCommentsOrThrow() {
const rowComments = useRowComments()
if (!rowComments) {
throw new Error('useRowComments is not provided')
}
return rowComments
}