Commit 35d0de8f367e949c3bab50506916ca87eeb5d5ab
Exists in
master
and in
4 other branches
merging upstream changes
Showing
49 changed files
with
511 additions
and
168 deletions
Show diff stats
app/assets/javascripts/application.js
@@ -11,6 +11,7 @@ | @@ -11,6 +11,7 @@ | ||
11 | //= require jquery.tagify | 11 | //= require jquery.tagify |
12 | //= require jquery.cookie | 12 | //= require jquery.cookie |
13 | //= require jquery.endless-scroll | 13 | //= require jquery.endless-scroll |
14 | +//= require jquery.highlight | ||
14 | //= require bootstrap-modal | 15 | //= require bootstrap-modal |
15 | //= require modernizr | 16 | //= require modernizr |
16 | //= require chosen | 17 | //= require chosen |
app/assets/javascripts/merge_requests.js
@@ -11,7 +11,7 @@ var MergeRequest = { | @@ -11,7 +11,7 @@ var MergeRequest = { | ||
11 | 11 | ||
12 | $(".tabs a.merge-notes-tab").live("click", function(e) { | 12 | $(".tabs a.merge-notes-tab").live("click", function(e) { |
13 | $(".merge-request-diffs").hide(); | 13 | $(".merge-request-diffs").hide(); |
14 | - $(".merge-request-notes").show(); | 14 | + $(".merge_request_notes").show(); |
15 | e.preventDefault(); | 15 | e.preventDefault(); |
16 | }); | 16 | }); |
17 | 17 | ||
@@ -19,7 +19,7 @@ var MergeRequest = { | @@ -19,7 +19,7 @@ var MergeRequest = { | ||
19 | if(!MergeRequest.diffs_loaded) { | 19 | if(!MergeRequest.diffs_loaded) { |
20 | MergeRequest.loadDiff(); | 20 | MergeRequest.loadDiff(); |
21 | } | 21 | } |
22 | - $(".merge-request-notes").hide(); | 22 | + $(".merge_request_notes").hide(); |
23 | $(".merge-request-diffs").show(); | 23 | $(".merge-request-diffs").show(); |
24 | e.preventDefault(); | 24 | e.preventDefault(); |
25 | }); | 25 | }); |
@@ -33,7 +33,7 @@ var MergeRequest = { | @@ -33,7 +33,7 @@ var MergeRequest = { | ||
33 | url: $(".merge-diffs-tab").attr("data-url"), | 33 | url: $(".merge-diffs-tab").attr("data-url"), |
34 | complete: function(){ | 34 | complete: function(){ |
35 | MergeRequest.diffs_loaded = true; | 35 | MergeRequest.diffs_loaded = true; |
36 | - $(".merge-request-notes").hide(); | 36 | + $(".merge_request_notes").hide(); |
37 | $(".dashboard-loader").hide()}, | 37 | $(".dashboard-loader").hide()}, |
38 | dataType: "script"}); | 38 | dataType: "script"}); |
39 | } | 39 | } |
app/assets/stylesheets/common.scss
@@ -3,7 +3,7 @@ a { | @@ -3,7 +3,7 @@ a { | ||
3 | color: $link_color; | 3 | color: $link_color; |
4 | &:hover { | 4 | &:hover { |
5 | text-decoration:none; | 5 | text-decoration:none; |
6 | - color: $style_color; | 6 | + color: $blue_link; |
7 | } | 7 | } |
8 | 8 | ||
9 | &.btn { | 9 | &.btn { |
@@ -11,6 +11,18 @@ a { | @@ -11,6 +11,18 @@ a { | ||
11 | } | 11 | } |
12 | } | 12 | } |
13 | 13 | ||
14 | +.btn { | ||
15 | + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#f1f1f1), color-stop(25%, #f1f1f1), to(#e6e6e6)); | ||
16 | + background-image: -webkit-linear-gradient(#f1f1f1, #f1f1f1 25%, #e6e6e6); | ||
17 | + background-image: -moz-linear-gradient(top, #f1f1f1, #f1f1f1 25%, #e6e6e6); | ||
18 | + background-image: -ms-linear-gradient(#f1f1f1, #f1f1f1 25%, #e6e6e6); | ||
19 | + background-image: -o-linear-gradient(#f1f1f1, #f1f1f1 25%, #e6e6e6); | ||
20 | + background-image: linear-gradient(#f1f1f1, #f1f1f1 25%, #e6e6e6); | ||
21 | + | ||
22 | + &:hover { | ||
23 | + } | ||
24 | +} | ||
25 | + | ||
14 | a:focus { | 26 | a:focus { |
15 | outline: none; | 27 | outline: none; |
16 | } | 28 | } |
@@ -29,6 +41,29 @@ a:focus { | @@ -29,6 +41,29 @@ a:focus { | ||
29 | 41 | ||
30 | .label { | 42 | .label { |
31 | background-color: #474D57; | 43 | background-color: #474D57; |
44 | + | ||
45 | + &.pushed { | ||
46 | + background-color: $link_color; | ||
47 | + } | ||
48 | +} | ||
49 | + | ||
50 | +.pretty_label { | ||
51 | + @include round-borders-all(4px); | ||
52 | + padding:2px 4px; | ||
53 | + background-image: -webkit-gradient(linear, 0 0, 0 26, color-stop(0.076, #fefefe), to(#F6F7F8)); | ||
54 | + background-image: -webkit-linear-gradient(#fefefe 7.6%, #F6F7F8); | ||
55 | + background-image: -moz-linear-gradient(#fefefe 7.6%, #F6F7F8); | ||
56 | + background-image: -o-linear-gradient(#fefefe 7.6%, #F6F7F8); | ||
57 | + color: #777; | ||
58 | + border: 1px solid #DEDFE1; | ||
59 | + | ||
60 | + &.branch { | ||
61 | + border:none; | ||
62 | + font-size:13px; | ||
63 | + background: #474D57; | ||
64 | + color:#fff; | ||
65 | + font-family: monospace; | ||
66 | + } | ||
32 | } | 67 | } |
33 | 68 | ||
34 | .tabs > li > a, .pills > li > a { | 69 | .tabs > li > a, .pills > li > a { |
@@ -807,12 +842,19 @@ p.time { | @@ -807,12 +842,19 @@ p.time { | ||
807 | width:840px; | 842 | width:840px; |
808 | margin:auto; | 843 | margin:auto; |
809 | 844 | ||
810 | - .wll { | ||
811 | - padding:5px; | ||
812 | - margin-top:5px; | 845 | + .dash_project_item { |
846 | + margin-bottom:10px; | ||
813 | border:none; | 847 | border:none; |
814 | &:hover { | 848 | &:hover { |
815 | background:none; | 849 | background:none; |
850 | + | ||
851 | + h4 { | ||
852 | + color:#2FA0BB; | ||
853 | + .arrow { | ||
854 | + background:#2FA0BB; | ||
855 | + color:#fff; | ||
856 | + } | ||
857 | + } | ||
816 | } | 858 | } |
817 | 859 | ||
818 | h4 { | 860 | h4 { |
@@ -887,7 +929,7 @@ p.time { | @@ -887,7 +929,7 @@ p.time { | ||
887 | } | 929 | } |
888 | a:last-child h4 { border:none; } | 930 | a:last-child h4 { border:none; } |
889 | 931 | ||
890 | - a.active { | 932 | + a:hover { |
891 | h4 { | 933 | h4 { |
892 | color:#111; | 934 | color:#111; |
893 | border-right:4px solid $styled_border_color; | 935 | border-right:4px solid $styled_border_color; |
@@ -974,3 +1016,32 @@ p.time { | @@ -974,3 +1016,32 @@ p.time { | ||
974 | } | 1016 | } |
975 | } | 1017 | } |
976 | } | 1018 | } |
1019 | + | ||
1020 | +.highlight_word { | ||
1021 | + background:#EEDC94; | ||
1022 | +} | ||
1023 | + | ||
1024 | +.status_info { | ||
1025 | + font-size:14px; | ||
1026 | + padding:5px 15px; | ||
1027 | + line-height:24px; | ||
1028 | + width:60px; | ||
1029 | + text-align:center; | ||
1030 | + float:left; | ||
1031 | + margin-right:20px; | ||
1032 | +} | ||
1033 | + | ||
1034 | +.merge_request_status_holder { | ||
1035 | + margin-bottom:20px; | ||
1036 | +} | ||
1037 | + | ||
1038 | +.arrow{ | ||
1039 | + float: right; | ||
1040 | + background: #E3E5EA; | ||
1041 | + padding: 10px; | ||
1042 | + border-radius: 5px; | ||
1043 | + text-shadow: none; | ||
1044 | + color: #999; | ||
1045 | + line-height: 16px; | ||
1046 | + font-weight:bold; | ||
1047 | +} |
app/assets/stylesheets/main.scss
@@ -15,7 +15,7 @@ $app_padding:20px; | @@ -15,7 +15,7 @@ $app_padding:20px; | ||
15 | $bg_color: #FFF; | 15 | $bg_color: #FFF; |
16 | $styled_border_color: #2FA0BB; | 16 | $styled_border_color: #2FA0BB; |
17 | $color: "#4BB8D2"; | 17 | $color: "#4BB8D2"; |
18 | -$blue_link: "#2fa0bb"; | 18 | +$blue_link: #2fa0bb; |
19 | 19 | ||
20 | 20 | ||
21 | /** Style colors **/ | 21 | /** Style colors **/ |
app/assets/stylesheets/ui_basic.scss
app/controllers/dashboard_controller.rb
@@ -18,7 +18,7 @@ class DashboardController < ApplicationController | @@ -18,7 +18,7 @@ class DashboardController < ApplicationController | ||
18 | # Get authored or assigned open merge requests | 18 | # Get authored or assigned open merge requests |
19 | def merge_requests | 19 | def merge_requests |
20 | @projects = current_user.projects.all | 20 | @projects = current_user.projects.all |
21 | - @merge_requests = MergeRequest.where("author_id = :id or assignee_id = :id", :id => current_user.id).opened.order("created_at DESC").limit(40) | 21 | + @merge_requests = current_user.cared_merge_requests.order("created_at DESC").limit(40) |
22 | end | 22 | end |
23 | 23 | ||
24 | # Get only assigned issues | 24 | # Get only assigned issues |
app/controllers/merge_requests_controller.rb
@@ -41,13 +41,9 @@ class MergeRequestsController < ApplicationController | @@ -41,13 +41,9 @@ class MergeRequestsController < ApplicationController | ||
41 | 41 | ||
42 | @note = @project.notes.new(:noteable => @merge_request) | 42 | @note = @project.notes.new(:noteable => @merge_request) |
43 | 43 | ||
44 | - @commits = @project.repo. | ||
45 | - commits_between(@merge_request.target_branch, @merge_request.source_branch). | ||
46 | - map {|c| Commit.new(c)}. | ||
47 | - sort_by(&:created_at). | ||
48 | - reverse | ||
49 | - | ||
50 | - render_full_content | 44 | + # Get commits from repository |
45 | + # or from cache if already merged | ||
46 | + @commits = @merge_request.commits | ||
51 | 47 | ||
52 | respond_to do |format| | 48 | respond_to do |format| |
53 | format.html | 49 | format.html |
@@ -76,6 +72,7 @@ class MergeRequestsController < ApplicationController | @@ -76,6 +72,7 @@ class MergeRequestsController < ApplicationController | ||
76 | 72 | ||
77 | respond_to do |format| | 73 | respond_to do |format| |
78 | if @merge_request.save | 74 | if @merge_request.save |
75 | + @merge_request.reload_code | ||
79 | format.html { redirect_to [@project, @merge_request], notice: 'Merge request was successfully created.' } | 76 | format.html { redirect_to [@project, @merge_request], notice: 'Merge request was successfully created.' } |
80 | format.json { render json: @merge_request, status: :created, location: @merge_request } | 77 | format.json { render json: @merge_request, status: :created, location: @merge_request } |
81 | else | 78 | else |
@@ -88,6 +85,7 @@ class MergeRequestsController < ApplicationController | @@ -88,6 +85,7 @@ class MergeRequestsController < ApplicationController | ||
88 | def update | 85 | def update |
89 | respond_to do |format| | 86 | respond_to do |format| |
90 | if @merge_request.update_attributes(params[:merge_request].merge(:author_id_of_changes => current_user.id)) | 87 | if @merge_request.update_attributes(params[:merge_request].merge(:author_id_of_changes => current_user.id)) |
88 | + @merge_request.reload_code | ||
91 | format.html { redirect_to [@project, @merge_request], notice: 'Merge request was successfully updated.' } | 89 | format.html { redirect_to [@project, @merge_request], notice: 'Merge request was successfully updated.' } |
92 | format.json { head :ok } | 90 | format.json { head :ok } |
93 | else | 91 | else |
app/controllers/projects_controller.rb
@@ -13,6 +13,7 @@ class ProjectsController < ApplicationController | @@ -13,6 +13,7 @@ class ProjectsController < ApplicationController | ||
13 | def index | 13 | def index |
14 | @projects = current_user.projects | 14 | @projects = current_user.projects |
15 | @projects = @projects.select(&:last_activity_date).sort_by(&:last_activity_date).reverse | 15 | @projects = @projects.select(&:last_activity_date).sort_by(&:last_activity_date).reverse |
16 | + @events = Event.where(:project_id => @projects.map(&:id)).recent.limit(40) | ||
16 | end | 17 | end |
17 | 18 | ||
18 | def new | 19 | def new |
@@ -78,7 +79,6 @@ class ProjectsController < ApplicationController | @@ -78,7 +79,6 @@ class ProjectsController < ApplicationController | ||
78 | render "projects/empty" | 79 | render "projects/empty" |
79 | end | 80 | end |
80 | end | 81 | end |
81 | - format.js | ||
82 | end | 82 | end |
83 | end | 83 | end |
84 | 84 |
@@ -0,0 +1,12 @@ | @@ -0,0 +1,12 @@ | ||
1 | +class SearchController < ApplicationController | ||
2 | + def show | ||
3 | + query = params[:search] | ||
4 | + if query.blank? | ||
5 | + @projects = [] | ||
6 | + @merge_requests = [] | ||
7 | + else | ||
8 | + @projects = Project.search(query).limit(10) | ||
9 | + @merge_requests = MergeRequest.search(query).limit(10) | ||
10 | + end | ||
11 | + end | ||
12 | +end |
app/models/event.rb
@@ -7,6 +7,7 @@ class Event < ActiveRecord::Base | @@ -7,6 +7,7 @@ class Event < ActiveRecord::Base | ||
7 | Reopened = 4 | 7 | Reopened = 4 |
8 | Pushed = 5 | 8 | Pushed = 5 |
9 | Commented = 6 | 9 | Commented = 6 |
10 | + Merged = 7 | ||
10 | 11 | ||
11 | belongs_to :project | 12 | belongs_to :project |
12 | belongs_to :target, :polymorphic => true | 13 | belongs_to :target, :polymorphic => true |
app/models/merge_request.rb
1 | +require File.join(Rails.root, "app/models/commit") | ||
2 | + | ||
1 | class MergeRequest < ActiveRecord::Base | 3 | class MergeRequest < ActiveRecord::Base |
2 | belongs_to :project | 4 | belongs_to :project |
3 | belongs_to :author, :class_name => "User" | 5 | belongs_to :author, :class_name => "User" |
4 | belongs_to :assignee, :class_name => "User" | 6 | belongs_to :assignee, :class_name => "User" |
5 | has_many :notes, :as => :noteable, :dependent => :destroy | 7 | has_many :notes, :as => :noteable, :dependent => :destroy |
6 | 8 | ||
9 | + serialize :st_commits | ||
10 | + serialize :st_diffs | ||
11 | + | ||
7 | attr_protected :author, :author_id, :project, :project_id | 12 | attr_protected :author, :author_id, :project, :project_id |
8 | attr_accessor :author_id_of_changes | 13 | attr_accessor :author_id_of_changes |
9 | 14 | ||
@@ -32,6 +37,13 @@ class MergeRequest < ActiveRecord::Base | @@ -32,6 +37,13 @@ class MergeRequest < ActiveRecord::Base | ||
32 | scope :closed, where(:closed => true) | 37 | scope :closed, where(:closed => true) |
33 | scope :assigned, lambda { |u| where(:assignee_id => u.id)} | 38 | scope :assigned, lambda { |u| where(:assignee_id => u.id)} |
34 | 39 | ||
40 | + def self.search query | ||
41 | + where("title like :query", :query => "%#{query}%") | ||
42 | + end | ||
43 | + | ||
44 | + def self.find_all_by_branch(branch_name) | ||
45 | + where("source_branch like :branch or target_branch like :branch", :branch => branch_name) | ||
46 | + end | ||
35 | 47 | ||
36 | def validate_branches | 48 | def validate_branches |
37 | if target_branch == source_branch | 49 | if target_branch == source_branch |
@@ -39,23 +51,99 @@ class MergeRequest < ActiveRecord::Base | @@ -39,23 +51,99 @@ class MergeRequest < ActiveRecord::Base | ||
39 | end | 51 | end |
40 | end | 52 | end |
41 | 53 | ||
54 | + def reload_code | ||
55 | + self.reloaded_commits | ||
56 | + self.reloaded_diffs | ||
57 | + end | ||
58 | + | ||
42 | def new? | 59 | def new? |
43 | today? && created_at == updated_at | 60 | today? && created_at == updated_at |
44 | end | 61 | end |
45 | 62 | ||
46 | def diffs | 63 | def diffs |
64 | + st_diffs || [] | ||
65 | + end | ||
66 | + | ||
67 | + def reloaded_diffs | ||
68 | + if open? && unmerged_diffs.any? | ||
69 | + self.st_diffs = unmerged_diffs | ||
70 | + save | ||
71 | + end | ||
72 | + diffs | ||
73 | + end | ||
74 | + | ||
75 | + def unmerged_diffs | ||
47 | commits = project.repo.commits_between(target_branch, source_branch).map {|c| Commit.new(c)} | 76 | commits = project.repo.commits_between(target_branch, source_branch).map {|c| Commit.new(c)} |
48 | diffs = project.repo.diff(commits.first.prev_commit.id, commits.last.id) rescue [] | 77 | diffs = project.repo.diff(commits.first.prev_commit.id, commits.last.id) rescue [] |
49 | end | 78 | end |
50 | 79 | ||
51 | def last_commit | 80 | def last_commit |
52 | - project.commit(source_branch) | 81 | + commits.first |
82 | + end | ||
83 | + | ||
84 | + def merged? | ||
85 | + merged && merge_event | ||
86 | + end | ||
87 | + | ||
88 | + def merge_event | ||
89 | + self.project.events.where(:target_id => self.id, :target_type => "MergeRequest", :action => Event::Merged).last | ||
90 | + end | ||
91 | + | ||
92 | + def closed_event | ||
93 | + self.project.events.where(:target_id => self.id, :target_type => "MergeRequest", :action => Event::Closed).last | ||
53 | end | 94 | end |
54 | 95 | ||
96 | + | ||
55 | # Return the number of +1 comments (upvotes) | 97 | # Return the number of +1 comments (upvotes) |
56 | def upvotes | 98 | def upvotes |
57 | notes.select(&:upvote?).size | 99 | notes.select(&:upvote?).size |
58 | end | 100 | end |
101 | + | ||
102 | + def commits | ||
103 | + st_commits || [] | ||
104 | + end | ||
105 | + | ||
106 | + def probably_merged? | ||
107 | + unmerged_commits.empty? && | ||
108 | + commits.any? && open? | ||
109 | + end | ||
110 | + | ||
111 | + def open? | ||
112 | + !closed | ||
113 | + end | ||
114 | + | ||
115 | + def mark_as_merged! | ||
116 | + self.merged = true | ||
117 | + self.closed = true | ||
118 | + save | ||
119 | + end | ||
120 | + | ||
121 | + def reloaded_commits | ||
122 | + if open? && unmerged_commits.any? | ||
123 | + self.st_commits = unmerged_commits | ||
124 | + save | ||
125 | + end | ||
126 | + commits | ||
127 | + end | ||
128 | + | ||
129 | + def unmerged_commits | ||
130 | + self.project.repo. | ||
131 | + commits_between(self.target_branch, self.source_branch). | ||
132 | + map {|c| Commit.new(c)}. | ||
133 | + sort_by(&:created_at). | ||
134 | + reverse | ||
135 | + end | ||
136 | + | ||
137 | + def merge!(user_id) | ||
138 | + self.mark_as_merged! | ||
139 | + Event.create( | ||
140 | + :project => self.project, | ||
141 | + :action => Event::Merged, | ||
142 | + :target_id => self.id, | ||
143 | + :target_type => "MergeRequest", | ||
144 | + :author_id => user_id | ||
145 | + ) | ||
146 | + end | ||
59 | end | 147 | end |
60 | # == Schema Information | 148 | # == Schema Information |
61 | # | 149 | # |
app/models/project.rb
@@ -54,6 +54,10 @@ class Project < ActiveRecord::Base | @@ -54,6 +54,10 @@ class Project < ActiveRecord::Base | ||
54 | UsersProject.access_roles | 54 | UsersProject.access_roles |
55 | end | 55 | end |
56 | 56 | ||
57 | + def self.search query | ||
58 | + where("name like :query or code like :query or path like :query", :query => "%#{query}%") | ||
59 | + end | ||
60 | + | ||
57 | def to_param | 61 | def to_param |
58 | code | 62 | code |
59 | end | 63 | end |
@@ -73,6 +77,24 @@ class Project < ActiveRecord::Base | @@ -73,6 +77,24 @@ class Project < ActiveRecord::Base | ||
73 | ) | 77 | ) |
74 | end | 78 | end |
75 | 79 | ||
80 | + def update_merge_requests(oldrev, newrev, ref, author_key_id) | ||
81 | + return true unless ref =~ /heads/ | ||
82 | + branch_name = ref.gsub("refs/heads/", "") | ||
83 | + user = Key.find_by_identifier(author_key_id).user | ||
84 | + c_ids = self.commits_between(oldrev, newrev).map(&:id) | ||
85 | + | ||
86 | + # Update code for merge requests | ||
87 | + mrs = self.merge_requests.opened.find_all_by_branch(branch_name).all | ||
88 | + mrs.each { |merge_request| merge_request.reload_code } | ||
89 | + | ||
90 | + # Close merge requests | ||
91 | + mrs = self.merge_requests.opened.where(:target_branch => branch_name).all | ||
92 | + mrs = mrs.select(&:last_commit).select { |mr| c_ids.include?(mr.last_commit.id) } | ||
93 | + mrs.each { |merge_request| merge_request.merge!(user.id) } | ||
94 | + | ||
95 | + true | ||
96 | + end | ||
97 | + | ||
76 | def execute_web_hooks(oldrev, newrev, ref, author_key_id) | 98 | def execute_web_hooks(oldrev, newrev, ref, author_key_id) |
77 | ref_parts = ref.split('/') | 99 | ref_parts = ref.split('/') |
78 | 100 |
app/models/user.rb
@@ -86,6 +86,10 @@ class User < ActiveRecord::Base | @@ -86,6 +86,10 @@ class User < ActiveRecord::Base | ||
86 | ) | 86 | ) |
87 | end | 87 | end |
88 | end | 88 | end |
89 | + | ||
90 | + def cared_merge_requests | ||
91 | + MergeRequest.where("author_id = :id or assignee_id = :id", :id => self.id).opened | ||
92 | + end | ||
89 | end | 93 | end |
90 | # == Schema Information | 94 | # == Schema Information |
91 | # | 95 | # |
app/views/commits/show.html.haml
@@ -12,8 +12,8 @@ | @@ -12,8 +12,8 @@ | ||
12 | = @commit.committer_name | 12 | = @commit.committer_name |
13 | %small= @commit.committed_date.stamp("Aug 21, 2011 9:23pm") | 13 | %small= @commit.committed_date.stamp("Aug 21, 2011 9:23pm") |
14 | 14 | ||
15 | -%hr | ||
16 | -%pre.commit_message | 15 | +%br |
16 | +%pre.commit_message.prettyprint | ||
17 | = commit_msg_with_link_to_issues(@project, @commit.safe_message) | 17 | = commit_msg_with_link_to_issues(@project, @commit.safe_message) |
18 | .clear | 18 | .clear |
19 | %br | 19 | %br |
app/views/dashboard/_events_feed.html.haml
app/views/dashboard/_issues_feed.html.haml
@@ -3,8 +3,10 @@ | @@ -3,8 +3,10 @@ | ||
3 | = link_to [issue.project, issue] do | 3 | = link_to [issue.project, issue] do |
4 | %p | 4 | %p |
5 | %strong | 5 | %strong |
6 | - %span.label= issue.project.name | 6 | + %span.pretty_label= issue.project.name |
7 | – | 7 | – |
8 | Issue # | 8 | Issue # |
9 | = issue.id | 9 | = issue.id |
10 | = truncate issue.title, :length => 50 | 10 | = truncate issue.title, :length => 50 |
11 | + %span.right.cgray | ||
12 | + = issue.updated_at.stamp("Aug 21, 2011") |
app/views/dashboard/_merge_requests_feed.html.haml
@@ -3,8 +3,9 @@ | @@ -3,8 +3,9 @@ | ||
3 | = link_to [merge_request.project, merge_request] do | 3 | = link_to [merge_request.project, merge_request] do |
4 | %p | 4 | %p |
5 | %strong | 5 | %strong |
6 | - %span.label= merge_request.project.name | 6 | + %span.pretty_label= merge_request.project.name |
7 | – | 7 | – |
8 | - Merge Request # | ||
9 | - = merge_request.id | 8 | + Merge Request ##{merge_request.id} |
10 | = truncate merge_request.title, :length => 50 | 9 | = truncate merge_request.title, :length => 50 |
10 | + %span.right.cgray | ||
11 | + = merge_request.updated_at.stamp("Aug 21, 2011") |
app/views/dashboard/_projects_feed.html.haml
1 | -- @active_projects.first(5).each do |project| | ||
2 | - .wll | 1 | +- projects.first(5).each do |project| |
2 | + %div.dash_project_item | ||
3 | = link_to project do | 3 | = link_to project do |
4 | %h4 | 4 | %h4 |
5 | %span.ico.project | 5 | %span.ico.project |
@@ -7,3 +7,5 @@ | @@ -7,3 +7,5 @@ | ||
7 | %small | 7 | %small |
8 | last activity at | 8 | last activity at |
9 | = project.last_activity_date.stamp("Aug 25, 2011") | 9 | = project.last_activity_date.stamp("Aug 25, 2011") |
10 | + %span.right.arrow | ||
11 | + → |
app/views/dashboard/index.html.haml
@@ -20,7 +20,7 @@ | @@ -20,7 +20,7 @@ | ||
20 | .row | 20 | .row |
21 | .dashboard_block | 21 | .dashboard_block |
22 | .row | 22 | .row |
23 | - .span10= render "dashboard/projects_feed" | 23 | + .span10= render "dashboard/projects_feed", :projects => @active_projects |
24 | .span4.right | 24 | .span4.right |
25 | - if current_user.can_create_project? | 25 | - if current_user.can_create_project? |
26 | .alert-message.block-message.warning | 26 | .alert-message.block-message.warning |
@@ -65,4 +65,4 @@ | @@ -65,4 +65,4 @@ | ||
65 | 65 | ||
66 | %hr | 66 | %hr |
67 | .row | 67 | .row |
68 | - .dashboard_block= render "dashboard/events_feed" | 68 | + .dashboard_block= render @events |
app/views/events/_event_changed_issue.html.haml
1 | = image_tag gravatar_icon(event.author_email), :class => "avatar" | 1 | = image_tag gravatar_icon(event.author_email), :class => "avatar" |
2 | %strong #{event.author_name} | 2 | %strong #{event.author_name} |
3 | -- if event.closed? | ||
4 | - closed | ||
5 | -- else | ||
6 | - reopened | ||
7 | -issue | 3 | +%span.label.important |
4 | + - if event.closed? | ||
5 | + closed | ||
6 | + - else | ||
7 | + reopened | ||
8 | + issue | ||
8 | = link_to project_issue_path(event.project, event.issue) do | 9 | = link_to project_issue_path(event.project, event.issue) do |
9 | %strong= truncate event.issue_title | 10 | %strong= truncate event.issue_title |
10 | at | 11 | at |
app/views/events/_event_changed_merge_request.html.haml
1 | = image_tag gravatar_icon(event.author_email), :class => "avatar" | 1 | = image_tag gravatar_icon(event.author_email), :class => "avatar" |
2 | %strong #{event.author_name} | 2 | %strong #{event.author_name} |
3 | -- if event.closed? | ||
4 | - closed | ||
5 | -- else | ||
6 | - reopened | ||
7 | -merge request | 3 | +%span.label.important |
4 | + - if event.closed? | ||
5 | + closed | ||
6 | + - else | ||
7 | + reopened | ||
8 | + merge request | ||
8 | = link_to project_merge_request_path(event.project, event.merge_request) do | 9 | = link_to project_merge_request_path(event.project, event.merge_request) do |
9 | %strong= truncate event.merge_request_title | 10 | %strong= truncate event.merge_request_title |
10 | at | 11 | at |
@@ -12,7 +13,6 @@ at | @@ -12,7 +13,6 @@ at | ||
12 | %span.cgray | 13 | %span.cgray |
13 | = time_ago_in_words(event.created_at) | 14 | = time_ago_in_words(event.created_at) |
14 | ago. | 15 | ago. |
15 | -%br | ||
16 | %span.label= event.merge_request.source_branch | 16 | %span.label= event.merge_request.source_branch |
17 | → | 17 | → |
18 | %span.label= event.merge_request.target_branch | 18 | %span.label= event.merge_request.target_branch |
app/views/events/_event_new_issue.html.haml
1 | = image_tag gravatar_icon(event.author_email), :class => "avatar" | 1 | = image_tag gravatar_icon(event.author_email), :class => "avatar" |
2 | %strong #{event.author_name} | 2 | %strong #{event.author_name} |
3 | -created new issue | 3 | +%span.label.success created |
4 | + new issue | ||
4 | = link_to project_issue_path(event.project, event.issue) do | 5 | = link_to project_issue_path(event.project, event.issue) do |
5 | %strong= truncate event.issue_title | 6 | %strong= truncate event.issue_title |
6 | at | 7 | at |
app/views/events/_event_new_merge_request.html.haml
1 | = image_tag gravatar_icon(event.author_email), :class => "avatar" | 1 | = image_tag gravatar_icon(event.author_email), :class => "avatar" |
2 | %strong #{event.author_name} | 2 | %strong #{event.author_name} |
3 | -requested merge | 3 | +%span.label.success requested |
4 | + merge | ||
4 | = link_to project_merge_request_path(event.project, event.merge_request) do | 5 | = link_to project_merge_request_path(event.project, event.merge_request) do |
5 | %strong= truncate event.merge_request_title | 6 | %strong= truncate event.merge_request_title |
6 | at | 7 | at |
@@ -8,7 +9,6 @@ at | @@ -8,7 +9,6 @@ at | ||
8 | %span.cgray | 9 | %span.cgray |
9 | = time_ago_in_words(event.created_at) | 10 | = time_ago_in_words(event.created_at) |
10 | ago. | 11 | ago. |
11 | -%br | ||
12 | %span.label= event.merge_request.source_branch | 12 | %span.label= event.merge_request.source_branch |
13 | → | 13 | → |
14 | %span.label= event.merge_request.target_branch | 14 | %span.label= event.merge_request.target_branch |
app/views/events/_event_push.html.haml
1 | - if event.new_branch? || event.new_tag? | 1 | - if event.new_branch? || event.new_tag? |
2 | = image_tag gravatar_icon(event.author_email), :class => "avatar" | 2 | = image_tag gravatar_icon(event.author_email), :class => "avatar" |
3 | %strong #{event.author_name} | 3 | %strong #{event.author_name} |
4 | - pushed new | 4 | + %span.label.pushed pushed |
5 | + new | ||
5 | - if event.new_tag? | 6 | - if event.new_tag? |
6 | tag | 7 | tag |
7 | = link_to project_commits_path(event.project, :ref => event.tag_name) do | 8 | = link_to project_commits_path(event.project, :ref => event.tag_name) do |
@@ -18,7 +19,8 @@ | @@ -18,7 +19,8 @@ | ||
18 | - else | 19 | - else |
19 | = image_tag gravatar_icon(event.author_email), :class => "avatar" | 20 | = image_tag gravatar_icon(event.author_email), :class => "avatar" |
20 | %strong #{event.author_name} | 21 | %strong #{event.author_name} |
21 | - pushed to | 22 | + %span.label.pushed pushed |
23 | + to | ||
22 | = link_to project_commits_path(event.project, :ref => event.branch_name) do | 24 | = link_to project_commits_path(event.project, :ref => event.branch_name) do |
23 | %strong= event.branch_name | 25 | %strong= event.branch_name |
24 | at | 26 | at |
@@ -30,10 +32,10 @@ | @@ -30,10 +32,10 @@ | ||
30 | = link_to compare_project_commits_path(event.project, :from => event.commits.first.prev_commit_id, :to => event.commits.last.id) do | 32 | = link_to compare_project_commits_path(event.project, :from => event.commits.first.prev_commit_id, :to => event.commits.last.id) do |
31 | Compare #{event.commits.first.commit.id[0..8]}...#{event.commits.last.id[0..8]} | 33 | Compare #{event.commits.first.commit.id[0..8]}...#{event.commits.last.id[0..8]} |
32 | - @project = event.project | 34 | - @project = event.project |
33 | - %ul.unstyled | ||
34 | - - if event.commits.size > 4 | ||
35 | - = render event.commits[0..2] | ||
36 | - %li ... and #{event.commits.size - 3} more commits | 35 | + %ul.unstyled.event_commits |
36 | + - if event.commits.size > 3 | ||
37 | + = render event.commits[0...2] | ||
38 | + %li ... and #{event.commits.size - 2} more commits | ||
37 | - else | 39 | - else |
38 | = render event.commits | 40 | = render event.commits |
39 | 41 |
app/views/layouts/_app_menu.html.haml
1 | %nav.main_menu | 1 | %nav.main_menu |
2 | = render "layouts/const_menu_links" | 2 | = render "layouts/const_menu_links" |
3 | = link_to "Projects", projects_path, :class => "#{"current" if current_page?(projects_path)}" | 3 | = link_to "Projects", projects_path, :class => "#{"current" if current_page?(projects_path)}" |
4 | - = link_to "Issues", dashboard_issues_path, :class => "#{"current" if current_page?(dashboard_issues_path)}", :id => "issues_slide" | ||
5 | - = link_to "Requests", dashboard_merge_requests_path, :class => "#{"current" if current_page?(dashboard_merge_requests_path)}", :id => "merge_requests_slide" | 4 | + = link_to dashboard_issues_path, :class => "#{"current" if current_page?(dashboard_issues_path)}", :id => "issues_slide" do |
5 | + Issues | ||
6 | + %span.count= current_user.assigned_issues.opened.count | ||
7 | + = link_to dashboard_merge_requests_path, :class => "#{"current" if current_page?(dashboard_merge_requests_path)}", :id => "merge_requests_slide" do | ||
8 | + Requests | ||
9 | + %span.count= current_user.cared_merge_requests.count | ||
10 | + = link_to "Search", search_path, :class => "#{"current" if current_page?(search_path)}" | ||
6 | = link_to "Help", help_path, :class => "#{"current" if controller.controller_name == "help"}" | 11 | = link_to "Help", help_path, :class => "#{"current" if controller.controller_name == "help"}" |
app/views/layouts/_head_panel.html.haml
@@ -7,7 +7,9 @@ | @@ -7,7 +7,9 @@ | ||
7 | %h1 | 7 | %h1 |
8 | GITLAB | 8 | GITLAB |
9 | %h1.project_name= title | 9 | %h1.project_name= title |
10 | - .search= text_field_tag "search", nil, :placeholder => "Search", :class => "search-input" | 10 | + .search |
11 | + = form_tag search_path, :method => :get do |f| | ||
12 | + = text_field_tag "search", nil, :placeholder => "Search", :class => "search-input" | ||
11 | - if current_user.is_admin? | 13 | - if current_user.is_admin? |
12 | = link_to admin_projects_path, :class => "admin_link", :title => "Admin area" do | 14 | = link_to admin_projects_path, :class => "admin_link", :title => "Admin area" do |
13 | = image_tag "admin.PNG", :width => 16 | 15 | = image_tag "admin.PNG", :width => 16 |
app/views/merge_requests/_commits.html.haml
app/views/merge_requests/_how_to_merge.html.haml
@@ -15,7 +15,7 @@ | @@ -15,7 +15,7 @@ | ||
15 | :javascript | 15 | :javascript |
16 | $(function(){ | 16 | $(function(){ |
17 | var modal = $('#modal_merge_info').modal({modal: true}); | 17 | var modal = $('#modal_merge_info').modal({modal: true}); |
18 | - $('.info_link').bind("click", function(){ | 18 | + $('.how_to_merge_link').bind("click", function(){ |
19 | modal.show(); | 19 | modal.show(); |
20 | }); | 20 | }); |
21 | $('.modal-header .close').bind("click", function(){ | 21 | $('.modal-header .close').bind("click", function(){ |
app/views/merge_requests/_merge_request.html.haml
@@ -6,7 +6,7 @@ | @@ -6,7 +6,7 @@ | ||
6 | = time_ago_in_words(merge_request.created_at) | 6 | = time_ago_in_words(merge_request.created_at) |
7 | ago | 7 | ago |
8 | - if merge_request.notes.any? | 8 | - if merge_request.notes.any? |
9 | - %span.label= pluralize merge_request.notes.count, 'note' | 9 | + %span.pretty_label= pluralize merge_request.notes.count, 'note' |
10 | - if merge_request.upvotes > 0 | 10 | - if merge_request.upvotes > 0 |
11 | %span.label.success= "+#{merge_request.upvotes}" | 11 | %span.label.success= "+#{merge_request.upvotes}" |
12 | .right | 12 | .right |
app/views/merge_requests/show.html.haml
1 | %h3 | 1 | %h3 |
2 | = "Merge Request ##{@merge_request.id}:" | 2 | = "Merge Request ##{@merge_request.id}:" |
3 | | 3 | |
4 | - %span.label= @merge_request.source_branch | 4 | + %span.pretty_label.branch= @merge_request.source_branch |
5 | → | 5 | → |
6 | - %span.label= @merge_request.target_branch | 6 | + %span.pretty_label.branch= @merge_request.target_branch |
7 | 7 | ||
8 | %small | 8 | %small |
9 | created at | 9 | created at |
@@ -11,12 +11,10 @@ | @@ -11,12 +11,10 @@ | ||
11 | 11 | ||
12 | %span.right | 12 | %span.right |
13 | - if can?(current_user, :modify_merge_request, @merge_request) | 13 | - if can?(current_user, :modify_merge_request, @merge_request) |
14 | - - if @merge_request.closed | ||
15 | - = link_to 'Reopen', project_merge_request_path(@project, @merge_request, :merge_request => {:closed => false }, :status_only => true), :method => :put, :class => "btn" | ||
16 | - - else | 14 | + - if @merge_request.open? |
17 | = link_to 'Close', project_merge_request_path(@project, @merge_request, :merge_request => {:closed => true }, :status_only => true), :method => :put, :class => "btn", :title => "Close merge request" | 15 | = link_to 'Close', project_merge_request_path(@project, @merge_request, :merge_request => {:closed => true }, :status_only => true), :method => :put, :class => "btn", :title => "Close merge request" |
18 | - = link_to edit_project_merge_request_path(@project, @merge_request), :class => "btn" do | ||
19 | - Edit | 16 | + = link_to edit_project_merge_request_path(@project, @merge_request), :class => "btn" do |
17 | + Edit | ||
20 | 18 | ||
21 | %br | 19 | %br |
22 | - if @merge_request.upvotes > 0 | 20 | - if @merge_request.upvotes > 0 |
@@ -28,17 +26,27 @@ | @@ -28,17 +26,27 @@ | ||
28 | 26 | ||
29 | 27 | ||
30 | %hr | 28 | %hr |
31 | -- if @merge_request.closed | ||
32 | - .alert-message.error Closed | ||
33 | -- else | ||
34 | - .alert-message.success | ||
35 | - = link_to "#", :class => "info_link", :title => "How To Merge" do | ||
36 | - = image_tag "Info-UI.PNG" | ||
37 | - Open | 29 | +.merge_request_status_holder |
30 | + - if @merge_request.closed | ||
31 | + %h5 | ||
32 | + .alert-message.error.status_info Closed | ||
33 | + - if @merge_request.merged? | ||
34 | + %span | ||
35 | + Merged by #{@merge_request.merge_event.author_name} | ||
36 | + %small #{time_ago_in_words(@merge_request.merge_event.created_at)} ago. | ||
37 | + - elsif @merge_request.closed_event | ||
38 | + %span | ||
39 | + Closed by #{@merge_request.closed_event.author_name} | ||
40 | + %small #{time_ago_in_words(@merge_request.closed_event.created_at)} ago. | ||
41 | + %br | ||
42 | + - else | ||
43 | + %h5 | ||
44 | + .alert-message.success.status_info Open | ||
45 | + = link_to "How to merge", "#", :class => "vlink how_to_merge_link", :title => "How To Merge" | ||
38 | 46 | ||
39 | = render "merge_requests/how_to_merge" | 47 | = render "merge_requests/how_to_merge" |
40 | 48 | ||
41 | -%div.well | 49 | +%div.well.prettyprint |
42 | %div | 50 | %div |
43 | %cite.cgray Created by | 51 | %cite.cgray Created by |
44 | = image_tag gravatar_icon(@merge_request.author_email), :width => 16, :class => "lil_av" | 52 | = image_tag gravatar_icon(@merge_request.author_email), :width => 16, :class => "lil_av" |
app/views/profile/password.html.haml
1 | -%h3 Password | ||
2 | -%hr | ||
3 | -= form_for @user, :url => profile_password_path, :method => :put do |f| | ||
4 | - .data | ||
5 | - .alert-message.block-message.warning | ||
6 | - %p After successfull password update you will be redirected to login page where you should login with new password | ||
7 | - -if @user.errors.any? | ||
8 | - .alert-message.block-message.error | ||
9 | - %ul | ||
10 | - - @user.errors.full_messages.each do |msg| | ||
11 | - %li= msg | 1 | +.row |
2 | + .span8 | ||
3 | + %h3 Password | ||
4 | + %hr | ||
5 | + = form_for @user, :url => profile_password_path, :method => :put do |f| | ||
6 | + .data | ||
7 | + .alert-message.block-message.warning | ||
8 | + %p After successfull password update you will be redirected to login page where you should login with new password | ||
9 | + -if @user.errors.any? | ||
10 | + .alert-message.block-message.error | ||
11 | + %ul | ||
12 | + - @user.errors.full_messages.each do |msg| | ||
13 | + %li= msg | ||
14 | + | ||
15 | + .clearfix | ||
16 | + = f.label :password | ||
17 | + .input= f.password_field :password | ||
18 | + .clearfix | ||
19 | + = f.label :password_confirmation | ||
20 | + .input= f.password_field :password_confirmation | ||
21 | + .actions | ||
22 | + = f.submit 'Save', :class => "btn" | ||
12 | 23 | ||
13 | - .clearfix | ||
14 | - = f.label :password | ||
15 | - .input= f.password_field :password | ||
16 | - .clearfix | ||
17 | - = f.label :password_confirmation | ||
18 | - .input= f.password_field :password_confirmation | ||
19 | - .actions | ||
20 | - = f.submit 'Save', :class => "btn" | ||
21 | - | ||
22 | -%h3 | ||
23 | - Private token | ||
24 | - %span.cred.right | ||
25 | - keep it in secret! | ||
26 | -%hr | ||
27 | -= form_for @user, :url => profile_reset_private_token_path, :method => :put do |f| | ||
28 | - .data | ||
29 | - %p Private token used to access application resources without authentication. | ||
30 | - %p For example its required to access commits feed. | 24 | + .span7.right |
25 | + %h3 | ||
26 | + Private token | ||
27 | + %span.cred.right | ||
28 | + keep it in secret! | ||
31 | %hr | 29 | %hr |
32 | - %p.cgray | ||
33 | - - if current_user.private_token | ||
34 | - = text_field_tag "token", current_user.private_token | ||
35 | - - else | ||
36 | - You don`t have one yet. Click generate to fix it. | ||
37 | - .actions | ||
38 | - - if current_user.private_token | ||
39 | - = f.submit 'Reset', :confirm => "Are you sure?", :class => "btn" | ||
40 | - - else | ||
41 | - = f.submit 'Generate', :class => "btn" | 30 | + = form_for @user, :url => profile_reset_private_token_path, :method => :put do |f| |
31 | + .data | ||
32 | + .alert-message.block-message.warning | ||
33 | + %p Private token used to access application resources without authentication. | ||
34 | + %hr | ||
35 | + %p * required for rss feed | ||
36 | + %p.cgray | ||
37 | + - if current_user.private_token | ||
38 | + = text_field_tag "token", current_user.private_token | ||
39 | + - else | ||
40 | + You don`t have one yet. Click generate to fix it. | ||
41 | + .actions | ||
42 | + - if current_user.private_token | ||
43 | + = f.submit 'Reset', :confirm => "Are you sure?", :class => "btn" | ||
44 | + - else | ||
45 | + = f.submit 'Generate', :class => "btn" | ||
42 | 46 |
app/views/projects/_show.html.haml
app/views/projects/empty.html.haml
@@ -6,7 +6,7 @@ | @@ -6,7 +6,7 @@ | ||
6 | %li Visit profile → keys and add public key of every machine you want to use for work with gitlabhq. | 6 | %li Visit profile → keys and add public key of every machine you want to use for work with gitlabhq. |
7 | 7 | ||
8 | .alert-message.block-message.error | 8 | .alert-message.block-message.error |
9 | - %ul.alert_holder | 9 | + %ul.unstyled.alert_holder |
10 | %li You should push repository to proceed. | 10 | %li You should push repository to proceed. |
11 | %li After push you will be able to browse code, commits etc. | 11 | %li After push you will be able to browse code, commits etc. |
12 | 12 |
app/views/projects/index.html.haml
1 | - if @projects.any? | 1 | - if @projects.any? |
2 | .row | 2 | .row |
3 | - .span4 | 3 | + .span11 |
4 | + = render @events | ||
5 | + .span5.right | ||
4 | %div.leftbar.ui-box | 6 | %div.leftbar.ui-box |
5 | %h5 | 7 | %h5 |
6 | Projects | 8 | Projects |
9 | + %small | ||
10 | + (#{@projects.count}) | ||
7 | - if current_user.can_create_project? | 11 | - if current_user.can_create_project? |
8 | %span.right | 12 | %span.right |
9 | = link_to new_project_path, :class => "btn very_small info" do | 13 | = link_to new_project_path, :class => "btn very_small info" do |
10 | New Project | 14 | New Project |
11 | .content_list | 15 | .content_list |
12 | - @projects.each do |project| | 16 | - @projects.each do |project| |
13 | - = link_to project_path(project), :remote => true, :class => dom_class(project) do | 17 | + = link_to project_path(project), :class => dom_class(project) do |
14 | %h4 | 18 | %h4 |
15 | %span.ico.project | 19 | %span.ico.project |
16 | - = truncate(project.name, :length => 22) | ||
17 | - .span12.right | ||
18 | - .show_holder.ui-box.padded | ||
19 | - .loading | 20 | + = truncate(project.name, :length => 25) |
21 | + %span.right | ||
22 | + → | ||
20 | 23 | ||
21 | - else | 24 | - else |
22 | %h3 Nothing here | 25 | %h3 Nothing here |
@@ -31,20 +34,3 @@ | @@ -31,20 +34,3 @@ | ||
31 | New Project » | 34 | New Project » |
32 | - else | 35 | - else |
33 | If you will be added to project - it will be displayed here | 36 | If you will be added to project - it will be displayed here |
34 | - | ||
35 | - | ||
36 | -:javascript | ||
37 | - $(function(){ | ||
38 | - $("a.project").live("ajax:before", function() { | ||
39 | - $(".show_holder").html("<div class='loading'>"); | ||
40 | - $('a.project').removeClass("active"); | ||
41 | - $(this).addClass("active"); | ||
42 | - }); | ||
43 | - $('a.project:first-child').trigger("click"); | ||
44 | - }); | ||
45 | - | ||
46 | -- if @projects.count == @limit | ||
47 | - :javascript | ||
48 | - $(function(){ | ||
49 | - Pager.init(#{@limit}); | ||
50 | - }); |
app/views/projects/show.html.haml
@@ -21,9 +21,13 @@ | @@ -21,9 +21,13 @@ | ||
21 | = text_field_tag :project_clone, @project.url_to_repo, :class => "xlarge one_click_select git_clone_url" | 21 | = text_field_tag :project_clone, @project.url_to_repo, :class => "xlarge one_click_select git_clone_url" |
22 | 22 | ||
23 | - if @project.description.present? | 23 | - if @project.description.present? |
24 | - = markdown @project.description | 24 | + .prettyprint= markdown @project.description |
25 | - unless @events.blank? | 25 | - unless @events.blank? |
26 | - %h5.cgray Recent Activity | 26 | + %br |
27 | + %h5.cgray | ||
28 | + %span.ico.activities | ||
29 | + Recent Activity | ||
30 | + %hr | ||
27 | .content_list= render @events | 31 | .content_list= render @events |
28 | 32 | ||
29 | 33 |
app/views/projects/show.js.haml
@@ -1,7 +0,0 @@ | @@ -1,7 +0,0 @@ | ||
1 | -- if @project.repo_exists? && @project.has_commits? | ||
2 | - :plain | ||
3 | - $(".show_holder").html("#{escape_javascript(render(:partial => 'projects/show'))}"); | ||
4 | -- else | ||
5 | - :plain | ||
6 | - $(".show_holder").html("#{escape_javascript(render(:template => 'projects/empty'))}"); | ||
7 | - |
No preview for this file type
@@ -0,0 +1,41 @@ | @@ -0,0 +1,41 @@ | ||
1 | += form_tag search_path, :method => :get do |f| | ||
2 | + .padded | ||
3 | + = label_tag :search, "Looking for" | ||
4 | + .input | ||
5 | + = text_field_tag :search, params[:search],:placeholder => "issue 143", :class => "xxlarge" | ||
6 | + = submit_tag 'Search', :class => "btn primary" | ||
7 | +- if params[:search].present? | ||
8 | + %br | ||
9 | + %h3 Search results | ||
10 | + %hr | ||
11 | + .search_results | ||
12 | + - if @projects.empty? && @merge_requests.empty? | ||
13 | + %h3 | ||
14 | + %small Nothing here | ||
15 | + - else | ||
16 | + - if @projects.any? | ||
17 | + - @projects.each do |project| | ||
18 | + = link_to project do | ||
19 | + %h4 | ||
20 | + %span.ico.project | ||
21 | + = project.name | ||
22 | + %small | ||
23 | + last activity at | ||
24 | + = project.last_activity_date.stamp("Aug 25, 2011") | ||
25 | + - if @merge_requests.any? | ||
26 | + - @merge_requests.each do |merge_request| | ||
27 | + = link_to [merge_request.project, merge_request] do | ||
28 | + %h5 | ||
29 | + Merge Request # | ||
30 | + = merge_request.id | ||
31 | + – | ||
32 | + = truncate merge_request.title, :length => 50 | ||
33 | + %small | ||
34 | + updated at | ||
35 | + = merge_request.updated_at.stamp("Aug 25, 2011") | ||
36 | + %strong | ||
37 | + %span.label= merge_request.project.name | ||
38 | + :javascript | ||
39 | + $(function() { | ||
40 | + $(".search_results").highlight("#{params[:search]}"); | ||
41 | + }) |
app/workers/post_receive.rb
@@ -8,7 +8,13 @@ class PostReceive | @@ -8,7 +8,13 @@ class PostReceive | ||
8 | # Ignore push from non-gitlab users | 8 | # Ignore push from non-gitlab users |
9 | return false unless Key.find_by_identifier(author_key_id) | 9 | return false unless Key.find_by_identifier(author_key_id) |
10 | 10 | ||
11 | + # Create push event | ||
11 | project.observe_push(oldrev, newrev, ref, author_key_id) | 12 | project.observe_push(oldrev, newrev, ref, author_key_id) |
13 | + | ||
14 | + # Close merged MR | ||
15 | + project.update_merge_requests(oldrev, newrev, ref, author_key_id) | ||
16 | + | ||
17 | + # Execute web hooks | ||
12 | project.execute_web_hooks(oldrev, newrev, ref, author_key_id) | 18 | project.execute_web_hooks(oldrev, newrev, ref, author_key_id) |
13 | end | 19 | end |
14 | end | 20 | end |
config/routes.rb
1 | Gitlab::Application.routes.draw do | 1 | Gitlab::Application.routes.draw do |
2 | - | 2 | + get 'search' => "search#show" |
3 | 3 | ||
4 | # Optionally, enable Resque here | 4 | # Optionally, enable Resque here |
5 | require 'resque/server' | 5 | require 'resque/server' |
@@ -40,6 +40,7 @@ Gitlab::Application.routes.draw do | @@ -40,6 +40,7 @@ Gitlab::Application.routes.draw do | ||
40 | get "dashboard", :to => "dashboard#index" | 40 | get "dashboard", :to => "dashboard#index" |
41 | get "dashboard/issues", :to => "dashboard#issues" | 41 | get "dashboard/issues", :to => "dashboard#issues" |
42 | get "dashboard/merge_requests", :to => "dashboard#merge_requests" | 42 | get "dashboard/merge_requests", :to => "dashboard#merge_requests" |
43 | + get "dashboard/activities", :to => "dashboard#activities" | ||
43 | 44 | ||
44 | #get "profile/:id", :to => "profile#show" | 45 | #get "profile/:id", :to => "profile#show" |
45 | 46 |
db/migrate/20120315111711_add_commits_diff_store_to_merge_request.rb
0 → 100644
db/migrate/20120315132931_add_merged_to_merge_request.rb
0 → 100644
db/schema.rb
@@ -11,7 +11,7 @@ | @@ -11,7 +11,7 @@ | ||
11 | # | 11 | # |
12 | # It's strongly recommended to check this file into your version control system. | 12 | # It's strongly recommended to check this file into your version control system. |
13 | 13 | ||
14 | -ActiveRecord::Schema.define(:version => 20120307095918) do | 14 | +ActiveRecord::Schema.define(:version => 20120315132931) do |
15 | 15 | ||
16 | create_table "events", :force => true do |t| | 16 | create_table "events", :force => true do |t| |
17 | t.string "target_type" | 17 | t.string "target_type" |
@@ -61,6 +61,9 @@ ActiveRecord::Schema.define(:version => 20120307095918) do | @@ -61,6 +61,9 @@ ActiveRecord::Schema.define(:version => 20120307095918) do | ||
61 | t.boolean "closed", :default => false, :null => false | 61 | t.boolean "closed", :default => false, :null => false |
62 | t.datetime "created_at", :null => false | 62 | t.datetime "created_at", :null => false |
63 | t.datetime "updated_at", :null => false | 63 | t.datetime "updated_at", :null => false |
64 | + t.text "st_commits" | ||
65 | + t.text "st_diffs" | ||
66 | + t.boolean "merged", :default => false, :null => false | ||
64 | end | 67 | end |
65 | 68 | ||
66 | add_index "merge_requests", ["project_id"], :name => "index_merge_requests_on_project_id" | 69 | add_index "merge_requests", ["project_id"], :name => "index_merge_requests_on_project_id" |
doc/installation.md
@@ -209,7 +209,7 @@ Application can be started with next command: | @@ -209,7 +209,7 @@ Application can be started with next command: | ||
209 | 209 | ||
210 | cd /home/gitlab/gitlab | 210 | cd /home/gitlab/gitlab |
211 | sudo -u gitlab cp config/unicorn.rb.orig config/unicorn.rb | 211 | sudo -u gitlab cp config/unicorn.rb.orig config/unicorn.rb |
212 | - sudo -u gitlab unicorn_rails -c config/unicorn.rb -E production -D | 212 | + sudo -u gitlab bundle exec unicorn_rails -c config/unicorn.rb -E production -D |
213 | 213 | ||
214 | Edit /etc/nginx/nginx.conf. Add next code to **http** section: | 214 | Edit /etc/nginx/nginx.conf. Add next code to **http** section: |
215 | 215 | ||
@@ -256,33 +256,38 @@ Create init script in /etc/init.d/gitlab: | @@ -256,33 +256,38 @@ Create init script in /etc/init.d/gitlab: | ||
256 | NAME=unicorn | 256 | NAME=unicorn |
257 | DESC="Gitlab service" | 257 | DESC="Gitlab service" |
258 | PID=/home/gitlab/gitlab/tmp/pids/unicorn.pid | 258 | PID=/home/gitlab/gitlab/tmp/pids/unicorn.pid |
259 | + RESQUE_PID=/home/gitlab/gitlab/tmp/pids/resque_worker.pid | ||
259 | 260 | ||
260 | case "$1" in | 261 | case "$1" in |
261 | start) | 262 | start) |
262 | CD_TO_APP_DIR="cd /home/gitlab/gitlab" | 263 | CD_TO_APP_DIR="cd /home/gitlab/gitlab" |
263 | START_DAEMON_PROCESS="bundle exec unicorn_rails $DAEMON_OPTS" | 264 | START_DAEMON_PROCESS="bundle exec unicorn_rails $DAEMON_OPTS" |
265 | + START_RESQUE_PROCESS="./resque.sh" | ||
264 | 266 | ||
265 | echo -n "Starting $DESC: " | 267 | echo -n "Starting $DESC: " |
266 | if [ `whoami` = root ]; then | 268 | if [ `whoami` = root ]; then |
267 | - sudo -u gitlab sh -c "$CD_TO_APP_DIR > /dev/null 2>&1 && $START_DAEMON_PROCESS" | 269 | + sudo -u gitlab sh -c "$CD_TO_APP_DIR > /dev/null 2>&1 && $START_DAEMON_PROCESS && $START_RESQUE_PROCESS" |
268 | else | 270 | else |
269 | - $CD_TO_APP_DIR > /dev/null 2>&1 && $START_DAEMON_PROCESS | 271 | + $CD_TO_APP_DIR > /dev/null 2>&1 && $START_DAEMON_PROCESS && $START_RESQUE_PROCESS |
270 | fi | 272 | fi |
271 | echo "$NAME." | 273 | echo "$NAME." |
272 | ;; | 274 | ;; |
273 | stop) | 275 | stop) |
274 | echo -n "Stopping $DESC: " | 276 | echo -n "Stopping $DESC: " |
275 | kill -QUIT `cat $PID` | 277 | kill -QUIT `cat $PID` |
278 | + kill -QUIT `cat $RESQUE_PID` | ||
276 | echo "$NAME." | 279 | echo "$NAME." |
277 | ;; | 280 | ;; |
278 | restart) | 281 | restart) |
279 | echo -n "Restarting $DESC: " | 282 | echo -n "Restarting $DESC: " |
280 | kill -USR2 `cat $PID` | 283 | kill -USR2 `cat $PID` |
284 | + kill -USR2 `cat $RESQUE_PID` | ||
281 | echo "$NAME." | 285 | echo "$NAME." |
282 | ;; | 286 | ;; |
283 | reload) | 287 | reload) |
284 | echo -n "Reloading $DESC configuration: " | 288 | echo -n "Reloading $DESC configuration: " |
285 | kill -HUP `cat $PID` | 289 | kill -HUP `cat $PID` |
290 | + kill -HUP `cat $RESQUE_PID` | ||
286 | echo "$NAME." | 291 | echo "$NAME." |
287 | ;; | 292 | ;; |
288 | *) | 293 | *) |
resque.sh
1 | mkdir tmp/pids | 1 | mkdir tmp/pids |
2 | -nohup bundle exec rake environment resque:work QUEUE=* RAILS_ENV=production PIDFILE=tmp/pids/resque_worker_QUEUE.pid & >> log/resque_worker_QUEUE.log 2>&1 | 2 | +nohup bundle exec rake environment resque:work QUEUE=* RAILS_ENV=production PIDFILE=tmp/pids/resque_worker.pid & >> log/resque_worker.log 2>&1 |
spec/models/project_spec.rb
@@ -160,6 +160,34 @@ describe Project do | @@ -160,6 +160,34 @@ describe Project do | ||
160 | end | 160 | end |
161 | end | 161 | end |
162 | end | 162 | end |
163 | + | ||
164 | + describe :update_merge_requests do | ||
165 | + let(:project) { Factory :project } | ||
166 | + | ||
167 | + before do | ||
168 | + @merge_request = Factory :merge_request, | ||
169 | + :project => project, | ||
170 | + :merged => false, | ||
171 | + :closed => false | ||
172 | + @key = Factory :key, :user_id => project.owner.id | ||
173 | + end | ||
174 | + | ||
175 | + it "should close merge request if last commit from source branch was pushed to target branch" do | ||
176 | + @merge_request.reloaded_commits | ||
177 | + @merge_request.last_commit.id.should == "bcf03b5de6c33f3869ef70d68cf06e679d1d7f9a" | ||
178 | + project.update_merge_requests("8716fc78f3c65bbf7bcf7b574febd583bc5d2812", "bcf03b5de6c33f3869ef70d68cf06e679d1d7f9a", "refs/heads/stable", @key.identifier) | ||
179 | + @merge_request.reload | ||
180 | + @merge_request.merged.should be_true | ||
181 | + @merge_request.closed.should be_true | ||
182 | + end | ||
183 | + | ||
184 | + it "should update merge request commits with new one if pushed to source branch" do | ||
185 | + @merge_request.last_commit.should == nil | ||
186 | + project.update_merge_requests("8716fc78f3c65bbf7bcf7b574febd583bc5d2812", "bcf03b5de6c33f3869ef70d68cf06e679d1d7f9a", "refs/heads/master", @key.identifier) | ||
187 | + @merge_request.reload | ||
188 | + @merge_request.last_commit.id.should == "bcf03b5de6c33f3869ef70d68cf06e679d1d7f9a" | ||
189 | + end | ||
190 | + end | ||
163 | end | 191 | end |
164 | # == Schema Information | 192 | # == Schema Information |
165 | # | 193 | # |
spec/requests/dashboard_spec.rb
1 | require 'spec_helper' | 1 | require 'spec_helper' |
2 | -__END__ | ||
3 | -# Disabled for now | ||
4 | describe "Dashboard" do | 2 | describe "Dashboard" do |
5 | before do | 3 | before do |
6 | @project = Factory :project | 4 | @project = Factory :project |
@@ -22,19 +20,7 @@ describe "Dashboard" do | @@ -22,19 +20,7 @@ describe "Dashboard" do | ||
22 | end | 20 | end |
23 | 21 | ||
24 | it "should have projects panel" do | 22 | it "should have projects panel" do |
25 | - within ".project-list" do | ||
26 | - page.should have_content(@project.name) | ||
27 | - end | 23 | + page.should have_content(@project.name) |
28 | end | 24 | end |
29 | - | ||
30 | - # Temporary disabled cause of travis | ||
31 | - # TODO: fix or rewrite | ||
32 | - #it "should have news feed" do | ||
33 | - #within "#news-feed" do | ||
34 | - #page.should have_content("commit") | ||
35 | - #page.should have_content(@project.commit.author.name) | ||
36 | - #page.should have_content(@project.commit.safe_message) | ||
37 | - #end | ||
38 | - #end | ||
39 | end | 25 | end |
40 | end | 26 | end |
spec/requests/merge_requests_spec.rb
@@ -42,7 +42,7 @@ describe "MergeRequests" do | @@ -42,7 +42,7 @@ describe "MergeRequests" do | ||
42 | 42 | ||
43 | it { should have_content(@merge_request.title[0..10]) } | 43 | it { should have_content(@merge_request.title[0..10]) } |
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 | - page.should have_content "Reopen" | 45 | + page.should have_content "Closed" |
46 | end | 46 | end |
47 | end | 47 | end |
48 | end | 48 | end |
@@ -0,0 +1,53 @@ | @@ -0,0 +1,53 @@ | ||
1 | +/* | ||
2 | + | ||
3 | +highlight v3 | ||
4 | + | ||
5 | +Highlights arbitrary terms. | ||
6 | + | ||
7 | +<http://johannburkard.de/blog/programming/javascript/highlight-javascript-text-higlighting-jquery-plugin.html> | ||
8 | + | ||
9 | +MIT license. | ||
10 | + | ||
11 | +Johann Burkard | ||
12 | +<http://johannburkard.de> | ||
13 | +<mailto:jb@eaio.com> | ||
14 | + | ||
15 | +*/ | ||
16 | + | ||
17 | +jQuery.fn.highlight = function(pat) { | ||
18 | + function innerHighlight(node, pat) { | ||
19 | + var skip = 0; | ||
20 | + if (node.nodeType == 3) { | ||
21 | + var pos = node.data.toUpperCase().indexOf(pat); | ||
22 | + if (pos >= 0) { | ||
23 | + var spannode = document.createElement('span'); | ||
24 | + spannode.className = 'highlight_word'; | ||
25 | + var middlebit = node.splitText(pos); | ||
26 | + var endbit = middlebit.splitText(pat.length); | ||
27 | + var middleclone = middlebit.cloneNode(true); | ||
28 | + spannode.appendChild(middleclone); | ||
29 | + middlebit.parentNode.replaceChild(spannode, middlebit); | ||
30 | + skip = 1; | ||
31 | + } | ||
32 | + } | ||
33 | + else if (node.nodeType == 1 && node.childNodes && !/(script|style)/i.test(node.tagName)) { | ||
34 | + for (var i = 0; i < node.childNodes.length; ++i) { | ||
35 | + i += innerHighlight(node.childNodes[i], pat); | ||
36 | + } | ||
37 | + } | ||
38 | + return skip; | ||
39 | + } | ||
40 | + return this.each(function() { | ||
41 | + innerHighlight(this, pat.toUpperCase()); | ||
42 | + }); | ||
43 | +}; | ||
44 | + | ||
45 | +jQuery.fn.removeHighlight = function() { | ||
46 | + return this.find("span.highlight").each(function() { | ||
47 | + this.parentNode.firstChild.nodeName; | ||
48 | + with (this.parentNode) { | ||
49 | + replaceChild(this.firstChild, this); | ||
50 | + normalize(); | ||
51 | + } | ||
52 | + }).end(); | ||
53 | +}; |