summaryrefslogtreecommitdiff
path: root/app/helpers
diff options
context:
space:
mode:
authorDmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>2015-12-24 12:24:57 +0000
committerDmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>2015-12-24 12:24:57 +0000
commit76b7e24f855c99814fc09e286fb061b7aea3954c (patch)
tree498970380a63da563d29b24078bf293ce66a7658 /app/helpers
parent84e75ebd4cd463cf5e0dea9c46e7bcef50b98f50 (diff)
parentcfa716ebe0f149fd3f152d90c4dcf32ea450b486 (diff)
downloadgitlab-ce-76b7e24f855c99814fc09e286fb061b7aea3954c.tar.gz
Merge branch 'edit-on-fork' into 'master'
Automatically fork a project when not allowed to edit a file. Fixes #3215. To do: - [ ] Add tests ----- ## "Edit" button on file in a project the user does NOT have write access to ![edit_file](/uploads/7602157420768aef483a6586bba2d164/edit_file.png) ## Clicking will automatically create a fork ![during_fork](/uploads/32f4f5dff9f24ea99522000b0bf881c5/during_fork.png) ## When the fork has been created, the user is returned to the edit page on the original project with a notice ![edit_notice](/uploads/94ed1319404370ff1e9c0d672fb41e03/edit_notice.png) ## The user cannot change the target branch and is informed that editing will start an MR ![edit_footer](/uploads/4da68d4795c7177e575b7c434d16eeae/edit_footer.png) ## Hitting "Commit changes" will commit and start an MR from my fork to the origin project ![Screen_Shot_2015-12-17_at_23.38.08](/uploads/d777a4db6f38a5a1be84031694465bc1/Screen_Shot_2015-12-17_at_23.38.08.png) ----- ## "Create file, "Upload file" and "New directory" buttons in a project the user does NOT have write access to ![new_directory](/uploads/72f556248f30d6652523bbb4be01b3e0/new_directory.png) ## Clicking any of these options will automatically create a fork ![during_fork](/uploads/32f4f5dff9f24ea99522000b0bf881c5/during_fork.png) ## When the fork has been created, the user is returned to the tree page on the original project with a notice ![new_directory_notice](/uploads/a1a3e11308ae0e8f0913fae6813a37ed/new_directory_notice.png) ## Clicking "New directory" again will show the modal. The user cannot change the target branch and is informed that editing will start an MR ![new_dir](/uploads/99ca8cbfb2f70603e352b3fdf67b6281/new_dir.png) ## Hitting "Create directory" will commit and start an MR from my fork to the origin project ![Screen_Shot_2015-12-17_at_23.39.19](/uploads/3713d0235abf831361b803a6198c5bc1/Screen_Shot_2015-12-17_at_23.39.19.png) cc @dzaporozhets @skyruler See merge request !2145
Diffstat (limited to 'app/helpers')
-rw-r--r--app/helpers/blob_helper.rb102
-rw-r--r--app/helpers/tree_helper.rb41
2 files changed, 113 insertions, 30 deletions
diff --git a/app/helpers/blob_helper.rb b/app/helpers/blob_helper.rb
index 68e5d5be600..d31d4cde08f 100644
--- a/app/helpers/blob_helper.rb
+++ b/app/helpers/blob_helper.rb
@@ -22,32 +22,90 @@ module BlobHelper
%w(credits changelog news copying copyright license authors)
end
- def edit_blob_link(project, ref, path, options = {})
- blob =
- begin
- project.repository.blob_at(ref, path)
- rescue
- nil
- end
-
- return unless blob && blob.text? && blob_editable?(blob)
-
- text = 'Edit'
- after = options[:after] || ''
+ def edit_blob_link(project = @project, ref = @ref, path = @path, options = {})
+ return unless current_user
+
+ blob = project.repository.blob_at(ref, path) rescue nil
+
+ return unless blob && blob_text_viewable?(blob)
+
from_mr = options[:from_merge_request_id]
link_opts = {}
link_opts[:from_merge_request_id] = from_mr if from_mr
- cls = 'btn btn-small'
- link_to(text,
- namespace_project_edit_blob_path(project.namespace, project,
- tree_join(ref, path),
- link_opts),
- class: cls
- ) + after.html_safe
+
+ edit_path = namespace_project_edit_blob_path(project.namespace, project,
+ tree_join(ref, path),
+ link_opts)
+
+ if !on_top_of_branch?
+ button_tag "Edit", class: "btn btn-default disabled has_tooltip", title: "You can only edit files when you are on a branch", data: { container: 'body' }
+ elsif can_edit_blob?(blob)
+ link_to "Edit", edit_path, class: 'btn btn-small'
+ elsif can?(current_user, :fork_project, project)
+ continue_params = {
+ to: edit_path,
+ notice: edit_in_new_fork_notice,
+ notice_now: edit_in_new_fork_notice_now
+ }
+ fork_path = namespace_project_fork_path(project.namespace, project, namespace_key: current_user.namespace.id,
+ continue: continue_params)
+
+ link_to "Edit", fork_path, class: 'btn btn-small', method: :post
+ end
+ end
+
+ def modify_file_link(project = @project, ref = @ref, path = @path, label:, action:, btn_class:, modal_type:)
+ return unless current_user
+
+ blob = project.repository.blob_at(ref, path) rescue nil
+
+ return unless blob
+
+ if !on_top_of_branch?
+ button_tag label, class: "btn btn-#{btn_class} disabled has_tooltip", title: "You can only #{action} files when you are on a branch", data: { container: 'body' }
+ elsif blob.lfs_pointer?
+ button_tag label, class: "btn btn-#{btn_class} disabled has_tooltip", title: "It is not possible to #{action} files that are stored in LFS using the web interface", data: { container: 'body' }
+ elsif can_edit_blob?(blob)
+ button_tag label, class: "btn btn-#{btn_class}", 'data-target' => "#modal-#{modal_type}-blob", 'data-toggle' => 'modal'
+ elsif can?(current_user, :fork_project, project)
+ continue_params = {
+ to: request.fullpath,
+ notice: edit_in_new_fork_notice + " Try to #{action} this file again.",
+ notice_now: edit_in_new_fork_notice_now
+ }
+ fork_path = namespace_project_fork_path(project.namespace, project, namespace_key: current_user.namespace.id,
+ continue: continue_params)
+
+ link_to label, fork_path, class: "btn btn-#{btn_class}", method: :post
+ end
+ end
+
+ def replace_blob_link(project = @project, ref = @ref, path = @path)
+ modify_file_link(
+ project,
+ ref,
+ path,
+ label: "Replace",
+ action: "replace",
+ btn_class: "default",
+ modal_type: "upload"
+ )
+ end
+
+ def delete_blob_link(project = @project, ref = @ref, path = @path)
+ modify_file_link(
+ project,
+ ref,
+ path,
+ label: "Delete",
+ action: "delete",
+ btn_class: "remove",
+ modal_type: "remove"
+ )
end
- def blob_editable?(blob, project = @project, ref = @ref)
- !blob.lfs_pointer? && allowed_tree_edit?(project, ref)
+ def can_edit_blob?(blob, project = @project, ref = @ref)
+ !blob.lfs_pointer? && can_edit_tree?(project, ref)
end
def leave_edit_message
@@ -70,7 +128,7 @@ module BlobHelper
icon("#{file_type_icon_class('file', mode, name)} fw")
end
- def blob_viewable?(blob)
+ def blob_text_viewable?(blob)
blob && blob.text? && !blob.lfs_pointer?
end
diff --git a/app/helpers/tree_helper.rb b/app/helpers/tree_helper.rb
index f448dd0ab61..2ad7c80dae0 100644
--- a/app/helpers/tree_helper.rb
+++ b/app/helpers/tree_helper.rb
@@ -50,24 +50,49 @@ module TreeHelper
project.repository.branch_names.include?(ref)
end
- def allowed_tree_edit?(project = nil, ref = nil)
+ def can_edit_tree?(project = nil, ref = nil)
project ||= @project
ref ||= @ref
+
return false unless on_top_of_branch?(project, ref)
- can?(current_user, :push_code, project)
+ can?(current_user, :push_code, project) ||
+ (current_user && current_user.already_forked?(project))
end
def tree_edit_branch(project = @project, ref = @ref)
- if allowed_tree_edit?(project, ref)
- if can_push_branch?(project, ref)
- ref
- else
- project.repository.next_patch_branch
- end
+ return unless can_edit_tree?(project, ref)
+
+ if can_push_branch?(project, ref)
+ ref
+ else
+ project = tree_edit_project(project)
+ project.repository.next_patch_branch
+ end
+ end
+
+ def tree_edit_project(project = @project)
+ if can?(current_user, :push_code, project)
+ project
+ elsif current_user && current_user.already_forked?(project)
+ current_user.fork_of(project)
end
end
+ def edit_in_new_fork_notice_now
+ "You're not allowed to make changes to this project directly." +
+ " A fork of this project is being created that you can make changes in, so you can submit a merge request."
+ end
+
+ def edit_in_new_fork_notice
+ "You're not allowed to make changes to this project directly." +
+ " A fork of this project has been created that you can make changes in, so you can submit a merge request."
+ end
+
+ def commit_in_fork_help
+ "A new branch will be created in your fork and a new merge request will be started."
+ end
+
def tree_breadcrumbs(tree, max_links = 2)
if @path.present?
part_path = ""