Setup Vue app for repository file listing

Part of https://gitlab.com/gitlab-org/gitlab-ce/issues/61578
This commit is contained in:
Phil Hughes 2019-05-20 08:41:28 +00:00 committed by Filipa Lacerda
parent 2f613f28ba
commit 404314c619
24 changed files with 184 additions and 4 deletions

View file

@ -46,4 +46,12 @@ document.addEventListener('DOMContentLoaded', () => {
GpgBadges.fetch(); GpgBadges.fetch();
leaveByUrl('project'); leaveByUrl('project');
if (document.getElementById('js-tree-list')) {
import('~/repository')
.then(m => m.default())
.catch(e => {
throw e;
});
}
}); });

View file

@ -40,4 +40,12 @@ document.addEventListener('DOMContentLoaded', () => {
} }
GpgBadges.fetch(); GpgBadges.fetch();
if (document.getElementById('js-tree-list')) {
import('~/repository')
.then(m => m.default())
.catch(e => {
throw e;
});
}
}); });

View file

@ -0,0 +1,3 @@
<template>
<router-view />
</template>

View file

@ -0,0 +1,11 @@
import Vue from 'vue';
import VueApollo from 'vue-apollo';
import createDefaultClient from '~/lib/graphql';
Vue.use(VueApollo);
const defaultClient = createDefaultClient({});
export default new VueApollo({
defaultClient,
});

View file

@ -0,0 +1,25 @@
import Vue from 'vue';
import createRouter from './router';
import App from './components/app.vue';
import apolloProvider from './graphql';
export default function setupVueRepositoryList() {
const el = document.getElementById('js-tree-list');
const { projectPath, ref } = el.dataset;
apolloProvider.clients.defaultClient.cache.writeData({
data: {
projectPath,
ref,
},
});
return new Vue({
el,
router: createRouter(projectPath, ref),
apolloProvider,
render(h) {
return h(App);
},
});
}

View file

@ -0,0 +1,24 @@
<script>
import getRef from '../queries/getRef.graphql';
export default {
apollo: {
ref: {
query: getRef,
},
},
data() {
return {
ref: '',
};
},
};
</script>
<template>
<div>
<router-link :to="{ path: `/tree/${ref}/app` }">
Go to tree
</router-link>
</div>
</template>

View file

@ -0,0 +1,15 @@
<script>
export default {
props: {
path: {
type: String,
required: false,
default: '/',
},
},
};
</script>
<template>
<div>{{ path }}</div>
</template>

View file

@ -0,0 +1,3 @@
query getRef {
ref @client
}

View file

@ -0,0 +1,36 @@
import Vue from 'vue';
import VueRouter from 'vue-router';
import { joinPaths } from '../lib/utils/url_utility';
import IndexPage from './pages/index.vue';
import TreePage from './pages/tree.vue';
Vue.use(VueRouter);
export default function createRouter(base, baseRef) {
return new VueRouter({
mode: 'history',
base: joinPaths(gon.relative_url_root || '', base),
routes: [
{
path: '/',
name: 'projectRoot',
component: IndexPage,
},
{
path: `/tree/${baseRef}(/.*)?`,
name: 'treePath',
component: TreePage,
props: route => ({
path: route.params.pathMatch,
}),
beforeEnter(to, from, next) {
document
.querySelectorAll('.js-hide-on-navigation')
.forEach(el => el.classList.add('hidden'));
next();
},
},
],
});
}

View file

@ -4,6 +4,7 @@
- project = local_assigns.fetch(:project) { @project } - project = local_assigns.fetch(:project) { @project }
- content_url = local_assigns.fetch(:content_url) { @tree.readme ? project_blob_path(@project, tree_join(@ref, @tree.readme.path)) : project_tree_path(@project, @ref) } - content_url = local_assigns.fetch(:content_url) { @tree.readme ? project_blob_path(@project, tree_join(@ref, @tree.readme.path)) : project_tree_path(@project, @ref) }
- show_auto_devops_callout = show_auto_devops_callout?(@project) - show_auto_devops_callout = show_auto_devops_callout?(@project)
- vue_file_list = Feature.enabled?(:vue_file_list, @project)
#tree-holder.tree-holder.clearfix #tree-holder.tree-holder.clearfix
.nav-block .nav-block
@ -13,7 +14,12 @@
= render 'shared/commit_well', commit: commit, ref: ref, project: project = render 'shared/commit_well', commit: commit, ref: ref, project: project
- if is_project_overview - if is_project_overview
.project-buttons.append-bottom-default .project-buttons.append-bottom-default{ class: ("js-hide-on-navigation" if vue_file_list) }
= render 'stat_anchor_list', anchors: @project.statistics_buttons(show_auto_devops_callout: show_auto_devops_callout) = render 'stat_anchor_list', anchors: @project.statistics_buttons(show_auto_devops_callout: show_auto_devops_callout)
= render 'projects/tree/tree_content', tree: @tree, content_url: content_url - if vue_file_list
#js-tree-list{ data: { project_path: @project.full_path, ref: ref } }
- if @tree.readme
= render "projects/tree/readme", readme: @tree.readme
- else
= render 'projects/tree/tree_content', tree: @tree, content_url: content_url

View file

@ -1,7 +1,7 @@
- empty_repo = @project.empty_repo? - empty_repo = @project.empty_repo?
- show_auto_devops_callout = show_auto_devops_callout?(@project) - show_auto_devops_callout = show_auto_devops_callout?(@project)
- max_project_topic_length = 15 - max_project_topic_length = 15
.project-home-panel{ class: ("empty-project" if empty_repo) } .project-home-panel{ class: [("empty-project" if empty_repo), ("js-hide-on-navigation" if Feature.enabled?(:vue_file_list, @project))] }
.row.append-bottom-8 .row.append-bottom-8
.home-panel-title-row.col-md-12.col-lg-6.d-flex .home-panel-title-row.col-md-12.col-lg-6.d-flex
.avatar-container.rect-avatar.s64.home-panel-avatar.append-right-default.float-none .avatar-container.rect-avatar.s64.home-panel-avatar.append-right-default.float-none

