Commit e7bfa5f1 authored by Jacques Erasmus's avatar Jacques Erasmus Committed by Mark Florian

Add Blob Page to the repository vue app

Added a blob page in preparation for the blob viewer refactor
parent e8906a60
...@@ -12,6 +12,7 @@ import { escapeRegExp } from 'lodash'; ...@@ -12,6 +12,7 @@ import { escapeRegExp } from 'lodash';
import { escapeFileUrl } from '~/lib/utils/url_utility'; import { escapeFileUrl } from '~/lib/utils/url_utility';
import FileIcon from '~/vue_shared/components/file_icon.vue'; import FileIcon from '~/vue_shared/components/file_icon.vue';
import TimeagoTooltip from '~/vue_shared/components/time_ago_tooltip.vue'; import TimeagoTooltip from '~/vue_shared/components/time_ago_tooltip.vue';
import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import getRefMixin from '../../mixins/get_ref'; import getRefMixin from '../../mixins/get_ref';
import commitQuery from '../../queries/commit.query.graphql'; import commitQuery from '../../queries/commit.query.graphql';
...@@ -41,7 +42,7 @@ export default { ...@@ -41,7 +42,7 @@ export default {
}, },
}, },
}, },
mixins: [getRefMixin], mixins: [getRefMixin, glFeatureFlagMixin()],
props: { props: {
id: { id: {
type: String, type: String,
...@@ -103,10 +104,21 @@ export default { ...@@ -103,10 +104,21 @@ export default {
}; };
}, },
computed: { computed: {
refactorBlobViewerEnabled() {
return this.glFeatures.refactorBlobViewer;
},
routerLinkTo() { routerLinkTo() {
return this.isFolder const blobRouteConfig = { path: `/-/blob/${this.escapedRef}/${escapeFileUrl(this.path)}` };
? { path: `/-/tree/${this.escapedRef}/${escapeFileUrl(this.path)}` } const treeRouteConfig = { path: `/-/tree/${this.escapedRef}/${escapeFileUrl(this.path)}` };
: null;
if (this.refactorBlobViewerEnabled && this.isBlob) {
return blobRouteConfig;
}
return this.isFolder ? treeRouteConfig : null;
},
isBlob() {
return this.type === 'blob';
}, },
isFolder() { isFolder() {
return this.type === 'tree'; return this.type === 'tree';
...@@ -115,7 +127,7 @@ export default { ...@@ -115,7 +127,7 @@ export default {
return this.type === 'commit'; return this.type === 'commit';
}, },
linkComponent() { linkComponent() {
return this.isFolder ? 'router-link' : 'a'; return this.isFolder || (this.refactorBlobViewerEnabled && this.isBlob) ? 'router-link' : 'a';
}, },
fullPath() { fullPath() {
return this.path.replace(new RegExp(`^${escapeRegExp(this.currentPath)}/`), ''); return this.path.replace(new RegExp(`^${escapeRegExp(this.currentPath)}/`), '');
......
<script>
// This file is in progress and behind a feature flag, please see the following issue for more:
// https://gitlab.com/gitlab-org/gitlab/-/issues/323200
// TODO (follow-up MR): import BlobContentViewer from '../components/blob_content_viewer.vue';
export default {
components: {
// TODO (follow-up MR): BlobContentViewer,
},
};
</script>
<template>
<div></div>
<!-- TODO (follow-up MR): <blob-content-viewer/> -->
</template>
...@@ -2,6 +2,7 @@ import { escapeRegExp } from 'lodash'; ...@@ -2,6 +2,7 @@ import { escapeRegExp } from 'lodash';
import Vue from 'vue'; import Vue from 'vue';
import VueRouter from 'vue-router'; import VueRouter from 'vue-router';
import { joinPaths } from '../lib/utils/url_utility'; import { joinPaths } from '../lib/utils/url_utility';
import BlobPage from './pages/blob.vue';
import IndexPage from './pages/index.vue'; import IndexPage from './pages/index.vue';
import TreePage from './pages/tree.vue'; import TreePage from './pages/tree.vue';
...@@ -15,6 +16,13 @@ export default function createRouter(base, baseRef) { ...@@ -15,6 +16,13 @@ export default function createRouter(base, baseRef) {
}), }),
}; };
const blobPathRoute = {
component: BlobPage,
props: (route) => ({
path: route.params.path,
}),
};
return new VueRouter({ return new VueRouter({
mode: 'history', mode: 'history',
base: joinPaths(gon.relative_url_root || '', base), base: joinPaths(gon.relative_url_root || '', base),
...@@ -31,6 +39,18 @@ export default function createRouter(base, baseRef) { ...@@ -31,6 +39,18 @@ export default function createRouter(base, baseRef) {
path: `(/-)?/tree/${escapeRegExp(baseRef)}/:path*`, path: `(/-)?/tree/${escapeRegExp(baseRef)}/:path*`,
...treePathRoute, ...treePathRoute,
}, },
{
name: 'blobPathDecoded',
// Sometimes the ref needs decoding depending on how the backend sends it to us
path: `(/-)?/blob/${decodeURI(baseRef)}/:path*`,
...blobPathRoute,
},
{
name: 'blobPath',
// Support without decoding as well just in case the ref doesn't need to be decoded
path: `(/-)?/blob/${escapeRegExp(baseRef)}/:path*`,
...blobPathRoute,
},
{ {
path: '/', path: '/',
name: 'projectRoot', name: 'projectRoot',
......
...@@ -35,6 +35,10 @@ class ProjectsController < Projects::ApplicationController ...@@ -35,6 +35,10 @@ class ProjectsController < Projects::ApplicationController
push_frontend_feature_flag(:allow_editing_commit_messages, @project) push_frontend_feature_flag(:allow_editing_commit_messages, @project)
end end
before_action do
push_frontend_feature_flag(:refactor_blob_viewer, @project, default_enabled: :yaml)
end
layout :determine_layout layout :determine_layout
feature_category :projects, [ feature_category :projects, [
......
---
name: refactor_blob_viewer
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/57326
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/324351
milestone: '13.11'
type: development
group: group::source code
default_enabled: false
...@@ -290,6 +290,7 @@ RSpec.describe 'Project' do ...@@ -290,6 +290,7 @@ RSpec.describe 'Project' do
let(:project) { create(:forked_project_with_submodules) } let(:project) { create(:forked_project_with_submodules) }
before do before do
stub_feature_flags(refactor_blob_viewer: false)
project.add_maintainer(user) project.add_maintainer(user)
sign_in user sign_in user
visit project_path(project) visit project_path(project)
......
...@@ -19,6 +19,9 @@ function factory(propsData = {}) { ...@@ -19,6 +19,9 @@ function factory(propsData = {}) {
projectPath: 'gitlab-org/gitlab-ce', projectPath: 'gitlab-org/gitlab-ce',
url: `https://test.com`, url: `https://test.com`,
}, },
provide: {
glFeatures: { refactorBlobViewer: true },
},
mocks: { mocks: {
$router, $router,
}, },
...@@ -81,7 +84,7 @@ describe('Repository table row component', () => { ...@@ -81,7 +84,7 @@ describe('Repository table row component', () => {
it.each` it.each`
type | component | componentName type | component | componentName
${'tree'} | ${RouterLinkStub} | ${'RouterLink'} ${'tree'} | ${RouterLinkStub} | ${'RouterLink'}
${'file'} | ${'a'} | ${'hyperlink'} ${'blob'} | ${RouterLinkStub} | ${'RouterLink'}
${'commit'} | ${'a'} | ${'hyperlink'} ${'commit'} | ${'a'} | ${'hyperlink'}
`('renders a $componentName for type $type', ({ type, component }) => { `('renders a $componentName for type $type', ({ type, component }) => {
factory({ factory({
......
import BlobPage from '~/repository/pages/blob.vue';
import IndexPage from '~/repository/pages/index.vue'; import IndexPage from '~/repository/pages/index.vue';
import TreePage from '~/repository/pages/tree.vue'; import TreePage from '~/repository/pages/tree.vue';
import createRouter from '~/repository/router'; import createRouter from '~/repository/router';
...@@ -11,6 +12,7 @@ describe('Repository router spec', () => { ...@@ -11,6 +12,7 @@ describe('Repository router spec', () => {
${'/-/tree/master'} | ${'master'} | ${TreePage} | ${'TreePage'} ${'/-/tree/master'} | ${'master'} | ${TreePage} | ${'TreePage'}
${'/-/tree/master/app/assets'} | ${'master'} | ${TreePage} | ${'TreePage'} ${'/-/tree/master/app/assets'} | ${'master'} | ${TreePage} | ${'TreePage'}
${'/-/tree/123/app/assets'} | ${'master'} | ${null} | ${'null'} ${'/-/tree/123/app/assets'} | ${'master'} | ${null} | ${'null'}
${'/-/blob/master/file.md'} | ${'master'} | ${BlobPage} | ${'BlobPage'}
`('sets component as $componentName for path "$path"', ({ path, component, branch }) => { `('sets component as $componentName for path "$path"', ({ path, component, branch }) => {
const router = createRouter('', branch); const router = createRouter('', branch);
......
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