diff options
24 files changed, 184 insertions, 4 deletions
diff --git a/app/assets/javascripts/pages/projects/show/index.js b/app/assets/javascripts/pages/projects/show/index.js index 869f70e7d33..6aa41d0825b 100644 --- a/app/assets/javascripts/pages/projects/show/index.js +++ b/app/assets/javascripts/pages/projects/show/index.js @@ -46,4 +46,12 @@ document.addEventListener('DOMContentLoaded', () => { GpgBadges.fetch(); leaveByUrl('project'); + + if (document.getElementById('js-tree-list')) { + import('~/repository') + .then(m => m.default()) + .catch(e => { + throw e; + }); + } }); diff --git a/app/assets/javascripts/pages/projects/tree/show/index.js b/app/assets/javascripts/pages/projects/tree/show/index.js index 400aed35e32..7b90a3a4f6e 100644 --- a/app/assets/javascripts/pages/projects/tree/show/index.js +++ b/app/assets/javascripts/pages/projects/tree/show/index.js @@ -40,4 +40,12 @@ document.addEventListener('DOMContentLoaded', () => { } GpgBadges.fetch(); + + if (document.getElementById('js-tree-list')) { + import('~/repository') + .then(m => m.default()) + .catch(e => { + throw e; + }); + } }); diff --git a/app/assets/javascripts/repository/components/app.vue b/app/assets/javascripts/repository/components/app.vue new file mode 100644 index 00000000000..98240aef810 --- /dev/null +++ b/app/assets/javascripts/repository/components/app.vue @@ -0,0 +1,3 @@ +<template> + <router-view /> +</template> diff --git a/app/assets/javascripts/repository/graphql.js b/app/assets/javascripts/repository/graphql.js new file mode 100644 index 00000000000..febfcce780c --- /dev/null +++ b/app/assets/javascripts/repository/graphql.js @@ -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, +}); diff --git a/app/assets/javascripts/repository/index.js b/app/assets/javascripts/repository/index.js new file mode 100644 index 00000000000..00b69362312 --- /dev/null +++ b/app/assets/javascripts/repository/index.js @@ -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); + }, + }); +} diff --git a/app/assets/javascripts/repository/pages/index.vue b/app/assets/javascripts/repository/pages/index.vue new file mode 100644 index 00000000000..fdbf195f0f6 --- /dev/null +++ b/app/assets/javascripts/repository/pages/index.vue @@ -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> diff --git a/app/assets/javascripts/repository/pages/tree.vue b/app/assets/javascripts/repository/pages/tree.vue new file mode 100644 index 00000000000..f51aafee775 --- /dev/null +++ b/app/assets/javascripts/repository/pages/tree.vue @@ -0,0 +1,15 @@ +<script> +export default { + props: { + path: { + type: String, + required: false, + default: '/', + }, + }, +}; +</script> + +<template> + <div>{{ path }}</div> +</template> diff --git a/app/assets/javascripts/repository/queries/getRef.graphql b/app/assets/javascripts/repository/queries/getRef.graphql new file mode 100644 index 00000000000..58c09844c3f --- /dev/null +++ b/app/assets/javascripts/repository/queries/getRef.graphql @@ -0,0 +1,3 @@ +query getRef { + ref @client +} diff --git a/app/assets/javascripts/repository/router.js b/app/assets/javascripts/repository/router.js new file mode 100644 index 00000000000..b42a96a4ee2 --- /dev/null +++ b/app/assets/javascripts/repository/router.js @@ -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(); + }, + }, + ], + }); +} diff --git a/app/views/projects/_files.html.haml b/app/views/projects/_files.html.haml index 22a721ee9ad..0edd8ee5e46 100644 --- a/app/views/projects/_files.html.haml +++ b/app/views/projects/_files.html.haml @@ -4,6 +4,7 @@ - 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) } - show_auto_devops_callout = show_auto_devops_callout?(@project) +- vue_file_list = Feature.enabled?(:vue_file_list, @project) #tree-holder.tree-holder.clearfix .nav-block @@ -13,7 +14,12 @@ = render 'shared/commit_well', commit: commit, ref: ref, project: project - 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 '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 diff --git a/app/views/projects/_home_panel.html.haml b/app/views/projects/_home_panel.html.haml index 3ca4abddbb8..a97322dace4 100644 --- a/app/views/projects/_home_panel.html.haml +++ b/app/views/projects/_home_panel.html.haml @@ -1,7 +1,7 @@ - empty_repo = @project.empty_repo? - show_auto_devops_callout = show_auto_devops_callout?(@project) - 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 .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 diff --git a/app/views/projects/tree/_readme.html.haml b/app/views/projects/tree/_readme.html.haml index 4daacbe157c..e935af23659 100644 --- a/app/views/projects/tree/_readme.html.haml +++ b/app/views/projects/tree/_readme.html.haml @@ -1,5 +1,5 @@ - 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 = blob_icon readme.mode, readme.name = link_to project_blob_path(@project, tree_join(@ref, readme.path)) do diff --git a/spec/features/projects/files/files_sort_submodules_with_folders_spec.rb b/spec/features/projects/files/files_sort_submodules_with_folders_spec.rb index b6dbf76bc9b..51c884201a6 100644 --- a/spec/features/projects/files/files_sort_submodules_with_folders_spec.rb +++ b/spec/features/projects/files/files_sort_submodules_with_folders_spec.rb @@ -5,6 +5,8 @@ describe 'Projects > Files > User views files page' do let(:user) { project.owner } before do + stub_feature_flags(vue_file_list: false) + sign_in user visit project_tree_path(project, project.repository.root_ref) end diff --git a/spec/features/projects/files/user_browses_files_spec.rb b/spec/features/projects/files/user_browses_files_spec.rb index 66268355345..a5d849db8a3 100644 --- a/spec/features/projects/files/user_browses_files_spec.rb +++ b/spec/features/projects/files/user_browses_files_spec.rb @@ -11,6 +11,7 @@ describe "User browses files" do let(:user) { project.owner } before do + stub_feature_flags(vue_file_list: false) stub_feature_flags(csslab: false) sign_in(user) end diff --git a/spec/features/projects/files/user_browses_lfs_files_spec.rb b/spec/features/projects/files/user_browses_lfs_files_spec.rb index d56476adb05..d5cb8f9212d 100644 --- a/spec/features/projects/files/user_browses_lfs_files_spec.rb +++ b/spec/features/projects/files/user_browses_lfs_files_spec.rb @@ -5,6 +5,8 @@ describe 'Projects > Files > User browses LFS files' do let(:user) { project.owner } before do + stub_feature_flags(vue_file_list: false) + sign_in(user) end diff --git a/spec/features/projects/files/user_creates_directory_spec.rb b/spec/features/projects/files/user_creates_directory_spec.rb index 847b5f0860f..e29e867492e 100644 --- a/spec/features/projects/files/user_creates_directory_spec.rb +++ b/spec/features/projects/files/user_creates_directory_spec.rb @@ -11,6 +11,8 @@ describe 'Projects > Files > User creates a directory', :js do let(:user) { create(:user) } before do + stub_feature_flags(vue_file_list: false) + project.add_developer(user) sign_in(user) visit project_tree_path(project, 'master') diff --git a/spec/features/projects/files/user_deletes_files_spec.rb b/spec/features/projects/files/user_deletes_files_spec.rb index 614b11fa5c8..11ee87f245b 100644 --- a/spec/features/projects/files/user_deletes_files_spec.rb +++ b/spec/features/projects/files/user_deletes_files_spec.rb @@ -12,6 +12,8 @@ describe 'Projects > Files > User deletes files', :js do let(:user) { create(:user) } before do + stub_feature_flags(vue_file_list: false) + sign_in(user) end diff --git a/spec/features/projects/files/user_edits_files_spec.rb b/spec/features/projects/files/user_edits_files_spec.rb index 2de22582b2c..26efb5e6787 100644 --- a/spec/features/projects/files/user_edits_files_spec.rb +++ b/spec/features/projects/files/user_edits_files_spec.rb @@ -10,6 +10,7 @@ describe 'Projects > Files > User edits files', :js do before do stub_feature_flags(web_ide_default: false) + stub_feature_flags(vue_file_list: false) sign_in(user) end diff --git a/spec/features/projects/files/user_replaces_files_spec.rb b/spec/features/projects/files/user_replaces_files_spec.rb index e3da28d73c3..bfd612e4cc8 100644 --- a/spec/features/projects/files/user_replaces_files_spec.rb +++ b/spec/features/projects/files/user_replaces_files_spec.rb @@ -14,6 +14,8 @@ describe 'Projects > Files > User replaces files', :js do let(:user) { create(:user) } before do + stub_feature_flags(vue_file_list: false) + sign_in(user) end diff --git a/spec/features/projects/files/user_uploads_files_spec.rb b/spec/features/projects/files/user_uploads_files_spec.rb index af3fc528a20..25ff3fdf411 100644 --- a/spec/features/projects/files/user_uploads_files_spec.rb +++ b/spec/features/projects/files/user_uploads_files_spec.rb @@ -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) } before do + stub_feature_flags(vue_file_list: false) + project.add_maintainer(user) sign_in(user) end diff --git a/spec/features/projects/tree/tree_show_spec.rb b/spec/features/projects/tree/tree_show_spec.rb index 45e81e1c040..3ccea2db705 100644 --- a/spec/features/projects/tree/tree_show_spec.rb +++ b/spec/features/projects/tree/tree_show_spec.rb @@ -8,6 +8,7 @@ describe 'Projects tree', :js do let(:test_sha) { '7975be0116940bf2ad4321f79d02a55c5f7779aa' } before do + stub_feature_flags(vue_file_list: false) project.add_maintainer(user) sign_in(user) end diff --git a/spec/features/projects_spec.rb b/spec/features/projects_spec.rb index ff4e6197746..4fe45311b2d 100644 --- a/spec/features/projects_spec.rb +++ b/spec/features/projects_spec.rb @@ -5,6 +5,7 @@ describe 'Project' do include MobileHelpers before do + stub_feature_flags(vue_file_list: false) stub_feature_flags(approval_rules: false) end diff --git a/spec/frontend/repository/router_spec.js b/spec/frontend/repository/router_spec.js new file mode 100644 index 00000000000..f61a0ccd1e6 --- /dev/null +++ b/spec/frontend/repository/router_spec.js @@ -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); + } + }); +}); diff --git a/spec/views/projects/tree/show.html.haml_spec.rb b/spec/views/projects/tree/show.html.haml_spec.rb index 3b098320ad7..5bb0173ab89 100644 --- a/spec/views/projects/tree/show.html.haml_spec.rb +++ b/spec/views/projects/tree/show.html.haml_spec.rb @@ -7,6 +7,8 @@ describe 'projects/tree/show' do let(:repository) { project.repository } before do + stub_feature_flags(vue_file_list: false) + assign(:project, project) assign(:repository, repository) assign(:lfs_blob_ids, []) |