summaryrefslogtreecommitdiff
path: root/app/helpers/tree_helper.rb
blob: 8693acad994bee290a0e5f92b4aa4dea00cf7043 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
module TreeHelper
  # Sorts a repository's tree so that folders are before files and renders
  # their corresponding partials
  #
  # contents - A Grit::Tree object for the current tree
  def render_tree(tree)
    # Render Folders before Files/Submodules
    folders, files, submodules = tree.trees, tree.blobs, tree.submodules

    tree = ""

    # Render folders if we have any
    tree << render(partial: 'projects/tree/tree_item', collection: folders,
                   locals: { type: 'folder' }) if folders.present?

    # Render files if we have any
    tree << render(partial: 'projects/tree/blob_item', collection: files,
                   locals: { type: 'file' }) if files.present?

    # Render submodules if we have any
    tree << render(partial: 'projects/tree/submodule_item',
                   collection: submodules) if submodules.present?

    tree.html_safe
  end

  def render_readme(readme)
    if gitlab_markdown?(readme.name)
      preserve(markdown(readme.data))
    elsif markup?(readme.name)
      render_markup(readme.name, readme.data)
    else
      simple_format(readme.data)
    end
  end

  # Return an image icon depending on the file type
  #
  # type - String type of the tree item; either 'folder' or 'file'
  def tree_icon(type)
    icon_class = if type == 'folder'
                   'fa fa-folder'
                 else
                   'fa fa-file-o'
                 end

    content_tag :i, nil, class: icon_class
  end

  def tree_hex_class(content)
    "file_#{hexdigest(content.name)}"
  end

  # Simple shortcut to File.join
  def tree_join(*args)
    File.join(*args)
  end

  def allowed_tree_edit?(project = nil, ref = nil)
    project ||= @project
    ref ||= @ref
    return false unless project.repository.branch_names.include?(ref)

    if project.protected_branch? ref
      can?(current_user, :push_code_to_protected_branches, project)
    else
      can?(current_user, :push_code, project)
    end
  end

  def edit_blob_link(project, ref, path, options = {})
    blob =
      begin
        project.repository.blob_at(ref, path)
      rescue
        nil
      end

    if blob && blob.text?
      text = 'Edit'
      after = options[:after] || ''
      from_mr = options[:from_merge_request_id]
      link_opts = {}
      link_opts[:from_merge_request_id] = from_mr if from_mr
      cls = 'btn btn-small'
      if allowed_tree_edit?(project, ref)
        link_to text, project_edit_tree_path(project, tree_join(ref, path),
                                             link_opts), class: cls
      else
        content_tag :span, text, class: cls + ' disabled'
      end + after.html_safe
    else
      ''
    end
  end

  def tree_breadcrumbs(tree, max_links = 2)
    if @path.present?
      part_path = ""
      parts = @path.split('/')

      yield('..', nil) if parts.count > max_links

      parts.each do |part|
        part_path = File.join(part_path, part) unless part_path.empty?
        part_path = part if part_path.empty?

        next unless parts.last(2).include?(part) if parts.count > max_links
        yield(part, tree_join(@ref, part_path))
      end
    end
  end

  def up_dir_path(tree)
    file = File.join(@path, "..")
    tree_join(@ref, file)
  end

  def leave_edit_message
    "Leave edit mode?\nAll unsaved changes will be lost."
  end

  def editing_preview_title(filename)
    if Gitlab::MarkdownHelper.previewable?(filename)
      'Preview'
    else
      'Diff'
    end
  end
end