mirror of https://github.com/go-gitea/gitea.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
62 lines
2.2 KiB
62 lines
2.2 KiB
<script lang="ts" setup> |
|
import ViewFileTreeItem from './ViewFileTreeItem.vue'; |
|
import {onMounted, ref} from 'vue'; |
|
import {pathEscapeSegments} from '../utils/url.ts'; |
|
import {GET} from '../modules/fetch.ts'; |
|
|
|
const elRoot = ref<HTMLElement | null>(null); |
|
|
|
const props = defineProps({ |
|
repoLink: {type: String, required: true}, |
|
treePath: {type: String, required: true}, |
|
currentRefNameSubURL: {type: String, required: true}, |
|
}); |
|
|
|
const files = ref([]); |
|
const selectedItem = ref(''); |
|
|
|
async function loadChildren(treePath: string, subPath: string = '') { |
|
const response = await GET(`${props.repoLink}/tree-view/${props.currentRefNameSubURL}/${pathEscapeSegments(treePath)}?sub_path=${encodeURIComponent(subPath)}`); |
|
const json = await response.json(); |
|
return json.fileTreeNodes ?? null; |
|
} |
|
|
|
async function loadViewContent(url: string) { |
|
url = url.includes('?') ? url.replace('?', '?only_content=true') : `${url}?only_content=true`; |
|
const response = await GET(url); |
|
document.querySelector('.repo-view-content').innerHTML = await response.text(); |
|
} |
|
|
|
async function navigateTreeView(treePath: string) { |
|
const url = `${props.repoLink}/src/${props.currentRefNameSubURL}/${pathEscapeSegments(treePath)}`; |
|
window.history.pushState({treePath, url}, null, url); |
|
selectedItem.value = treePath; |
|
await loadViewContent(url); |
|
} |
|
|
|
onMounted(async () => { |
|
selectedItem.value = props.treePath; |
|
files.value = await loadChildren('', props.treePath); |
|
elRoot.value.closest('.is-loading')?.classList?.remove('is-loading'); |
|
window.addEventListener('popstate', (e) => { |
|
selectedItem.value = e.state?.treePath || ''; |
|
if (e.state?.url) loadViewContent(e.state.url); |
|
}); |
|
}); |
|
</script> |
|
|
|
<template> |
|
<div class="view-file-tree-items" ref="elRoot"> |
|
<!-- only render the tree if we're visible. in many cases this is something that doesn't change very often --> |
|
<ViewFileTreeItem v-for="item in files" :key="item.name" :item="item" :selected-item="selectedItem" :navigate-view-content="navigateTreeView" :load-children="loadChildren"/> |
|
</div> |
|
</template> |
|
|
|
<style scoped> |
|
.view-file-tree-items { |
|
display: flex; |
|
flex-direction: column; |
|
gap: 1px; |
|
margin-right: .5rem; |
|
} |
|
</style>
|
|
|