Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 22 additions & 2 deletions frontend/src/components/community/CommunityPage.vue
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,14 @@
@showDiscussionDetail="showDiscussionDetail"
@showNewDiscussion="showNewDiscussion">
</DiscussionCards>
<CsgPagination
v-if="communityActionName === 'list' && cards.length > 0"
class="mt-6"
:perPage="perPage"
:currentPage="currentPage"
:total="totalDiscussions"
@currentChange="getDiscussion"
/>

<NewCommunityDiscussion
v-if="communityActionName === 'new'"
Expand Down Expand Up @@ -52,6 +60,7 @@
import useFetchApi from '../../packs/useFetchApi'
import { useRepoTabStore } from '../../stores/RepoTabStore'
import { validateCommunityActionName, ToNotFoundPage } from '../../packs/utils'
import CsgPagination from '../shared/CsgPagination.vue'

const props = defineProps({
repoType: String,
Expand All @@ -71,10 +80,20 @@
const currentDiscussionCreateUserId = ref('')
const currentDiscussionTime = ref('')
const currentDiscussionData = ref(null)

const perPage = ref(10)
const currentPage = ref(1)
const totalDiscussions = ref(0)

const isDataLoading = ref(false)

const getDiscussion = async () => {
const getDiscussion = async (childCurrent) => {
if (childCurrent) {
currentPage.value = childCurrent
}
const params = new URLSearchParams()
params.append('per', perPage.value)
params.append('page', currentPage.value)
isDataLoading.value = true
if (!props.repoPath || props.repoPath === '') {
isDataLoading.value = false
Expand All @@ -87,9 +106,10 @@
}

try {
const { data, error } = await useFetchApi(discussionCreateEndpoint).json()
const { data, error } = await useFetchApi(`${discussionCreateEndpoint}?${params.toString()}`).json()
if (data.value) {
const discussions = data.value.data.discussions || []
totalDiscussions.value = data.value.total || 0
cards.value = discussions.sort((a, b) => b.id - a.id)
} else {
ElMessage({
Expand Down
133 changes: 86 additions & 47 deletions frontend/src/components/community/DiscussionDetails.vue
Original file line number Diff line number Diff line change
@@ -1,53 +1,65 @@
<template>
<div class="flex flex-col gap-[16px]">
<div class="flex justify-between items-center">
<div class="flex items-center gap-2">
<div class="text-gray-700 text-md leading-6 font-medium flex items-center gap-2">
<div v-show="!isEdit" class="text-gray-700 text-md leading-6 font-medium flex items-center gap-2">
<div>{{ title }}</div>
<el-tooltip content="Edit title" placement="top">
<div v-if="canEdit" @click="editTitle" class="cursor-pointer">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" fill="none">
<path d="M8.5 1.5H5.5C4.11929 1.5 3 2.61929 3 4V12C3 13.3807 4.11929 14.5 5.5 14.5H10.5C11.8807 14.5 13 13.3807 13 12V9" stroke="#606266" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M12.5 2.5L13.5 3.5L6.5 10.5H5.5V9.5L12.5 2.5Z" stroke="#606266" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
</div>
</el-tooltip>
</div>
<div v-show="isEdit" class="text-gray-700 text-md leading-6 font-medium flex items-center gap-2">
<input type="text"
ref="inputTitle"
v-model="theTitle"
@change="saveTitle"
@blur="isEdit=false">
</div>
<div class="text-gray-500 flex gap-2 text-sm leading-5">
<a :href="`/profile/${userName}`" class="hover:text-brand-600 hover:underline cursor-pointer">{{userName}}</a>
<div>·</div>
<a>{{ time }}</a>
<template v-if="!isDataLoading">
<div class="flex justify-between items-center">
<div class="flex items-center gap-2">
<div class="text-gray-700 text-md leading-6 font-medium flex items-center gap-2">
<div v-show="!isEdit" class="text-gray-700 text-md leading-6 font-medium flex items-center gap-2">
<div>{{ title }}</div>
<el-tooltip content="Edit title" placement="top">
<div v-if="canEdit" @click="editTitle" class="cursor-pointer">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" fill="none">
<path d="M8.5 1.5H5.5C4.11929 1.5 3 2.61929 3 4V12C3 13.3807 4.11929 14.5 5.5 14.5H10.5C11.8807 14.5 13 13.3807 13 12V9" stroke="#606266" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M12.5 2.5L13.5 3.5L6.5 10.5H5.5V9.5L12.5 2.5Z" stroke="#606266" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
</div>
</el-tooltip>
</div>
<div v-show="isEdit" class="text-gray-700 text-md leading-6 font-medium flex items-center gap-2">
<input type="text"
ref="inputTitle"
v-model="theTitle"
@change="saveTitle"
@blur="isEdit=false">
</div>
<div class="text-gray-500 flex gap-2 text-sm leading-5">
<a :href="`/profile/${userName}`" class="hover:text-brand-600 hover:underline cursor-pointer">{{userName}}</a>
<div>·</div>
<a>{{ time }}</a>
</div>
</div>
</div>
</div>
</div>

<!-- 评论列表 -->
<div class="border border-gray-200 border-b-0.5 rounded-lg" v-for="comment in commentData" :key="comment.id">
<div class="flex justify-between gap-1 border-b rounded-t-lg border-gray-200 items-center px-3 py-2 bg-gray-100">
<div class="flex items-center gap-2 text-md leading-5 text-gray-700 font-normal">
<el-avatar :size="24" :src="comment.user.avatar"></el-avatar>
<div class="flex items-center gap-1">
<a :href="`/profile/${comment.user.name}`" class="hover:text-brand-600 hover:underline cursor-pointer">{{comment.user.name}}</a>
<div>·</div>
<el-tooltip
:content="formatFullTime(comment.created_at)"
placement="top">
<div class="cursor-help">{{formatTime(comment.created_at)}}</div>
</el-tooltip>
<!-- 评论列表 -->
<div class="border border-gray-200 border-b-0.5 rounded-lg" v-for="comment in commentData" :key="comment.id">
<div class="flex justify-between gap-1 border-b rounded-t-lg border-gray-200 items-center px-3 py-2 bg-gray-100">
<div class="flex items-center gap-2 text-md leading-5 text-gray-700 font-normal">
<el-avatar :size="24" :src="comment.user.avatar"></el-avatar>
<div class="flex items-center gap-1">
<a :href="`/profile/${comment.user.name}`" class="hover:text-brand-600 hover:underline cursor-pointer">{{comment.user.name}}</a>
<div>·</div>
<el-tooltip
:content="formatFullTime(comment.created_at)"
placement="top">
<div class="cursor-help">{{formatTime(comment.created_at)}}</div>
</el-tooltip>
</div>
</div>
</div>
<div class="px-3 py-3 rounded-b-lg text-gray-700 text-md font-normal markdown-body" v-html="renderMarkdown(comment.content)"></div>
</div>
<div class="px-3 py-3 rounded-b-lg text-gray-700 text-md font-normal markdown-body" v-html="renderMarkdown(comment.content)"></div>
</div>
</template>
<LoadingSpinner
:loading="isDataLoading"
:text="$t('repo.loadingComments')"
/>
<CsgPagination
class="mt-4"
:perPage="perPage"
:currentPage="currentPage"
:total="totalComments"
@currentChange="handlePageChange"
/>

<!-- 评论输入框 -->
<CommunityMDTextarea ref="mdTextarea" :desc="desc" @inputChange="handleInputChange"></CommunityMDTextarea>
Expand All @@ -68,6 +80,8 @@
</template>

<script>
import CsgPagination from '../shared/CsgPagination.vue'
import LoadingSpinner from '../shared/LoadingSpinner.vue'
import CommunityTimeLine from './CommunityTimeLine.vue'
import CommunityMDTextarea from './CommunityMDTextarea.vue'
import { format } from 'timeago.js'
Expand All @@ -88,7 +102,9 @@ export default {
},
components: {
CommunityTimeLine,
CommunityMDTextarea
CommunityMDTextarea,
CsgPagination,
LoadingSpinner
},
data() {
return {
Expand All @@ -102,7 +118,11 @@ export default {
timelineData: [{ name: 'Username', type: 'change status', state: 'closed', date: '2022-01-01', text: 'Event 1' },
{ name: 'Username', type: 'change status', state: 'open', date: '2023-03-15', text: 'Event 2' },
{ name: 'Username', type: 'change title', title_from: 'xxx', title_to: 'xyx', date: '2023-04-10', text: 'Event 3' }],
userStore: useUserStore()
userStore: useUserStore(),
perPage: 10,
currentPage: 1,
totalComments: 0,
isDataLoading: false,
};
},
computed: {
Expand Down Expand Up @@ -263,17 +283,36 @@ export default {
this.theTitle = this.oldTitle
}
},
async getComment(discussionId) {
async getComment(discussionId, childCurrent) {
if (!discussionId) {
return
}
const commentCreateEndpoint = `/discussions/${discussionId}/comments`
if (childCurrent) {
this.currentPage = childCurrent
}
this.isDataLoading = true
const params = new URLSearchParams()
params.append('per', this.perPage)
params.append('page', this.currentPage)
const commentCreateEndpoint = `/discussions/${discussionId}/comments?${params.toString()}`
const {data, error} = await useFetchApi(commentCreateEndpoint).json()
if (data.value) {
this.commentData = data.value.data
this.commentData = data.value.data || []
this.totalComments = data.value.total || 0
} else {
ElMessage.warning(error.value?.msg || '获取评论失败')
}
this.isDataLoading = false
this.scrollToTop()
},

scrollToTop() {
window.scrollTo({ top: 0, behavior: 'smooth' })
},

handlePageChange(page) {
this.currentPage = page
this.getComment(this.discussionId, page)
},
async createComment(discussionId) {
if (!discussionId) {
Expand Down
1 change: 1 addition & 0 deletions frontend/src/locales/en_js/repo.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
export const repo = {
loading: 'Loading repository information...',
loadingCommunity: 'Loading discussion list...',
loadingComments: 'Loading comments...',
edit: {
fileName: "File Name",
main: "Directly submit to the main branch",
Expand Down
1 change: 1 addition & 0 deletions frontend/src/locales/zh_hant_js/repo.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
export const repo = {
loading: '正在載入倉庫資訊...',
loadingCommunity: '正在載入討論列表...',
loadingComments: '正在載入評論...',
edit: {
fileName: "檔案名稱",
main: "直接提交到 main 分支",
Expand Down
1 change: 1 addition & 0 deletions frontend/src/locales/zh_js/repo.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
export const repo = {
loading: '正在加载仓库信息...',
loadingCommunity: '正在加载讨论列表...',
loadingComments: '正在加载评论...',
edit: {
fileName: "文件名",
main: "直接提交到 main 分支",
Expand Down