debian-mirror-gitlab/app/assets/javascripts/repository/components/table/index.vue
2019-09-04 21:01:54 +05:30

146 lines
3.8 KiB
Vue

<script>
import { GlLoadingIcon } from '@gitlab/ui';
import createFlash from '~/flash';
import { sprintf, __ } from '../../../locale';
import getRefMixin from '../../mixins/get_ref';
import getFiles from '../../queries/getFiles.graphql';
import getProjectPath from '../../queries/getProjectPath.graphql';
import TableHeader from './header.vue';
import TableRow from './row.vue';
import ParentRow from './parent_row.vue';
const PAGE_SIZE = 100;
export default {
components: {
GlLoadingIcon,
TableHeader,
TableRow,
ParentRow,
},
mixins: [getRefMixin],
apollo: {
projectPath: {
query: getProjectPath,
},
},
props: {
path: {
type: String,
required: true,
},
},
data() {
return {
projectPath: '',
nextPageCursor: '',
entries: {
trees: [],
submodules: [],
blobs: [],
},
isLoadingFiles: false,
};
},
computed: {
tableCaption() {
return sprintf(
__('Files, directories, and submodules in the path %{path} for commit reference %{ref}'),
{ path: this.path, ref: this.ref },
);
},
showParentRow() {
return !this.isLoadingFiles && ['', '/'].indexOf(this.path) === -1;
},
},
watch: {
$route: function routeChange() {
this.entries.trees = [];
this.entries.submodules = [];
this.entries.blobs = [];
this.nextPageCursor = '';
this.fetchFiles();
},
},
mounted() {
// We need to wait for `ref` and `projectPath` to be set
this.$nextTick(() => this.fetchFiles());
},
methods: {
fetchFiles() {
this.isLoadingFiles = true;
return this.$apollo
.query({
query: getFiles,
variables: {
projectPath: this.projectPath,
ref: this.ref,
path: this.path,
nextPageCursor: this.nextPageCursor,
pageSize: PAGE_SIZE,
},
})
.then(({ data }) => {
if (!data) return;
const pageInfo = this.hasNextPage(data.project.repository.tree);
this.isLoadingFiles = false;
this.entries = Object.keys(this.entries).reduce(
(acc, key) => ({
...acc,
[key]: this.normalizeData(key, data.project.repository.tree[key].edges),
}),
{},
);
if (pageInfo && pageInfo.hasNextPage) {
this.nextPageCursor = pageInfo.endCursor;
this.fetchFiles();
}
})
.catch(() => createFlash(__('An error occurred while fetching folder content.')));
},
normalizeData(key, data) {
return this.entries[key].concat(data.map(({ node }) => node));
},
hasNextPage(data) {
return []
.concat(data.trees.pageInfo, data.submodules.pageInfo, data.blobs.pageInfo)
.find(({ hasNextPage }) => hasNextPage);
},
},
};
</script>
<template>
<div class="tree-content-holder">
<div class="table-holder bordered-box">
<table class="table tree-table qa-file-tree" aria-live="polite">
<caption class="sr-only">
{{
tableCaption
}}
</caption>
<table-header v-once />
<tbody>
<parent-row v-show="showParentRow" :commit-ref="ref" :path="path" />
<template v-for="val in entries">
<table-row
v-for="entry in val"
:id="entry.id"
:key="`${entry.flatPath}-${entry.id}`"
:current-path="path"
:path="entry.flatPath"
:type="entry.type"
:url="entry.webUrl"
:lfs-oid="entry.lfsOid"
/>
</template>
</tbody>
</table>
<gl-loading-icon v-show="isLoadingFiles" class="my-3" size="md" />
</div>
</div>
</template>