Files
Situation-Awareness-Platfor…/src/views/Mobile/Repo/Merge/components/FileDiffDiscussionsItemNote.vue
2025-03-12 18:41:20 +08:00

261 lines
6.6 KiB
Vue

<template>
<div class="comment-box">
<GAvatar
class="pt-2"
:src="props.note.author?.avatar_url"
:name="props.note.author.name"
:width="20"
:height="20"
></GAvatar>
<div class="comment-info">
<div class="comment-box-header">
<div class="comment-user">
<span class="comment-user-name">{{ props.note.author.name }}</span>
<span class="comment-user-date">{{ formatTime(props.note.created_at) }}</span>
</div>
<div class="comment-operate">
<div class="comment-state" v-if="isAdmin?.value && props.isFirstNote">
<Switch v-model="resolved" @change="(e) => resolveChange(e)" size="sm">
<template #checkedContent>
<i class="icon-right"></i>
</template>
<template #uncheckedContent>
<i class="icon-error"></i>
</template>
</Switch>
<span>{{ resolved ? '已解决' : '未解决' }}</span>
</div>
<Button v-if="arts_id === props.note.author.id" icon="edit" @click="inEdit = true" variant="text"></Button>
<Button
v-if="arts_id === props.note.author.id"
@click="delVisible = true"
icon="delete"
variant="text"
></Button>
</div>
</div>
<div class="comment-box-content">
<MdRender v-if="!inEdit" :content="props.note.body"></MdRender>
<div v-if="inEdit">
<EditorMd v-model="noteEditText" class="mb-4"></EditorMd>
<div class="flex justify-end">
<Button @click="updateNote" :disabled="!noteEditText?.trim()" variant="solid" class="mb-4" color="primary"
>确定</Button
>
<Button @click="inEdit = false" class="ml-2 mb-4">取消</Button>
</div>
</div>
</div>
</div>
</div>
<!-- 删除 -->
<Modal v-model="delVisible">
<template #header>
<ModalHeader>
<span>提示</span>
</ModalHeader>
</template>
<div>确认删除</div>
<template #footer>
<ModalFooter style="text-align: right; padding-right: 20px">
<Button @click="() => onDelNote() & (delVisible = false)" variant="solid" color="primary">确认</Button>
<Button @click="delVisible = false">取消</Button>
</ModalFooter>
</template>
</Modal>
</template>
<script setup lang="ts">
import { ref, onMounted, watch, reactive, inject } from 'vue';
import GAvatar from '@/components/GAvatar/index.vue';
import { Switch } from 'vue-devui/switch';
import { Button } from 'vue-devui/button';
import { Message } from 'vue-devui/message';
import { Modal, ModalHeader, ModalFooter } from 'vue-devui/modal';
import { EditorMd } from 'vue-devui/editor-md';
import { MdRender } from 'vue-devui/editor-md';
import { putDis, delNote, putNote } from '@/api/merge/index';
import { escapeResData } from '@/utils';
import { repoInfoStore } from '@/stores/Repo';
import { formatTime } from './support';
const { isAdmin } = repoInfoStore();
const repoId = inject('repoId');
const iid = inject('iid');
const arts_id = inject('arts_id');
const onMergeAble = inject('onMergeAble');
const props = defineProps({
discussion: {
type: Object,
default: () => ({})
},
note: {
type: Object,
default: () => ({})
},
isFirstNote: {
type: Boolean,
default: false
}
});
const emit = defineEmits(['onDelNote']);
const inEdit = ref(false);
const delVisible = ref(false);
const resolved = ref(props.discussion?.resolved || false);
const onDelNote = () => {
delNote(reactive({ repoId, iid, noteId: props.note.id }))
.then((res) => {
// notes.value = notes.value.filter((m) => m.id !== theNote.value?.id);
Message.success('操作成功');
emit('onDelNote', props.note.id);
//
})
.catch((error) => {});
};
const resolveChange = (e) => {
putDis(
reactive({
repoId,
iid,
disId: props.discussion.id,
resolved: e
})
).then((res) => {
Message.success('操作成功');
onMergeAble();
});
};
const showReplayMD = ref(false);
const noteEditText = ref(props.note.body);
const updateNote = () => {
showReplayMD.value = false;
putNote(
reactive({
repoId: repoId,
iid: iid,
noteId: props.note.id,
//
body: noteEditText.value,
severity: 'suggestion',
assignee_id: arts_id
})
)
.then((res) => {
const data = escapeResData(res);
if (data.id) {
// Message.success('')
props.note.body = noteEditText.value;
inEdit.value = false;
}
})
.catch((error) => {});
};
onMounted(() => {});
</script>
<style scoped lang="scss">
@import 'devui-theme/styles-var/devui-var.scss';
.comment-box {
display: flex;
padding: 12px 16px 0px;
border-bottom: 1px solid $devui-dividing-line;
&:first-child {
}
&:not(:first-child) {
padding-left: 32px;
}
img {
width: 32px;
height: 32px;
border-radius: 50%;
}
.comment-info {
display: flex;
flex-direction: column;
width: 100%;
.comment-box-header {
display: flex;
justify-content: space-between;
align-items: center;
margin: 4px 0;
.comment-user {
padding: 0 12px;
.comment-user-name {
font-size: $devui-font-size;
font-weight: 500;
color: $devui-text;
}
.comment-user-date {
&::before {
content: '·';
padding: 0 4px;
}
font-size: $devui-font-size-sm;
color: $devui-aide-text;
}
.comment-user-severity {
:deep(.devui-tag--md) {
margin-left: 8px;
font-size: $devui-font-size-sm;
height: 20px;
line-height: 20px;
color: $devui-aide-text;
background-color: $devui-label-bg;
cursor: default;
&:hover {
color: initial;
}
}
}
}
.comment-operate {
display: flex;
align-items: center;
font-size: $devui-font-size-page-title;
color: $devui-icon-text;
.comment-state {
display: flex;
align-items: center;
margin-right: 12px;
span {
display: inline-block;
font-size: $devui-font-size-sm;
color: $devui-aide-text;
line-height: 20px;
margin-left: 4px;
}
}
button:last-of-type {
margin-left: 4px;
}
}
}
.comment-box-content {
padding-left: 12px;
word-break: break-word;
}
}
}
</style>