261 lines
6.6 KiB
Vue
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>
|