View file

@ -1,5 +1,5 @@
- if readme.rich_viewer - if readme.rich_viewer
%article.file-holder.readme-holder{ id: 'readme', class: ("limited-width-container" unless fluid_layout) } %article.file-holder.readme-holder{ id: 'readme', class: [("limited-width-container" unless fluid_layout), ("js-hide-on-navigation" if Feature.enabled?(:vue_file_list, @project))] }
.js-file-title.file-title .js-file-title.file-title
= blob_icon readme.mode, readme.name = blob_icon readme.mode, readme.name
= link_to project_blob_path(@project, tree_join(@ref, readme.path)) do = link_to project_blob_path(@project, tree_join(@ref, readme.path)) do

View file

@ -5,6 +5,8 @@ describe 'Projects > Files > User views files page' do
let(:user) { project.owner } let(:user) { project.owner }
before do before do
stub_feature_flags(vue_file_list: false)
sign_in user sign_in user
visit project_tree_path(project, project.repository.root_ref) visit project_tree_path(project, project.repository.root_ref)
end end

View file

@ -11,6 +11,7 @@ describe "User browses files" do
let(:user) { project.owner } let(:user) { project.owner }
before do before do
stub_feature_flags(vue_file_list: false)
stub_feature_flags(csslab: false) stub_feature_flags(csslab: false)
sign_in(user) sign_in(user)
end end

View file

@ -5,6 +5,8 @@ describe 'Projects > Files > User browses LFS files' do
let(:user) { project.owner } let(:user) { project.owner }
before do before do
stub_feature_flags(vue_file_list: false)
sign_in(user) sign_in(user)
end end

View file

@ -11,6 +11,8 @@ describe 'Projects > Files > User creates a directory', :js do
let(:user) { create(:user) } let(:user) { create(:user) }
before do before do
stub_feature_flags(vue_file_list: false)
project.add_developer(user) project.add_developer(user)
sign_in(user) sign_in(user)
visit project_tree_path(project, 'master') visit project_tree_path(project, 'master')

View file

@ -12,6 +12,8 @@ describe 'Projects > Files > User deletes files', :js do
let(:user) { create(:user) } let(:user) { create(:user) }
before do before do
stub_feature_flags(vue_file_list: false)
sign_in(user) sign_in(user)
end end

View file

@ -10,6 +10,7 @@ describe 'Projects > Files > User edits files', :js do
before do before do
stub_feature_flags(web_ide_default: false) stub_feature_flags(web_ide_default: false)
stub_feature_flags(vue_file_list: false)
sign_in(user) sign_in(user)
end end

View file

@ -14,6 +14,8 @@ describe 'Projects > Files > User replaces files', :js do
let(:user) { create(:user) } let(:user) { create(:user) }
before do before do
stub_feature_flags(vue_file_list: false)
sign_in(user) sign_in(user)
end end

View file

@ -14,6 +14,8 @@ describe 'Projects > Files > User uploads files' do
let(:project2_tree_path_root_ref) { project_tree_path(project2, project2.repository.root_ref) } let(:project2_tree_path_root_ref) { project_tree_path(project2, project2.repository.root_ref) }
before do before do
stub_feature_flags(vue_file_list: false)
project.add_maintainer(user) project.add_maintainer(user)
sign_in(user) sign_in(user)
end end

View file

@ -8,6 +8,7 @@ describe 'Projects tree', :js do
let(:test_sha) { '7975be0116940bf2ad4321f79d02a55c5f7779aa' } let(:test_sha) { '7975be0116940bf2ad4321f79d02a55c5f7779aa' }
before do before do
stub_feature_flags(vue_file_list: false)
project.add_maintainer(user) project.add_maintainer(user)
sign_in(user) sign_in(user)
end end

View file

@ -5,6 +5,7 @@ describe 'Project' do
include MobileHelpers include MobileHelpers
before do before do
stub_feature_flags(vue_file_list: false)
stub_feature_flags(approval_rules: false) stub_feature_flags(approval_rules: false)
end end

View file

@ -0,0 +1,23 @@
import IndexPage from '~/repository/pages/index.vue';
import TreePage from '~/repository/pages/tree.vue';
import createRouter from '~/repository/router';
describe('Repository router spec', () => {
it.each`
path | component | componentName
${'/'} | ${IndexPage} | ${'IndexPage'}
${'/tree/master'} | ${TreePage} | ${'TreePage'}
${'/tree/master/app/assets'} | ${TreePage} | ${'TreePage'}
${'/tree/123/app/assets'} | ${null} | ${'null'}
`('sets component as $componentName for path "$path"', ({ path, component }) => {
const router = createRouter('', 'master');
const componentsForRoute = router.getMatchedComponents(path);
expect(componentsForRoute.length).toBe(component ? 1 : 0);
if (component) {
expect(componentsForRoute).toContain(component);
}
});
});

View file

@ -7,6 +7,8 @@ describe 'projects/tree/show' do
let(:repository) { project.repository } let(:repository) { project.repository }
before do before do
stub_feature_flags(vue_file_list: false)
assign(:project, project) assign(:project, project)
assign(:repository, repository) assign(:repository, repository)
assign(:lfs_blob_ids, []) assign(:lfs_blob_ids, [])