summaryrefslogtreecommitdiff
path: root/app/assets/javascripts/repository/components/table/index.vue
diff options
context:
space:
mode:
authorPhil Hughes <me@iamphill.com>2019-05-24 10:39:18 +0100
committerPhil Hughes <me@iamphill.com>2019-05-24 13:58:11 +0100
commitd8bb8d458c09146d70261026a5c90e97903b99c4 (patch)
tree5403eb594816cf2010aa213d1446d1fa871a6a4a /app/assets/javascripts/repository/components/table/index.vue
parentc509b35b489ff69121c4760faa52d81e7666e9ca (diff)
downloadgitlab-ce-d8bb8d458c09146d70261026a5c90e97903b99c4.tar.gz
Pull files for repository tree from GraphQL API
Diffstat (limited to 'app/assets/javascripts/repository/components/table/index.vue')
-rw-r--r--app/assets/javascripts/repository/components/table/index.vue103
1 files changed, 83 insertions, 20 deletions
diff --git a/app/assets/javascripts/repository/components/table/index.vue b/app/assets/javascripts/repository/components/table/index.vue
index ad3d8f9329d..758f4b88be2 100644
--- a/app/assets/javascripts/repository/components/table/index.vue
+++ b/app/assets/javascripts/repository/components/table/index.vue
@@ -1,11 +1,15 @@
<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';
+const PAGE_SIZE = 100;
+
export default {
components: {
GlLoadingIcon,
@@ -14,14 +18,8 @@ export default {
},
mixins: [getRefMixin],
apollo: {
- files: {
- query: getFiles,
- variables() {
- return {
- ref: this.ref,
- path: this.path,
- };
- },
+ projectPath: {
+ query: getProjectPath,
},
},
props: {
@@ -32,7 +30,14 @@ export default {
},
data() {
return {
- files: [],
+ projectPath: '',
+ nextPageCursor: '',
+ entries: {
+ trees: [],
+ submodules: [],
+ blobs: [],
+ },
+ isLoadingFiles: false,
};
},
computed: {
@@ -42,8 +47,63 @@ export default {
{ path: this.path, ref: this.ref },
);
},
- isLoadingFiles() {
- return this.$apollo.queries.files.loading;
+ },
+ 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 occurding 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);
},
},
};
@@ -58,18 +118,21 @@ export default {
tableCaption
}}
</caption>
- <table-header />
+ <table-header v-once />
<tbody>
- <table-row
- v-for="entry in files"
- :id="entry.id"
- :key="entry.id"
- :path="entry.flatPath"
- :type="entry.type"
- />
+ <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"
+ />
+ </template>
</tbody>
</table>
- <gl-loading-icon v-if="isLoadingFiles" class="my-3" size="md" />
+ <gl-loading-icon v-show="isLoadingFiles" class="my-3" size="md" />
</div>
</div>
</template>