266 lines
6.7 KiB
Vue
266 lines
6.7 KiB
Vue
|
|
<template>
|
||
|
|
<custom-header v-if="false" class="stars-repos-left-header" title="Starred 项目" :count="starredTotal"></custom-header>
|
||
|
|
<DataPanel :empty="!starredRepoList?.length" skeleton :loading="starredRepoList?.length ? false : loading">
|
||
|
|
<div v-loading="loading" :view="{ top: '300px', left: '50%' }" class="stars-repos-content" v-if="starredRepoList?.length">
|
||
|
|
<template v-for="(item, index) in starredRepoList" :key="item.id">
|
||
|
|
<repo-item
|
||
|
|
:iconHandleList="item.iconHandleList"
|
||
|
|
:id="item.id"
|
||
|
|
:imgSrc="item.imgSrc"
|
||
|
|
:title="item.title"
|
||
|
|
:tag-list="item.tagList"
|
||
|
|
:desc="item.desc"
|
||
|
|
:isStar="item.isStar"
|
||
|
|
:web_url="item.web_url"
|
||
|
|
:hide-star="!isSelf"
|
||
|
|
:topic-names="item.topicNames"
|
||
|
|
:class="{ 'is-last': index === starredRepoList.length - 1 }"
|
||
|
|
@handle-star="({isStar}) => item.isStar = isStar"
|
||
|
|
/>
|
||
|
|
</template>
|
||
|
|
</div>
|
||
|
|
</DataPanel>
|
||
|
|
<teleport v-if="tel" :to="tel">
|
||
|
|
<div class="stars-repos-filters">
|
||
|
|
<div class="stars-repos-filter-item filter-item-input">
|
||
|
|
<d-input
|
||
|
|
v-model="search"
|
||
|
|
clearable
|
||
|
|
placeholder="搜索项目"
|
||
|
|
class="stars-repos-filter-form-item"
|
||
|
|
style="width: 100%"
|
||
|
|
maxlength="100"
|
||
|
|
@change="onSearch" @clear="onSearch">
|
||
|
|
<template #prefix>
|
||
|
|
<Icon name="gt-search" color="#B3B4B5" style="font-size: inherit;" />
|
||
|
|
</template>
|
||
|
|
</d-input>
|
||
|
|
</div>
|
||
|
|
<div class="stars-repos-filter-item filter-item-selects">
|
||
|
|
<div class="stars-repos-filter-item">
|
||
|
|
<d-select
|
||
|
|
class="stars-repos-filter-select"
|
||
|
|
v-model="filter.type"
|
||
|
|
:options="types"
|
||
|
|
allow-clear
|
||
|
|
placeholder="类型"
|
||
|
|
>
|
||
|
|
</d-select>
|
||
|
|
</div>
|
||
|
|
<div class="stars-repos-filter-item">
|
||
|
|
<d-select
|
||
|
|
class="stars-repos-filter-select"
|
||
|
|
v-model="filter.lang"
|
||
|
|
:options="langList"
|
||
|
|
allow-clear
|
||
|
|
placeholder="语言"
|
||
|
|
>
|
||
|
|
</d-select>
|
||
|
|
</div>
|
||
|
|
<div class="stars-repos-filter-item is-last">
|
||
|
|
<d-select
|
||
|
|
class="stars-repos-filter-select last-select"
|
||
|
|
style="max-width: 120px;"
|
||
|
|
v-model="filter.sort"
|
||
|
|
:options="sorts"
|
||
|
|
allow-clear
|
||
|
|
placeholder="排序"
|
||
|
|
>
|
||
|
|
</d-select>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</teleport>
|
||
|
|
<div v-show="pager.total > pager.pageSize" class="stars-repos-pagination">
|
||
|
|
<d-pagination
|
||
|
|
:total="pager.total"
|
||
|
|
v-model:pageSize="pager.pageSize"
|
||
|
|
v-model:pageIndex="pager.pageIndex"
|
||
|
|
:can-view-total="true"
|
||
|
|
:can-change-page-size="true"
|
||
|
|
:max-items="5"
|
||
|
|
/>
|
||
|
|
</div>
|
||
|
|
</template>
|
||
|
|
|
||
|
|
<script lang="ts">
|
||
|
|
export default {
|
||
|
|
name: 'stars-repos'
|
||
|
|
};
|
||
|
|
</script>
|
||
|
|
|
||
|
|
<script setup lang="ts">
|
||
|
|
import { ref, watch } from 'vue';
|
||
|
|
import RepoItem from '@/components/RepoItem/index.vue';
|
||
|
|
import { useRepoList } from '@/views/User/hooks/useRepoList';
|
||
|
|
import { useUserInfo } from '@/views/User/hooks/useUserInfo';
|
||
|
|
import { REPO_TYPES, SORT_TYPES } from '@/views/User/constant/const';
|
||
|
|
import CustomHeader from '@/components/CustomHeader/index.vue';
|
||
|
|
import { useUserLang } from '@/views/User/hooks/useUserLang';
|
||
|
|
|
||
|
|
withDefaults(defineProps<{
|
||
|
|
tel: any;
|
||
|
|
}>(), {
|
||
|
|
tel: 'body'
|
||
|
|
});
|
||
|
|
|
||
|
|
const filter = ref({
|
||
|
|
type: null,
|
||
|
|
lang: null,
|
||
|
|
sort: null
|
||
|
|
});
|
||
|
|
const types = ref(REPO_TYPES);
|
||
|
|
const sorts = ref(SORT_TYPES);
|
||
|
|
|
||
|
|
const pager = ref({
|
||
|
|
total: 0,
|
||
|
|
pageSize: 10,
|
||
|
|
pageIndex: 1
|
||
|
|
});
|
||
|
|
|
||
|
|
const { isSelf, namespace } = useUserInfo();
|
||
|
|
|
||
|
|
const { langList } = useUserLang('starred');
|
||
|
|
|
||
|
|
const search = ref('');
|
||
|
|
const getQueryParams = () => {
|
||
|
|
return {
|
||
|
|
starred: {
|
||
|
|
params: {
|
||
|
|
user_name: namespace,
|
||
|
|
page: pager.value.pageIndex,
|
||
|
|
per_page: pager.value.pageSize,
|
||
|
|
order_by: filter.value?.sort?.split(':')[0] || '',
|
||
|
|
sort: filter.value?.sort?.split(':')[1] || '',
|
||
|
|
search: search.value || null,
|
||
|
|
visibility: isSelf ? filter.value.type : 'public',
|
||
|
|
with_programming_language: filter.value.lang || null
|
||
|
|
}
|
||
|
|
},
|
||
|
|
auto: true
|
||
|
|
};
|
||
|
|
};
|
||
|
|
|
||
|
|
const { starredRepoList, starredTotal, loading, toggleRepoStar, init } = useRepoList(getQueryParams(), getQueryParams);
|
||
|
|
|
||
|
|
watch(() => starredTotal.value, (val) => {
|
||
|
|
pager.value.total = val || 0;
|
||
|
|
});
|
||
|
|
|
||
|
|
watch(() => pager.value.pageIndex, () => {
|
||
|
|
init(getQueryParams());
|
||
|
|
}, { deep: true, flush: 'post' });
|
||
|
|
|
||
|
|
watch(() => pager.value.pageSize, (val) => {
|
||
|
|
if (val > 1) {
|
||
|
|
pager.value.pageIndex = 1;
|
||
|
|
} else {
|
||
|
|
init(getQueryParams());
|
||
|
|
}
|
||
|
|
}, { deep: true, flush: 'post' });
|
||
|
|
|
||
|
|
watch(() => filter.value, () => {
|
||
|
|
init(getQueryParams());
|
||
|
|
}, { deep: true, flush: 'post' });
|
||
|
|
|
||
|
|
const onSearch = () => {
|
||
|
|
init(getQueryParams());
|
||
|
|
};
|
||
|
|
</script>
|
||
|
|
|
||
|
|
<style scoped lang="scss">
|
||
|
|
$stars-repos-border-color: #808080;
|
||
|
|
$stars-repos-border-color-second: #E6E7E8;
|
||
|
|
$stars-repos-border-radius: 4px;
|
||
|
|
$stars-repos-stars-color: #000000;
|
||
|
|
.stars-repos {
|
||
|
|
&-left-header {
|
||
|
|
display: flex;
|
||
|
|
align-items: center;
|
||
|
|
margin-bottom: 24px;
|
||
|
|
&-title {
|
||
|
|
display: flex;
|
||
|
|
align-items: center;
|
||
|
|
font-size: 20px;
|
||
|
|
color: $stars-repos-stars-color;
|
||
|
|
font-weight: 500;
|
||
|
|
margin-right: 8px;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
&-content {
|
||
|
|
overflow: hidden;
|
||
|
|
.is-last {
|
||
|
|
:deep(.g-repo-item) {
|
||
|
|
border-bottom: none;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
:deep(.g-repo-item) {
|
||
|
|
border-top: none;
|
||
|
|
border-left: none;
|
||
|
|
border-right: none;
|
||
|
|
border-radius: 0;
|
||
|
|
box-shadow: none;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
&-pagination {
|
||
|
|
padding-top: 20px;
|
||
|
|
padding-bottom: 20px;
|
||
|
|
display: flex;
|
||
|
|
justify-content: center;
|
||
|
|
}
|
||
|
|
&-filters {
|
||
|
|
display: flex;
|
||
|
|
align-items: center;
|
||
|
|
flex: 1;
|
||
|
|
}
|
||
|
|
&-filter-form-item {
|
||
|
|
:deep(.devui-input__wrapper) {
|
||
|
|
border-color: $stars-repos-border-color-second;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
&-filter-item {
|
||
|
|
margin-right: 0;
|
||
|
|
&.filter-item-input {
|
||
|
|
margin-right: 8px;
|
||
|
|
flex: 1;
|
||
|
|
overflow: hidden;
|
||
|
|
}
|
||
|
|
&.filter-item-selects {
|
||
|
|
display: flex;
|
||
|
|
align-items: center;
|
||
|
|
border: 1px solid $stars-repos-border-color-second;
|
||
|
|
border-radius: $stars-repos-border-radius;
|
||
|
|
overflow: hidden;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
&-filter-select {
|
||
|
|
max-width: 100px;
|
||
|
|
position: relative;
|
||
|
|
&::after {
|
||
|
|
content: '';
|
||
|
|
height: 14px;
|
||
|
|
width: 1px;
|
||
|
|
background-color: $stars-repos-border-color-second;
|
||
|
|
display: block;
|
||
|
|
position: absolute;
|
||
|
|
top: 50%;
|
||
|
|
right: 0;
|
||
|
|
z-index: 20;
|
||
|
|
transform: translateY(-50%);
|
||
|
|
}
|
||
|
|
&.last-select {
|
||
|
|
&::after {
|
||
|
|
display: none;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
:deep(.devui-select__selection) {
|
||
|
|
border: none;
|
||
|
|
border-radius: 0;
|
||
|
|
}
|
||
|
|
:deep(.devui-select__input) {
|
||
|
|
padding-left: 16px;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
</style>
|