Files
Situation-Awareness-Platfor…/src/layouts/RepoLayout/index.vue
2025-03-12 18:41:20 +08:00

188 lines
5.6 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<DefaultLayout class="g-repo-layout">
<template #contentBanner v-if="hasPermission">
<div class="g-repo-header">
<ContentLayout>
<div class="pt-8 g-repo-dashboard-header">
<div class="g-repo-dashboard-width">
<RepoHeaderInfo :widthType="widthType" />
</div>
</div>
</ContentLayout>
</div>
<div class="g-archived" v-if="isArchived">此项目已归档</div>
</template>
<template #content>
<ErrorPage :code="errorCode" v-if="errorCode" />
</template>
<template v-if="hasPermission" #sidebar>
<NavSidebar :key="route.fullPath" :showAvatar="false" />
</template>
</DefaultLayout>
</template>
<script setup lang="ts">
import { ref, computed, watch, onUnmounted } from 'vue';
import { useRoute, useRouter } from 'vue-router';
import { getSettingsValues } from '@/api/repo';
import { reqCatch } from '@/utils/catch';
import { useRepoId } from '@/utils/hooks/useRepoId';
import { repoInfoStore } from '@/stores/Repo';
import { useGlobalInfoStore } from '@/stores/Global';
import { storeToRefs } from 'pinia';
import DefaultLayout from '@/layouts/DefaultLayout/index.vue';
import NavSidebar from '@/components/NavSidebar/index.vue';
import { addEventListener, offEvent } from '@/utils/eventBus';
import { getOrgInfo } from '@/views/Org/hooks/orgInfo';
import * as types from '@/api/org/types';
import { getCommunityInfo } from '@/api/org/index';
import { orgInfoStore } from '@/stores/Org/index';
import setting from '@/setting';
import ErrorPage from '@/views/ErrorPage/index.vue';
import { usePagePermission } from '@/layouts/hooks/usePagePermission';
import RepoHeaderInfo from '@/components/Repo/RepoHeaderInfo/index.vue';
import ContentLayout from '@/components/ContentLayout/index.vue';
import { usePageResize } from '@/utils/hooks/usePageResize';
const { repoId } = useRepoId();
const { widthType } = usePageResize();
const { access_level, isPrivate, repoInfo, isArchived } = storeToRefs(repoInfoStore()); // pinia直接解构会失去响应式
const { hasPermission } = usePagePermission(access_level.value, isPrivate.value);
const globalInfo = useGlobalInfoStore();
globalInfo.updateMenuNum('repoIssues', repoInfo.value.open_issues_count);
globalInfo.updateMenuNum('repoMerge', repoInfo.value.open_merge_requests_count);
globalInfo.updateMenuNum('repoMember', repoInfo.value.member_count);
// 根据权限及是否允许显示设置错误页面
const errorCode = computed(() => {
if (globalInfo.isNotFound) {
return 404;
}
if (!hasPermission.value) {
return 403;
}
return null;
})
// 获取组织namespace
const { namespace } = getOrgInfo();
const route = useRoute();
// 获取仓库
const orgStore = orgInfoStore();
// 社区基本信息
const getCommunityInfoFun = async() => {
const params: types.commonGroupReqType = {
orgId: namespace.value
};
const { data, error } = await reqCatch(getCommunityInfo, params);
if (!error && data) {
orgStore.setCommunityUrl({
communityUrl: `https://${data.data.custom_domain}`,
communityactivityUrl: `https://${data.data.custom_domain}/activelist`
});
orgStore.setCommunityInfo(data.data);
}
};
const filterFn = ref<Function | null>(null);
const nameMap = new Map([
['WIKI', 'repoWiki'],
['ISSUE', 'repoIssues'],
['MERGE_REQUEST', 'repoMerge'],
['FORK', 'repoFork'],
['ANALYSIS', 'repoAnalysis'],
['DISCUSSION', 'repoDiscussion'],
['COMMUNITY', 'reqCommunity']
]);
async function getModuleState() {
const res = await getSettingsValues({
repoId: repoId.value,
group_id: namespace.value
});
if (res.data) {
const { modules } = res.data.data;
const vModules = new Set();
modules.forEach(({ key, value }) => {
// 判断是否获取社区基本信息,拿到社区跳转链接
if (key === 'COMMUNITY' && value === '1') {
getCommunityInfoFun();
}
if (nameMap.get(key) && value === '0') vModules.add(nameMap.get(key));
});
filterFn.value = (item: any) => {
const isAllowed = !item.permission || access_level.value >= setting.role[item.permission];
if (item.id === 'reqCommunity') {
const par = modules.find((item: any) => item.key === 'COMMUNITY');
return !!(par && par.value === '1');
}
const isEnabled = !vModules.has(item.id);
return isEnabled && isAllowed;
};
}
}
// @TODO 此处只用于repo切换时读取项目模块配置信息。是否直接从repo详情获取
watch(repoId, () => getModuleState(), { flush: 'post', immediate: true });
addEventListener('updateNaviBar', getModuleState);
onUnmounted(() => offEvent('updateNaviBar', getModuleState));
</script>
<style scoped lang="scss">
.breadcrumb {
:deep(.g-link) {
font-weight: 500;
color: var(--color-CG600);
line-height: 20px;
&:last-child {
color: var(--color-G900);
}
}
&-splitter {
font-weight: 500;
color: var(--color-CG600);
line-height: 20px;
padding: 0 2px;
}
}
.g-archived {
width: 100%;
padding: 8px;
background-color: var(--color-Y100);
font-weight: bold;
color: var(--color-G900);
line-height: 20px;
text-align: center;
border-bottom: 1px solid var(--color-Y200);
}
.g-repo-header {
background-color: #F9F9FB;
border-bottom: 1px solid #F1F1F8;
position: relative;
z-index: 1;
}
.g-repo-content {
.g-repo-content-width {
max-width: 1536px;
margin: 0 auto;
}
.g-repo-content-header {
border-bottom: 1px solid #f1f1f8;
background: #f9f9fb;
}
}
.g-repo-layout {
:deep(.devui-layout) {
background-color: #fff;
}
:deep(.devui-layout__content) {
background: #fff;
}
}
</style>