Commit 76cdbe85 authored by Peter Leitzen's avatar Peter Leitzen

Merge branch '202159-open-fork' into 'master'

When opening Web IDE, follow path to fork if it exists

See merge request gitlab-org/gitlab!36548
parents 3122ee2e d79ec3f6
<script>
import TreeActionLink from './tree_action_link.vue';
import { __ } from '~/locale';
import { webIDEUrl } from '~/lib/utils/url_utility';
export default {
components: {
TreeActionLink,
},
props: {
projectPath: {
type: String,
required: true,
},
refSha: {
type: String,
required: true,
},
canPushCode: {
type: Boolean,
required: false,
default: true,
},
forkPath: {
type: String,
required: false,
default: '',
},
},
computed: {
showLinkToFork() {
return !this.canPushCode && this.forkPath;
},
text() {
return this.showLinkToFork ? __('Edit fork in Web IDE') : __('Web IDE');
},
path() {
const path = this.showLinkToFork ? this.forkPath : this.projectPath;
return webIDEUrl(`/${path}/edit/${this.refSha}/-/${this.$route.params.path || ''}`);
},
},
};
</script>
<template>
<tree-action-link :path="path" :text="text" data-qa-selector="web_ide_button" />
</template>
......@@ -4,18 +4,26 @@ import App from './components/app.vue';
import Breadcrumbs from './components/breadcrumbs.vue';
import LastCommit from './components/last_commit.vue';
import TreeActionLink from './components/tree_action_link.vue';
import WebIdeLink from './components/web_ide_link.vue';
import DirectoryDownloadLinks from './components/directory_download_links.vue';
import apolloProvider from './graphql';
import { setTitle } from './utils/title';
import { updateFormAction } from './utils/dom';
import { parseBoolean } from '../lib/utils/common_utils';
import { webIDEUrl } from '../lib/utils/url_utility';
import { __ } from '../locale';
export default function setupVueRepositoryList() {
const el = document.getElementById('js-tree-list');
const { dataset } = el;
const { projectPath, projectShortPath, ref, escapedRef, fullName } = dataset;
const {
canPushCode,
projectPath,
projectShortPath,
forkPath,
ref,
escapedRef,
fullName,
} = dataset;
const router = createRouter(projectPath, escapedRef);
apolloProvider.clients.defaultClient.cache.writeData({
......@@ -117,11 +125,12 @@ export default function setupVueRepositoryList() {
el: webIdeLinkEl,
router,
render(h) {
return h(TreeActionLink, {
return h(WebIdeLink, {
props: {
path: webIDEUrl(`/${projectPath}/edit/${ref}/-/${this.$route.params.path || ''}`),
text: __('Web IDE'),
cssClass: 'qa-web-ide-button',
projectPath,
refSha: ref,
forkPath,
canPushCode: parseBoolean(canPushCode),
},
});
},
......
......@@ -191,8 +191,10 @@ module TreeHelper
def vue_file_list_data(project, ref)
{
can_push_code: current_user&.can?(:push_code, project) && "true",
project_path: project.full_path,
project_short_path: project.path,
fork_path: current_user&.fork_of(project)&.full_path,
ref: ref,
escaped_ref: ActionDispatch::Journey::Router::Utils.escape_path(ref),
full_name: project.name_with_namespace
......
---
title: If a user does not have write access to repo, but a fork exists, the Web IDE
button should take them to the fork
merge_request: 36548
author:
type: added
......@@ -8532,6 +8532,9 @@ msgstr ""
msgid "Edit files in the editor and commit changes here"
msgstr ""
msgid "Edit fork in Web IDE"
msgstr ""
msgid "Edit group: %{group_name}"
msgstr ""
......
......@@ -56,7 +56,7 @@ module QA
element :new_file_option
end
view 'app/assets/javascripts/repository/index.js' do
view 'app/assets/javascripts/repository/components/web_ide_link.vue' do
element :web_ide_button
end
......
import WebIdeLink from '~/repository/components/web_ide_link.vue';
import { mount } from '@vue/test-utils';
describe('Web IDE link component', () => {
let wrapper;
function createComponent(props) {
wrapper = mount(WebIdeLink, {
propsData: { ...props },
mocks: {
$route: {
params: {},
},
},
});
}
afterEach(() => {
wrapper.destroy();
});
it('renders link to the Web IDE for a project if only projectPath is given', () => {
createComponent({ projectPath: 'gitlab-org/gitlab', refSha: 'master' });
expect(wrapper.attributes('href')).toBe('/-/ide/project/gitlab-org/gitlab/edit/master/-/');
expect(wrapper.text()).toBe('Web IDE');
});
it('renders link to the Web IDE for a project even if both projectPath and forkPath are given', () => {
createComponent({
projectPath: 'gitlab-org/gitlab',
refSha: 'master',
forkPath: 'my-namespace/gitlab',
});
expect(wrapper.attributes('href')).toBe('/-/ide/project/gitlab-org/gitlab/edit/master/-/');
expect(wrapper.text()).toBe('Web IDE');
});
it('renders link to the forked project if it exists and cannot write to the repo', () => {
createComponent({
projectPath: 'gitlab-org/gitlab',
refSha: 'master',
forkPath: 'my-namespace/gitlab',
canPushCode: false,
});
expect(wrapper.attributes('href')).toBe('/-/ide/project/my-namespace/gitlab/edit/master/-/');
expect(wrapper.text()).toBe('Edit fork in Web IDE');
});
});
......@@ -154,4 +154,58 @@ RSpec.describe TreeHelper do
expect(helper.commit_in_single_accessible_branch).to include(escaped_branch_name)
end
end
describe '#vue_file_list_data' do
before do
allow(helper).to receive(:current_user).and_return(nil)
end
it 'returns a list of attributes related to the project' do
expect(helper.vue_file_list_data(project, sha)).to include(
can_push_code: nil,
fork_path: nil,
escaped_ref: sha,
ref: sha,
project_path: project.full_path,
project_short_path: project.path,
full_name: project.name_with_namespace
)
end
context 'user does not have write access but a personal fork exists' do
include ProjectForksHelper
let_it_be(:user) { create(:user) }
let!(:forked_project) { create(:project, :repository, namespace: user.namespace) }
before do
project.add_guest(user)
fork_project(project, nil, target_project: forked_project)
allow(helper).to receive(:current_user).and_return(user)
end
it 'includes fork_path too' do
expect(helper.vue_file_list_data(project, sha)).to include(
fork_path: forked_project.full_path
)
end
end
context 'user has write access' do
let_it_be(:user) { create(:user) }
before do
project.add_developer(user)
allow(helper).to receive(:current_user).and_return(user)
end
it 'includes can_push_code: true' do
expect(helper.vue_file_list_data(project, sha)).to include(
can_push_code: "true"
)
end
end
end
end
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