201 lines
4.9 KiB
Vue
201 lines
4.9 KiB
Vue
|
|
<template>
|
||
|
|
<Panel class="docinf overflow-hidden" v-if="showReadme">
|
||
|
|
<template #header>
|
||
|
|
<div class="docinf-lefthead">
|
||
|
|
<Icon name="gt-file-c" class="docinf-icon"></Icon>
|
||
|
|
<span class="docinf-rspan">README.md</span>
|
||
|
|
</div>
|
||
|
|
</template>
|
||
|
|
<template #headerRight>
|
||
|
|
<span v-if="isAdmin" class="cursor-pointer"
|
||
|
|
@click="naviTo"><Icon
|
||
|
|
name="gt-edit"></Icon></span>
|
||
|
|
</template>
|
||
|
|
<div ref="eleRef" class="docinf-content" v-loading="readmeLoading">
|
||
|
|
<MdRender v-model="readmeText"></MdRender >
|
||
|
|
</div>
|
||
|
|
</Panel>
|
||
|
|
<!-- <GLink v-if="visitableReport" @click="emit('report')" class="report">举报</GLink> -->
|
||
|
|
</template>
|
||
|
|
<script setup lang="ts">
|
||
|
|
defineOptions({ name: 'docker-info' });
|
||
|
|
import { useShowMore } from '@/utils/hooks/useShowMore';
|
||
|
|
import MdRender from '@/components/MdRender/index.vue';
|
||
|
|
import { ref, reactive, useSlots, watch, onUnmounted } from 'vue';
|
||
|
|
import { storeToRefs } from 'pinia';
|
||
|
|
import Panel from '@/components/Panel/index.vue';
|
||
|
|
import { useRouter } from 'vue-router';
|
||
|
|
import { getRepo, getRepoReadme } from '@/api/repo';
|
||
|
|
import { reqCatch } from '@/utils/catch';
|
||
|
|
import utf8 from 'crypto-js/enc-utf8';
|
||
|
|
import Base64 from 'crypto-js/enc-base64';
|
||
|
|
import { getOrgInfo } from '@/views/Org/hooks/orgInfo';
|
||
|
|
import { orgInfoStore } from '@/stores/Org';
|
||
|
|
// 获取组织path方法
|
||
|
|
const { namespace } = getOrgInfo();
|
||
|
|
interface IData {
|
||
|
|
// full_path?: string, // 组织路径
|
||
|
|
visitableReport?: boolean; // 举报 默认可见
|
||
|
|
}
|
||
|
|
|
||
|
|
interface RepoData {
|
||
|
|
name?: string,
|
||
|
|
visibility?: string,
|
||
|
|
readme_url?: string,
|
||
|
|
tag_count?: number,
|
||
|
|
watch_count?: number,
|
||
|
|
forks_count?: number,
|
||
|
|
star_count?: number,
|
||
|
|
branch_count?: number,
|
||
|
|
open_merge_requests_count?: number,
|
||
|
|
http_url_to_repo?: string,
|
||
|
|
ssh_url_to_repo?: string,
|
||
|
|
description?: string,
|
||
|
|
tag_list?: [],
|
||
|
|
web_url?: string,
|
||
|
|
default_branch?: string,
|
||
|
|
namespace?: {}
|
||
|
|
[propName: string]: any;
|
||
|
|
}
|
||
|
|
const { isAdmin } = storeToRefs(orgInfoStore());
|
||
|
|
const props = withDefaults(defineProps<IData>(), {
|
||
|
|
visitableReport: true
|
||
|
|
});
|
||
|
|
|
||
|
|
const eleRef = ref(null);
|
||
|
|
const { stop } = useShowMore(eleRef);
|
||
|
|
onUnmounted(() => {
|
||
|
|
stop && stop();
|
||
|
|
});
|
||
|
|
// 监听组织路径变化
|
||
|
|
// 监听路由后面需要优化成路由监听
|
||
|
|
let lastNameSpace = namespace.value;
|
||
|
|
watch(() => namespace.value, (val, oldVal) => {
|
||
|
|
if (val !== lastNameSpace) {
|
||
|
|
showReadme.value = false;
|
||
|
|
readmeText.value = '';
|
||
|
|
getProInfo();
|
||
|
|
}
|
||
|
|
lastNameSpace = val;
|
||
|
|
}, {
|
||
|
|
deep: true
|
||
|
|
});
|
||
|
|
// 获取rederme文件
|
||
|
|
const readmeLoading = ref<boolean>(true);
|
||
|
|
const readmeText = ref<string>('');
|
||
|
|
const showReadme = ref<boolean>(false);// 是否展示readme
|
||
|
|
const redUrl = ref<string>();
|
||
|
|
const getProReadme = async() => {
|
||
|
|
if (!namespace.value) return;
|
||
|
|
const proName = namespace.value.split('%2F');
|
||
|
|
const params = {
|
||
|
|
repoId: `${namespace.value}%2F${proName[proName.length - 1]}`
|
||
|
|
};
|
||
|
|
const { data, error } = await getRepoReadme(params);
|
||
|
|
readmeLoading.value = false;
|
||
|
|
if (!error && data?.data) {
|
||
|
|
readmeText.value = utf8.stringify(Base64.parse(data.data.content || ''));
|
||
|
|
redUrl.value = data.data.readme_url;
|
||
|
|
showReadme.value = !!data.data.readme_url;
|
||
|
|
}
|
||
|
|
};
|
||
|
|
getProReadme();
|
||
|
|
// const slots = useSlots();
|
||
|
|
// const emit = defineEmits<{(e: 'report', /* orgname : string */): void }>();
|
||
|
|
|
||
|
|
const router = useRouter();
|
||
|
|
const naviTo = () => {
|
||
|
|
// router.push({ name, params });
|
||
|
|
if (redUrl.value) {
|
||
|
|
window.location.assign(redUrl.value);
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
const mode = ref('readonly');
|
||
|
|
</script>
|
||
|
|
<style lang="scss" scoped>
|
||
|
|
.docinf {
|
||
|
|
.docinf-lefthead {
|
||
|
|
line-height: 20px;
|
||
|
|
display: flex;
|
||
|
|
align-items: center;
|
||
|
|
|
||
|
|
.docinf-icon {
|
||
|
|
margin-right: 20px;
|
||
|
|
}
|
||
|
|
|
||
|
|
.docinf-dspan {
|
||
|
|
color: var(--color-CG600);
|
||
|
|
font-size: var(--text-sm);
|
||
|
|
font-weight: 500;
|
||
|
|
margin-right: 4px;
|
||
|
|
}
|
||
|
|
|
||
|
|
.docinf-rspan {
|
||
|
|
color: var(--color-G900);
|
||
|
|
font-size: var(--text-sm);
|
||
|
|
font-weight: 500;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
.docinf-content {
|
||
|
|
position: relative;
|
||
|
|
max-height: 400px;
|
||
|
|
overflow: auto;
|
||
|
|
&.show-all {
|
||
|
|
max-height: 100%;
|
||
|
|
}
|
||
|
|
&-btn {
|
||
|
|
position: absolute;
|
||
|
|
left: 50%;
|
||
|
|
bottom: 0;
|
||
|
|
transform: translateX(-50%);
|
||
|
|
z-index: 2;
|
||
|
|
width: 100%;
|
||
|
|
text-align: center;
|
||
|
|
background: #fff;
|
||
|
|
&:hover {
|
||
|
|
cursor: pointer;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
.docinf-section {}
|
||
|
|
|
||
|
|
.docinf-section1 {
|
||
|
|
margin-top: 32px;
|
||
|
|
}
|
||
|
|
|
||
|
|
.docinf-section-title {
|
||
|
|
color: var(--color-G900);
|
||
|
|
font-size: var(--text-2xl);
|
||
|
|
font-weight: 500;
|
||
|
|
}
|
||
|
|
|
||
|
|
.docinf-section-line {
|
||
|
|
width: 100%;
|
||
|
|
height: 1px;
|
||
|
|
background: #F0F1F2;
|
||
|
|
margin-top: 16px;
|
||
|
|
}
|
||
|
|
|
||
|
|
.docinf-section-content {
|
||
|
|
color: var(--color-G900);
|
||
|
|
font-size: var(--text-sm);
|
||
|
|
font-weight: 400;
|
||
|
|
margin-top: 16px;
|
||
|
|
}
|
||
|
|
|
||
|
|
.docinf-section-origin {
|
||
|
|
padding-left: 16px;
|
||
|
|
}
|
||
|
|
|
||
|
|
.docinf-section-subtitle {
|
||
|
|
color: var(--color-G900);
|
||
|
|
font-size: var(--text-sm);
|
||
|
|
font-weight: 500;
|
||
|
|
margin-top: 16px;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
</style>
|