Commit 8a008f80 authored by Himanshu Kapoor's avatar Himanshu Kapoor Committed by Stan Hu

Add a link to WebIDE on project page in all cases

Add a link to the WebIDE on project page in case the user doesn't have
write access to the repo. Clicking the link will actually create a fork
first and then redirect to the WebIDE in the forked repo.

A confirm modal is shown before forking the project.

The button would not appear if the user cannot create a fork or an MR
in the fork.
parent 5d760ac8
......@@ -356,6 +356,7 @@ linters:
- 'app/views/shared/_auto_devops_implicitly_enabled_banner.html.haml'
- 'app/views/shared/_commit_message_container.html.haml'
- 'app/views/shared/_confirm_modal.html.haml'
- 'app/views/shared/_confirm_fork_modal.html.haml'
- 'app/views/shared/_delete_label_modal.html.haml'
- 'app/views/shared/_group_form.html.haml'
- 'app/views/shared/_group_tips.html.haml'
......
......@@ -32,6 +32,14 @@ module BlobHelper
File.join(segments)
end
def ide_fork_and_edit_path(project = @project, ref = @ref, path = @path, options = {})
if current_user
project_forks_path(project,
namespace_key: current_user&.namespace&.id,
continue: edit_blob_fork_params(ide_edit_path(project, ref, path)))
end
end
def encode_ide_path(path)
url_encode(path).gsub('%2F', '/')
end
......
......@@ -41,7 +41,7 @@
%li
= link_to '#modal-create-new-dir', { 'data-target' => '#modal-create-new-dir', 'data-toggle' => 'modal' } do
#{ _('New directory') }
- elsif can?(current_user, :fork_project, @project) && can?(current_user, :create_merge_request_in, @project)
- elsif can_create_mr_from_fork
%li
- continue_params = { to: project_new_blob_path(@project, @id),
notice: edit_in_new_fork_notice,
......@@ -81,10 +81,15 @@
= render 'projects/find_file_link'
- if can_collaborate
- if can_create_mr_from_fork
= succeed " " do
= link_to ide_edit_path(@project, @ref, @path), class: 'btn btn-default qa-web-ide-button' do
= _('Web IDE')
- if can_collaborate || current_user&.already_forked?(@project)
= link_to ide_edit_path(@project, @ref, @path), class: 'btn btn-default qa-web-ide-button' do
= _('Web IDE')
- else
= link_to '#modal-confirm-fork', class: 'btn btn-default qa-web-ide-button', data: { target: '#modal-confirm-fork', toggle: 'modal'} do
= _('Web IDE')
= render 'shared/confirm_fork_modal', fork_path: ide_fork_and_edit_path(@project, @ref, @path)
- if show_xcode_link?(@project)
.project-action-button.project-xcode.inline
......
#modal-confirm-fork.modal.qa-confirm-fork-modal
.modal-dialog
.modal-content
.modal-header
%h3.page-title= _('Fork project?')
%button.close{ type: "button", "data-dismiss": "modal", "aria-label" => _('Close') }
%span{ "aria-hidden": true } ×
.modal-body.p-3
%p= sprintf(_("You're not allowed to %{tag_start}edit%{tag_end} files in this project directly. Please fork this project, make your changes there, and submit a merge request."), { tag_start: '', tag_end: ''})
.modal-footer
= link_to _('Cancel'), '#', class: "btn btn-cancel", "data-dismiss" => "modal"
= link_to _('Fork project'), fork_path, class: 'btn btn-success', method: :post
---
title: Web IDE button should fork and open forked project when selected from read-only
project
merge_request: 17672
author:
type: added
......@@ -7247,6 +7247,9 @@ msgstr ""
msgid "Fork project"
msgstr ""
msgid "Fork project?"
msgstr ""
msgid "ForkedFromProjectPath|Forked from"
msgstr ""
......
......@@ -270,4 +270,32 @@ describe BlobHelper do
end
end
end
describe '#ide_fork_and_edit_path' do
let(:project) { create(:project) }
let(:current_user) { create(:user) }
let(:can_push_code) { true }
before do
allow(helper).to receive(:current_user).and_return(current_user)
allow(helper).to receive(:can?).and_return(can_push_code)
end
it 'returns path to fork the repo with a redirect param to the full IDE path' do
uri = URI(helper.ide_fork_and_edit_path(project, "master", ""))
params = CGI.unescape(uri.query)
expect(uri.path).to eq("/#{project.namespace.path}/#{project.path}/-/forks")
expect(params).to include("continue[to]=/-/ide/project/#{project.namespace.path}/#{project.path}/edit/master")
expect(params).to include("namespace_key=#{current_user.namespace.id}")
end
context 'when user is not logged in' do
let(:current_user) { nil }
it 'returns nil' do
expect(helper.ide_fork_and_edit_path(project, "master", "")).to be_nil
end
end
end
end
# frozen_string_literal: true
require 'spec_helper'
describe 'projects/tree/_tree_header' do
let(:project) { create(:project, :repository) }
let(:current_user) { create(:user) }
let(:repository) { project.repository }
before do
assign(:project, project)
assign(:repository, repository)
assign(:id, File.join('master', ''))
assign(:ref, 'master')
allow(view).to receive(:current_user).and_return(current_user)
allow(view).to receive(:can_collaborate_with_project?) { true }
end
it 'does not render the WebIDE button when user cannot create fork or cannot open MR' do
allow(view).to receive(:can?) { false }
render
expect(rendered).not_to have_link('Web IDE')
end
it 'renders the WebIDE button when user can create fork and can open MR in project' do
allow(view).to receive(:can?) { true }
render
expect(rendered).to have_link('Web IDE')
end
it 'opens a popup confirming a fork if the user can create fork/MR but cannot collaborate with the project' do
allow(view).to receive(:can?) { true }
allow(view).to receive(:can_collaborate_with_project?) { false }
render
expect(rendered).to have_link('Web IDE', href: '#modal-confirm-fork')
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