Commit eac596f7 authored by Martin Wortschack's avatar Martin Wortschack

Merge branch 'ph/vueFilePrefetch' into 'master'

Preload data before Vue route navigation

See merge request gitlab-org/gitlab!19754
parents 96fbb15f 70726603
...@@ -90,7 +90,7 @@ export default { ...@@ -90,7 +90,7 @@ export default {
<template> <template>
<div class="info-well d-none d-sm-flex project-last-commit commit p-3"> <div class="info-well d-none d-sm-flex project-last-commit commit p-3">
<gl-loading-icon v-if="isLoading" size="md" class="m-auto" /> <gl-loading-icon v-if="isLoading" size="md" color="dark" class="m-auto" />
<template v-else> <template v-else>
<user-avatar-link <user-avatar-link
v-if="commit.author" v-if="commit.author"
......
...@@ -44,7 +44,7 @@ export default { ...@@ -44,7 +44,7 @@ export default {
</div> </div>
</div> </div>
<div class="blob-viewer"> <div class="blob-viewer">
<gl-loading-icon v-if="loading > 0" size="md" class="my-4 mx-auto" /> <gl-loading-icon v-if="loading > 0" size="md" color="dark" class="my-4 mx-auto" />
<div v-else-if="readme" v-html="readme.html"></div> <div v-else-if="readme" v-html="readme.html"></div>
</div> </div>
</article> </article>
......
...@@ -34,6 +34,11 @@ export default { ...@@ -34,6 +34,11 @@ export default {
type: Boolean, type: Boolean,
required: true, required: true,
}, },
loadingPath: {
type: String,
required: false,
default: '',
},
}, },
data() { data() {
return { return {
...@@ -69,7 +74,12 @@ export default { ...@@ -69,7 +74,12 @@ export default {
<table :aria-label="tableCaption" class="table tree-table qa-file-tree" aria-live="polite"> <table :aria-label="tableCaption" class="table tree-table qa-file-tree" aria-live="polite">
<table-header v-once /> <table-header v-once />
<tbody> <tbody>
<parent-row v-show="showParentRow" :commit-ref="ref" :path="path" /> <parent-row
v-show="showParentRow"
:commit-ref="ref"
:path="path"
:loading-path="loadingPath"
/>
<template v-for="val in entries"> <template v-for="val in entries">
<table-row <table-row
v-for="entry in val" v-for="entry in val"
...@@ -84,6 +94,7 @@ export default { ...@@ -84,6 +94,7 @@ export default {
:url="entry.webUrl" :url="entry.webUrl"
:submodule-tree-url="entry.treeUrl" :submodule-tree-url="entry.treeUrl"
:lfs-oid="entry.lfsOid" :lfs-oid="entry.lfsOid"
:loading-path="loadingPath"
/> />
</template> </template>
<template v-if="isLoading"> <template v-if="isLoading">
......
<script> <script>
import { GlLoadingIcon } from '@gitlab/ui';
export default { export default {
components: {
GlLoadingIcon,
},
props: { props: {
commitRef: { commitRef: {
type: String, type: String,
...@@ -9,13 +14,21 @@ export default { ...@@ -9,13 +14,21 @@ export default {
type: String, type: String,
required: true, required: true,
}, },
loadingPath: {
type: String,
required: false,
default: null,
},
}, },
computed: { computed: {
parentRoute() { parentPath() {
const splitArray = this.path.split('/'); const splitArray = this.path.split('/');
splitArray.pop(); splitArray.pop();
return { path: `/tree/${this.commitRef}/${splitArray.join('/')}` }; return splitArray.join('/');
},
parentRoute() {
return { path: `/tree/${this.commitRef}/${this.parentPath}` };
}, },
}, },
methods: { methods: {
...@@ -29,7 +42,13 @@ export default { ...@@ -29,7 +42,13 @@ export default {
<template> <template>
<tr class="tree-item"> <tr class="tree-item">
<td colspan="3" class="tree-item-file-name" @click.self="clickRow"> <td colspan="3" class="tree-item-file-name" @click.self="clickRow">
<router-link :to="parentRoute" :aria-label="__('Go to parent')"> <gl-loading-icon
v-if="parentPath === loadingPath"
size="sm"
inline
class="d-inline-block align-text-bottom"
/>
<router-link v-else :to="parentRoute" :aria-label="__('Go to parent')">
.. ..
</router-link> </router-link>
</td> </td>
......
<script> <script>
import { GlBadge, GlLink, GlSkeletonLoading, GlTooltipDirective } from '@gitlab/ui'; import { GlBadge, GlLink, GlSkeletonLoading, GlTooltipDirective, GlLoadingIcon } from '@gitlab/ui';
import { visitUrl } from '~/lib/utils/url_utility'; import { visitUrl } from '~/lib/utils/url_utility';
import TimeagoTooltip from '~/vue_shared/components/time_ago_tooltip.vue'; import TimeagoTooltip from '~/vue_shared/components/time_ago_tooltip.vue';
import Icon from '~/vue_shared/components/icon.vue'; import Icon from '~/vue_shared/components/icon.vue';
...@@ -12,6 +12,7 @@ export default { ...@@ -12,6 +12,7 @@ export default {
GlBadge, GlBadge,
GlLink, GlLink,
GlSkeletonLoading, GlSkeletonLoading,
GlLoadingIcon,
TimeagoTooltip, TimeagoTooltip,
Icon, Icon,
}, },
...@@ -76,6 +77,11 @@ export default { ...@@ -76,6 +77,11 @@ export default {
required: false, required: false,
default: null, default: null,
}, },
loadingPath: {
type: String,
required: false,
default: '',
},
}, },
data() { data() {
return { return {
...@@ -125,7 +131,13 @@ export default { ...@@ -125,7 +131,13 @@ export default {
<template> <template>
<tr :class="`file_${id}`" class="tree-item" @click="openRow"> <tr :class="`file_${id}`" class="tree-item" @click="openRow">
<td class="tree-item-file-name"> <td class="tree-item-file-name">
<i :aria-label="type" role="img" :class="iconName" class="fa fa-fw"></i> <gl-loading-icon
v-if="path === loadingPath"
size="sm"
inline
class="d-inline-block align-text-bottom fa-fw"
/>
<i v-else :aria-label="type" role="img" :class="iconName" class="fa fa-fw"></i>
<component :is="linkComponent" :to="routerLinkTo" :href="url" class="str-truncated"> <component :is="linkComponent" :to="routerLinkTo" :href="url" class="str-truncated">
{{ fullPath }} {{ fullPath }}
</component> </component>
......
...@@ -27,6 +27,11 @@ export default { ...@@ -27,6 +27,11 @@ export default {
required: false, required: false,
default: '/', default: '/',
}, },
loadingPath: {
type: String,
required: false,
default: '',
},
}, },
data() { data() {
return { return {
...@@ -109,7 +114,12 @@ export default { ...@@ -109,7 +114,12 @@ export default {
<template> <template>
<div> <div>
<file-table :path="path" :entries="entries" :is-loading="isLoadingFiles" /> <file-table
:path="path"
:entries="entries"
:is-loading="isLoadingFiles"
:loading-path="loadingPath"
/>
<file-preview v-if="readme" :blob="readme" /> <file-preview v-if="readme" :blob="readme" />
</div> </div>
</template> </template>
import getFiles from '../queries/getFiles.query.graphql';
import getRefMixin from './get_ref';
import getProjectPath from '../queries/getProjectPath.query.graphql';
export default {
mixins: [getRefMixin],
apollo: {
projectPath: {
query: getProjectPath,
},
},
data() {
return { projectPath: '', loadingPath: null };
},
beforeRouteUpdate(to, from, next) {
this.preload(to.params.pathMatch, next);
},
methods: {
preload(path, next) {
this.loadingPath = path.replace(/^\//, '');
return this.$apollo
.query({
query: getFiles,
variables: {
projectPath: this.projectPath,
ref: this.ref,
path: this.loadingPath,
nextPageCursor: '',
pageSize: 100,
},
})
.then(() => next());
},
},
};
<script> <script>
import TreeContent from '../components/tree_content.vue'; import TreeContent from '../components/tree_content.vue';
import { updateElementsVisibility } from '../utils/dom'; import { updateElementsVisibility } from '../utils/dom';
import preloadMixin from '../mixins/preload';
export default { export default {
components: { components: {
TreeContent, TreeContent,
}, },
mixins: [preloadMixin],
props: { props: {
path: { path: {
type: String, type: String,
...@@ -34,5 +36,5 @@ export default { ...@@ -34,5 +36,5 @@ export default {
</script> </script>
<template> <template>
<tree-content :path="path" /> <tree-content :path="path" :loading-path="loadingPath" />
</template> </template>
...@@ -22,7 +22,8 @@ describe 'Path Locks', :js do ...@@ -22,7 +22,8 @@ describe 'Path Locks', :js do
within '.tree-content-holder' do within '.tree-content-holder' do
click_link "encoding" click_link "encoding"
end end
click_link "Lock"
find('.js-path-lock').click
expect(page).to have_link('Unlock') expect(page).to have_link('Unlock')
end end
......
...@@ -41,6 +41,11 @@ describe "User browses files" do ...@@ -41,6 +41,11 @@ describe "User browses files" do
it "shows the `Browse Directory` link" do it "shows the `Browse Directory` link" do
click_link("files") click_link("files")
page.within('.repo-breadcrumb') do
expect(page).to have_link('files')
end
click_link("History") click_link("History")
expect(page).to have_link("Browse Directory").and have_no_link("Browse Code") expect(page).to have_link("Browse Directory").and have_no_link("Browse Code")
......
...@@ -19,7 +19,17 @@ describe 'Projects > Files > User browses LFS files' do ...@@ -19,7 +19,17 @@ describe 'Projects > Files > User browses LFS files' do
it 'is possible to see raw content of LFS pointer' do it 'is possible to see raw content of LFS pointer' do
click_link 'files' click_link 'files'
page.within('.repo-breadcrumb') do
expect(page).to have_link('files')
end
click_link 'lfs' click_link 'lfs'
page.within('.repo-breadcrumb') do
expect(page).to have_link('lfs')
end
click_link 'lfs_object.iso' click_link 'lfs_object.iso'
expect(page).to have_content 'version https://git-lfs.github.com/spec/v1' expect(page).to have_content 'version https://git-lfs.github.com/spec/v1'
...@@ -38,6 +48,11 @@ describe 'Projects > Files > User browses LFS files' do ...@@ -38,6 +48,11 @@ describe 'Projects > Files > User browses LFS files' do
it 'shows an LFS object' do it 'shows an LFS object' do
click_link('files') click_link('files')
page.within('.repo-breadcrumb') do
expect(page).to have_link('files')
end
click_link('lfs') click_link('lfs')
click_link('lfs_object.iso') click_link('lfs_object.iso')
......
import { shallowMount, RouterLinkStub } from '@vue/test-utils'; import { shallowMount, RouterLinkStub } from '@vue/test-utils';
import { GlLoadingIcon } from '@gitlab/ui';
import ParentRow from '~/repository/components/table/parent_row.vue'; import ParentRow from '~/repository/components/table/parent_row.vue';
let vm; let vm;
let $router; let $router;
function factory(path) { function factory(path, loadingPath) {
$router = { $router = {
push: jest.fn(), push: jest.fn(),
}; };
...@@ -13,6 +14,7 @@ function factory(path) { ...@@ -13,6 +14,7 @@ function factory(path) {
propsData: { propsData: {
commitRef: 'master', commitRef: 'master',
path, path,
loadingPath,
}, },
stubs: { stubs: {
RouterLink: RouterLinkStub, RouterLink: RouterLinkStub,
...@@ -61,4 +63,10 @@ describe('Repository parent row component', () => { ...@@ -61,4 +63,10 @@ describe('Repository parent row component', () => {
path: '/tree/master/app', path: '/tree/master/app',
}); });
}); });
it('renders loading icon when loading parent', () => {
factory('app/assets', 'app');
expect(vm.find(GlLoadingIcon).exists()).toBe(true);
});
}); });
import { shallowMount, RouterLinkStub } from '@vue/test-utils'; import { shallowMount, RouterLinkStub } from '@vue/test-utils';
import { GlBadge, GlLink } from '@gitlab/ui'; import { GlBadge, GlLink, GlLoadingIcon } from '@gitlab/ui';
import { visitUrl } from '~/lib/utils/url_utility'; import { visitUrl } from '~/lib/utils/url_utility';
import TableRow from '~/repository/components/table/row.vue'; import TableRow from '~/repository/components/table/row.vue';
import Icon from '~/vue_shared/components/icon.vue'; import Icon from '~/vue_shared/components/icon.vue';
...@@ -198,4 +198,17 @@ describe('Repository table row component', () => { ...@@ -198,4 +198,17 @@ describe('Repository table row component', () => {
expect(vm.find(Icon).exists()).toBe(true); expect(vm.find(Icon).exists()).toBe(true);
}); });
}); });
it('renders loading icon when path is loading', () => {
factory({
id: '1',
sha: '1',
path: 'test',
type: 'tree',
currentPath: '/',
loadingPath: 'test',
});
expect(vm.find(GlLoadingIcon).exists()).toBe(true);
});
}); });
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment