Files
Situation-Awareness-Platfor…/src/layouts/RepoLayout/index.vue

188 lines
5.6 KiB
Vue
Raw Normal View History

2025-03-12 18:41:20 +08:00
<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>