feat(公共组件): 增加评论人ids

This commit is contained in:
xinxin.wu 2024-01-29 19:13:51 +08:00 committed by Craftsman
parent a3e8453536
commit b3822a3607
13 changed files with 63 additions and 15 deletions

View File

@ -795,7 +795,6 @@
/*** 徽标 ****/
.arco-badge-number {
width: 30px !important;
height: 16px !important;
line-height: 16px;
text-align: center;

View File

@ -74,6 +74,8 @@ export default defineComponent({
currentItem.parentId = item.parentId || '';
};
const noticeUserIds = ref<string[]>([]);
const renderInput = (item: CommentItem) => {
return (
<CommentInput

View File

@ -10,7 +10,7 @@
<div class="w-full items-center">
<a-input v-if="!isActive" class="w-full" @click="isActive = true"></a-input>
<div v-else class="flex flex-col justify-between">
<MsRichText v-model:raw="currentContent" class="w-full" />
<MsRichText v-model:raw="currentContent" v-model:commentIds="commentIds" class="w-full" />
<div class="mt-4 flex flex-row justify-end gap-[12px]">
<a-button @click="cancelClick">{{ t('common.cancel') }}</a-button>
<a-button type="primary" :disabled="!currentContent" @click="publish">{{ t('common.publish') }}</a-button>
@ -22,6 +22,7 @@
<script lang="ts" setup>
import { ref } from 'vue';
import { useVModel } from '@vueuse/core';
import MsAvatar from '@/components/pure/ms-avatar/index.vue';
import MsRichText from '@/components/pure/ms-rich-text/MsRichText.vue';
@ -38,6 +39,7 @@
isShowAvatar: boolean; //
isUseBottom: boolean; //
defaultValue?: string; //
noticeUserIds?: string[]; // id
}>();
const currentContent = ref(props.defaultValue || '');
@ -48,6 +50,7 @@
}>();
const isActive = ref(false);
const commentIds = useVModel(props, 'noticeUserIds', emit);
const publish = () => {
emit('publish', currentContent.value);

View File

@ -128,6 +128,7 @@
popupContainer: 'body',
disabledWidthDrag: false,
okPermission: () => [], //
closable: true,
});
const emit = defineEmits(['update:visible', 'confirm', 'cancel', 'continue']);

View File

@ -1,5 +1,5 @@
<template>
<FormCreate v-model:api="formApi" :rule="formRules" :option="option"></FormCreate>
<FormCreate v-model:api="formApi" :rule="formRules" :option="props.option"></FormCreate>
</template>
<script setup lang="ts">

View File

@ -94,6 +94,7 @@
uploadImage?: (file: File) => Promise<any>;
maxHeight?: string;
filedIds?: string[];
commentIds?: string[];
}>(),
{
raw: '',
@ -107,9 +108,11 @@
(event: 'update:raw', value: string): void;
(event: 'update:filedIds', value: string[]): void;
(event: 'update', value: string): void;
(event: 'update:commentIds', value: string): void;
}>();
const imagesNodes = useVModel(props, 'filedIds', emit);
const imagesNodesIds = useVModel(props, 'filedIds', emit);
const commentNodeIds = useVModel(props, 'commentIds', emit);
async function asyncWorker(arg: Task): Promise<void> {
if (!props.uploadImage) {
@ -142,6 +145,7 @@
const attachmentSelectorModal = ref(false);
const selectedimagesNode = ref<string>();
const selectedCommentNode = ref<string>();
onMounted(() => {
const debounceOnUpdate = useDebounceFn(() => {
@ -194,7 +198,7 @@
images.push(node.attrs.fileId);
}
});
imagesNodes.value = images;
imagesNodesIds.value = images;
if (!selectedimagesNode.value) {
// eslint-disable-next-line prefer-destructuring
selectedimagesNode.value = images[0];
@ -206,6 +210,32 @@
];
},
}),
Extension.create({
addProseMirrorPlugins() {
return [
new Plugin({
key: new PluginKey(Mention.name),
props: {
decorations: (state) => {
const commentUsers: string[] = [];
const { doc } = state;
doc.descendants((node) => {
if (node.type.name === 'mention') {
commentUsers.push(node.attrs.id);
}
});
commentNodeIds.value = commentUsers;
if (!selectedCommentNode.value) {
// eslint-disable-next-line prefer-destructuring
selectedCommentNode.value = commentUsers[0];
}
return DecorationSet.empty;
},
},
}),
];
},
}),
ExtensionTaskList,
ExtensionLink.configure({
autolink: false,

View File

@ -37,6 +37,7 @@ export default {
'menu.caseManagement.featureCaseRecycle': 'Recycle',
'menu.caseManagement.featureCaseList': 'Case list',
'menu.caseManagement.featureCaseDetail': 'Create Case',
'menu.caseManagement.featureCaseEdit': 'Edit Case',
'menu.caseManagement.featureCaseCreateSuccess': 'Create Success',
'menu.caseManagement.caseManagementReview': 'Feature Case Review',
'menu.caseManagement.caseManagementReviewCreate': 'Create Review',

View File

@ -41,6 +41,7 @@ export default {
'menu.caseManagement.featureCaseRecycle': '回收站',
'menu.caseManagement.featureCaseList': '用例列表',
'menu.caseManagement.featureCaseDetail': '创建用例',
'menu.caseManagement.featureCaseEdit': '编辑用例',
'menu.caseManagement.featureCaseCreateSuccess': '创建用例成功',
'menu.caseManagement.caseManagementReview': '用例评审',
'menu.caseManagement.caseManagementReviewCreate': '创建评审',

View File

@ -224,6 +224,7 @@ export interface TabItemType {
key: string;
title: string;
enable: boolean;
total: number;
}
// 需求

View File

@ -42,8 +42,9 @@ const CaseManagement: AppRouteRecordRaw = {
},
{
name: CaseManagementRouteEnum.CASE_MANAGEMENT_CASE_DETAIL,
editTag: 'id',
locale: 'menu.caseManagement.featureCaseDetail',
editTag: 'id',
editLocale: 'menu.caseManagement.featureCaseEdit',
},
],
},

View File

@ -146,6 +146,7 @@
:content="commentContent"
is-show-avatar
is-use-bottom
:notice-user-ids="noticeUserIds"
@publish="publishHandler"
/>
</template>
@ -205,6 +206,7 @@
const appStore = useAppStore();
const commentContent = ref('');
const commentRef = ref();
const noticeUserIds = ref<string[]>([]); // ids
const currentProjectId = computed(() => appStore.currentProjectId);

View File

@ -12,6 +12,7 @@
:pagination="props.pagination"
:table-data="props.tableData"
:page-change="props.pageChange"
:mask-closable="true"
@loaded="loadedCase"
>
<template #titleLeft>
@ -184,6 +185,7 @@
</div>
<inputComment
v-model:content="content"
v-model:notice-user-ids="noticeUserIds"
v-permission="['FUNCTIONAL_CASE:READ+COMMENT']"
:is-active="isActive"
is-show-avatar
@ -483,8 +485,9 @@
watch(
() => props.visible,
(val) => {
showDrawerVisible.value = val;
if (val) {
showDrawerVisible.value = val;
activeTab.value = 'detail';
settingDrawerRef.value.getTabModule();
}
}
@ -508,21 +511,17 @@
const content = ref('');
const commentRef = ref();
const isActive = ref<boolean>(false);
const noticeUserIds = ref<string[]>([]);
async function publishHandler(currentContent: string) {
const regex = /data-id="([^"]*)"/g;
const matchesNotifier = currentContent.match(regex);
let notifiers = '';
if (matchesNotifier?.length) {
notifiers = matchesNotifier.map((match) => match.replace('data-id="', '').replace('"', '')).join(';');
}
try {
const params: CommentParams = {
caseId: detailInfo.value.id,
notifier: notifiers,
notifier: noticeUserIds.value.join(';'),
replyUser: '',
parentId: '',
content: currentContent,
event: notifiers ? 'AT' : 'COMMENT', // (: COMMENT; @: AT; /@: REPLAY;)
event: noticeUserIds.value.join(';') ? 'AT' : 'COMMENT', // (: COMMENT; @: AT; /@: REPLAY;)
};
await createCommentList(params);
commentRef.value.getAllCommentList();

View File

@ -82,11 +82,13 @@
key: 'requirement',
title: 'caseManagement.featureCase.requirement',
enable: true,
total: 0,
},
{
key: 'bug',
title: 'caseManagement.featureCase.bug',
enable: true,
total: 0,
},
],
// testPlan: [
@ -108,31 +110,37 @@
key: 'changeHistory',
title: 'caseManagement.featureCase.changeHistory',
enable: true,
total: 0,
},
];
}
return [];
}
const tabDefaultSettingList = ref<TabItemType[]>([
{
key: 'case',
title: 'caseManagement.featureCase.case',
enable: true,
total: 0,
},
{
key: 'dependency',
title: 'caseManagement.featureCase.dependency',
enable: true,
total: 0,
},
{
key: 'caseReview',
title: 'caseManagement.featureCase.caseReview',
enable: true,
total: 0,
},
{
key: 'comments',
title: 'caseManagement.featureCase.comments',
enable: true,
total: 0,
},
// TOTO Xpack
// ...getTabList(),