Commit 6c47bcef02c96ab61e2bd632d01f03fa1c8340e6
Exists in
master
and in
4 other branches
Merge branch 'refactor_merge_requests'
Showing
13 changed files
with
258 additions
and
122 deletions
Show diff stats
app/assets/images/.directory
app/assets/javascripts/merge_requests.js
... | ... | @@ -0,0 +1,59 @@ |
1 | +var MergeRequest = { | |
2 | + diffs_loaded: false, | |
3 | + commits_loaded: false, | |
4 | + | |
5 | + init: | |
6 | + function() { | |
7 | + $(".merge-tabs a").live("click", function() { | |
8 | + $(".merge-tabs a").removeClass("active"); | |
9 | + $(this).addClass("active"); | |
10 | + }); | |
11 | + | |
12 | + $(".merge-tabs a.merge-notes-tab").live("click", function() { | |
13 | + $(".merge-request-commits, .merge-request-diffs").hide(); | |
14 | + $(".merge-request-notes").show(); | |
15 | + }); | |
16 | + | |
17 | + $(".merge-tabs a.merge-commits-tab").live("click", function() { | |
18 | + if(!MergeRequest.commits_loaded) { | |
19 | + MergeRequest.loadCommits(); | |
20 | + } | |
21 | + $(".merge-request-notes, .merge-request-diffs").hide(); | |
22 | + $(".merge-request-commits").show(); | |
23 | + }); | |
24 | + | |
25 | + $(".merge-tabs a.merge-diffs-tab").live("click", function() { | |
26 | + if(!MergeRequest.diffs_loaded) { | |
27 | + MergeRequest.loadDiff(); | |
28 | + } | |
29 | + $(".merge-request-notes, .merge-request-commits").hide(); | |
30 | + $(".merge-request-diffs").show(); | |
31 | + }); | |
32 | + }, | |
33 | + | |
34 | + loadCommits: | |
35 | + function() { | |
36 | + $(".dashboard-loader").show(); | |
37 | + $.ajax({ | |
38 | + type: "GET", | |
39 | + url: $(".merge-commits-tab").attr("data-url"), | |
40 | + complete: function(){ | |
41 | + MergeRequest.commits_loaded = true; | |
42 | + $(".merge-request-notes, .merge-request-diffs").hide(); | |
43 | + $(".dashboard-loader").hide()}, | |
44 | + dataType: "script"}); | |
45 | + }, | |
46 | + | |
47 | + loadDiff: | |
48 | + function() { | |
49 | + $(".dashboard-loader").show(); | |
50 | + $.ajax({ | |
51 | + type: "GET", | |
52 | + url: $(".merge-diffs-tab").attr("data-url"), | |
53 | + complete: function(){ | |
54 | + MergeRequest.diffs_loaded = true; | |
55 | + $(".merge-request-notes, .merge-request-commits").hide(); | |
56 | + $(".dashboard-loader").hide()}, | |
57 | + dataType: "script"}); | |
58 | + } | |
59 | +} | ... | ... |
app/assets/stylesheets/projects.css.scss
... | ... | @@ -438,42 +438,6 @@ body.project-page table.no-borders td{ |
438 | 438 | border:none; |
439 | 439 | } |
440 | 440 | |
441 | -#gitlab-tabs { | |
442 | - .ui-tabs-nav { | |
443 | - border-bottom: 1px solid #DEDFE1; | |
444 | - | |
445 | - li { | |
446 | - background: none; | |
447 | - border:none; | |
448 | - font-size: 16px; | |
449 | - margin: 0; | |
450 | - padding: 0; | |
451 | - | |
452 | - a { | |
453 | - margin: 0; | |
454 | - padding: 10px 16px; | |
455 | - width:150px; | |
456 | - } | |
457 | - | |
458 | - &.ui-tabs-selected { | |
459 | - background-image: -webkit-gradient(linear, 0 0, 0 26, color-stop(0.076, #fefefe), to(#F6F7F8)); | |
460 | - background-image: -webkit-linear-gradient(#fefefe 7.6%, #F6F7F8); | |
461 | - background-image: -moz-linear-gradient(#fefefe 7.6%, #F6F7F8); | |
462 | - background-image: -o-linear-gradient(#fefefe 7.6%, #F6F7F8); | |
463 | - font-weight: bold; | |
464 | - border:1px solid #DEDFE1; | |
465 | - border-bottom: 1px solid #DEDFE1; | |
466 | - -webkit-border-top-left-radius: 5px; | |
467 | - -webkit-border-top-right-radius: 5px; | |
468 | - -moz-border-radius-topleft: 5px; | |
469 | - -moz-border-radius-topright: 5px; | |
470 | - border-top-left-radius: 5px; | |
471 | - border-top-right-radius: 5px; | |
472 | - } | |
473 | - } | |
474 | - } | |
475 | -} | |
476 | - | |
477 | 441 | .ajax-tab-loading { |
478 | 442 | padding:40px; |
479 | 443 | display:none; |
... | ... | @@ -587,3 +551,82 @@ h4.middle-panel { |
587 | 551 | margin-right:30px; |
588 | 552 | display:none; |
589 | 553 | } |
554 | + | |
555 | +.merge-tabs { | |
556 | + margin: 0; | |
557 | + border: 1px solid #ccc; | |
558 | + padding: 5px; | |
559 | + font-size: 12px; | |
560 | + background: #F7F7F7; | |
561 | + margin-bottom:20px; | |
562 | + height:26px; | |
563 | + | |
564 | + .tab { | |
565 | + font-weight: bold; | |
566 | + text-transform: uppercase; | |
567 | + border-right: 1px solid #ddd; | |
568 | + background:none; | |
569 | + padding: 10px; | |
570 | + width:60px; | |
571 | + float:left; | |
572 | + position:relative; | |
573 | + top:-5px; | |
574 | + left:-5px; | |
575 | + height:16px; | |
576 | + padding-left:34px; | |
577 | + | |
578 | + span { | |
579 | + width: 20px; | |
580 | + height: 20px; | |
581 | + display: inline-block; | |
582 | + position: absolute; | |
583 | + left: 8px; | |
584 | + top: 8px; | |
585 | + } | |
586 | + | |
587 | + &.active { | |
588 | + background: #eaeaea; | |
589 | + } | |
590 | + } | |
591 | +} | |
592 | + | |
593 | +.merge-notes-tab span { background: url("images.png") no-repeat -161px -1px; } | |
594 | +.merge-commits-tab span { background: url("images.png") no-repeat -86px 1px; } | |
595 | +.merge-diffs-tab span { background: url("images.png") no-repeat -118px 1px; } | |
596 | +.merge-tabs .dashboard-loader { padding:8px; } | |
597 | + | |
598 | +.user-mention { | |
599 | + color: #2FA0BB; | |
600 | + font-weight: bold; | |
601 | +} | |
602 | + | |
603 | +.author { | |
604 | + color: #999; | |
605 | +} | |
606 | + | |
607 | + | |
608 | +.red-button{ | |
609 | + border-radius: 5px; | |
610 | + font-size: 12px; | |
611 | + font-weight: bold; | |
612 | + padding: 5px 17px; | |
613 | + border: 1px solid #999; | |
614 | + color: #666; | |
615 | + display: inline-block; | |
616 | + box-shadow: 0 1px 2px rgba(0,0,0,.3); | |
617 | + background: #D12F19; | |
618 | + color: white; | |
619 | +} | |
620 | + | |
621 | +.positive-button{ | |
622 | + border-radius: 5px; | |
623 | + font-size: 12px; | |
624 | + font-weight: bold; | |
625 | + padding: 5px 17px; | |
626 | + border: 1px solid #999; | |
627 | + color: #666; | |
628 | + display: inline-block; | |
629 | + box-shadow: 0 1px 2px rgba(0,0,0,.3); | |
630 | + background: #4A2; | |
631 | + color: white; | |
632 | +} | ... | ... |
app/assets/stylesheets/style.scss
... | ... | @@ -130,7 +130,7 @@ table tr:hover, .listed_items tr.odd:hover{background-color:#FFFFCF} |
130 | 130 | border-radius: 5px; |
131 | 131 | font-size: 12px; |
132 | 132 | font-weight: bold; |
133 | - padding: 6px 20px; | |
133 | + padding: 5px 17px; | |
134 | 134 | border: 1px solid #999; |
135 | 135 | color: #666; |
136 | 136 | display: inline-block; | ... | ... |
app/controllers/merge_requests_controller.rb
... | ... | @@ -30,14 +30,11 @@ class MergeRequestsController < ApplicationController |
30 | 30 | |
31 | 31 | def commits |
32 | 32 | @commits = @project.repo.commits_between(@merge_request.target_branch, @merge_request.source_branch).map {|c| Commit.new(c)} |
33 | - render :template => "merge_requests/_commits", :layout => false | |
34 | 33 | end |
35 | 34 | |
36 | 35 | def diffs |
37 | 36 | @diffs = @merge_request.diffs |
38 | 37 | @commit = @merge_request.last_commit |
39 | - | |
40 | - render :template => "merge_requests/_diffs", :layout => false | |
41 | 38 | end |
42 | 39 | |
43 | 40 | def new | ... | ... |
app/models/project.rb
... | ... | @@ -90,6 +90,10 @@ class Project < ActiveRecord::Base |
90 | 90 | users_projects.find_by_user_id(user.id) if user |
91 | 91 | end |
92 | 92 | |
93 | + def team_member_by_id(user_id) | |
94 | + users_projects.find_by_user_id(user_id) | |
95 | + end | |
96 | + | |
93 | 97 | def fresh_issues(n) |
94 | 98 | issues.includes(:project, :author).order("created_at desc").first(n) |
95 | 99 | end | ... | ... |
app/views/merge_requests/_form.html.haml
1 | -%div.merge-request-form-holder | |
2 | - .ui-box.width-100p | |
3 | - %h3 | |
4 | - = @merge_request.new_record? ? "New Merge Request" : "Edit Merge Request ##{@merge_request.id}" | |
5 | - = form_for [@project, @merge_request] do |f| | |
6 | - .data | |
7 | - %table.no-borders | |
8 | - -if @merge_request.errors.any? | |
9 | - %tr | |
10 | - %td Errors | |
11 | - %td | |
12 | - #error_explanation | |
13 | - - @merge_request.errors.full_messages.each do |msg| | |
14 | - %span= msg | |
15 | - %br | |
1 | += form_for [@project, @merge_request] do |f| | |
2 | + %div | |
3 | + %span.entity-info | |
4 | + - if @merge_request.new_record? | |
5 | + = link_to project_merge_requests_path(@project) do | |
6 | + .entity-button | |
7 | + Back | |
8 | + %i | |
9 | + - else | |
10 | + = link_to project_merge_request_path(@project, @merge_request) do | |
11 | + .entity-button | |
12 | + Back | |
13 | + %i | |
14 | + | |
15 | + %h2= @merge_request.new_record? ? "New Merge Request" : "Edit Merge Request ##{@merge_request.id}" | |
16 | + | |
17 | + %hr | |
18 | + %table.no-borders | |
19 | + -if @merge_request.errors.any? | |
20 | + %tr | |
21 | + %td{:colspan => 2} | |
22 | + #error_explanation | |
23 | + - @merge_request.errors.full_messages.each do |msg| | |
24 | + %span= msg | |
25 | + %br | |
26 | + %tr | |
27 | + %td= f.label :source_branch, "From" | |
28 | + %td= f.select(:source_branch, @project.heads.map(&:name), { :include_blank => "Select branch" }, :style => "width:250px") | |
29 | + %tr | |
30 | + %td= f.label :target_branch, "To" | |
31 | + %td= f.select(:target_branch, @project.heads.map(&:name), { :include_blank => "Select branch" }, :style => "width:250px") | |
32 | + %tr | |
33 | + %td= f.label :assignee_id, "Assign to" | |
34 | + %td= f.select(:assignee_id, @project.users.all.collect {|p| [ p.name, p.id ] }, { :include_blank => "Select user" }, :style => "width:250px") | |
35 | + = f.text_area :title, :style => "width:718px; height:100px", :maxlength => 255 | |
36 | + %br | |
37 | + %br | |
38 | + .merge-tabs | |
39 | + = f.submit 'Save', :class => "grey-button" | |
40 | + | |
41 | + - unless @merge_request.new_record? | |
42 | + .right | |
43 | + = link_to 'Remove', [@project, @merge_request], :confirm => 'Are you sure?', :method => :delete, :class => "red-button" | |
44 | + | |
45 | + | |
16 | 46 | |
17 | - %tr | |
18 | - %td= f.label :title | |
19 | - %td= f.text_field :title | |
20 | - %tr | |
21 | - %td= f.label :source_branch, "From" | |
22 | - %td= f.select(:source_branch, @project.heads.map(&:name), { :include_blank => "Select branch" }) | |
23 | - %tr | |
24 | - %td= f.label :target_branch, "To" | |
25 | - %td= f.select(:target_branch, @project.heads.map(&:name), { :include_blank => "Select branch" }) | |
26 | - %tr | |
27 | - %td= f.label :assignee_id, "Assign to" | |
28 | - %td= f.select(:assignee_id, @project.users.all.collect {|p| [ p.name, p.id ] }, { :include_blank => "Select user" }) | |
29 | - .buttons | |
30 | - = f.submit 'Save', :class => "grey-button" | |
31 | - .right= link_to 'Back', project_merge_requests_path(@project), :class => "grey-button" | |
32 | 47 | |
33 | 48 | :javascript |
34 | 49 | $(function(){ | ... | ... |
app/views/merge_requests/_merge_request.html.haml
1 | 1 | %a.update-item{:href => project_merge_request_path(merge_request.project, merge_request)} |
2 | 2 | = image_tag gravatar_icon(merge_request.author_email), :class => "left", :width => 40 |
3 | 3 | %span.update-title |
4 | - = merge_request.title | |
4 | + = truncate(merge_request.title, :length => 60) | |
5 | 5 | %span.update-author |
6 | 6 | %strong= merge_request.author_name |
7 | 7 | authored | ... | ... |
app/views/merge_requests/show.html.haml
1 | -.merge-request-show-holder.ui-box.width-100p | |
2 | - %h3 | |
3 | - = "Merge Request ##{@merge_request.id}:" | |
4 | - | |
5 | - .tag.commit.inline= @merge_request.source_branch | |
6 | - → | |
7 | - .tag.commit.inline= @merge_request.target_branch | |
8 | - .right | |
9 | - - if @merge_request.closed | |
10 | - %span.tag.high Closed | |
11 | - - else | |
12 | - %span.tag.today Open | |
13 | - | |
14 | - .data | |
15 | - %p= @merge_request.title | |
16 | - | |
17 | - - if @merge_request.author == @merge_request.assignee | |
18 | - = image_tag gravatar_icon(@merge_request.assignee_email), :width => 20, :style => "padding:0 5px;" | |
19 | - = @merge_request.assignee_name | |
20 | - - else | |
21 | - = image_tag gravatar_icon(@merge_request.author_email), :width => 20, :style => "padding:0 5px;" | |
22 | - = @merge_request.author_name | |
1 | +%div | |
2 | + %span.entity-info | |
3 | + - if can?(current_user, :admin_project, @project) || @merge_request.author == current_user | |
4 | + = link_to edit_project_merge_request_path(@project, @merge_request) do | |
5 | + .entity-button | |
6 | + Edit Merge Request | |
7 | + %i | |
8 | + = image_tag gravatar_icon(@merge_request.author_email), :class => "left", :width => 40, :style => "padding-right:5px;" | |
9 | + %span.commit-title | |
10 | + %strong | |
11 | + = "Merge Request ##{@merge_request.id}:" | |
12 | + | |
13 | + .tag.commit.inline= @merge_request.source_branch | |
23 | 14 | → |
24 | - = image_tag gravatar_icon(@merge_request.assignee_email), :width => 20, :style => "padding:0 5px;" | |
25 | - = @merge_request.assignee_name | |
26 | - .right | |
27 | - %cite.cgray= @merge_request.created_at.stamp("21 Aug 2011, 11:15pm") | |
28 | - .clear | |
15 | + .tag.commit.inline= @merge_request.target_branch | |
16 | + %span.commit-author | |
17 | + %strong | |
18 | + = link_to project_team_member_path(@project, @project.team_member_by_id(@merge_request.author.id)) do | |
19 | + %span.author= @merge_request.author_name | |
20 | + → | |
21 | + = link_to project_team_member_path(@project, @project.team_member_by_id(@merge_request.assignee.id)) do | |
22 | + %span.author= @merge_request.assignee_name | |
29 | 23 | |
30 | - .buttons | |
31 | - - if can? current_user, :write_project, @project | |
32 | - - if @merge_request.closed | |
33 | - = link_to 'Reopen', project_merge_request_path(@project, @merge_request, :merge_request => {:closed => false }, :status_only => true), :method => :put, :class => "grey-button" | |
34 | - - else | |
35 | - = link_to 'Close', project_merge_request_path(@project, @merge_request, :merge_request => {:closed => true }, :status_only => true), :method => :put, :class => "grey-button" | |
36 | - .right | |
37 | - = link_to 'Edit', edit_project_merge_request_path(@project, @merge_request), :class => "grey-button positive" | |
24 | + | |
25 | + | |
26 | + = @merge_request.created_at.stamp("Aug 21, 2011 9:23pm") | |
27 | + | |
28 | + %hr | |
29 | + %br | |
30 | + %h3 | |
31 | + = simple_format @merge_request.title | |
38 | 32 | |
39 | 33 | .clear |
40 | 34 | %br |
41 | 35 | %br |
42 | 36 | |
43 | -#gitlab-tabs | |
44 | - %ul | |
45 | - %li= link_to "Notes", "#merge-notes" | |
46 | - %li= link_to "Commits", commits_project_merge_request_path(@project, @merge_request) | |
47 | - %li= link_to "Diff", diffs_project_merge_request_path(@project, @merge_request) | |
37 | +.merge-tabs | |
38 | + = link_to "#notes", :class => "merge-notes-tab active tab" do | |
39 | + %span | |
40 | + Notes | |
41 | + = link_to "#commits", "data-url" => commits_project_merge_request_path(@project, @merge_request), :class => "merge-commits-tab tab" do | |
42 | + %span | |
43 | + Commits | |
44 | + = link_to "#diffs", "data-url" => diffs_project_merge_request_path(@project, @merge_request), :class => "merge-diffs-tab tab" do | |
45 | + %span | |
46 | + Diff | |
47 | + | |
48 | + - if can?(current_user, :admin_project, @project) || @merge_request.author == current_user | |
49 | + .right | |
50 | + - if @merge_request.closed | |
51 | + = link_to 'Reopen', project_merge_request_path(@project, @merge_request, :merge_request => {:closed => false }, :status_only => true), :method => :put, :class => "red-button" | |
52 | + - else | |
53 | + = link_to 'Close', project_merge_request_path(@project, @merge_request, :merge_request => {:closed => true }, :status_only => true), :method => :put, :class => "positive-button", :title => "Close merge request" | |
54 | + %img{:src => "/assets/ajax-loader-facebook.gif", :class => "dashboard-loader"} | |
55 | + | |
56 | +.merge-request-notes | |
57 | + .issue_notes= render "notes/notes" | |
58 | + .loading{ :style => "display:none;"} | |
59 | + %center= image_tag "ajax-loader.gif" | |
60 | + .clear | |
48 | 61 | |
49 | - #merge-notes | |
50 | - .issue_notes= render "notes/notes" | |
51 | - .loading{ :style => "display:none;"} | |
52 | - %center= image_tag "ajax-loader.gif" | |
53 | - .clear | |
62 | +.merge-request-commits | |
63 | +.merge-request-diffs | |
54 | 64 | |
55 | 65 | |
56 | 66 | :javascript |
57 | 67 | $(function(){ |
58 | - $("#gitlab-tabs").tabs(); | |
68 | + MergeRequest.init(); | |
59 | 69 | }) | ... | ... |
spec/requests/merge_requests_spec.rb
... | ... | @@ -42,8 +42,8 @@ describe "MergeRequests" do |
42 | 42 | |
43 | 43 | it { should have_content(@merge_request.title) } |
44 | 44 | it "Show page should inform user that merge request closed" do |
45 | - within ".merge-request-show-holder h3" do | |
46 | - page.should have_content "Closed" | |
45 | + within ".merge-tabs" do | |
46 | + page.should have_content "Reopen" | |
47 | 47 | end |
48 | 48 | end |
49 | 49 | end |
... | ... | @@ -62,7 +62,7 @@ describe "MergeRequests" do |
62 | 62 | it { current_path.should == project_merge_request_path(project, project.merge_requests.last) } |
63 | 63 | |
64 | 64 | it "should create merge request" do |
65 | - page.should have_content "Open" | |
65 | + page.should have_content "Close" | |
66 | 66 | page.should have_content @user.name |
67 | 67 | end |
68 | 68 | end | ... | ... |
vendor/assets/stylesheets/jquery-ui/jquery-ui.css