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 @@ | @@ -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,42 +438,6 @@ body.project-page table.no-borders td{ | ||
438 | border:none; | 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 | .ajax-tab-loading { | 441 | .ajax-tab-loading { |
478 | padding:40px; | 442 | padding:40px; |
479 | display:none; | 443 | display:none; |
@@ -587,3 +551,82 @@ h4.middle-panel { | @@ -587,3 +551,82 @@ h4.middle-panel { | ||
587 | margin-right:30px; | 551 | margin-right:30px; |
588 | display:none; | 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,7 +130,7 @@ table tr:hover, .listed_items tr.odd:hover{background-color:#FFFFCF} | ||
130 | border-radius: 5px; | 130 | border-radius: 5px; |
131 | font-size: 12px; | 131 | font-size: 12px; |
132 | font-weight: bold; | 132 | font-weight: bold; |
133 | - padding: 6px 20px; | 133 | + padding: 5px 17px; |
134 | border: 1px solid #999; | 134 | border: 1px solid #999; |
135 | color: #666; | 135 | color: #666; |
136 | display: inline-block; | 136 | display: inline-block; |
app/controllers/merge_requests_controller.rb
@@ -30,14 +30,11 @@ class MergeRequestsController < ApplicationController | @@ -30,14 +30,11 @@ class MergeRequestsController < ApplicationController | ||
30 | 30 | ||
31 | def commits | 31 | def commits |
32 | @commits = @project.repo.commits_between(@merge_request.target_branch, @merge_request.source_branch).map {|c| Commit.new(c)} | 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 | end | 33 | end |
35 | 34 | ||
36 | def diffs | 35 | def diffs |
37 | @diffs = @merge_request.diffs | 36 | @diffs = @merge_request.diffs |
38 | @commit = @merge_request.last_commit | 37 | @commit = @merge_request.last_commit |
39 | - | ||
40 | - render :template => "merge_requests/_diffs", :layout => false | ||
41 | end | 38 | end |
42 | 39 | ||
43 | def new | 40 | def new |
app/models/project.rb
@@ -90,6 +90,10 @@ class Project < ActiveRecord::Base | @@ -90,6 +90,10 @@ class Project < ActiveRecord::Base | ||
90 | users_projects.find_by_user_id(user.id) if user | 90 | users_projects.find_by_user_id(user.id) if user |
91 | end | 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 | def fresh_issues(n) | 97 | def fresh_issues(n) |
94 | issues.includes(:project, :author).order("created_at desc").first(n) | 98 | issues.includes(:project, :author).order("created_at desc").first(n) |
95 | end | 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 | :javascript | 48 | :javascript |
34 | $(function(){ | 49 | $(function(){ |
app/views/merge_requests/_merge_request.html.haml
1 | %a.update-item{:href => project_merge_request_path(merge_request.project, merge_request)} | 1 | %a.update-item{:href => project_merge_request_path(merge_request.project, merge_request)} |
2 | = image_tag gravatar_icon(merge_request.author_email), :class => "left", :width => 40 | 2 | = image_tag gravatar_icon(merge_request.author_email), :class => "left", :width => 40 |
3 | %span.update-title | 3 | %span.update-title |
4 | - = merge_request.title | 4 | + = truncate(merge_request.title, :length => 60) |
5 | %span.update-author | 5 | %span.update-author |
6 | %strong= merge_request.author_name | 6 | %strong= merge_request.author_name |
7 | authored | 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 | .clear | 33 | .clear |
40 | %br | 34 | %br |
41 | %br | 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 | :javascript | 66 | :javascript |
57 | $(function(){ | 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,8 +42,8 @@ describe "MergeRequests" do | ||
42 | 42 | ||
43 | it { should have_content(@merge_request.title) } | 43 | it { should have_content(@merge_request.title) } |
44 | it "Show page should inform user that merge request closed" do | 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 | end | 47 | end |
48 | end | 48 | end |
49 | end | 49 | end |
@@ -62,7 +62,7 @@ describe "MergeRequests" do | @@ -62,7 +62,7 @@ describe "MergeRequests" do | ||
62 | it { current_path.should == project_merge_request_path(project, project.merge_requests.last) } | 62 | it { current_path.should == project_merge_request_path(project, project.merge_requests.last) } |
63 | 63 | ||
64 | it "should create merge request" do | 64 | it "should create merge request" do |
65 | - page.should have_content "Open" | 65 | + page.should have_content "Close" |
66 | page.should have_content @user.name | 66 | page.should have_content @user.name |
67 | end | 67 | end |
68 | end | 68 | end |
vendor/assets/stylesheets/jquery-ui/jquery-ui.css
1 | /* | 1 | /* |
2 | - * jQuery UI CSS Framework 1.8.16 | 2 | + * jQuery UI CSS Framework 1.8.16 Patched for GitLab HQ |
3 | * | 3 | * |
4 | * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) | 4 | * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) |
5 | * Dual licensed under the MIT or GPL Version 2 licenses. | 5 | * Dual licensed under the MIT or GPL Version 2 licenses. |