diff options
Diffstat (limited to 'app/views/projects')
135 files changed, 2896 insertions, 1 deletions
diff --git a/app/views/projects/blame/_head.html.haml b/app/views/projects/blame/_head.html.haml new file mode 100644 index 00000000000..3a883829562 --- /dev/null +++ b/app/views/projects/blame/_head.html.haml @@ -0,0 +1,2 @@ +%div.tree-ref-holder + = render 'shared/ref_switcher', destination: 'tree', path: params[:path] diff --git a/app/views/projects/blame/show.html.haml b/app/views/projects/blame/show.html.haml new file mode 100644 index 00000000000..3f68db659fc --- /dev/null +++ b/app/views/projects/blame/show.html.haml @@ -0,0 +1,49 @@ += render "head" + +#tree-holder.tree-holder + %ul.breadcrumb + %li + %i.icon-angle-right + = link_to project_tree_path(@project, @ref) do + = @project.name + - tree_breadcrumbs(@tree, 6) do |link| + \/ + %li= link + .clear + + .file_holder + .file_title + %i.icon-file + %span.file_name + = @blob.name + %small= number_to_human_size @blob.size + %span.options= render "projects/blob/actions" + .file_content.blame + %table + - current_line = 1 + - @blame.each do |commit, lines| + - commit = Commit.new(commit) + %tr + %td.blame-commit + %span.commit + = link_to commit.short_id(8), project_commit_path(@project, commit), class: "commit_short_id" + + = commit_author_link(commit, avatar: true, size: 16) + + = link_to_gfm truncate(commit.title, length: 20), project_commit_path(@project, commit.id), class: "row_title" + %td.lines.blame-numbers + %pre + - if lines.empty? + = current_line + - current_line += 1 + - else + - lines.each do |line| + = current_line + \ + - current_line += 1 + %td.lines + %pre + :erb + <% lines.each do |line| %> + <%= line %> + <% end %> diff --git a/app/views/projects/blob/_actions.html.haml b/app/views/projects/blob/_actions.html.haml new file mode 100644 index 00000000000..456c7432c94 --- /dev/null +++ b/app/views/projects/blob/_actions.html.haml @@ -0,0 +1,12 @@ +.btn-group.tree-btn-group + -# only show edit link for text files + - if @blob.text? + = link_to "edit", project_edit_tree_path(@project, @id), class: "btn btn-tiny", disabled: !allowed_tree_edit? + = link_to "raw", project_raw_path(@project, @id), class: "btn btn-tiny", target: "_blank" + -# only show normal/blame view links for text files + - if @blob.text? + - if current_page? project_blame_path(@project, @id) + = link_to "normal view", project_blob_path(@project, @id), class: "btn btn-tiny" + - else + = link_to "blame", project_blame_path(@project, @id), class: "btn btn-tiny" unless @blob.empty? + = link_to "history", project_commits_path(@project, @id), class: "btn btn-tiny" diff --git a/app/views/projects/blob/_blob.html.haml b/app/views/projects/blob/_blob.html.haml new file mode 100644 index 00000000000..68d6c06065c --- /dev/null +++ b/app/views/projects/blob/_blob.html.haml @@ -0,0 +1,32 @@ +%ul.breadcrumb + %li + %i.icon-angle-right + = link_to project_tree_path(@project, @ref) do + = @project.path + - tree_breadcrumbs(@tree, 6) do |title, path| + \/ + %li + - if path + - if path.end_with?(@path) + = link_to project_blob_path(@project, path) do + %span.cblue + = truncate(title, length: 40) + - else + = link_to truncate(title, length: 40), project_tree_path(@project, path) + - else + = link_to title, '#' + +%div#tree-content-holder.tree-content-holder + .file_holder + .file_title + %i.icon-file + %span.file_name + = blob.name + %small= number_to_human_size blob.size + %span.options= render "actions" + - if blob.text? + = render "text", blob: blob + - elsif blob.image? + = render "image", blob: blob + - else + = render "download", blob: blob diff --git a/app/views/projects/blob/_download.html.haml b/app/views/projects/blob/_download.html.haml new file mode 100644 index 00000000000..864c209db76 --- /dev/null +++ b/app/views/projects/blob/_download.html.haml @@ -0,0 +1,8 @@ +.file_content.blob_file + %center + = link_to project_blob_path(@project, @id) do + %div.padded + %h4 + %i.icon-download-alt + %br + Download (#{number_to_human_size blob.size}) diff --git a/app/views/projects/blob/_image.html.haml b/app/views/projects/blob/_image.html.haml new file mode 100644 index 00000000000..7b23f0c810c --- /dev/null +++ b/app/views/projects/blob/_image.html.haml @@ -0,0 +1,2 @@ +.file_content.image_file + %img{ src: "data:#{blob.mime_type};base64,#{Base64.encode64(blob.data)}"} diff --git a/app/views/projects/blob/_text.html.haml b/app/views/projects/blob/_text.html.haml new file mode 100644 index 00000000000..122e275219d --- /dev/null +++ b/app/views/projects/blob/_text.html.haml @@ -0,0 +1,14 @@ +- if gitlab_markdown?(blob.name) + .file_content.wiki + = preserve do + = markdown(blob.data) +- elsif markup?(blob.name) + .file_content.wiki + = raw GitHub::Markup.render(blob.name, blob.data) +- else + .file_content.code + - unless blob.empty? + %div{class: user_color_scheme_class} + = raw blob.colorize(formatter: :gitlab) + - else + %p.nothing_here_message Empty file diff --git a/app/views/projects/blob/show.html.haml b/app/views/projects/blob/show.html.haml new file mode 100644 index 00000000000..d96595bc7f0 --- /dev/null +++ b/app/views/projects/blob/show.html.haml @@ -0,0 +1,4 @@ +%div.tree-ref-holder + = render 'shared/ref_switcher', destination: 'blob', path: @path +%div#tree-holder.tree-holder + = render 'blob', blob: @blob diff --git a/app/views/projects/commit/_commit_box.html.haml b/app/views/projects/commit/_commit_box.html.haml new file mode 100644 index 00000000000..646791773b2 --- /dev/null +++ b/app/views/projects/commit/_commit_box.html.haml @@ -0,0 +1,50 @@ +.ui-box.ui-box-show + .ui-box-head + .pull-right + - if @notes_count > 0 + %span.btn.disabled.grouped + %i.icon-comment + = @notes_count + .left.btn-group + %a.btn.grouped.dropdown-toggle{ data: {toggle: :dropdown} } + %i.icon-download-alt + Download as + %span.caret + %ul.dropdown-menu + %li= link_to "Email Patches", project_commit_path(@project, @commit, format: :patch) + %li= link_to "Plain Diff", project_commit_path(@project, @commit, format: :diff) + = link_to project_tree_path(@project, @commit), class: "btn btn-primary grouped" do + %span Browse Code » + %h3.commit-title.page_title + = gfm escape_once(@commit.title) + - if @commit.description.present? + %pre.commit-description + = gfm escape_once(@commit.description) + .ui-box-body + .row + .span5 + .author + = commit_author_link(@commit, avatar: true, size: 32) + authored + %time{title: @commit.authored_date.stamp("Aug 21, 2011 9:23pm")} + #{time_ago_in_words(@commit.authored_date)} ago + - if @commit.different_committer? + .committer + → + = commit_committer_link(@commit) + committed + %time{title: @commit.committed_date.stamp("Aug 21, 2011 9:23pm")} + #{time_ago_in_words(@commit.committed_date)} ago + .span6.pull-right + .pull-right + .sha-block + %span.cgray commit + %span.label_commit= @commit.id + .clearfix + .pull-right + .sha-block + %span.cgray= pluralize(@commit.parents.count, "parent") + - @commit.parents.each do |parent| + = link_to parent.id[0...10], project_commit_path(@project, parent) + + diff --git a/app/views/projects/commit/huge_commit.html.haml b/app/views/projects/commit/huge_commit.html.haml new file mode 100644 index 00000000000..5d447d6cee5 --- /dev/null +++ b/app/views/projects/commit/huge_commit.html.haml @@ -0,0 +1,3 @@ += render "commit/commit_box" +.alert.alert-error + %h4 Commit diffs are too big to be displayed diff --git a/app/views/projects/commit/show.html.haml b/app/views/projects/commit/show.html.haml new file mode 100644 index 00000000000..603406202ca --- /dev/null +++ b/app/views/projects/commit/show.html.haml @@ -0,0 +1,11 @@ += render "commit_box" + +- unless @commit.has_zero_stats? + %p.pull-right.cgray + This commit has + %span.cgreen #{@commit.stats.additions} additions + and + %span.cred #{@commit.stats.deletions} deletions + += render "projects/commits/diffs", diffs: @commit.diffs += render "projects/notes/notes_with_form" diff --git a/app/views/projects/commits/_commit.html.haml b/app/views/projects/commits/_commit.html.haml new file mode 100644 index 00000000000..eba6c206c46 --- /dev/null +++ b/app/views/projects/commits/_commit.html.haml @@ -0,0 +1,21 @@ +%li.commit + .browse_code_link_holder + %p + %strong= link_to "Browse Code »", project_tree_path(@project, commit), class: "right" + %p + = link_to commit.short_id(8), project_commit_path(@project, commit), class: "commit_short_id" + = commit_author_link(commit, avatar: true, size: 24) + + = link_to_gfm truncate(commit.title, length: 70), project_commit_path(@project, commit.id), class: "row_title" + + %time.committed_ago{ datetime: commit.committed_date, title: commit.committed_date.stamp("Aug 21, 2011 9:23pm") } + = time_ago_in_words(commit.committed_date) + ago + + + %span.notes_count + - notes = @project.notes.for_commit_id(commit.id) + - if notes.any? + %span.badge.badge-info + %i.icon-comment + = notes.count diff --git a/app/views/projects/commits/_commits.html.haml b/app/views/projects/commits/_commits.html.haml new file mode 100644 index 00000000000..933780e4534 --- /dev/null +++ b/app/views/projects/commits/_commits.html.haml @@ -0,0 +1,9 @@ +- @commits.group_by { |c| c.committed_date.to_date }.sort.reverse.each do |day, commits| + %div.ui-box + %h5.title + %i.icon-calendar + %span= day.stamp("28 Aug, 2010") + + .pull-right + %small= pluralize(commits.count, 'commit') + %ul.well-list= render commits diff --git a/app/views/projects/commits/_diff_head.html.haml b/app/views/projects/commits/_diff_head.html.haml new file mode 100644 index 00000000000..5aa542287fe --- /dev/null +++ b/app/views/projects/commits/_diff_head.html.haml @@ -0,0 +1,26 @@ +%ul.bordered-list + - diffs.each_with_index do |diff, i| + %li + - if diff.deleted_file + %span.deleted-file + %a{href: "#diff-#{i}"} + %i.icon-minus + = diff.old_path + - elsif diff.renamed_file + %span.renamed-file + %a{href: "#diff-#{i}"} + %i.icon-minus + = diff.old_path + = "->" + = diff.new_path + - elsif diff.new_file + %span.new-file + %a{href: "#diff-#{i}"} + %i.icon-plus + = diff.new_path + - else + %span.edit-file + %a{href: "#diff-#{i}"} + %i.icon-adjust + = diff.new_path + diff --git a/app/views/projects/commits/_diffs.html.haml b/app/views/projects/commits/_diffs.html.haml new file mode 100644 index 00000000000..8e3cbff8f3e --- /dev/null +++ b/app/views/projects/commits/_diffs.html.haml @@ -0,0 +1,49 @@ +- if @suppress_diff + .alert.alert-block + %p + %strong Warning! Large commit with more than #{Commit::DIFF_SAFE_SIZE} files changed. + %p To prevent performance issue we rejected diff information. + %p + But if you still want to see diff + = link_to "click this link", project_commit_path(@project, @commit, force_show_diff: true), class: "underlined_link" + +%p.cgray + Showing #{pluralize(diffs.count, "changed file")} +.file-stats + = render "projects/commits/diff_head", diffs: diffs + +.files + - unless @suppress_diff + - diffs.each_with_index do |diff, i| + - next if diff.diff.empty? + - file = Gitlab::Git::Blob.new(@repository, @commit.id, @ref, diff.new_path) + - file = Gitlab::Git::Blob.new(@repository, @commit.parent_id, @ref, diff.old_path) unless file.exists? + - next unless file.exists? + .file{id: "diff-#{i}"} + .header + - if diff.deleted_file + %span= diff.old_path + + - if @commit.parent_ids.present? + = link_to project_blob_path(@project, tree_join(@commit.parent_id, diff.new_path)), {:class => 'btn btn-tiny pull-right view-file'} do + View file @ + %span.commit-short-id= @commit.short_id(6) + - else + %span= diff.new_path + - if diff.a_mode && diff.b_mode && diff.a_mode != diff.b_mode + %span.file-mode= "#{diff.a_mode} → #{diff.b_mode}" + + = link_to project_blob_path(@project, tree_join(@commit.id, diff.new_path)), {:class => 'btn btn-tiny pull-right view-file'} do + View file @ + %span.commit-short-id= @commit.short_id(6) + + .content + -# Skipp all non non-supported blobs + - next unless file.respond_to?('text?') + - if file.text? + = render "projects/commits/text_file", diff: diff, index: i + - elsif file.image? + - old_file = Gitlab::Git::Blob.new(@repository, @commit.parent_id, @ref, diff.old_path) if @commit.parent_id + = render "projects/commits/image", diff: diff, old_file: old_file, file: file, index: i + - else + %p.nothing_here_message No preview for this file type diff --git a/app/views/projects/commits/_head.html.haml b/app/views/projects/commits/_head.html.haml new file mode 100644 index 00000000000..20b9195c4c3 --- /dev/null +++ b/app/views/projects/commits/_head.html.haml @@ -0,0 +1,27 @@ +%ul.nav.nav-tabs + %li= render partial: 'shared/ref_switcher', locals: {destination: 'commits'} + + = nav_link(controller: [:commit, :commits]) do + = link_to 'Commits', project_commits_path(@project, @repository.root_ref) + = nav_link(controller: :compare) do + = link_to 'Compare', project_compare_index_path(@project) + + = nav_link(html_options: {class: branches_tab_class}) do + = link_to project_repository_path(@project) do + Branches + %span.badge= @repository.branches.length + + = nav_link(controller: :repositories, action: :tags) do + = link_to tags_project_repository_path(@project) do + Tags + %span.badge= @repository.tags.length + + = nav_link(controller: :repositories, action: :stats) do + = link_to stats_project_repository_path(@project) do + Stats + + + - if current_controller?(:commits) && current_user.private_token + %li.pull-right + = link_to project_commits_path(@project, @ref, {format: :atom, private_token: current_user.private_token}), title: "Feed" do + %i.icon-rss diff --git a/app/views/projects/commits/_image.html.haml b/app/views/projects/commits/_image.html.haml new file mode 100644 index 00000000000..db02fa333b9 --- /dev/null +++ b/app/views/projects/commits/_image.html.haml @@ -0,0 +1,63 @@ +- if diff.renamed_file || diff.new_file || diff.deleted_file + .image + %span.wrap + .frame{class: image_diff_class(diff)} + %img{src: "data:#{file.mime_type};base64,#{Base64.encode64(file.data)}"} + %p.image-info= "#{number_to_human_size file.size}" +- else + .image + %div.two-up.view + %span.wrap + .frame.deleted + %a{href: project_tree_path(@project, tree_join(@commit.id, diff.old_path))} + %img{src: "data:#{old_file.mime_type};base64,#{Base64.encode64(old_file.data)}"} + %p.image-info.hide + %span.meta-filesize= "#{number_to_human_size old_file.size}" + | + %b W: + %span.meta-width + | + %b H: + %span.meta-height + %span.wrap + .frame.added + %a{href: project_tree_path(@project, tree_join(@commit.id, diff.new_path))} + %img{src: "data:#{file.mime_type};base64,#{Base64.encode64(file.data)}"} + %p.image-info.hide + %span.meta-filesize= "#{number_to_human_size file.size}" + | + %b W: + %span.meta-width + | + %b H: + %span.meta-height + + %div.swipe.view.hide + .swipe-frame + .frame.deleted + %img{src: "data:#{old_file.mime_type};base64,#{Base64.encode64(old_file.data)}"} + .swipe-wrap + .frame.added + %img{src: "data:#{file.mime_type};base64,#{Base64.encode64(file.data)}"} + %span.swipe-bar + %span.top-handle + %span.bottom-handle + + %div.onion-skin.view.hide + .onion-skin-frame + .frame.deleted + %img{src: "data:#{old_file.mime_type};base64,#{Base64.encode64(old_file.data)}"} + .frame.added + %img{src: "data:#{file.mime_type};base64,#{Base64.encode64(file.data)}"} + .controls + .transparent + .drag-track + .dragger{:style => "left: 0px;"} + .opaque + + + .view-modes.hide + %ul.view-modes-menu + %li.two-up{data: {mode: 'two-up'}} 2-up + %li.swipe{data: {mode: 'swipe'}} Swipe + %li.onion-skin{data: {mode: 'onion-skin'}} Onion skin
\ No newline at end of file diff --git a/app/views/projects/commits/_text_file.html.haml b/app/views/projects/commits/_text_file.html.haml new file mode 100644 index 00000000000..bfc3180a84c --- /dev/null +++ b/app/views/projects/commits/_text_file.html.haml @@ -0,0 +1,23 @@ +- too_big = diff.diff.lines.count > 1000 +- if too_big + %a.supp_diff_link Diff suppressed. Click to show + +%table.text-file{class: "#{'hide' if too_big}"} + - each_diff_line(diff, index) do |line, type, line_code, line_new, line_old| + %tr.line_holder{ id: line_code, class: "#{type}" } + - if type == "match" + %td.old_line= "..." + %td.new_line= "..." + %td.line_content.matched= line + - else + %td.old_line + = link_to raw(type == "new" ? " " : line_old), "##{line_code}", id: line_code + - if @comments_allowed + = render "projects/notes/diff_note_link", line_code: line_code + %td.new_line= link_to raw(type == "old" ? " " : line_new) , "##{line_code}", id: line_code + %td.line_content{class: "noteable_line #{type} #{line_code}", "line_code" => line_code}= raw diff_line_content(line) + + - if @reply_allowed + - comments = @line_notes.select { |n| n.line_code == line_code }.sort_by(&:created_at) + - unless comments.empty? + = render "projects/notes/diff_notes_with_reply", notes: comments diff --git a/app/views/projects/commits/show.atom.builder b/app/views/projects/commits/show.atom.builder new file mode 100644 index 00000000000..46f9838e84a --- /dev/null +++ b/app/views/projects/commits/show.atom.builder @@ -0,0 +1,23 @@ +xml.instruct! +xml.feed "xmlns" => "http://www.w3.org/2005/Atom", "xmlns:media" => "http://search.yahoo.com/mrss/" do + xml.title "Recent commits to #{@project.name}:#{@ref}" + xml.link :href => project_commits_url(@project, @ref, format: :atom), :rel => "self", :type => "application/atom+xml" + xml.link :href => project_commits_url(@project, @ref), :rel => "alternate", :type => "text/html" + xml.id project_commits_url(@project) + xml.updated @commits.first.committed_date.strftime("%Y-%m-%dT%H:%M:%SZ") if @commits.any? + + @commits.each do |commit| + xml.entry do + xml.id project_commit_url(@project, :id => commit.id) + xml.link :href => project_commit_url(@project, :id => commit.id) + xml.title truncate(commit.title, :length => 80) + xml.updated commit.committed_date.strftime("%Y-%m-%dT%H:%M:%SZ") + xml.media :thumbnail, :width => "40", :height => "40", :url => gravatar_icon(commit.author_email) + xml.author do |author| + xml.name commit.author_name + xml.email commit.author_email + end + xml.summary gfm(commit.description) + end + end +end diff --git a/app/views/projects/commits/show.html.haml b/app/views/projects/commits/show.html.haml new file mode 100644 index 00000000000..cb9ef820d3e --- /dev/null +++ b/app/views/projects/commits/show.html.haml @@ -0,0 +1,15 @@ += render "head" + +- if @path.present? + %ul.breadcrumb + = commits_breadcrumbs + +%div{id: dom_id(@project)} + #commits-list= render "commits" +.clear +.loading{ style: "display:none;"} + +- if @commits.count == @limit + :javascript + CommitsList.init("#{@ref}", #{@limit}); + diff --git a/app/views/projects/commits/show.js.haml b/app/views/projects/commits/show.js.haml new file mode 100644 index 00000000000..797bc14cc1b --- /dev/null +++ b/app/views/projects/commits/show.js.haml @@ -0,0 +1,3 @@ +:plain + CommitsList.append(#{@commits.count}, "#{escape_javascript(render(partial: 'commits/commits'))}"); + diff --git a/app/views/projects/compare/_form.html.haml b/app/views/projects/compare/_form.html.haml new file mode 100644 index 00000000000..ccdd0fc98eb --- /dev/null +++ b/app/views/projects/compare/_form.html.haml @@ -0,0 +1,37 @@ +%div + - unless params[:to] + %p.slead + Fill input field with commit id like + %code.label-branch 4eedf23 + or branch/tag name like + %code.label-branch master + and press compare button for commits list, code diff. + + %br + + = form_tag project_compare_index_path(@project), method: :post do + .clearfix + .pull-left + - if params[:to] && params[:from] + = link_to 'switch', {from: params[:to], to: params[:from]}, {class: 'commits-compare-switch has_tooltip', title: 'Switch base of comparison'} + = text_field_tag :from, params[:from], placeholder: "master", class: "xlarge" + = "..." + = text_field_tag :to, params[:to], placeholder: "aa8b4ef", class: "xlarge" + .pull-left + + = submit_tag "Compare", class: "btn btn-primary wide commits-compare-btn" + - if @refs_are_same + .alert + %span Refs are the same + + + +:javascript + var availableTags = #{@project.repository.ref_names.to_json}; + + $("#from, #to").autocomplete({ + source: availableTags, + minLength: 1 + }); + + disableButtonIfEmptyField('#to', '.commits-compare-btn'); diff --git a/app/views/projects/compare/index.html.haml b/app/views/projects/compare/index.html.haml new file mode 100644 index 00000000000..95cfb60d885 --- /dev/null +++ b/app/views/projects/compare/index.html.haml @@ -0,0 +1,7 @@ += render "projects/commits/head" + +%h3.page_title + Compare View +%hr + += render "form" diff --git a/app/views/projects/compare/show.html.haml b/app/views/projects/compare/show.html.haml new file mode 100644 index 00000000000..51e88d1c47d --- /dev/null +++ b/app/views/projects/compare/show.html.haml @@ -0,0 +1,23 @@ += render "projects/commits/head" + +%h3.page_title + Compare View +%hr + += render "form" + +- if @commits.size > 100 + .alert.alert-block + %p + %strong Warning! This comparison include 100+ commits. + %p To prevent performance issue we dont show diff information. + +- if @commits.present? + %div.ui-box + %h5.title + Commits (#{@commits.count}) + %ul.well-list= render Commit.decorate(@commits) + + - unless @diffs.empty? + %h4 Diff + = render "projects/commits/diffs", diffs: @diffs diff --git a/app/views/projects/deploy_keys/_deploy_key.html.haml b/app/views/projects/deploy_keys/_deploy_key.html.haml new file mode 100644 index 00000000000..45f80ecd556 --- /dev/null +++ b/app/views/projects/deploy_keys/_deploy_key.html.haml @@ -0,0 +1,25 @@ +%li + .pull-right + - if @available_keys.include?(deploy_key) + = link_to enable_project_deploy_key_path(@project, deploy_key), class: 'btn btn-small', method: :put do + %i.icon-plus + Enable + - else + - if deploy_key.projects.count > 1 + = link_to disable_project_deploy_key_path(@project, deploy_key), class: 'btn btn-small', method: :put do + %i.icon-off + Disable + - else + = link_to 'Remove', project_deploy_key_path(@project, deploy_key), confirm: 'You are going to remove deploy key. Are you sure?', method: :delete, class: "btn btn-remove delete-key btn-small pull-right" + + + = link_to project_deploy_key_path(deploy_key.projects.include?(@project) ? @project : deploy_key.projects.first, deploy_key) do + %i.icon-key + %strong= deploy_key.title + + %p.light.prepend-top-10 + - deploy_key.projects.map(&:name_with_namespace).each do |project_name| + %span.label= project_name + %small.pull-right + Created #{time_ago_in_words(deploy_key.created_at)} ago + diff --git a/app/views/projects/deploy_keys/_form.html.haml b/app/views/projects/deploy_keys/_form.html.haml new file mode 100644 index 00000000000..71bf309dd8b --- /dev/null +++ b/app/views/projects/deploy_keys/_form.html.haml @@ -0,0 +1,23 @@ +%div + = form_for [@project, @key], url: project_deploy_keys_path do |f| + -if @key.errors.any? + .alert.alert-error + %ul + - @key.errors.full_messages.each do |msg| + %li= msg + + .clearfix + = f.label :title + .input= f.text_field :title + .clearfix + = f.label :key + .input + = f.text_area :key, class: [:xxlarge, :thin_area] + %p.hint + Paste a machine public key here. Read more about how generate it + = link_to "here", help_ssh_path + + .actions + = f.submit 'Create', class: "btn-create btn" + = link_to "Cancel", project_deploy_keys_path(@project), class: "btn btn-cancel" + diff --git a/app/views/projects/deploy_keys/index.html.haml b/app/views/projects/deploy_keys/index.html.haml new file mode 100644 index 00000000000..a1fa3475a84 --- /dev/null +++ b/app/views/projects/deploy_keys/index.html.haml @@ -0,0 +1,30 @@ +%p.slead + Deploy keys allow read-only access to repository. They can be used for CI, staging or production servers + +%p + You can create a deploy key or add existing one + = link_to new_project_deploy_key_path(@project), class: "btn btn-primary pull-right", title: "New Deploy Key" do + %i.icon-plus + New Deploy Key + +%hr.clearfix + +.row + .span5.enabled-keys + %h5.cgreen + Enabled deploy keys + %small for this project + %ul.bordered-list + = render @enabled_keys + - if @enabled_keys.blank? + .light-well + %p.nothing_here_message Create #{link_to 'new deploy key', new_project_deploy_key_path(@project)} or add existing one + .span5.available-keys + %h5 + Available deploy keys + %small from projects you are able to manage + %ul.bordered-list + = render @available_keys + - if @available_keys.blank? + .light-well + %p.nothing_here_message All deploy keys created in projects you own will be displayed here diff --git a/app/views/projects/deploy_keys/new.html.haml b/app/views/projects/deploy_keys/new.html.haml new file mode 100644 index 00000000000..b0e2a8b2949 --- /dev/null +++ b/app/views/projects/deploy_keys/new.html.haml @@ -0,0 +1,4 @@ +%h3.page_title New Deploy key +%hr + += render 'form' diff --git a/app/views/projects/deploy_keys/show.html.haml b/app/views/projects/deploy_keys/show.html.haml new file mode 100644 index 00000000000..26fd7428b7e --- /dev/null +++ b/app/views/projects/deploy_keys/show.html.haml @@ -0,0 +1,13 @@ +%h3.page_title + Deploy key: + = @key.title + %small + created at + = @key.created_at.stamp("Aug 21, 2011") +.back_link + = link_to project_deploy_keys_path(@project) do + ← To keys list +%hr +%pre= @key.key +.pull-right + = link_to 'Remove', project_deploy_key_path(@project, @key), confirm: 'Are you sure?', method: :delete, class: "btn-remove btn delete-key" diff --git a/app/views/projects/edit_tree/show.html.haml b/app/views/projects/edit_tree/show.html.haml new file mode 100644 index 00000000000..101b479afed --- /dev/null +++ b/app/views/projects/edit_tree/show.html.haml @@ -0,0 +1,45 @@ +.file-editor + = form_tag(project_edit_tree_path(@project, @id), method: :put, class: "form-horizontal") do + .file_holder + .file_title + %i.icon-file + %span.file_name + = @path + %small + on + %strong= @ref + %span.options + .btn-group.tree-btn-group + = link_to "Cancel", project_blob_path(@project, @id), class: "btn btn-tiny btn-cancel", confirm: leave_edit_message + .file_content.code + %pre#editor= @blob.data + + .control-group.commit_message-group + = label_tag 'commit_message', class: "control-label" do + Commit message + .controls + = text_area_tag 'commit_message', '', placeholder: "Update #{@blob.name}", required: true, rows: 3 + .form-actions + = hidden_field_tag 'last_commit', @last_commit + = hidden_field_tag 'content', '', id: :file_content + .commit-button-annotation + = button_tag "Commit changes", class: 'btn commit-btn js-commit-button btn-primary' + .message + to branch + %strong= @ref + = link_to "Cancel", project_blob_path(@project, @id), class: "btn btn-cancel", confirm: leave_edit_message + +:javascript + ace.config.set("modePath", "#{Gitlab::Application.config.assets.prefix}/ace-src-noconflict") + var ace_mode = "#{@blob.language.try(:ace_mode)}"; + var editor = ace.edit("editor"); + if (ace_mode) { + editor.getSession().setMode('ace/mode/' + ace_mode); + } + + disableButtonIfEmptyField("#commit_message", ".js-commit-button"); + + $(".js-commit-button").click(function(){ + $("#file_content").val(editor.getValue()); + $(".file-editor form").submit(); + }); diff --git a/app/views/projects/graphs/show.html.haml b/app/views/projects/graphs/show.html.haml new file mode 100644 index 00000000000..05bc1436e6d --- /dev/null +++ b/app/views/projects/graphs/show.html.haml @@ -0,0 +1,31 @@ +.loading-graph + %center + .loading + %h3.page_title Building repository graph. Please wait a moment. + +.stat-graph + .header.clearfix + .pull-right + %select + %option{:value => "commits"} Commits + %option{:value => "additions"} Additions + %option{:value => "deletions"} Deletions + %h3#date_header.page_title + %input#brush_change{:type => "hidden"} + .graphs + #contributors-master + #contributors.clearfix + %ol.contributors-list.clearfix + +:javascript + $(".stat-graph").hide(); + + $.ajax({ + type: "GET", + url: location.href, + complete: function() { + $(".loading-graph").hide(); + $(".stat-graph").show(); + }, + dataType: "script" + }); diff --git a/app/views/projects/graphs/show.js.haml b/app/views/projects/graphs/show.js.haml new file mode 100644 index 00000000000..b7c9b4113e9 --- /dev/null +++ b/app/views/projects/graphs/show.js.haml @@ -0,0 +1,16 @@ +:plain + controller = new ContributorsStatGraph + controller.init(#{@log}) + + $("select").change( function () { + var field = $(this).val() + controller.set_current_field(field) + controller.redraw_master() + controller.redraw_authors() + }) + + $("#brush_change").change( function () { + controller.change_date_header() + controller.redraw_authors() + }) + diff --git a/app/views/projects/hooks/_data_ex.html.erb b/app/views/projects/hooks/_data_ex.html.erb new file mode 100644 index 00000000000..b4281fa18c7 --- /dev/null +++ b/app/views/projects/hooks/_data_ex.html.erb @@ -0,0 +1,43 @@ +<% data_ex_str = <<eos +{ + "before": "95790bf891e76fee5e1747ab589903a6a1f80f22", + "after": "da1560886d4f094c3e6c9ef40349f7d38b5d27d7", + "ref": "refs/heads/master", + "user_id": 4, + "user_name": "John Smith", + "repository": { + "name": "Diaspora", + "url": "git@localhost:diaspora.git", + "description": "", + "homepage": "http://localhost/diaspora", + }, + "commits": [ + { + "id": "b6568db1bc1dcd7f8b4d5a946b0b91f9dacd7327", + "message": "Update Catalan translation to e38cb41.", + "timestamp": "2011-12-12T14:27:31+02:00", + "url": "http://localhost/diaspora/commits/b6568db1bc1dcd7f8b4d5a946b0b91f9dacd7327", + "author": { + "name": "Jordi Mallach", + "email": "jordi@softcatala.org", + } + }, + // ... + { + "id": "da1560886d4f094c3e6c9ef40349f7d38b5d27d7", + "message": "fixed readme", + "timestamp": "2012-01-03T23:36:29+02:00", + "url": "http://localhost/diaspora/commits/da1560886d4f094c3e6c9ef40349f7d38b5d27d7", + "author": { + "name": "GitLab dev user", + "email": "gitlabdev@dv6700.(none)", + }, + }, + ], + "total_commits_count": 4, +}; +eos +%> +<div class="<%= user_color_scheme_class%>"> + <%= raw Pygments::Lexer[:js].highlight(data_ex_str) %> +</div> diff --git a/app/views/projects/hooks/index.html.haml b/app/views/projects/hooks/index.html.haml new file mode 100644 index 00000000000..641ab082d8d --- /dev/null +++ b/app/views/projects/hooks/index.html.haml @@ -0,0 +1,34 @@ +- if can? current_user, :admin_project, @project + .alert.alert-info + %span + Post receive hooks for binding events when someone push to repository. + %br + Read more about web hooks + %strong #{link_to "here", help_web_hooks_path, class: "vlink"} + += form_for [@project, @hook], as: :hook, url: project_hooks_path(@project), html: { class: 'form-inline' } do |f| + -if @hook.errors.any? + .alert.alert-error + - @hook.errors.full_messages.each do |msg| + %p= msg + .clearfix + = f.label :url, "URL:" + .input + = f.text_field :url, class: "text_field xxlarge" + + = f.submit "Add Web Hook", class: "btn btn-create" +%hr + +-if @hooks.any? + .ui-box + %h5.title + Hooks (#{@hooks.count}) + %ul.well-list + - @hooks.each do |hook| + %li + %span.badge.badge-info POST + → + %span.monospace= hook.url + .pull-right + = link_to 'Test Hook', test_project_hook_path(@project, hook), class: "btn btn-small grouped" + = link_to 'Remove', project_hook_path(@project, hook), confirm: 'Are you sure?', method: :delete, class: "btn btn-remove btn-small grouped" diff --git a/app/views/projects/issues/_filter.html.haml b/app/views/projects/issues/_filter.html.haml new file mode 100644 index 00000000000..8495c323cb8 --- /dev/null +++ b/app/views/projects/issues/_filter.html.haml @@ -0,0 +1,23 @@ += form_tag project_issues_path(@project), method: 'get' do + %fieldset + %ul.nav.nav-pills.nav-stacked + %li{class: ("active" if !params[:status] || params[:status].blank?)} + = link_to project_issues_path(@project, status: nil) do + Open + %li{class: ("active" if params[:status] == 'assigned-to-me')} + = link_to project_issues_path(@project, status: 'assigned-to-me') do + Assigned to me + %li{class: ("active" if params[:status] == 'created-by-me')} + = link_to project_issues_path(@project, status: 'created-by-me') do + Created by me + %li{class: ("active" if params[:status] == 'closed')} + = link_to project_issues_path(@project, status: 'closed') do + Closed + %li{class: ("active" if params[:status] == 'all')} + = link_to project_issues_path(@project, status: 'all') do + All + + %fieldset + %hr + = link_to "Reset", project_issues_path(@project), class: 'btn pull-right' + diff --git a/app/views/projects/issues/_form.html.haml b/app/views/projects/issues/_form.html.haml new file mode 100644 index 00000000000..38aea6f06dc --- /dev/null +++ b/app/views/projects/issues/_form.html.haml @@ -0,0 +1,95 @@ +%div.issue-form-holder + %h3.page_title= @issue.new_record? ? "New Issue" : "Edit Issue ##{@issue.id}" + = form_for [@project, @issue] do |f| + -if @issue.errors.any? + .alert.alert-error + - @issue.errors.full_messages.each do |msg| + %span= msg + %br + .ui-box.ui-box-show + .ui-box-head + .clearfix + = f.label :title do + %strong= "Subject *" + .input + = f.text_field :title, maxlength: 255, class: "xxlarge js-gfm-input", autofocus: true, required: true + .ui-box-body + .clearfix + .issue_assignee.pull-left + = f.label :assignee_id do + %i.icon-user + Assign to + .input + .pull-left + = f.select(:assignee_id, @project.team.members.sort_by(&:name).map {|p| [ p.name, p.id ] }, { include_blank: "Select a user" }, {class: 'chosen'}) + .pull-right + + = link_to 'Assign to me', '#', class: 'btn btn-small assign-to-me-link' + .issue_milestone.pull-left + = f.label :milestone_id do + %i.icon-time + Milestone + .input= f.select(:milestone_id, @project.milestones.active.all.collect {|p| [ p.title, p.id ] }, { include_blank: "Select milestone" }, {class: 'chosen'}) + + .ui-box-bottom + .clearfix + = f.label :label_list do + %i.icon-tag + Labels + .input + = f.text_field :label_list, maxlength: 2000, class: "xxlarge" + %p.hint Separate with comma. + + .clearfix + = f.label :description, "Details" + .input + = f.text_area :description, class: "xxlarge js-gfm-input", rows: 14 + %p.hint Issues are parsed with #{link_to "GitLab Flavored Markdown", help_markdown_path, target: '_blank'}. + + + .actions + - if @issue.new_record? + = f.submit 'Submit new issue', class: "btn btn-create" + -else + = f.submit 'Save changes', class: "btn-save btn" + + - cancel_path = @issue.new_record? ? project_issues_path(@project) : project_issue_path(@project, @issue) + = link_to "Cancel", cancel_path, class: 'btn btn-cancel' + + + + +:javascript + $("#issue_label_list") + .bind( "keydown", function( event ) { + if ( event.keyCode === $.ui.keyCode.TAB && + $( this ).data( "autocomplete" ).menu.active ) { + event.preventDefault(); + } + }) + .bind( "click", function( event ) { + $( this ).autocomplete("search", ""); + }) + .autocomplete({ + minLength: 0, + source: function( request, response ) { + response( $.ui.autocomplete.filter( + #{raw labels_autocomplete_source}, extractLast( request.term ) ) ); + }, + focus: function() { + return false; + }, + select: function(event, ui) { + var terms = split( this.value ); + terms.pop(); + terms.push( ui.item.value ); + terms.push( "" ); + this.value = terms.join( ", " ); + return false; + } + }); + + $('.assign-to-me-link').on('click', function(e){ + $('#issue_assignee_id').val("#{current_user.id}").trigger("liszt:updated"); + e.preventDefault(); + }); diff --git a/app/views/projects/issues/_head.html.haml b/app/views/projects/issues/_head.html.haml new file mode 100644 index 00000000000..44d14d5cdf9 --- /dev/null +++ b/app/views/projects/issues/_head.html.haml @@ -0,0 +1,10 @@ +%ul.nav.nav-tabs + = nav_link(controller: :issues) do + = link_to 'Browse Issues', project_issues_path(@project), class: "tab" + = nav_link(controller: :milestones) do + = link_to 'Milestones', project_milestones_path(@project), class: "tab" + = nav_link(controller: :labels) do + = link_to 'Labels', project_labels_path(@project), class: "tab" + %li.pull-right + = link_to project_issues_path(@project, :atom, { private_token: current_user.private_token }) do + %i.icon-rss diff --git a/app/views/projects/issues/_issue.html.haml b/app/views/projects/issues/_issue.html.haml new file mode 100644 index 00000000000..f44c0a6c81f --- /dev/null +++ b/app/views/projects/issues/_issue.html.haml @@ -0,0 +1,44 @@ +%li{ id: dom_id(issue), class: issue_css_classes(issue), url: project_issue_path(issue.project, issue) } + - if controller.controller_name == 'issues' + .issue-check + = check_box_tag dom_id(issue,"selected"), nil, false, 'data-id' => issue.id, class: "selected_issue", disabled: !can?(current_user, :modify_issue, issue) + + .issue-title + %span.light= "##{issue.id}" + = link_to_gfm truncate(issue.title, length: 100), project_issue_path(issue.project, issue), class: "row_title" + + .issue-info + - if issue.assignee + assigned to #{link_to_member(@project, issue.assignee)} + - else + unassigned + - if issue.votes_count > 0 + = render 'votes/votes_inline', votable: issue + - if issue.notes.any? + %span + %i.icon-comments + = issue.notes.count + - if issue.milestone_id? + %span + %i.icon-time + = issue.milestone.title + .pull-right + %small updated #{time_ago_in_words(issue.updated_at)} ago + + .issue-labels + - issue.labels.each do |label| + %span{class: "label #{label_css_class(label.name)}"} + %i.icon-tag + = label.name + + .issue-actions + - if can? current_user, :modify_issue, issue + - if issue.closed? + = link_to 'Reopen', project_issue_path(issue.project, issue, issue: {state_event: :reopen }, status_only: true), method: :put, class: "btn btn-small grouped reopen_issue", remote: true + - else + = link_to 'Close', project_issue_path(issue.project, issue, issue: {state_event: :close }, status_only: true), method: :put, class: "btn btn-small grouped close_issue", remote: true + = link_to edit_project_issue_path(issue.project, issue), class: "btn btn-small edit-issue-link grouped" do + %i.icon-edit + Edit + + diff --git a/app/views/projects/issues/_issues.html.haml b/app/views/projects/issues/_issues.html.haml new file mode 100644 index 00000000000..68598684f90 --- /dev/null +++ b/app/views/projects/issues/_issues.html.haml @@ -0,0 +1,94 @@ +.ui-box + .title + = check_box_tag "check_all_issues", nil, false, class: "check_all_issues left" + .clearfix + .issues_bulk_update.hide + = form_tag bulk_update_project_issues_path(@project), method: :post do + %span.update_issues_text Update selected issues with + .left + = select_tag('update[status]', options_for_select(['open', 'closed']), prompt: "Status") + = select_tag('update[assignee_id]', options_from_collection_for_select(@project.team.members, "id", "name", params[:assignee_id]), prompt: "Assignee") + = select_tag('update[milestone_id]', options_from_collection_for_select(issues_active_milestones, "id", "title", params[:milestone_id]), prompt: "Milestone") + = hidden_field_tag 'update[issues_ids]', [] + = hidden_field_tag :status, params[:status] + = button_tag "Save", class: "btn update_selected_issues btn-small btn-save" + .issues-filters + %span Filter by + .dropdown.inline.prepend-left-10 + %a.dropdown-toggle.btn.btn-small{href: '#', "data-toggle" => "dropdown"} + %i.icon-tags + %span.light labels: + - if params[:label_name].present? + %strong= params[:label_name] + - else + Any + %b.caret + %ul.dropdown-menu + %li + = link_to project_issues_with_filter_path(@project, label_name: nil) do + Any + - issue_label_names.each do |label_name| + %li + = link_to project_issues_with_filter_path(@project, label_name: label_name) do + %span{class: "label #{label_css_class(label_name)}"} + %i.icon-tag + = label_name + .dropdown.inline.prepend-left-10 + %a.dropdown-toggle.btn.btn-small{href: '#', "data-toggle" => "dropdown"} + %i.icon-user + %span.light assignee: + - if @assignee.present? + %strong= @assignee.name + - elsif params[:assignee_id] == "0" + Unassigned + - else + Any + %b.caret + %ul.dropdown-menu + %li + = link_to project_issues_with_filter_path(@project, assignee_id: nil) do + Any + = link_to project_issues_with_filter_path(@project, assignee_id: 0) do + Unassigned + - @project.team.members.sort_by(&:name).each do |user| + %li + = link_to project_issues_with_filter_path(@project, assignee_id: user.id) do + = image_tag gravatar_icon(user.email), class: "avatar s16" + = user.name + + .dropdown.inline.prepend-left-10 + %a.dropdown-toggle.btn.btn-small{href: '#', "data-toggle" => "dropdown"} + %i.icon-time + %span.light milestone: + - if @milestone.present? + %strong= @milestone.title + - elsif params[:milestone_id] == "0" + Unspecified + - else + Any + %b.caret + %ul.dropdown-menu + %li + = link_to project_issues_with_filter_path(@project, milestone_id: nil) do + Any + = link_to project_issues_with_filter_path(@project, milestone_id: 0) do + Unspecified + - issues_active_milestones.each do |milestone| + %li + = link_to project_issues_with_filter_path(@project, milestone_id: milestone.id) do + %strong= milestone.title + %small.light= milestone.expires_at + + + %ul.well-list.issues-list + = render @issues + - if @issues.blank? + %li + %h4.nothing_here_message Nothing to show here + +- if @issues.present? + .pull-right + %span.issue_counter #{@issues.total_count} + issues for this filter + + = paginate @issues, remote: true, theme: "gitlab" diff --git a/app/views/projects/issues/edit.html.haml b/app/views/projects/issues/edit.html.haml new file mode 100644 index 00000000000..b1bc3ba0eba --- /dev/null +++ b/app/views/projects/issues/edit.html.haml @@ -0,0 +1 @@ += render "form" diff --git a/app/views/projects/issues/index.atom.builder b/app/views/projects/issues/index.atom.builder new file mode 100644 index 00000000000..00ddd4bf702 --- /dev/null +++ b/app/views/projects/issues/index.atom.builder @@ -0,0 +1,23 @@ +xml.instruct! +xml.feed "xmlns" => "http://www.w3.org/2005/Atom", "xmlns:media" => "http://search.yahoo.com/mrss/" do + xml.title "#{@project.name} issues" + xml.link :href => project_issues_url(@project, :atom), :rel => "self", :type => "application/atom+xml" + xml.link :href => project_issues_url(@project), :rel => "alternate", :type => "text/html" + xml.id project_issues_url(@project) + xml.updated @issues.first.created_at.strftime("%Y-%m-%dT%H:%M:%SZ") if @issues.any? + + @issues.each do |issue| + xml.entry do + xml.id project_issue_url(@project, issue) + xml.link :href => project_issue_url(@project, issue) + xml.title truncate(issue.title, :length => 80) + xml.updated issue.created_at.strftime("%Y-%m-%dT%H:%M:%SZ") + xml.media :thumbnail, :width => "40", :height => "40", :url => gravatar_icon(issue.author_email) + xml.author do |author| + xml.name issue.author_name + xml.email issue.author_email + end + xml.summary issue.title + end + end +end diff --git a/app/views/projects/issues/index.html.haml b/app/views/projects/issues/index.html.haml new file mode 100644 index 00000000000..d3fd9886d45 --- /dev/null +++ b/app/views/projects/issues/index.html.haml @@ -0,0 +1,25 @@ += render "head" +.issues_content + %h3.page_title + Issues + %span (<span class=issue_counter>#{@issues.total_count}</span>) + .pull-right + .span6 + - if can? current_user, :write_issue, @project + = link_to new_project_issue_path(@project, issue: { assignee_id: params[:assignee_id], milestone_id: params[:milestone_id]}), class: "btn btn-primary pull-right", title: "New Issue", id: "new_issue_link" do + %i.icon-plus + New Issue + = form_tag project_issues_path(@project), method: :get, remote: true, id: "issue_search_form", class: 'pull-right' do + = hidden_field_tag :status, params[:status], id: 'search_status' + = hidden_field_tag :assignee_id, params[:assignee_id], id: 'search_assignee_id' + = hidden_field_tag :milestone_id, params[:milestone_id], id: 'search_milestone_id' + = hidden_field_tag :label_name, params[:label_name], id: 'search_label_name' + = search_field_tag :issue_search, nil, { placeholder: 'Search', class: 'issue_search input-xlarge append-right-10 search-text-input' } + + .clearfix + +.row + .span3 + = render 'filter', entity: 'issue' + .span9.issues-holder + = render "issues" diff --git a/app/views/projects/issues/index.js.haml b/app/views/projects/issues/index.js.haml new file mode 100644 index 00000000000..1be6a64f535 --- /dev/null +++ b/app/views/projects/issues/index.js.haml @@ -0,0 +1,4 @@ +:plain + $('.issues-holder').html("#{escape_javascript(render('issues'))}"); + History.replaceState({path: "#{request.url}"}, document.title, "#{request.url}"); + Issues.reload(); diff --git a/app/views/projects/issues/new.html.haml b/app/views/projects/issues/new.html.haml new file mode 100644 index 00000000000..b1bc3ba0eba --- /dev/null +++ b/app/views/projects/issues/new.html.haml @@ -0,0 +1 @@ += render "form" diff --git a/app/views/projects/issues/show.html.haml b/app/views/projects/issues/show.html.haml new file mode 100644 index 00000000000..138db92eac0 --- /dev/null +++ b/app/views/projects/issues/show.html.haml @@ -0,0 +1,68 @@ +%h3.page_title + Issue ##{@issue.id} + + %small + created at + = @issue.created_at.stamp("Aug 21, 2011") + + %span.pull-right + = link_to new_project_issue_path(@project), class: "btn grouped", title: "New Issue", id: "new_issue_link" do + %i.icon-plus + New Issue + - if can?(current_user, :modify_issue, @issue) + - if @issue.closed? + = link_to 'Reopen', project_issue_path(@project, @issue, issue: {state_event: :reopen }, status_only: true), method: :put, class: "btn grouped reopen_issue" + - else + = link_to 'Close', project_issue_path(@project, @issue, issue: {state_event: :close }, status_only: true), method: :put, class: "btn grouped close_issue", title: "Close Issue" + + = link_to edit_project_issue_path(@project, @issue), class: "btn grouped" do + %i.icon-edit + Edit + +.pull-right + .span3#votes= render 'votes/votes_block', votable: @issue + +.back_link + = link_to project_issues_path(@project) do + ← To issues list + + +.ui-box.ui-box-show + .ui-box-head + %h4.box-title + - if @issue.closed? + .error.status_info Closed + = gfm escape_once(@issue.title) + + .ui-box-body + %cite.cgray + Created by #{link_to_member(@project, @issue.author)} + - if @issue.assignee + \ and currently assigned to #{link_to_member(@project, @issue.assignee)} + + - if @issue.milestone + - milestone = @issue.milestone + %cite.cgray and attached to milestone + %strong= link_to_gfm truncate(milestone.title, length: 20), project_milestone_path(milestone.project, milestone) + + .pull-right + - @issue.labels.each do |label| + %span{class: "label #{label_css_class(label.name)}"} + %i.icon-tag + = label.name + + + - if @issue.description.present? + .ui-box-bottom + .wiki + = preserve do + = markdown @issue.description + +- content_for :note_actions do + - if can?(current_user, :modify_issue, @issue) + - if @issue.closed? + = link_to 'Reopen Issue', project_issue_path(@project, @issue, issue: {state_event: :reopen }, status_only: true), method: :put, class: "btn grouped reopen_issue" + - else + = link_to 'Close Issue', project_issue_path(@project, @issue, issue: {state_event: :close }, status_only: true), method: :put, class: "btn grouped close_issue", title: "Close Issue" + +.voting_notes#notes= render "projects/notes/notes_with_form" diff --git a/app/views/projects/issues/update.js.haml b/app/views/projects/issues/update.js.haml new file mode 100644 index 00000000000..7f66022a2de --- /dev/null +++ b/app/views/projects/issues/update.js.haml @@ -0,0 +1,4 @@ +- if params[:status_only] + - if @issue.valid? + :plain + $("##{dom_id(@issue)}").fadeOut(); diff --git a/app/views/projects/labels/_label.html.haml b/app/views/projects/labels/_label.html.haml new file mode 100644 index 00000000000..2b1aafc546b --- /dev/null +++ b/app/views/projects/labels/_label.html.haml @@ -0,0 +1,15 @@ +- frequency = @project.issues.tagged_with(label.name).count +%li + %strong + %span{class: "label #{label_css_class(label.name)}"} + %i.icon-tag + - if frequency.zero? + %span.light= label.name + - else + = label.name + .pull-right + - unless frequency.zero? + = link_to project_issues_path(label_name: label.name) do + %strong + = pluralize(frequency, 'issue') + = "»" diff --git a/app/views/projects/labels/index.html.haml b/app/views/projects/labels/index.html.haml new file mode 100644 index 00000000000..b6a4b07b9ae --- /dev/null +++ b/app/views/projects/labels/index.html.haml @@ -0,0 +1,14 @@ += render "projects/issues/head" + +%h3.page_title + Labels +%br + +- if @labels.present? + %ul.bordered-list.labels-table + - @labels.each do |label| + = render 'label', label: label + +- else + .light-well + %h3.nothing_here_message Add first label to your issues or #{link_to 'generate', generate_project_labels_path(@project), method: :post} default set of labels diff --git a/app/views/projects/merge_requests/_filter.html.haml b/app/views/projects/merge_requests/_filter.html.haml new file mode 100644 index 00000000000..4b48306ed05 --- /dev/null +++ b/app/views/projects/merge_requests/_filter.html.haml @@ -0,0 +1,20 @@ += form_tag project_issues_path(@project), method: 'get' do + %fieldset + %ul.nav.nav-pills.nav-stacked + %li{class: ("active" if (params[:f] == 'open' || !params[:f]))} + = link_to project_merge_requests_path(@project, f: 'open', milestone_id: params[:milestone_id]) do + Open + %li{class: ("active" if params[:f] == "closed")} + = link_to project_merge_requests_path(@project, f: "closed", milestone_id: params[:milestone_id]) do + Closed + %li{class: ("active" if params[:f] == 'assigned-to-me')} + = link_to project_merge_requests_path(@project, f: 'assigned-to-me', milestone_id: params[:milestone_id]) do + Assigned To Me + %li{class: ("active" if params[:f] == 'all')} + = link_to project_merge_requests_path(@project, f: 'all', milestone_id: params[:milestone_id]) do + All + + %fieldset + %hr + = link_to "Reset", project_merge_requests_path(@project), class: 'btn pull-right' + diff --git a/app/views/projects/merge_requests/_form.html.haml b/app/views/projects/merge_requests/_form.html.haml new file mode 100644 index 00000000000..b3da15608e4 --- /dev/null +++ b/app/views/projects/merge_requests/_form.html.haml @@ -0,0 +1,79 @@ += form_for [@project, @merge_request], html: { class: "#{controller.action_name}-merge-request form-horizontal" } do |f| + -if @merge_request.errors.any? + .alert.alert-error + %ul + - @merge_request.errors.full_messages.each do |msg| + %li= msg + + %fieldset + %legend 1. Select Branches + + .row + .span5 + .mr_branch_box + %h5.cgray From (Head Branch) + .body + .padded= f.select(:source_branch, @repository.branch_names, { include_blank: "Select branch" }, {class: 'chosen span4'}) + .mr_source_commit + + .span2 + %center= image_tag "merge.png", class: 'mr_direction_tip' + .span5 + .mr_branch_box + %h5.cgray To (Base Branch) + .body + .padded= f.select(:target_branch, @repository.branch_names, { include_blank: "Select branch" }, {class: 'chosen span4'}) + .mr_target_commit + + %fieldset + %legend 2. Fill info + + .ui-box.ui-box-show + .ui-box-head + .clearfix + = f.label :title do + %strong= "Title *" + .input= f.text_field :title, class: "input-xxlarge pad js-gfm-input", maxlength: 255, rows: 5, required: true + .ui-box-body + .clearfix + .left + = f.label :assignee_id do + %i.icon-user + Assign to + .input= f.select(:assignee_id, @project.team.members.sort_by(&:name).map {|p| [ p.name, p.id ] }, { include_blank: "Select user" }, {class: 'chosen span3'}) + .left + = f.label :milestone_id do + %i.icon-time + Milestone + .input= f.select(:milestone_id, @project.milestones.active.all.map {|p| [ p.title, p.id ] }, { include_blank: "Select milestone" }, {class: 'chosen'}) + + .control-group + + .form-actions + - if @merge_request.new_record? + = f.submit 'Submit merge request', class: "btn btn-create" + -else + = f.submit 'Save changes', class: "btn btn-save" + - if @merge_request.new_record? + = link_to project_merge_requests_path(@project), class: "btn btn-cancel" do + Cancel + - else + = link_to project_merge_request_path(@project, @merge_request), class: "btn btn-cancel" do + Cancel + +:javascript + disableButtonIfEmptyField("#merge_request_title", ".btn-save"); + + var source_branch = $("#merge_request_source_branch") + , target_branch = $("#merge_request_target_branch"); + + $.get("#{branch_from_project_merge_requests_path(@project)}", {ref: source_branch.val() }); + $.get("#{branch_to_project_merge_requests_path(@project)}", {ref: target_branch.val() }); + + source_branch.live("change", function() { + $.get("#{branch_from_project_merge_requests_path(@project)}", {ref: $(this).val() }); + }); + + target_branch.live("change", function() { + $.get("#{branch_to_project_merge_requests_path(@project)}", {ref: $(this).val() }); + }); diff --git a/app/views/projects/merge_requests/_head.html.haml b/app/views/projects/merge_requests/_head.html.haml new file mode 100644 index 00000000000..35a86e6511c --- /dev/null +++ b/app/views/projects/merge_requests/_head.html.haml @@ -0,0 +1,5 @@ +.top-tabs + = link_to project_merge_requests_path(@project), class: "tab #{'active' if current_page?(project_merge_requests_path(@project)) }" do + %span + Merge Requests + diff --git a/app/views/projects/merge_requests/_merge_request.html.haml b/app/views/projects/merge_requests/_merge_request.html.haml new file mode 100644 index 00000000000..ffc6b8fda1e --- /dev/null +++ b/app/views/projects/merge_requests/_merge_request.html.haml @@ -0,0 +1,29 @@ +%li{ class: mr_css_classes(merge_request) } + .merge-request-title + %span.light= "##{merge_request.id}" + = link_to_gfm truncate(merge_request.title, length: 80), project_merge_request_path(merge_request.project, merge_request), class: "row_title" + - if merge_request.merged? + %small.pull-right + %i.icon-ok + = "MERGED" + - else + %span.pull-right + %i.icon-angle-right + = merge_request.target_branch + .merge-request-info + - if merge_request.author + authored by #{link_to_member(@project, merge_request.author)} + - if merge_request.votes_count > 0 + = render 'votes/votes_inline', votable: merge_request + - if merge_request.notes.any? + %span + %i.icon-comments + = merge_request.mr_and_commit_notes.count + - if merge_request.milestone_id? + %span + %i.icon-time + = merge_request.milestone.title + + + .pull-right + %small updated #{time_ago_in_words(merge_request.updated_at)} ago diff --git a/app/views/projects/merge_requests/_show.html.haml b/app/views/projects/merge_requests/_show.html.haml new file mode 100644 index 00000000000..987fb4bcc49 --- /dev/null +++ b/app/views/projects/merge_requests/_show.html.haml @@ -0,0 +1,37 @@ +.merge-request + = render "projects/merge_requests/show/mr_title" + = render "projects/merge_requests/show/how_to_merge" + = render "projects/merge_requests/show/mr_box" + = render "projects/merge_requests/show/mr_accept" + - if @project.gitlab_ci? + = render "projects/merge_requests/show/mr_ci" + = render "projects/merge_requests/show/commits" + + - if @commits.present? + %ul.nav.nav-tabs + %li.notes-tab{data: {action: 'notes'}} + = link_to project_merge_request_path(@project, @merge_request) do + %i.icon-comment + Discussion + %li.diffs-tab{data: {action: 'diffs'}} + = link_to diffs_project_merge_request_path(@project, @merge_request) do + %i.icon-list-alt + Diff + + .notes.tab-content.voting_notes#notes{ class: (controller.action_name == 'show') ? "" : "hide" } + = render "projects/notes/notes_with_form" + .diffs.tab-content + = render "projects/merge_requests/show/diffs" if @diffs + .status + +:javascript + var merge_request; + + merge_request = new MergeRequest({ + url_to_automerge_check: "#{automerge_check_project_merge_request_path(@project, @merge_request)}", + check_enable: #{@merge_request.unchecked? ? "true" : "false"}, + url_to_ci_check: "#{ci_status_project_merge_request_path(@project, @merge_request)}", + ci_enable: #{@project.gitlab_ci? ? "true" : "false"}, + current_status: "#{@merge_request.merge_status_name}", + action: "#{controller.action_name}" + }); diff --git a/app/views/projects/merge_requests/automerge.js.haml b/app/views/projects/merge_requests/automerge.js.haml new file mode 100644 index 00000000000..e01ff662e7d --- /dev/null +++ b/app/views/projects/merge_requests/automerge.js.haml @@ -0,0 +1,7 @@ +-if @status + :plain + location.reload(); +-else + :plain + merge_request.alreadyOrCannotBeMerged() + diff --git a/app/views/projects/merge_requests/branch_from.js.haml b/app/views/projects/merge_requests/branch_from.js.haml new file mode 100644 index 00000000000..0637fdcb72e --- /dev/null +++ b/app/views/projects/merge_requests/branch_from.js.haml @@ -0,0 +1,2 @@ +:plain + $(".mr_source_commit").html("#{commit_to_html(@commit)}"); diff --git a/app/views/projects/merge_requests/branch_to.js.haml b/app/views/projects/merge_requests/branch_to.js.haml new file mode 100644 index 00000000000..974100d1ba7 --- /dev/null +++ b/app/views/projects/merge_requests/branch_to.js.haml @@ -0,0 +1,2 @@ +:plain + $(".mr_target_commit").html("#{commit_to_html(@commit)}"); diff --git a/app/views/projects/merge_requests/commits.js.haml b/app/views/projects/merge_requests/commits.js.haml new file mode 100644 index 00000000000..923b1ea032f --- /dev/null +++ b/app/views/projects/merge_requests/commits.js.haml @@ -0,0 +1,4 @@ +:plain + merge_request.$(".commits").html("#{escape_javascript(render(partial: "commits"))}"); + + diff --git a/app/views/projects/merge_requests/diffs.html.haml b/app/views/projects/merge_requests/diffs.html.haml new file mode 100644 index 00000000000..2a5b8b1441e --- /dev/null +++ b/app/views/projects/merge_requests/diffs.html.haml @@ -0,0 +1 @@ += render "show" diff --git a/app/views/projects/merge_requests/diffs.js.haml b/app/views/projects/merge_requests/diffs.js.haml new file mode 100644 index 00000000000..2964f0ec462 --- /dev/null +++ b/app/views/projects/merge_requests/diffs.js.haml @@ -0,0 +1,2 @@ +:plain + merge_request.$(".diffs").html("#{escape_javascript(render(partial: "projects/merge_requests/show/diffs"))}"); diff --git a/app/views/projects/merge_requests/edit.html.haml b/app/views/projects/merge_requests/edit.html.haml new file mode 100644 index 00000000000..eee148994d7 --- /dev/null +++ b/app/views/projects/merge_requests/edit.html.haml @@ -0,0 +1,4 @@ +%h3.page_title + = "Edit merge request #{@merge_request.id}" +%hr += render 'form' diff --git a/app/views/projects/merge_requests/index.html.haml b/app/views/projects/merge_requests/index.html.haml new file mode 100644 index 00000000000..b9e9096e3ae --- /dev/null +++ b/app/views/projects/merge_requests/index.html.haml @@ -0,0 +1,35 @@ +- if can? current_user, :write_merge_request, @project + = link_to new_project_merge_request_path(@project), class: "pull-right btn btn-primary", title: "New Merge Request" do + %i.icon-plus + New Merge Request +%h3.page_title + Merge Requests + +%br + + +.row + .span3 + = render 'filter' + .span9 + .ui-box + .title + = form_tag project_merge_requests_path(@project), id: "merge_requests_search_form", method: :get, class: :left do + = select_tag(:assignee_id, options_from_collection_for_select([unassigned_filter] + @project.users.all, "id", "name", params[:assignee_id]), prompt: "Assignee") + = select_tag(:milestone_id, options_from_collection_for_select([unassigned_filter] + @project.milestones.order("id desc").all, "id", "title", params[:milestone_id]), prompt: "Milestone") + = hidden_field_tag :f, params[:f] + .clearfix + + %ul.well-list.mr-list + = render @merge_requests + - if @merge_requests.blank? + %li + %h4.nothing_here_message Nothing to show here + - if @merge_requests.present? + .pull-right + %span.cgray.pull-right #{@merge_requests.total_count} merge requests for this filter + + = paginate @merge_requests, theme: "gitlab" + +:javascript + $(merge_requestsPage); diff --git a/app/views/projects/merge_requests/invalid.html.haml b/app/views/projects/merge_requests/invalid.html.haml new file mode 100644 index 00000000000..c962811a3e4 --- /dev/null +++ b/app/views/projects/merge_requests/invalid.html.haml @@ -0,0 +1,17 @@ +.merge-request + = render "projects/merge_requests/show/mr_title" + = render "projects/merge_requests/show/mr_box" + + .alert.alert-error + %h5 + %i.icon-exclamation-sign + We cannot find + %span.label-branch= @merge_request.source_branch + or + %span.label-branch= @merge_request.target_branch + branches in the repository. + %p + Maybe it was removed or never pushed. + %p + Please close Merge Request or change branches with existing one + diff --git a/app/views/projects/merge_requests/new.html.haml b/app/views/projects/merge_requests/new.html.haml new file mode 100644 index 00000000000..594089995ea --- /dev/null +++ b/app/views/projects/merge_requests/new.html.haml @@ -0,0 +1,3 @@ +%h3.page_title New Merge Request +%hr += render 'form' diff --git a/app/views/projects/merge_requests/show.html.haml b/app/views/projects/merge_requests/show.html.haml new file mode 100644 index 00000000000..2a5b8b1441e --- /dev/null +++ b/app/views/projects/merge_requests/show.html.haml @@ -0,0 +1 @@ += render "show" diff --git a/app/views/projects/merge_requests/show.js.haml b/app/views/projects/merge_requests/show.js.haml new file mode 100644 index 00000000000..2ce6eb63290 --- /dev/null +++ b/app/views/projects/merge_requests/show.js.haml @@ -0,0 +1,2 @@ +:plain + merge_request.$(".notes").html("#{escape_javascript(render "notes/notes_with_form")}"); diff --git a/app/views/projects/merge_requests/show/_commits.html.haml b/app/views/projects/merge_requests/show/_commits.html.haml new file mode 100644 index 00000000000..8630f02d5d9 --- /dev/null +++ b/app/views/projects/merge_requests/show/_commits.html.haml @@ -0,0 +1,30 @@ +- if @commits.present? + .ui-box + %h5.title + %i.icon-list + Commits (#{@commits.count}) + .commits + - if @commits.count > 8 + %ul.first-commits.well-list + - @commits.first(8).each do |commit| + = render "projects/commits/commit", commit: commit + %li.bottom + 8 of #{@commits.count} commits displayed. + %strong + %a.show-all-commits Click here to show all + %ul.all-commits.hide.well-list + - @commits.each do |commit| + = render "projects/commits/commit", commit: commit + + - else + %ul.well-list + - @commits.each do |commit| + = render "projects/commits/commit", commit: commit + +- else + %h4.nothing_here_message + Nothing to merge from + %span.label-branch #{@merge_request.source_branch} + to + %span.label-branch #{@merge_request.target_branch} + %br diff --git a/app/views/projects/merge_requests/show/_diffs.html.haml b/app/views/projects/merge_requests/show/_diffs.html.haml new file mode 100644 index 00000000000..1d52e824fad --- /dev/null +++ b/app/views/projects/merge_requests/show/_diffs.html.haml @@ -0,0 +1,10 @@ +- if @merge_request.valid_diffs? + = render "projects/commits/diffs", diffs: @diffs +- elsif @merge_request.broken_diffs? + %h4.nothing_here_message + Can't load diff. + You can + = link_to "download it", project_merge_request_path(@project, @merge_request, format: :diff), class: "vlink" + instead. +- else + %h4.nothing_here_message Nothing to merge diff --git a/app/views/projects/merge_requests/show/_how_to_merge.html.haml b/app/views/projects/merge_requests/show/_how_to_merge.html.haml new file mode 100644 index 00000000000..7f1e33418de --- /dev/null +++ b/app/views/projects/merge_requests/show/_how_to_merge.html.haml @@ -0,0 +1,19 @@ +%div#modal_merge_info.modal.hide + .modal-header + %a.close{href: "#"} × + %h3 How To Merge + .modal-body + %p + %strong Step 1. + Checkout target branch and get recent objects from GitLab + %pre.dark + :preserve + git checkout #{@merge_request.target_branch} + git fetch origin + %p + %strong Step 2. + Merge source branch into target branch and push changes to GitLab + %pre.dark + :preserve + git merge origin/#{@merge_request.source_branch} + git push origin #{@merge_request.target_branch} diff --git a/app/views/projects/merge_requests/show/_mr_accept.html.haml b/app/views/projects/merge_requests/show/_mr_accept.html.haml new file mode 100644 index 00000000000..ac97f6327c0 --- /dev/null +++ b/app/views/projects/merge_requests/show/_mr_accept.html.haml @@ -0,0 +1,52 @@ +- unless @allowed_to_merge + .alert + %strong You don't have enough permissions to merge this MR + + +- if @show_merge_controls + .automerge_widget.can_be_merged{style: "display:none"} + .alert.alert-success + %span + = form_for [:automerge, @project, @merge_request], remote: true, method: :get do |f| + %p + You can accept this request automatically. + If you still want to do it manually - + %strong= link_to "click here", "#", class: "how_to_merge_link vlink", title: "How To Merge" + for instructions + .accept_group + = f.submit "Accept Merge Request", class: "btn success accept_merge_request" + - unless @project.root_ref? @merge_request.source_branch + .remove_branch_holder + = label_tag :should_remove_source_branch, class: "checkbox" do + = check_box_tag :should_remove_source_branch + Remove source-branch + .clearfix + + + .automerge_widget.no_satellite{style: "display:none"} + .alert.alert-error + %span + %strong This repository does not have satellite. Ask administrator to fix this issue + + .automerge_widget.cannot_be_merged{style: "display:none"} + .alert.alert-disabled + %span + = link_to "Show how to merge", "#", class: "how_to_merge_link btn btn-small padded", title: "How To Merge" + + %strong This request can't be merged with GitLab. You should do it manually + + .automerge_widget.unchecked + .alert + %strong + %i.icon-refresh + Checking for ability to automatically merge… + + .automerge_widget.already_cannot_be_merged{style: "display:none"} + .alert.alert-info + %strong This merge request already can not be merged. Try to reload page. + + .merge-in-progress.hide + %span.cgray + %i.icon-refresh.icon-spin + + Merge is in progress. Please wait. Page will be automatically reloaded. diff --git a/app/views/projects/merge_requests/show/_mr_box.html.haml b/app/views/projects/merge_requests/show/_mr_box.html.haml new file mode 100644 index 00000000000..594f4061c23 --- /dev/null +++ b/app/views/projects/merge_requests/show/_mr_box.html.haml @@ -0,0 +1,36 @@ +.ui-box.ui-box-show + .ui-box-head + %h4.box-title + = gfm escape_once(@merge_request.title) + - if @merge_request.merged? + .success.status_info + %i.icon-ok + Merged + - elsif @merge_request.closed? + .error.status_info Closed + + .ui-box-body + %div + %cite.cgray + Created at #{@merge_request.created_at.stamp("Aug 21, 2011")} by #{link_to_member(@project, @merge_request.author)} + - if @merge_request.assignee + \, currently assigned to #{link_to_member(@project, @merge_request.assignee)} + - if @merge_request.milestone + - milestone = @merge_request.milestone + %cite.cgray and attached to milestone + %strong= link_to_gfm truncate(milestone.title, length: 20), project_milestone_path(milestone.project, milestone) + + + - if @merge_request.closed? + .ui-box-bottom.alert-error + %span + %i.icon-remove + Closed by #{link_to_member(@project, @merge_request.closed_event.author)} + %small #{time_ago_in_words(@merge_request.closed_event.created_at)} ago. + - if @merge_request.merged? + .ui-box-bottom.alert-success + %span + %i.icon-ok + Merged by #{link_to_member(@project, @merge_request.merge_event.author)} + #{time_ago_in_words(@merge_request.merge_event.created_at)} ago. + diff --git a/app/views/projects/merge_requests/show/_mr_ci.html.haml b/app/views/projects/merge_requests/show/_mr_ci.html.haml new file mode 100644 index 00000000000..9b15c4526e9 --- /dev/null +++ b/app/views/projects/merge_requests/show/_mr_ci.html.haml @@ -0,0 +1,35 @@ +- if @commits.any? + .ci_widget.ci-success{style: "display:none"} + .alert.alert-success + %i.icon-ok + %strong CI build passed + for #{@merge_request.last_commit_short_sha}. + = link_to "Build page", ci_build_details_path(@merge_request) + + + .ci_widget.ci-failed{style: "display:none"} + .alert.alert-error + %i.icon-remove + %strong CI build failed + for #{@merge_request.last_commit_short_sha}. + = link_to "Build page", ci_build_details_path(@merge_request) + + - [:running, :pending].each do |status| + .ci_widget{class: "ci-#{status}", style: "display:none"} + .alert + %i.icon-time + %strong CI build #{status} + for #{@merge_request.last_commit_short_sha}. + = link_to "Build page", ci_build_details_path(@merge_request) + + .ci_widget + .alert + %strong + %i.icon-refresh + Checking for CI status for #{@merge_request.last_commit_short_sha} + + .ci_widget.ci-error{style: "display:none"} + .alert.alert-error + %i.icon-remove + %strong Cannot connect to CI server. Please check your setting + diff --git a/app/views/projects/merge_requests/show/_mr_title.html.haml b/app/views/projects/merge_requests/show/_mr_title.html.haml new file mode 100644 index 00000000000..24285c272a8 --- /dev/null +++ b/app/views/projects/merge_requests/show/_mr_title.html.haml @@ -0,0 +1,31 @@ +%h3.page_title + = "Merge Request ##{@merge_request.id}:" + + %span.label-branch= @merge_request.source_branch + → + %span.label-branch= @merge_request.target_branch + + %span.pull-right + - if can?(current_user, :modify_merge_request, @merge_request) + - if @merge_request.opened? + .left.btn-group + %a.btn.grouped.dropdown-toggle{ data: {toggle: :dropdown} } + %i.icon-download-alt + Download as + %span.caret + %ul.dropdown-menu + %li= link_to "Email Patches", project_merge_request_path(@project, @merge_request, format: :patch) + %li= link_to "Plain Diff", project_merge_request_path(@project, @merge_request, format: :diff) + + = link_to 'Close', project_merge_request_path(@project, @merge_request, merge_request: {state_event: :close }), method: :put, class: "btn grouped btn-close", title: "Close merge request" + + = link_to edit_project_merge_request_path(@project, @merge_request), class: "btn grouped" do + %i.icon-edit + Edit + +.pull-right + .span3#votes= render 'votes/votes_block', votable: @merge_request + +.back_link + = link_to project_merge_requests_path(@project) do + ← To merge requests diff --git a/app/views/projects/milestones/_form.html.haml b/app/views/projects/milestones/_form.html.haml new file mode 100644 index 00000000000..50e3e71b2c3 --- /dev/null +++ b/app/views/projects/milestones/_form.html.haml @@ -0,0 +1,47 @@ +%h3.page_title= @milestone.new_record? ? "New Milestone" : "Edit Milestone ##{@milestone.id}" +.back_link + = link_to project_milestones_path(@project) do + ← To milestones + +%hr + += form_for [@project, @milestone], html: {class: "new_milestone form-horizontal"} do |f| + -if @milestone.errors.any? + .alert.alert-error + %ul + - @milestone.errors.full_messages.each do |msg| + %li= msg + .row + .span6 + .control-group + = f.label :title, "Title", class: "control-label" + .controls + = f.text_field :title, maxlength: 255, class: "input-xlarge" + %p.hint Required + .control-group + = f.label :description, "Description", class: "control-label" + .controls + = f.text_area :description, maxlength: 2000, class: "input-xlarge", rows: 10 + %p.hint Milestones are parsed with #{link_to "GitLab Flavored Markdown", help_markdown_path, target: '_blank'}. + .span6 + .control-group + = f.label :due_date, "Due Date", class: "control-label" + .input= f.hidden_field :due_date + .controls + .datepicker + + .form-actions + - if @milestone.new_record? + = f.submit 'Create milestone', class: "btn-save btn" + = link_to "Cancel", project_milestones_path(@project), class: "btn btn-cancel" + -else + = f.submit 'Save changes', class: "btn-save btn" + = link_to "Cancel", project_milestone_path(@project, @milestone), class: "btn btn-cancel" + + +:javascript + disableButtonIfEmptyField("#milestone_title", ".btn-save"); + $( ".datepicker" ).datepicker({ + dateFormat: "yy-mm-dd", + onSelect: function(dateText, inst) { $("#milestone_due_date").val(dateText) } + }).datepicker("setDate", $.datepicker.parseDate('yy-mm-dd', $('#milestone_due_date').val())); diff --git a/app/views/projects/milestones/_issues.html.haml b/app/views/projects/milestones/_issues.html.haml new file mode 100644 index 00000000000..eccf3ddbfa5 --- /dev/null +++ b/app/views/projects/milestones/_issues.html.haml @@ -0,0 +1,11 @@ +.ui-box + %h5.title= title + %ul.well-list + - issues.each do |issue| + %li + = link_to [@project, issue] do + %span.badge{class: issue.closed? ? 'badge-important' : 'badge-info'} ##{issue.id} + = link_to_gfm truncate(issue.title, length: 60), [@project, issue] + - if issue.assignee + .pull-right + = image_tag gravatar_icon(issue.assignee.email, 16), class: "avatar s16" diff --git a/app/views/projects/milestones/_merge_request.html.haml b/app/views/projects/milestones/_merge_request.html.haml new file mode 100644 index 00000000000..7f815894069 --- /dev/null +++ b/app/views/projects/milestones/_merge_request.html.haml @@ -0,0 +1,5 @@ +%li + = link_to [@project, merge_request] do + %span.badge.badge-info ##{merge_request.id} + – + = link_to_gfm truncate(merge_request.title, length: 60), [@project, merge_request] diff --git a/app/views/projects/milestones/_milestone.html.haml b/app/views/projects/milestones/_milestone.html.haml new file mode 100644 index 00000000000..894fa6c1133 --- /dev/null +++ b/app/views/projects/milestones/_milestone.html.haml @@ -0,0 +1,28 @@ +%li{class: "milestone milestone-#{milestone.closed? ? 'closed' : 'open'}", id: dom_id(milestone) } + .pull-right + - if can?(current_user, :admin_milestone, milestone.project) and milestone.active? + = link_to edit_project_milestone_path(milestone.project, milestone), class: "btn btn-small edit-milestone-link grouped" do + %i.icon-edit + Edit + - if milestone.can_be_closed? + = link_to 'Close', project_milestone_path(@project, milestone, milestone: {state_event: :close }), method: :put, remote: true, class: "btn btn-small btn-remove" + %h4 + = link_to_gfm truncate(milestone.title, length: 100), project_milestone_path(milestone.project, milestone) + - if milestone.expired? and not milestone.closed? + %span.cred (Expired) + %small + = milestone.expires_at + - if milestone.is_empty? + %span.muted Empty + - else + %div + %div + = link_to project_issues_path(milestone.project, milestone_id: milestone.id) do + = pluralize milestone.issues.count, 'Issue' + + = link_to project_merge_requests_path(milestone.project, milestone_id: milestone.id) do + = pluralize milestone.merge_requests.count, 'Merge Request' + + %span.light #{milestone.percent_complete}% complete + .progress.progress-info + .bar{style: "width: #{milestone.percent_complete}%;"} diff --git a/app/views/projects/milestones/edit.html.haml b/app/views/projects/milestones/edit.html.haml new file mode 100644 index 00000000000..b1bc3ba0eba --- /dev/null +++ b/app/views/projects/milestones/edit.html.haml @@ -0,0 +1 @@ += render "form" diff --git a/app/views/projects/milestones/index.html.haml b/app/views/projects/milestones/index.html.haml new file mode 100644 index 00000000000..1bc359398ab --- /dev/null +++ b/app/views/projects/milestones/index.html.haml @@ -0,0 +1,32 @@ += render "projects/issues/head" +.milestones_content + %h3.page_title + Milestones + - if can? current_user, :admin_milestone, @project + = link_to new_project_milestone_path(@project), class: "pull-right btn btn-primary", title: "New Milestone" do + %i.icon-plus + New Milestone + %br + + .row + .span3 + %ul.nav.nav-pills.nav-stacked + %li{class: ("active" if (params[:f] == "active" || !params[:f]))} + = link_to project_milestones_path(@project, f: "active") do + Active + %li{class: ("active" if params[:f] == "closed")} + = link_to project_milestones_path(@project, f: "closed") do + Closed + %li{class: ("active" if params[:f] == "all")} + = link_to project_milestones_path(@project, f: "all") do + All + .span9 + .ui-box + %ul.well-list + = render @milestones + + - if @milestones.blank? + %li + %h3.nothing_here_message Nothing to show here + + = paginate @milestones, theme: "gitlab" diff --git a/app/views/projects/milestones/new.html.haml b/app/views/projects/milestones/new.html.haml new file mode 100644 index 00000000000..b1bc3ba0eba --- /dev/null +++ b/app/views/projects/milestones/new.html.haml @@ -0,0 +1 @@ += render "form" diff --git a/app/views/projects/milestones/show.html.haml b/app/views/projects/milestones/show.html.haml new file mode 100644 index 00000000000..d16de0da390 --- /dev/null +++ b/app/views/projects/milestones/show.html.haml @@ -0,0 +1,106 @@ += render "projects/issues/head" +.row + .span6 + %h3.page_title + Milestone ##{@milestone.id} + %small + = @milestone.expires_at + .back_link + = link_to project_milestones_path(@project) do + ← To milestones list + .span6 + .pull-right + - unless @milestone.closed? + = link_to new_project_issue_path(@project, issue: { milestone_id: @milestone.id }), class: "btn btn-small grouped", title: "New Issue" do + %i.icon-plus + New Issue + = link_to 'Browse Issues', project_issues_path(@milestone.project, milestone_id: @milestone.id), class: "btn edit-milestone-link small grouped" + - if can?(current_user, :admin_milestone, @project) + = link_to edit_project_milestone_path(@project, @milestone), class: "btn btn-small grouped" do + %i.icon-edit + Edit + + + +- if @milestone.can_be_closed? + %hr + %p + %span All issues for this milestone are closed. You may close milestone now. + = link_to 'Close Milestone', project_milestone_path(@project, @milestone, milestone: {state_event: :close }), method: :put, class: "btn btn-small btn-remove" + +.ui-box.ui-box-show + .ui-box-head + %h4.box-title + - if @milestone.closed? + .error.status_info Closed + - elsif @milestone.expired? + .error.status_info Expired + + = gfm escape_once(@milestone.title) + + .ui-box-body + %p + Progress: + #{@milestone.closed_items_count} closed + – + #{@milestone.open_items_count} open + %span.pull-right= @milestone.expires_at + .progress.progress-info + .bar{style: "width: #{@milestone.percent_complete}%;"} + + + - if @milestone.description.present? + .ui-box-bottom + = preserve do + = markdown @milestone.description + + +%ul.nav.nav-tabs + %li.active + = link_to '#tab-issues', 'data-toggle' => 'tab' do + Issues + %span.badge= @issues.count + %li + = link_to '#tab-merge-requests', 'data-toggle' => 'tab' do + Merge Requests + %span.badge= @merge_requests.count + %li + = link_to '#tab-participants', 'data-toggle' => 'tab' do + Participants + %span.badge= @users.count + + +.tab-content + .tab-pane.active#tab-issues + .row + .span4 + = render('issues', title: 'Unstarted Issues (open and unassigned)', issues: @issues.opened.unassigned) + .span4 + = render('issues', title: 'Ongoing Issues (open and assigned)', issues: @issues.opened.assigned) + .span4 + = render('issues', title: 'Completed Issues (closed)', issues: @issues.closed) + + .tab-pane#tab-merge-requests + .row + .span6 + .ui-box + %h5.title Open + %ul.well-list + - @merge_requests.opened.each do |merge_request| + = render 'merge_request', merge_request: merge_request + .span6 + .ui-box + %h5.title Closed + %ul.well-list + - @merge_requests.closed.each do |merge_request| + = render 'merge_request', merge_request: merge_request + + .tab-pane#tab-participants + %ul.bordered-list + - @users.each do |user| + %li + = link_to user, title: user.name, class: "dark" do + = image_tag gravatar_icon(user.email, 32), class: "avatar s32" + %strong= truncate(user.name, lenght: 40) + %br + %small.cgray= user.username diff --git a/app/views/projects/milestones/update.js.haml b/app/views/projects/milestones/update.js.haml new file mode 100644 index 00000000000..3ff84915e97 --- /dev/null +++ b/app/views/projects/milestones/update.js.haml @@ -0,0 +1,2 @@ +:plain + $('##{dom_id(@milestone)}').fadeOut(); diff --git a/app/views/projects/network/_head.html.haml b/app/views/projects/network/_head.html.haml new file mode 100644 index 00000000000..62ab8b049ac --- /dev/null +++ b/app/views/projects/network/_head.html.haml @@ -0,0 +1,26 @@ +%h3.page_title Project Network Graph +%hr + +.clearfix + .pull-left + = render partial: 'shared/ref_switcher', locals: {destination: 'graph'} + .pull-left + = form_tag project_network_path(@project, @id), method: :get do |f| + .control-group + = label_tag :filter_ref, "Show only selected ref", class: 'control-label light' + .controls + = check_box_tag :filter_ref, 1, @options[:filter_ref] + - @options.each do |key, value| + = hidden_field_tag(key, value, id: nil) unless key == "filter_ref" + + .search.pull-right + = form_tag project_network_path(@project, @id), method: :get do |f| + .control-group + = label_tag :search , "Looking for commit:", class: 'control-label light' + .controls + = text_field_tag :q, @options[:q], placeholder: "Input SHA", class: "search-input xlarge" + = button_tag type: 'submit', class: 'btn vtop' do + %i.icon-search + - @options.each do |key, value| + = hidden_field_tag(key, value, id: nil) unless key == "q" + diff --git a/app/views/projects/network/show.html.haml b/app/views/projects/network/show.html.haml new file mode 100644 index 00000000000..a480ceaf995 --- /dev/null +++ b/app/views/projects/network/show.html.haml @@ -0,0 +1,18 @@ += render "head" +.graph_holder + %h4 + %small You can move around the graph by using the arrow keys. + #holder.graph + .loading.loading-gray + +:javascript + var branch_graph; + $("#filter_ref").click(function() { + $(this).closest('form').submit(); + }); + branch_graph = new BranchGraph($("#holder"), { + url: '#{project_network_path(@project, @ref, @options.merge(format: :json))}', + commit_url: '#{project_commit_path(@project, 'ae45ca32').gsub("ae45ca32", "%s")}', + ref: '#{@ref}', + commit_id: '#{@commit.id}' + }); diff --git a/app/views/projects/network/show.json.erb b/app/views/projects/network/show.json.erb new file mode 100644 index 00000000000..9a62cdb3dc9 --- /dev/null +++ b/app/views/projects/network/show.json.erb @@ -0,0 +1,23 @@ +<% self.formats = ["html"] %> + +<%= raw( + { + days: @graph.days.compact.map { |d| [d.day, d.strftime("%b")] }, + commits: @graph.commits.map do |c| + { + parents: parents_zip_spaces(c.parents(@graph.map), c.parent_spaces), + author: { + name: c.author_name, + email: c.author_email, + icon: gravatar_icon(c.author_email, 20) + }, + time: c.time, + space: c.spaces.first, + refs: get_refs(c), + id: c.sha, + date: c.date, + message: c.message, + } + end + }.to_json +) %> diff --git a/app/views/projects/notes/_diff_note_link.html.haml b/app/views/projects/notes/_diff_note_link.html.haml new file mode 100644 index 00000000000..377c926a204 --- /dev/null +++ b/app/views/projects/notes/_diff_note_link.html.haml @@ -0,0 +1,10 @@ +- note = @project.notes.new(@comments_target.merge({ line_code: line_code })) += link_to "", + "javascript:;", + class: "add-diff-note js-add-diff-note-button", + data: { noteable_type: note.noteable_type, + noteable_id: note.noteable_id, + commit_id: note.commit_id, + line_code: note.line_code, + discussion_id: note.discussion_id }, + title: "Add a comment to this line" diff --git a/app/views/projects/notes/_diff_notes_with_reply.html.haml b/app/views/projects/notes/_diff_notes_with_reply.html.haml new file mode 100644 index 00000000000..5a1a945f399 --- /dev/null +++ b/app/views/projects/notes/_diff_notes_with_reply.html.haml @@ -0,0 +1,11 @@ +- note = notes.first # example note +%tr.notes_holder + %td.notes_line{ colspan: 2 } + %span.btn.disabled + %i.icon-comment + = notes.count + %td.notes_content + %ul.notes{ rel: note.discussion_id } + = render notes + + = render "projects/notes/discussion_reply_button", note: note diff --git a/app/views/projects/notes/_discussion.html.haml b/app/views/projects/notes/_discussion.html.haml new file mode 100644 index 00000000000..14d81bbb5ce --- /dev/null +++ b/app/views/projects/notes/_discussion.html.haml @@ -0,0 +1,63 @@ +- note = discussion_notes.first +.discussion.js-details-container.js-toggler-container.open{ class: note.discussion_id } + .discussion-header + .discussion-actions + = link_to "javascript:;", class: "js-details-target turn-on js-toggler-target" do + %i.icon-eye-close + Hide discussion + = link_to "javascript:;", class: "js-details-target turn-off js-toggler-target" do + %i.icon-eye-open + Show discussion + = image_tag gravatar_icon(note.author_email), class: "avatar s32" + %div + = link_to_member(@project, note.author, avatar: false) + - if note.for_merge_request? + - if note.diff + started a discussion on this merge request diff + = link_to_merge_request_diff_line_note(note) + - else + started + %strong + %i.icon-remove + outdated + discussion on this merge request diff + - elsif note.for_commit? + started a discussion on commit + #{link_to note.noteable.short_id, project_commit_path(@project, note.noteable)} + = link_to_commit_diff_line_note(note) if note.for_diff_line? + - else + %cite.cgray started a discussion + %div + - last_note = discussion_notes.last + last updated by + = link_to_member(@project, last_note.author, avatar: false) + %span.discussion-last-update + = time_ago_in_words(last_note.updated_at) + ago + .discussion-body + - if note.for_diff_line? + - if note.diff + .content + .file= render "projects/notes/discussion_diff", discussion_notes: discussion_notes, note: note + - else + = link_to 'show outdated discussion', '#', class: 'js-show-outdated-discussion' + %div.hide.outdated-discussion + .content + .notes{ rel: discussion_notes.first.discussion_id } + = render discussion_notes + + + - else + .content + .notes{ rel: discussion_notes.first.discussion_id } + = render discussion_notes + = render "projects/notes/discussion_reply_button", note: discussion_notes.first + + -# will be shown when the other one is hidden + .discussion-hidden.content.hide + .note + %em Hidden discussion. + = link_to "javascript:;", class: "js-details-target js-toggler-target" do + %i.icon-eye-open + Show + diff --git a/app/views/projects/notes/_discussion_diff.html.haml b/app/views/projects/notes/_discussion_diff.html.haml new file mode 100644 index 00000000000..c3f41a1b6b5 --- /dev/null +++ b/app/views/projects/notes/_discussion_diff.html.haml @@ -0,0 +1,24 @@ +- diff = note.diff +.header + - if diff.deleted_file + %span= diff.old_path + - else + %span= diff.new_path + - if diff.a_mode && diff.b_mode && diff.a_mode != diff.b_mode + %span.file-mode= "#{diff.a_mode} → #{diff.b_mode}" + %br/ +.content + %table + - each_diff_line_near(diff, note.diff_file_index, note.line_code) do |line, type, line_code, line_new, line_old| + %tr.line_holder{ id: line_code } + - if type == "match" + %td.old_line= "..." + %td.new_line= "..." + %td.line_content.matched= line + - else + %td.old_line= raw(type == "new" ? " " : line_old) + %td.new_line= raw(type == "old" ? " " : line_new) + %td.line_content{class: "noteable_line #{type} #{line_code}", "line_code" => line_code}= raw "#{line} " + + - if line_code == note.line_code + = render "projects/notes/diff_notes_with_reply", notes: discussion_notes diff --git a/app/views/projects/notes/_discussion_reply_button.html.haml b/app/views/projects/notes/_discussion_reply_button.html.haml new file mode 100644 index 00000000000..d1c5ccc29db --- /dev/null +++ b/app/views/projects/notes/_discussion_reply_button.html.haml @@ -0,0 +1,10 @@ += link_to "javascript:;", + class: "btn reply-btn js-discussion-reply-button", + data: { noteable_type: note.noteable_type, + noteable_id: note.noteable_id, + commit_id: note.commit_id, + line_code: note.line_code, + discussion_id: note.discussion_id }, + title: "Add a reply" do + %i.icon-comment + Reply diff --git a/app/views/projects/notes/_form.html.haml b/app/views/projects/notes/_form.html.haml new file mode 100644 index 00000000000..7add2921830 --- /dev/null +++ b/app/views/projects/notes/_form.html.haml @@ -0,0 +1,37 @@ += form_for [@project, @note], remote: true, html: { multipart: true, id: nil, class: "new_note js-new-note-form common-note-form" } do |f| + + = note_target_fields + = f.hidden_field :commit_id + = f.hidden_field :line_code + = f.hidden_field :noteable_id + = f.hidden_field :noteable_type + + .note_text_and_preview.js-toggler-container + %a.js-note-preview-button.js-toggler-target.turn-off{ href: "javascript:;", title: "Preview", data: {url: preview_project_notes_path(@project)} } + %i.icon-eye-open + %a.js-note-edit-button.js-toggler-target.turn-off{ href: "javascript:;", title: "Edit" } + %i.icon-edit + + = f.text_area :note, size: 255, class: 'note_text js-note-text js-gfm-input turn-on' + .note_preview.js-note-preview.turn-off + + .hint + .pull-right Comments are parsed with #{link_to "GitLab Flavored Markdown", help_markdown_path, target: '_blank'}. + .clearfix + + .note-form-actions + .buttons + = f.submit 'Add Comment', class: "btn comment-btn grouped js-comment-button" + = yield(:note_actions) + + %a.btn.grouped.js-close-discussion-note-form Cancel + + .note-form-option + %a.choose-btn.btn.btn-small.js-choose-note-attachment-button + %i.icon-paper-clip + %span Choose File ... + + %span.file_name.js-attachment-filename File name... + = f.file_field :attachment, class: "js-note-attachment-input hide" + + .clearfix diff --git a/app/views/projects/notes/_form_errors.html.haml b/app/views/projects/notes/_form_errors.html.haml new file mode 100644 index 00000000000..0851536f0da --- /dev/null +++ b/app/views/projects/notes/_form_errors.html.haml @@ -0,0 +1,3 @@ +.error_message.js-errors + - note.errors.full_messages.each do |msg| + %div= msg diff --git a/app/views/projects/notes/_note.html.haml b/app/views/projects/notes/_note.html.haml new file mode 100644 index 00000000000..6a1159bc8f0 --- /dev/null +++ b/app/views/projects/notes/_note.html.haml @@ -0,0 +1,37 @@ +%li{ id: dom_id(note), class: dom_class(note), data: { discussion: note.discussion_id } } + .note-header + .note-actions + = link_to "##{dom_id(note)}", name: dom_id(note) do + %i.icon-link + Link here + + - if(note.author_id == current_user.id) || can?(current_user, :admin_note, @project) + = link_to project_note_path(@project, note), title: "Remove comment", method: :delete, confirm: 'Are you sure you want to remove comment?', remote: true, class: "danger js-note-delete" do + %i.icon-trash.cred + = image_tag gravatar_icon(note.author_email), class: "avatar s32" + = link_to_member(@project, note.author, avatar: false) + %span.note-last-update + = time_ago_in_words(note.updated_at) + ago + + - if note.upvote? + %span.vote.upvote.label.label-success + %i.icon-thumbs-up + \+1 + - if note.downvote? + %span.vote.downvote.label.label-error + %i.icon-thumbs-down + \-1 + + + .note-body + = preserve do + = markdown(note.note) + - if note.attachment.url + - if note.attachment.image? + = image_tag note.attachment.url, class: 'note-image-attach' + .attachment.pull-right + = link_to note.attachment.secure_url, target: "_blank" do + %i.icon-paper-clip + = note.attachment_identifier + .clear diff --git a/app/views/projects/notes/_notes.html.haml b/app/views/projects/notes/_notes.html.haml new file mode 100644 index 00000000000..ac8901fe704 --- /dev/null +++ b/app/views/projects/notes/_notes.html.haml @@ -0,0 +1,11 @@ +- if @discussions.present? + - @discussions.each do |discussion_notes| + - note = discussion_notes.first + - if note_for_main_target?(note) + = render discussion_notes + - else + = render 'discussion', discussion_notes: discussion_notes +- else + - @notes.each do |note| + - next unless note.author + = render note diff --git a/app/views/projects/notes/_notes_with_form.html.haml b/app/views/projects/notes/_notes_with_form.html.haml new file mode 100644 index 00000000000..ac28c7432ef --- /dev/null +++ b/app/views/projects/notes/_notes_with_form.html.haml @@ -0,0 +1,9 @@ +%ul#notes-list.notes +.js-notes-busy + +.js-main-target-form +- if can? current_user, :write_note, @project + = render "projects/notes/form" + +:javascript + NoteList.init("#{@target_id}", "#{@target_type}", "#{project_notes_path(@project)}"); diff --git a/app/views/projects/notes/create.js.haml b/app/views/projects/notes/create.js.haml new file mode 100644 index 00000000000..c113b3482ec --- /dev/null +++ b/app/views/projects/notes/create.js.haml @@ -0,0 +1,18 @@ +- if @note.valid? + var noteHtml = "#{escape_javascript(render @note)}"; + + - if note_for_main_target?(@note) + NoteList.appendNewNote(#{@note.id}, noteHtml); + - else + :plain + var firstDiscussionNoteHtml = "#{escape_javascript(render "projects/notes/diff_notes_with_reply", notes: [@note])}"; + NoteList.appendNewDiscussionNote("#{@note.discussion_id}", + firstDiscussionNoteHtml, + noteHtml); + +- else + var errorsHtml = "#{escape_javascript(render 'projects/notes/form_errors', note: @note)}"; + - if note_for_main_target?(@note) + NoteList.errorsOnForm(errorsHtml); + - else + NoteList.errorsOnForm(errorsHtml, "#{@note.discussion_id}"); diff --git a/app/views/projects/notes/index.js.haml b/app/views/projects/notes/index.js.haml new file mode 100644 index 00000000000..6c4ed203497 --- /dev/null +++ b/app/views/projects/notes/index.js.haml @@ -0,0 +1,4 @@ +- unless @notes.blank? + var notesHtml = "#{escape_javascript(render 'projects/notes/notes')}"; + - new_note_ids = @notes.map(&:id) + NoteList.setContent(#{new_note_ids}, notesHtml); diff --git a/app/views/projects/protected_branches/index.html.haml b/app/views/projects/protected_branches/index.html.haml new file mode 100644 index 00000000000..f741f2f0495 --- /dev/null +++ b/app/views/projects/protected_branches/index.html.haml @@ -0,0 +1,54 @@ += render "projects/commits/head" +.row + .span3 + = render "projects/repositories/filter" + .span9 + .alert + %p Protected branches designed to prevent push for all except #{link_to "masters", help_permissions_path, class: "vlink"}. + %p This ability allows: + %ul + %li keep stable branches secured + %li forced code review before merge to protected branches + %p Read more about project permissions #{link_to "here", help_permissions_path, class: "vlink"} + + - if can? current_user, :admin_project, @project + = form_for [@project, @protected_branch] do |f| + -if @protected_branch.errors.any? + .alert.alert-error + %ul + - @protected_branch.errors.full_messages.each do |msg| + %li= msg + + .entry.clearfix + = f.label :name, "Branch" + .span3 + = f.select(:name, @project.open_branches.map { |br| [br.name, br.name] } , {include_blank: "Select branch"}, {class: "chosen span3"}) + + = f.submit 'Protect', class: "btn-primary btn" + + - unless @branches.empty? + %table + %thead + %tr + %th Name + %th Last commit + %th + %tbody + - @branches.each do |branch| + %tr + %td + = link_to project_commits_path(@project, branch.name) do + %strong= branch.name + - if @project.root_ref?(branch.name) + %span.label default + %td + - if branch.commit + = link_to project_commit_path(@project, branch.commit.id) do + = truncate branch.commit.id.to_s, length: 10 + = time_ago_in_words(branch.commit.committed_date) + ago + - else + (branch was removed from repository) + %td + - if can? current_user, :admin_project, @project + = link_to 'Unprotect', [@project, branch], confirm: 'Branch will be writable for developers. Are you sure?', method: :delete, class: "btn btn-remove btn-small" diff --git a/app/views/projects/refs/logs_tree.js.haml b/app/views/projects/refs/logs_tree.js.haml new file mode 100644 index 00000000000..1bea286a879 --- /dev/null +++ b/app/views/projects/refs/logs_tree.js.haml @@ -0,0 +1,8 @@ +- @logs.each do |content_data| + - file_name = content_data[:file_name] + - commit = content_data[:commit] + + :plain + var row = $("table.table_#{@hex_path} tr.file_#{hexdigest(file_name)}"); + row.find("td.tree_time_ago").html('#{escape_javascript time_ago_in_words(commit.committed_date)} ago'); + row.find("td.tree_commit").html('#{escape_javascript render("projects/tree/tree_commit_column", commit: commit)}'); diff --git a/app/views/projects/repositories/_branch.html.haml b/app/views/projects/repositories/_branch.html.haml new file mode 100644 index 00000000000..dd91e14b66b --- /dev/null +++ b/app/views/projects/repositories/_branch.html.haml @@ -0,0 +1,26 @@ +- commit = Commit.new(Gitlab::Git::Commit.new(branch.commit)) +%tr + %td + = link_to project_commits_path(@project, branch.name) do + - if @project.protected_branch? branch.name + %i.icon-lock + - else + %i.icon-unlock + %strong= truncate(branch.name, length: 60) + - if branch.name == @repository.root_ref + %span.label default + %td + = link_to project_commit_path(@project, commit.id), class: 'commit_short_id' do + = commit.short_id + = image_tag gravatar_icon(commit.author_email), class: "avatar s16" + %span.light + = gfm escape_once(truncate(commit.title, length: 40)) + %span + = time_ago_in_words(commit.committed_date) + ago + %td + - if can? current_user, :download_code, @project + = link_to archive_project_repository_path(@project, ref: branch.name) do + %i.icon-download-alt + Download + diff --git a/app/views/projects/repositories/_feed.html.haml b/app/views/projects/repositories/_feed.html.haml new file mode 100644 index 00000000000..6bb75265ffb --- /dev/null +++ b/app/views/projects/repositories/_feed.html.haml @@ -0,0 +1,19 @@ +- commit = update +%tr + %td + = link_to project_commits_path(@project, commit.head.name) do + %strong + = commit.head.name + - if @project.root_ref?(commit.head.name) + %span.label default + + %td + %div + = link_to project_commits_path(@project, commit.id) do + %code= commit.short_id + = image_tag gravatar_icon(commit.author_email), class: "", width: 16 + = gfm escape_once(truncate(commit.title, length: 40)) + %td + %span.pull-right.cgray + = time_ago_in_words(commit.committed_date) + ago diff --git a/app/views/projects/repositories/_filter.html.haml b/app/views/projects/repositories/_filter.html.haml new file mode 100644 index 00000000000..e718d48190a --- /dev/null +++ b/app/views/projects/repositories/_filter.html.haml @@ -0,0 +1,9 @@ +%ul.nav.nav-pills.nav-stacked + = nav_link(path: 'repositories#show') do + = link_to 'Recent', project_repository_path(@project) + = nav_link(path: 'protected_branches#index') do + = link_to project_protected_branches_path(@project) do + Protected + %i.icon-lock + = nav_link(path: 'repositories#branches') do + = link_to 'All branches', branches_project_repository_path(@project) diff --git a/app/views/projects/repositories/branches.html.haml b/app/views/projects/repositories/branches.html.haml new file mode 100644 index 00000000000..2bdd304cdac --- /dev/null +++ b/app/views/projects/repositories/branches.html.haml @@ -0,0 +1,15 @@ += render "projects/commits/head" +.row + .span3 + = render "filter" + .span9 + - unless @branches.empty? + %table + %thead + %tr + %th Name + %th Last commit + %th + %tbody + - @branches.each do |branch| + = render "projects/repositories/branch", branch: branch diff --git a/app/views/projects/repositories/show.html.haml b/app/views/projects/repositories/show.html.haml new file mode 100644 index 00000000000..84a32e62426 --- /dev/null +++ b/app/views/projects/repositories/show.html.haml @@ -0,0 +1,14 @@ += render "projects/commits/head" +.row + .span3 + = render "filter" + .span9 + %table + %thead + %tr + %th Name + %th Last commit + %th + - @activities.each do |update| + = render "branch", branch: update.head + diff --git a/app/views/projects/repositories/stats.html.haml b/app/views/projects/repositories/stats.html.haml new file mode 100644 index 00000000000..dfdbc898912 --- /dev/null +++ b/app/views/projects/repositories/stats.html.haml @@ -0,0 +1,33 @@ += render "projects/commits/head" +.row + .span6 + %div#activity-chart.chart + %hr + %p + %b Total commits: + %span= @stats.commits_count + %p + %b Total files in #{@repository.root_ref}: + %span= @stats.files_count + %p + %b Authors: + %span= @stats.authors_count + + + .span6 + %h4 Top 50 Committers: + %ol.styled + - @stats.authors[0...50].each do |author| + %li + = image_tag gravatar_icon(author.email, 16), class: 'avatar s16' + = author.name + %small.light= author.email + .pull-right + = author.commits + + +:javascript + var labels = [#{@graph.labels.to_json}]; + var commits = [#{@graph.commits.join(', ')}]; + var title = "Commit activity for last #{@graph.weeks} weeks"; + Chart.init(labels, commits, title); diff --git a/app/views/projects/repositories/tags.html.haml b/app/views/projects/repositories/tags.html.haml new file mode 100644 index 00000000000..5972ea6c531 --- /dev/null +++ b/app/views/projects/repositories/tags.html.haml @@ -0,0 +1,36 @@ += render "projects/commits/head" +- unless @tags.empty? + %ul.bordered-list + - @tags.each do |tag| + - commit = Commit.new(Gitlab::Git::Commit.new(tag.commit)) + %li + %h5 + = link_to project_commits_path(@project, tag.name), class: "" do + %i.icon-tag + = tag.name + %small + = truncate(tag.message || '', length: 70) + .pull-right + %span.light + = time_ago_in_words(commit.committed_date) + ago + %div.prepend-left-20 + = link_to commit.short_id(8), project_commit_path(@project, commit), class: "monospace" + – + = link_to_gfm truncate(commit.title, length: 70), project_commit_path(@project, commit.id), class: "cdark" + + - if can? current_user, :download_code, @project + .pull-right + = link_to archive_project_repository_path(@project, ref: tag.name) do + %i.icon-download-alt + Download + + +- else + %h3.nothing_here_message + Repository has no tags yet. + %br + %small + Use git tag command to add a new one: + %br + %span.monospace git tag -a v1.4 -m 'version 1.4' diff --git a/app/views/projects/services/_form.html.haml b/app/views/projects/services/_form.html.haml new file mode 100644 index 00000000000..ff6769531c4 --- /dev/null +++ b/app/views/projects/services/_form.html.haml @@ -0,0 +1,48 @@ +%h3.page_title + - if @service.activated? + %span.cgreen + %i.icon-circle + - else + %span.cgray + %i.icon-circle-blank + = @service.title + +%p= @service.description + +.back_link + = link_to project_services_path(@project) do + ← to services + +%hr + += form_for(@service, as: :service, url: project_service_path(@project, @service.to_param), method: :put) do |f| + - if @service.errors.any? + .alert.alert-error + %ul + - @service.errors.full_messages.each do |msg| + %li= msg + + + .control-group + = f.label :active, "Active", class: "control-label" + .controls + = f.check_box :active + + - @service.fields.each do |field| + - name = field[:name] + - type = field[:type] + - placeholder = field[:placeholder] + + .control-group + = f.label name, class: "control-label" + .controls + - if type == 'text' + = f.text_field name, class: "input-xlarge", placeholder: placeholder + - elsif type == 'checkbox' + = f.check_box name + + .form-actions + = f.submit 'Save', class: 'btn btn-save' + + - if @service.valid? && @service.activated? + = link_to 'Test settings', test_project_service_path(@project, @service.to_param), class: 'btn btn-small' diff --git a/app/views/projects/services/edit.html.haml b/app/views/projects/services/edit.html.haml new file mode 100644 index 00000000000..bcc5832792f --- /dev/null +++ b/app/views/projects/services/edit.html.haml @@ -0,0 +1 @@ += render 'form' diff --git a/app/views/projects/services/index.html.haml b/app/views/projects/services/index.html.haml new file mode 100644 index 00000000000..6d254f66f1c --- /dev/null +++ b/app/views/projects/services/index.html.haml @@ -0,0 +1,16 @@ +%h3.page_title Services +%br + +%ul.bordered-list + - @services.each do |service| + %li + %h4 + - if service.activated? + %span.cgreen + %i.icon-circle + - else + %span.cgray + %i.icon-circle-blank + = link_to edit_project_service_path(@project, service.to_param) do + = service.title + %p= service.description diff --git a/app/views/projects/snippets/show.html.haml b/app/views/projects/snippets/show.html.haml index da93e4bdbb1..36161c5706c 100644 --- a/app/views/projects/snippets/show.html.haml +++ b/app/views/projects/snippets/show.html.haml @@ -10,4 +10,4 @@ = @snippet.author_name %br %div= render 'projects/snippets/blob' -%div#notes= render "notes/notes_with_form" +%div#notes= render "projects/notes/notes_with_form" diff --git a/app/views/projects/team_members/_form.html.haml b/app/views/projects/team_members/_form.html.haml new file mode 100644 index 00000000000..4e8f67702cf --- /dev/null +++ b/app/views/projects/team_members/_form.html.haml @@ -0,0 +1,24 @@ +%h3.page_title + = "New Team member(s)" +%hr += form_for @user_project_relation, as: :team_member, url: project_team_members_path(@project) do |f| + -if @user_project_relation.errors.any? + .alert.alert-error + %ul + - @user_project_relation.errors.full_messages.each do |msg| + %li= msg + + %h6 1. Choose people you want in the team + .clearfix + = f.label :user_ids, "People" + .input + = users_select_tag(:user_ids, multiple: true) + + %h6 2. Set access level for them + .clearfix + = f.label :project_access, "Project Access" + .input= select_tag :project_access, options_for_select(Project.access_options, @user_project_relation.project_access), class: "project-access-select chosen" + + .actions + = f.submit 'Add users', class: "btn btn-create" + = link_to "Cancel", project_team_index_path(@project), class: "btn btn-cancel" diff --git a/app/views/projects/team_members/_group_members.html.haml b/app/views/projects/team_members/_group_members.html.haml new file mode 100644 index 00000000000..7d9333d38e6 --- /dev/null +++ b/app/views/projects/team_members/_group_members.html.haml @@ -0,0 +1,10 @@ +.ui-box + %h5.title + %strong #{@group.name} Group + members (#{@group.users_groups.count}) + .pull-right + = link_to people_group_path(@group), class: 'btn btn-small' do + %i.icon-edit + %ul.well-list + - @group.users_groups.order('group_access DESC').each do |member| + = render 'users_groups/users_group', member: member, show_controls: false diff --git a/app/views/projects/team_members/_team.html.haml b/app/views/projects/team_members/_team.html.haml new file mode 100644 index 00000000000..99231e92152 --- /dev/null +++ b/app/views/projects/team_members/_team.html.haml @@ -0,0 +1,9 @@ +.team-table + - can_admin_project = (can? current_user, :admin_project, @project) + .ui-box + %h5.title + %strong #{@project.name} Project + members (#{members.count}) + %ul.well-list + - members.each do |team_member| + = render 'team_member', member: team_member, current_user_can_admin_project: can_admin_project diff --git a/app/views/projects/team_members/_team_member.html.haml b/app/views/projects/team_members/_team_member.html.haml new file mode 100644 index 00000000000..916cf2e7a87 --- /dev/null +++ b/app/views/projects/team_members/_team_member.html.haml @@ -0,0 +1,17 @@ +- user = member.user +%li{id: dom_id(user), class: "team_member_row access-#{member.human_access.downcase}"} + .pull-right + - if current_user_can_admin_project + - unless @project.personal? && user == current_user + .pull-left + = form_for(member, as: :team_member, url: project_team_member_path(@project, member.user)) do |f| + = f.select :project_access, options_for_select(UsersProject.access_roles, member.project_access), {}, class: "medium project-access-select span2 trigger-submit" + + = link_to project_team_member_path(@project, user), confirm: remove_from_project_team_message(@project, user), method: :delete, class: "btn-tiny btn btn-remove", title: 'Remove user from team' do + %i.icon-minus.icon-white + = image_tag gravatar_icon(user.email, 32), class: "avatar s32" + %p + %strong= user.name + %span.cgray= user.username + + diff --git a/app/views/projects/team_members/import.html.haml b/app/views/projects/team_members/import.html.haml new file mode 100644 index 00000000000..2b22c917a16 --- /dev/null +++ b/app/views/projects/team_members/import.html.haml @@ -0,0 +1,15 @@ +%h3.page_title + = "Import team from another project" +%hr +%p.slead + Read more about project team import #{link_to "here", '#', class: 'vlink'}. += form_tag apply_import_project_team_members_path(@project), method: 'post' do + %p.slead Choose project you want to use as team source: + .padded + = label_tag :source_project_id, "Project" + .input= select_tag(:source_project_id, options_from_collection_for_select(current_user.authorized_projects, :id, :name_with_namespace), prompt: "Select project", class: "chosen xxlarge", required: true) + + .actions + = submit_tag 'Import', class: "btn btn-save" + = link_to "Cancel", project_team_index_path(@project), class: "btn btn-cancel" + diff --git a/app/views/projects/team_members/index.html.haml b/app/views/projects/team_members/index.html.haml new file mode 100644 index 00000000000..8f81390ca13 --- /dev/null +++ b/app/views/projects/team_members/index.html.haml @@ -0,0 +1,16 @@ +%h3.page_title + Users with access to this project + + - if can? current_user, :admin_team_member, @project + %span.pull-right + = link_to import_project_team_members_path(@project), class: "btn btn-small grouped", title: "Import team from another project" do + Import team from another project + = link_to new_project_team_member_path(@project), class: "btn btn-primary small grouped", title: "New Team Member" do + New Team Member + +%p.light + Read more about project permissions + %strong= link_to "here", help_permissions_path, class: "vlink" +- if @group + = render "group_members" += render "team", members: @users_projects diff --git a/app/views/projects/team_members/new.html.haml b/app/views/projects/team_members/new.html.haml new file mode 100644 index 00000000000..b1bc3ba0eba --- /dev/null +++ b/app/views/projects/team_members/new.html.haml @@ -0,0 +1 @@ += render "form" diff --git a/app/views/projects/team_members/update.js.haml b/app/views/projects/team_members/update.js.haml new file mode 100644 index 00000000000..c68fe9574a2 --- /dev/null +++ b/app/views/projects/team_members/update.js.haml @@ -0,0 +1,6 @@ +- if @user_project_relation.valid? + :plain + $("##{dom_id(@user_project_relation)}").effect("highlight", {color: "#529214"}, 1000);; +- else + :plain + $("##{dom_id(@user_project_relation)}").effect("highlight", {color: "#D12F19"}, 1000);; diff --git a/app/views/projects/tree/_blob_item.html.haml b/app/views/projects/tree/_blob_item.html.haml new file mode 100644 index 00000000000..ec15b608f85 --- /dev/null +++ b/app/views/projects/tree/_blob_item.html.haml @@ -0,0 +1,9 @@ +%tr{ class: "tree-item #{tree_hex_class(blob_item)}" } + %td.tree-item-file-name + = tree_icon(type) + %strong= link_to truncate(blob_item.name, length: 40), project_blob_path(@project, tree_join(@id || @commit.id, blob_item.name)) + %td.tree_time_ago.cgray + %span.log_loading.hide + Loading commit data... + = image_tag "ajax_loader_tree.gif", width: 14 + %td.tree_commit{ colspan: 2 } diff --git a/app/views/projects/tree/_readme.html.haml b/app/views/projects/tree/_readme.html.haml new file mode 100644 index 00000000000..e9bb112745b --- /dev/null +++ b/app/views/projects/tree/_readme.html.haml @@ -0,0 +1,13 @@ +.file_holder#README + .file_title + %i.icon-file + = readme.name + .file_content.wiki + - if gitlab_markdown?(readme.name) + = preserve do + = markdown(readme.data) + - elsif plain_text_readme?(readme.name) + %pre.clean + = readme.data + - else + = raw GitHub::Markup.render(readme.name, readme.data) diff --git a/app/views/projects/tree/_submodule_item.html.haml b/app/views/projects/tree/_submodule_item.html.haml new file mode 100644 index 00000000000..092a024afbc --- /dev/null +++ b/app/views/projects/tree/_submodule_item.html.haml @@ -0,0 +1,11 @@ +- url = submodule_item.url(@ref) rescue '' +- name = submodule_item.basename +- return '' unless url +%tr{ class: "tree-item", url: url } + %td.tree-item-file-name + = image_tag "submodule.png" + %strong= truncate(name, length: 40) + %td + %code= submodule_item.id[0..10] + %td{ colspan: 2 } + = link_to truncate(url, length: 40), url diff --git a/app/views/projects/tree/_tree.html.haml b/app/views/projects/tree/_tree.html.haml new file mode 100644 index 00000000000..0b1148b3e74 --- /dev/null +++ b/app/views/projects/tree/_tree.html.haml @@ -0,0 +1,51 @@ +%ul.breadcrumb + %li + %i.icon-angle-right + = link_to project_tree_path(@project, @ref) do + = @project.path + - tree_breadcrumbs(tree, 6) do |title, path| + \/ + %li + - if path + = link_to truncate(title, length: 40), project_tree_path(@project, path) + - else + = link_to title, '#' + +%div#tree-content-holder.tree-content-holder + %table#tree-slider{class: "table_#{@hex_path} tree-table" } + %thead + %tr + %th Name + %th Last Update + %th + Last Commit + + %i.icon-angle-right + + %small.light + = link_to @commit.short_id, project_commit_path(@project, @commit) + – + = truncate(@commit.title, length: 50) + %th= link_to "history", project_commits_path(@project, @id), class: "btn btn-tiny pull-right" + + - if tree.up_dir? + %tr.tree-item + %td.tree-item-file-name + = image_tag "file_empty.png", size: '16x16' + = link_to "..", project_tree_path(@project, up_dir_path(tree)) + %td + %td + %td + + = render_tree(tree) + + - if tree.readme + = render "projects/tree/readme", readme: tree.readme + +%div.tree_progress + +:javascript + // Load last commit log for each file in tree + $('#tree-slider').waitForImages(function() { + ajaxGet('#{@logs_path}'); + }); diff --git a/app/views/projects/tree/_tree_commit_column.html.haml b/app/views/projects/tree/_tree_commit_column.html.haml new file mode 100644 index 00000000000..7ae2582c130 --- /dev/null +++ b/app/views/projects/tree/_tree_commit_column.html.haml @@ -0,0 +1,2 @@ +%span.tree_author= commit_author_link(commit, avatar: true) += link_to_gfm truncate(commit.title, length: 80), project_commit_path(@project, commit.id), class: "tree-commit-link" diff --git a/app/views/projects/tree/_tree_item.html.haml b/app/views/projects/tree/_tree_item.html.haml new file mode 100644 index 00000000000..0a76d5c21b6 --- /dev/null +++ b/app/views/projects/tree/_tree_item.html.haml @@ -0,0 +1,9 @@ +%tr{ class: "tree-item #{tree_hex_class(tree_item)}" } + %td.tree-item-file-name + = tree_icon(type) + %strong= link_to truncate(tree_item.name, length: 40), project_tree_path(@project, tree_join(@id || @commit.id, tree_item.name)) + %td.tree_time_ago.cgray + %span.log_loading.hide + Loading commit data... + = image_tag "ajax_loader_tree.gif", width: 14 + %td.tree_commit{ colspan: 2 } diff --git a/app/views/projects/tree/show.html.haml b/app/views/projects/tree/show.html.haml new file mode 100644 index 00000000000..0f7692aba7f --- /dev/null +++ b/app/views/projects/tree/show.html.haml @@ -0,0 +1,4 @@ +%div.tree-ref-holder + = render 'shared/ref_switcher', destination: 'tree', path: @path +%div#tree-holder.tree-holder + = render "tree", tree: @tree diff --git a/app/views/projects/walls/show.html.haml b/app/views/projects/walls/show.html.haml new file mode 100644 index 00000000000..88aecee0815 --- /dev/null +++ b/app/views/projects/walls/show.html.haml @@ -0,0 +1,23 @@ +%div.wall-page + %ul.notes + + - if can? current_user, :write_note, @project + .note-form-holder + = form_for [@project, @note], remote: true, html: { multipart: true, id: nil, class: "new_note wall-note-form" } do |f| + = note_target_fields + .note_text_and_preview + = f.text_area :note, size: 255, class: 'note_text js-note-text js-gfm-input turn-on' + .note-form-actions + .buttons + = f.submit 'Add Comment', class: "btn comment-btn grouped js-comment-button" + + .note-form-option + %a.choose-btn.btn.btn-small.js-choose-note-attachment-button + %i.icon-paper-clip + %span Choose File ... + + %span.file_name.js-attachment-filename File name... + = f.file_field :attachment, class: "js-note-attachment-input hide" + + .hint.pull-right CTRL + Enter to send message + .clearfix diff --git a/app/views/projects/wikis/_form.html.haml b/app/views/projects/wikis/_form.html.haml new file mode 100644 index 00000000000..7cf08815f78 --- /dev/null +++ b/app/views/projects/wikis/_form.html.haml @@ -0,0 +1,36 @@ += form_for [@project, @wiki] do |f| + -if @wiki.errors.any? + #error_explanation + %h2= "#{pluralize(@wiki.errors.count, "error")} prohibited this wiki from being saved:" + %ul + - @wiki.errors.full_messages.each do |msg| + %li= msg + + .ui-box.ui-box-show + .ui-box-head + %h3.page_title + .edit-wiki-header + = @wiki.title.titleize + = f.hidden_field :title, value: @wiki.title + = f.select :format, options_for_select(GollumWiki::MARKUPS, {selected: @wiki.format}), {}, class: "pull-right input-medium" + = f.label :format, class: "pull-right", style: "padding-right: 20px;" + .ui-box-body + .input + %span.cgray + Wiki content is parsed with #{link_to "GitLab Flavored Markdown", help_markdown_path, target: '_blank'}. + To link to a (new) page you can just type + %code [Link Title](page-slug) + \. + + .ui-box-bottom + = f.label :content + .input= f.text_area :content, class: 'span8 js-gfm-input' + .ui-box-bottom + = f.label :commit_message + .input= f.text_field :message, class: 'span8' + .actions + = f.submit 'Save', class: "btn-save btn" + - if @wiki && @wiki.persisted? + = link_to "Cancel", project_wiki_path(@project, @wiki), class: "btn btn-cancel" + - else + = link_to "Cancel", project_wiki_path(@project, :home), class: "btn btn-cancel" diff --git a/app/views/projects/wikis/_main_links.html.haml b/app/views/projects/wikis/_main_links.html.haml new file mode 100644 index 00000000000..cb8ccf81c7b --- /dev/null +++ b/app/views/projects/wikis/_main_links.html.haml @@ -0,0 +1,8 @@ +%span.pull-right + - if (@wiki && @wiki.persisted?) + = link_to history_project_wiki_path(@project, @wiki), class: "btn btn-small grouped" do + Page History + - if can?(current_user, :write_wiki, @project) + = link_to edit_project_wiki_path(@project, @wiki), class: "btn btn-small grouped" do + %i.icon-edit + Edit diff --git a/app/views/projects/wikis/_nav.html.haml b/app/views/projects/wikis/_nav.html.haml new file mode 100644 index 00000000000..d62b46a7e5b --- /dev/null +++ b/app/views/projects/wikis/_nav.html.haml @@ -0,0 +1,19 @@ +%ul.nav.nav-tabs + = nav_link(html_options: {class: params[:id] == 'home' ? 'active' : '' }) do + = link_to 'Home', project_wiki_path(@project, :home) + + = nav_link(path: 'wikis#pages') do + = link_to 'Pages', pages_project_wikis_path(@project) + + = nav_link(path: 'wikis#git_access') do + = link_to git_access_project_wikis_path(@project) do + %i.icon-download-alt + Git Access + + - if can?(current_user, :write_wiki, @project) + .pull-right + = link_to '#', class: "add-new-wiki btn btn-small btn-primary" do + %i.icon-plus + New Page + += render 'projects/wikis/new' diff --git a/app/views/projects/wikis/_new.html.haml b/app/views/projects/wikis/_new.html.haml new file mode 100644 index 00000000000..ca8e7c1b4b4 --- /dev/null +++ b/app/views/projects/wikis/_new.html.haml @@ -0,0 +1,12 @@ +%div#modal-new-wiki.modal.hide + .modal-header + %a.close{href: "#"} × + %h3.page_title New Wiki Page + .modal-body + = label_tag :new_wiki_path do + %span Page slug + = text_field_tag :new_wiki_path, nil, placeholder: 'how-to-setup', class: 'input-xlarge', required: true, :'data-wikis-path' => project_wikis_path(@project) + %p.hint + Please dont use spaces and slashes + .modal-footer + = link_to 'Build', '#', class: 'build-new-wiki btn btn-create' diff --git a/app/views/projects/wikis/edit.html.haml b/app/views/projects/wikis/edit.html.haml new file mode 100644 index 00000000000..4e318c92db3 --- /dev/null +++ b/app/views/projects/wikis/edit.html.haml @@ -0,0 +1,10 @@ += render 'nav' +%h3.page_title + Editing page + = render 'main_links' += render 'form' + +.pull-right + - if @wiki.persisted? && can?(current_user, :admin_wiki, @project) + = link_to project_wiki_path(@project, @wiki), confirm: "Are you sure you want to delete this page?", method: :delete, class: "btn btn-small btn-remove" do + Delete this page diff --git a/app/views/projects/wikis/empty.html.haml b/app/views/projects/wikis/empty.html.haml new file mode 100644 index 00000000000..08b59f0328b --- /dev/null +++ b/app/views/projects/wikis/empty.html.haml @@ -0,0 +1,4 @@ +%h3.page_title Empty page +%hr +.error_message + You are not allowed to create wiki pages diff --git a/app/views/projects/wikis/git_access.html.haml b/app/views/projects/wikis/git_access.html.haml new file mode 100644 index 00000000000..71e2b48d370 --- /dev/null +++ b/app/views/projects/wikis/git_access.html.haml @@ -0,0 +1,37 @@ += render 'nav' +%h3.page_title + Git Access + %strong= @gollum_wiki.path_with_namespace + = render 'main_links' + +%br +.content + .project_clone_panel + .row + .span7 + .form-horizontal + .input-prepend.project_clone_holder + %button{class: "btn active", :"data-clone" => @gollum_wiki.ssh_url_to_repo} SSH + %button{class: "btn", :"data-clone" => @gollum_wiki.http_url_to_repo}= Gitlab.config.gitlab.protocol.upcase + = text_field_tag :project_clone, @gollum_wiki.url_to_repo, class: "one_click_select input-xxlarge", readonly: true + .git-empty + %fieldset + %legend Install Gollum: + %pre.dark + :preserve + gem install gollum + + %legend Clone Your Wiki: + %pre.dark + :preserve + git clone #{@gollum_wiki.ssh_url_to_repo} + cd #{@gollum_wiki.path} + + %legend Start Gollum And Edit Locally: + %pre.dark + :preserve + gollum + == Sinatra/1.3.5 has taken the stage on 4567 for development with backup from Thin + >> Thin web server (v1.5.0 codename Knife) + >> Maximum connections set to 1024 + >> Listening on 0.0.0.0:4567, CTRL+C to stop diff --git a/app/views/projects/wikis/history.html.haml b/app/views/projects/wikis/history.html.haml new file mode 100644 index 00000000000..138c384353d --- /dev/null +++ b/app/views/projects/wikis/history.html.haml @@ -0,0 +1,31 @@ += render 'nav' +%h3.page_title + %span.light History for + = @wiki.title.titleize + = render 'main_links' +%br +%table + %thead + %tr + %th Page version + %th Author + %th Commit Message + %th Last updated + %th Format + %tbody + - @wiki.versions.each do |version| + - commit = version + %tr + %td + = link_to project_wiki_path(@project, @wiki, version_id: commit.id) do + = commit.short_id + %td + = commit_author_link(commit, avatar: true, size: 24) + %td + = commit.title + %td + = time_ago_in_words(version.date) + ago + %td + %strong + = @wiki.page.wiki.page(@wiki.page.name, commit.id).try(:format) diff --git a/app/views/projects/wikis/pages.html.haml b/app/views/projects/wikis/pages.html.haml new file mode 100644 index 00000000000..07e942ec62f --- /dev/null +++ b/app/views/projects/wikis/pages.html.haml @@ -0,0 +1,25 @@ += render 'nav' +%h3.page_title + All Pages + = render 'main_links' +%br +%table + %thead + %tr + %th Title + %th Format + %th Last updated + %th Updated by + %tbody + - @wiki_pages.each do |wiki_page| + %tr + %td + %strong= link_to wiki_page.title.titleize, project_wiki_path(@project, wiki_page) + %td + %strong= wiki_page.format + %td + = wiki_page.created_at.to_s(:short) do + (#{time_ago_in_words(wiki_page.created_at)} + ago) + %td + = commit_author_link(wiki_page.version, avatar: true, size: 24) diff --git a/app/views/projects/wikis/show.html.haml b/app/views/projects/wikis/show.html.haml new file mode 100644 index 00000000000..d9d57e2d8be --- /dev/null +++ b/app/views/projects/wikis/show.html.haml @@ -0,0 +1,16 @@ += render 'nav' +%h3.page_title + = @wiki.title.titleize + = render 'main_links' +%br +- if @wiki.historical? + .warning_message + This is an old version of this page. + You can view the #{link_to "most recent version", project_wiki_path(@project, @wiki)} or browse the #{link_to "history", history_project_wiki_path(@project, @wiki)}. + +.file_holder + .file_content.wiki + = preserve do + = render_wiki_content(@wiki) + +%p.time Last edited by #{commit_author_link(@wiki.version, avatar: true, size: 16)} #{time_ago_in_words @wiki.created_at} ago |