Commit b80dd3d2422b59a1b241ccdae32140ca19f33dc3
1 parent
eae41ad1
Exists in
master
and in
4 other branches
Non-interactive AWS install by running a single script.
Merge branch 'master' into non-interactive-aws-install Conflicts: doc/installation.md Fix merge mess in installation.md
Showing
225 changed files
with
4550 additions
and
4069 deletions
Show diff stats
Too many changes.
To preserve performance only 100 of 225 files displayed.
.rails_footnotes
CHANGELOG
1 | +v 2.9.0 | |
2 | + - fixed inline notes bugs | |
3 | + - refactored rspecs | |
4 | + - refactored gitolite backend | |
5 | + - added factory_girl | |
6 | + - restyled projects list on dashboard | |
7 | + - ssh keys validation to prevent gitolite crash | |
8 | + - send notifications if changed premission in project | |
9 | + - scss refactoring. gitlab_bootstrap/ dir | |
10 | + - fix git push http body bigger than 112k problem | |
11 | + - list of labels page under issues tab | |
12 | + - API for milestones | |
13 | + - restyled buttons | |
14 | + | |
15 | +v 2.8.1 | |
16 | + - ability to disable gravatars | |
17 | + - improved MR diff logic | |
18 | + - ssh key help page | |
19 | + | |
1 | 20 | v 2.8.0 |
2 | 21 | - Gitlab Flavored Markdown |
3 | 22 | - Bulk issues update |
4 | 23 | - Issues API |
5 | 24 | - Cucumber coverage increased |
25 | + - Post-receive files fixed | |
26 | + - UI improved | |
27 | + - Application cleanup | |
28 | + - more cucumber | |
29 | + - capybara-webkit + headless | |
6 | 30 | |
7 | 31 | v 2.7.0 |
8 | 32 | - Issue Labels | ... | ... |
Gemfile
... | ... | @@ -54,7 +54,7 @@ gem "unicorn" |
54 | 54 | gem "acts-as-taggable-on", "2.3.1" |
55 | 55 | |
56 | 56 | # Decorators |
57 | -gem "drapper" | |
57 | +gem "draper" | |
58 | 58 | |
59 | 59 | # Background jobs |
60 | 60 | gem "resque", "~> 1.20.0" |
... | ... | @@ -92,7 +92,6 @@ end |
92 | 92 | |
93 | 93 | group :development do |
94 | 94 | gem "letter_opener" |
95 | - gem "rails-footnotes" | |
96 | 95 | gem "annotate", :git => "https://github.com/ctran/annotate_models.git" |
97 | 96 | gem 'rack-mini-profiler' |
98 | 97 | end |
... | ... | @@ -108,15 +107,18 @@ group :development, :test do |
108 | 107 | gem "awesome_print" |
109 | 108 | gem "database_cleaner" |
110 | 109 | gem "launchy" |
110 | + gem 'factory_girl_rails' | |
111 | 111 | end |
112 | 112 | |
113 | 113 | group :test do |
114 | 114 | gem 'cucumber-rails', :require => false |
115 | - gem 'minitest', ">= 2.10" | |
116 | - gem "turn", :require => false | |
117 | 115 | gem "simplecov", :require => false |
118 | 116 | gem "shoulda-matchers" |
119 | 117 | gem 'email_spec' |
120 | 118 | gem 'resque_spec' |
121 | 119 | gem "webmock" |
122 | 120 | end |
121 | + | |
122 | +group :production do | |
123 | + gem "gitlab_meta", '2.9' | |
124 | +end | ... | ... |
Gemfile.lock
... | ... | @@ -99,7 +99,6 @@ GEM |
99 | 99 | acts-as-taggable-on (2.3.1) |
100 | 100 | rails (~> 3.0) |
101 | 101 | addressable (2.2.8) |
102 | - ansi (1.4.2) | |
103 | 102 | arel (3.0.2) |
104 | 103 | autotest (4.4.6) |
105 | 104 | ZenTest (>= 4.4.1) |
... | ... | @@ -156,7 +155,9 @@ GEM |
156 | 155 | railties (~> 3.1) |
157 | 156 | warden (~> 1.2.1) |
158 | 157 | diff-lcs (1.1.3) |
159 | - drapper (0.8.4) | |
158 | + draper (0.17.0) | |
159 | + actionpack (~> 3.2) | |
160 | + activesupport (~> 3.2) | |
160 | 161 | email_spec (1.2.1) |
161 | 162 | mail (~> 2.2) |
162 | 163 | rspec (~> 2.0) |
... | ... | @@ -165,6 +166,11 @@ GEM |
165 | 166 | eventmachine (0.12.10) |
166 | 167 | execjs (1.4.0) |
167 | 168 | multi_json (~> 1.0) |
169 | + factory_girl (4.0.0) | |
170 | + activesupport (>= 3.0.0) | |
171 | + factory_girl_rails (4.0.0) | |
172 | + factory_girl (~> 4.0.0) | |
173 | + railties (>= 3.0.0) | |
168 | 174 | ffaker (1.14.0) |
169 | 175 | ffi (1.0.11) |
170 | 176 | foreman (0.47.0) |
... | ... | @@ -172,6 +178,7 @@ GEM |
172 | 178 | gherkin (2.11.0) |
173 | 179 | json (>= 1.4.6) |
174 | 180 | git (1.2.5) |
181 | + gitlab_meta (2.9) | |
175 | 182 | grape (0.2.1) |
176 | 183 | hashie (~> 1.2) |
177 | 184 | multi_json |
... | ... | @@ -218,7 +225,6 @@ GEM |
218 | 225 | treetop (~> 1.4.8) |
219 | 226 | method_source (0.7.1) |
220 | 227 | mime-types (1.19) |
221 | - minitest (3.1.0) | |
222 | 228 | modernizr (2.5.3) |
223 | 229 | sprockets (~> 2.0) |
224 | 230 | multi_json (1.3.6) |
... | ... | @@ -258,8 +264,6 @@ GEM |
258 | 264 | activesupport (= 3.2.8) |
259 | 265 | bundler (~> 1.0) |
260 | 266 | railties (= 3.2.8) |
261 | - rails-footnotes (3.7.8) | |
262 | - rails (>= 3.0.0) | |
263 | 267 | railties (3.2.8) |
264 | 268 | actionpack (= 3.2.8) |
265 | 269 | activesupport (= 3.2.8) |
... | ... | @@ -349,8 +353,6 @@ GEM |
349 | 353 | treetop (1.4.10) |
350 | 354 | polyglot |
351 | 355 | polyglot (>= 0.3.1) |
352 | - turn (0.9.5) | |
353 | - ansi | |
354 | 356 | tzinfo (0.3.33) |
355 | 357 | uglifier (1.0.3) |
356 | 358 | execjs (>= 0.3.0) |
... | ... | @@ -389,11 +391,13 @@ DEPENDENCIES |
389 | 391 | cucumber-rails |
390 | 392 | database_cleaner |
391 | 393 | devise (~> 2.1.0) |
392 | - drapper | |
394 | + draper | |
393 | 395 | email_spec |
396 | + factory_girl_rails | |
394 | 397 | ffaker |
395 | 398 | foreman |
396 | 399 | git |
400 | + gitlab_meta (= 2.9) | |
397 | 401 | gitolite! |
398 | 402 | grack! |
399 | 403 | grape (~> 0.2.1) |
... | ... | @@ -407,7 +411,6 @@ DEPENDENCIES |
407 | 411 | launchy |
408 | 412 | letter_opener |
409 | 413 | linguist (~> 1.0.0)! |
410 | - minitest (>= 2.10) | |
411 | 414 | modernizr (= 2.5.3) |
412 | 415 | mysql2 |
413 | 416 | omniauth-ldap! |
... | ... | @@ -415,7 +418,6 @@ DEPENDENCIES |
415 | 418 | pygments.rb! |
416 | 419 | rack-mini-profiler |
417 | 420 | rails (= 3.2.8) |
418 | - rails-footnotes | |
419 | 421 | raphael-rails (= 1.5.2) |
420 | 422 | redcarpet (~> 2.1.1) |
421 | 423 | resque (~> 1.20.0) |
... | ... | @@ -432,7 +434,6 @@ DEPENDENCIES |
432 | 434 | stamp |
433 | 435 | therubyracer |
434 | 436 | thin |
435 | - turn | |
436 | 437 | uglifier (= 1.0.3) |
437 | 438 | unicorn |
438 | 439 | webmock | ... | ... |
README.md
VERSION
app/assets/images/file_dir.png
593 Bytes
app/assets/javascripts/application.js
... | ... | @@ -72,7 +72,7 @@ $(document).ready(function(){ |
72 | 72 | * Note markdown preview |
73 | 73 | * |
74 | 74 | */ |
75 | - $('#preview-link').on('click', function(e) { | |
75 | + $(document).on('click', '#preview-link', function(e) { | |
76 | 76 | $('#preview-note').text('Loading...'); |
77 | 77 | |
78 | 78 | var previewLinkText = ($(this).text() == 'Preview' ? 'Edit' : 'Preview'); |
... | ... | @@ -128,3 +128,23 @@ function showDiff(link) { |
128 | 128 | function ajaxGet(url) { |
129 | 129 | $.ajax({type: "GET", url: url, dataType: "script"}); |
130 | 130 | } |
131 | + | |
132 | +/** | |
133 | + * Disable button if text field is empty | |
134 | + */ | |
135 | +function disableButtonIfEmtpyField(field_selector, button_selector) { | |
136 | + field = $(field_selector); | |
137 | + if(field.val() == "") { | |
138 | + field.closest("form").find(button_selector).attr("disabled", "disabled").addClass("disabled"); | |
139 | + } | |
140 | + | |
141 | + field.on('keyup', function(){ | |
142 | + var field = $(this); | |
143 | + var closest_submit = field.closest("form").find(button_selector); | |
144 | + if(field.val() == "") { | |
145 | + closest_submit.attr("disabled", "disabled").addClass("disabled"); | |
146 | + } else { | |
147 | + closest_submit.removeAttr("disabled").removeClass("disabled"); | |
148 | + } | |
149 | + }) | |
150 | +} | ... | ... |
app/assets/javascripts/issues.js
... | ... | @@ -5,6 +5,7 @@ function switchToNewIssue(form){ |
5 | 5 | $('select#issue_milestone_id').chosen(); |
6 | 6 | $("#new_issue_dialog").show("fade", { direction: "right" }, 150); |
7 | 7 | $('.top-tabs .add_new').hide(); |
8 | + disableButtonIfEmtpyField("#issue_title", ".save-btn"); | |
8 | 9 | }); |
9 | 10 | } |
10 | 11 | |
... | ... | @@ -15,6 +16,7 @@ function switchToEditIssue(form){ |
15 | 16 | $('select#issue_milestone_id').chosen(); |
16 | 17 | $("#edit_issue_dialog").show("fade", { direction: "right" }, 150); |
17 | 18 | $('.add_new').hide(); |
19 | + disableButtonIfEmtpyField("#issue_title", ".save-btn"); | |
18 | 20 | }); |
19 | 21 | } |
20 | 22 | ... | ... |
app/assets/javascripts/note.js
1 | 1 | var NoteList = { |
2 | 2 | |
3 | -notes_path: null, | |
4 | -target_params: null, | |
5 | -target_id: 0, | |
6 | -target_type: null, | |
7 | -first_id: 0, | |
8 | -last_id: 0, | |
9 | -disable:false, | |
10 | - | |
11 | -init: | |
12 | - function(tid, tt, path) { | |
13 | - this.notes_path = path + ".js"; | |
14 | - this.target_id = tid; | |
15 | - this.target_type = tt; | |
16 | - this.target_params = "&target_type=" + this.target_type + "&target_id=" + this.target_id; | |
17 | - | |
18 | - // get notes | |
19 | - this.getContent(); | |
20 | - | |
21 | - // get new notes every n seconds | |
22 | - this.initRefresh(); | |
23 | - | |
24 | - $('.delete-note').live('ajax:success', function() { | |
25 | - $(this).closest('li').fadeOut(); }); | |
26 | - | |
27 | - $("#new_note").live("ajax:before", function(){ | |
28 | - $(".submit_note").attr("disabled", "disabled"); | |
29 | - }) | |
30 | - | |
31 | - $("#new_note").live("ajax:complete", function(){ | |
32 | - $(".submit_note").removeAttr("disabled"); | |
33 | - }) | |
34 | - | |
35 | - $("#note_note").live("focus", function(){ | |
36 | - $(this).css("height", "80px"); | |
37 | - $('.note_advanced_opts').show(); | |
38 | - }); | |
39 | - | |
40 | - $("#note_attachment").change(function(e){ | |
3 | + notes_path: null, | |
4 | + target_params: null, | |
5 | + target_id: 0, | |
6 | + target_type: null, | |
7 | + first_id: 0, | |
8 | + last_id: 0, | |
9 | + disable:false, | |
10 | + | |
11 | + init: | |
12 | + function(tid, tt, path) { | |
13 | + this.notes_path = path + ".js"; | |
14 | + this.target_id = tid; | |
15 | + this.target_type = tt; | |
16 | + this.target_params = "&target_type=" + this.target_type + "&target_id=" + this.target_id; | |
17 | + | |
18 | + // get notes | |
19 | + this.getContent(); | |
20 | + | |
21 | + // get new notes every n seconds | |
22 | + this.initRefresh(); | |
23 | + | |
24 | + $('.delete-note').live('ajax:success', function() { | |
25 | + $(this).closest('li').fadeOut(); }); | |
26 | + | |
27 | + $(".note-form-holder").live("ajax:before", function(){ | |
28 | + $(".submit_note").attr("disabled", "disabled"); | |
29 | + }) | |
30 | + | |
31 | + $(".note-form-holder").live("ajax:complete", function(){ | |
32 | + $(".submit_note").removeAttr("disabled"); | |
33 | + }) | |
34 | + | |
35 | + disableButtonIfEmtpyField(".note-text", ".submit_note"); | |
36 | + | |
37 | + $(".note-text").live("focus", function(){ | |
38 | + $(this).css("height", "80px"); | |
39 | + $('.note_advanced_opts').show(); | |
40 | + }); | |
41 | + | |
42 | + $("#note_attachment").change(function(e){ | |
41 | 43 | var val = $('.input-file').val(); |
42 | 44 | var filename = val.replace(/^.*[\\\/]/, ''); |
43 | 45 | $(".file_name").text(filename); |
44 | - }); | |
46 | + }); | |
45 | 47 | |
46 | - }, | |
48 | + }, | |
47 | 49 | |
48 | 50 | |
49 | -/** | |
50 | - * Load new notes to fresh list called 'new_notes_list': | |
51 | - * - Replace 'new_notes_list' with new list every n seconds | |
52 | - * - Append new notes to this list after submit | |
53 | - */ | |
51 | + /** | |
52 | + * Load new notes to fresh list called 'new_notes_list': | |
53 | + * - Replace 'new_notes_list' with new list every n seconds | |
54 | + * - Append new notes to this list after submit | |
55 | + */ | |
54 | 56 | |
55 | -initRefresh: | |
56 | - function() { | |
57 | - // init timer | |
58 | - var intNew = setInterval("NoteList.getNew()", 10000); | |
59 | - }, | |
57 | + initRefresh: | |
58 | + function() { | |
59 | + // init timer | |
60 | + var intNew = setInterval("NoteList.getNew()", 10000); | |
61 | + }, | |
60 | 62 | |
61 | -replace: | |
62 | - function(html) { | |
63 | - $("#new_notes_list").html(html); | |
64 | - }, | |
63 | + replace: | |
64 | + function(html) { | |
65 | + $("#new_notes_list").html(html); | |
66 | + }, | |
65 | 67 | |
66 | -prepend: | |
67 | - function(id, html) { | |
68 | - if(id != this.last_id) { | |
69 | - $("#new_notes_list").prepend(html); | |
70 | - } | |
71 | - }, | |
68 | + prepend: | |
69 | + function(id, html) { | |
70 | + if(id != this.last_id) { | |
71 | + $("#new_notes_list").prepend(html); | |
72 | + } | |
73 | + }, | |
72 | 74 | |
73 | -getNew: | |
74 | - function() { | |
75 | - // refersh notes list | |
76 | - $.ajax({ | |
77 | - type: "GET", | |
75 | + getNew: | |
76 | + function() { | |
77 | + // refersh notes list | |
78 | + $.ajax({ | |
79 | + type: "GET", | |
78 | 80 | url: this.notes_path, |
79 | 81 | data: "last_id=" + this.last_id + this.target_params, |
80 | 82 | dataType: "script"}); |
81 | - }, | |
83 | + }, | |
82 | 84 | |
83 | -refresh: | |
84 | - function() { | |
85 | - // refersh notes list | |
86 | - $.ajax({ | |
87 | - type: "GET", | |
85 | + refresh: | |
86 | + function() { | |
87 | + // refersh notes list | |
88 | + $.ajax({ | |
89 | + type: "GET", | |
88 | 90 | url: this.notes_path, |
89 | 91 | data: "first_id=" + this.first_id + "&last_id=" + this.last_id + this.target_params, |
90 | 92 | dataType: "script"}); |
91 | - }, | |
93 | + }, | |
92 | 94 | |
93 | 95 | |
94 | -/** | |
95 | - * Init load of notes: | |
96 | - * 1. Get content with ajax call | |
97 | - * 2. Set content of notes list with loaded one | |
98 | - */ | |
96 | + /** | |
97 | + * Init load of notes: | |
98 | + * 1. Get content with ajax call | |
99 | + * 2. Set content of notes list with loaded one | |
100 | + */ | |
99 | 101 | |
100 | 102 | |
101 | -getContent: | |
102 | - function() { | |
103 | - $.ajax({ | |
104 | - type: "GET", | |
103 | + getContent: | |
104 | + function() { | |
105 | + $.ajax({ | |
106 | + type: "GET", | |
105 | 107 | url: this.notes_path, |
106 | 108 | data: "?" + this.target_params, |
107 | 109 | complete: function(){ $('.status').removeClass("loading")}, |
108 | 110 | beforeSend: function() { $('.status').addClass("loading") }, |
109 | 111 | dataType: "script"}); |
110 | - }, | |
112 | + }, | |
111 | 113 | |
112 | -setContent: | |
113 | - function(fid, lid, html) { | |
114 | + setContent: | |
115 | + function(fid, lid, html) { | |
114 | 116 | this.last_id = lid; |
115 | 117 | this.first_id = fid; |
116 | 118 | $("#notes-list").html(html); |
117 | 119 | |
118 | 120 | // Init infinite scrolling |
119 | 121 | this.initLoadMore(); |
120 | - }, | |
121 | - | |
122 | - | |
123 | -/** | |
124 | - * Paging for old notes when scroll to bottom: | |
125 | - * 1. Init scroll events with 'initLoadMore' | |
126 | - * 2. Load onlder notes with 'getOld' method | |
127 | - * 3. append old notes to bottom of list with 'append' | |
128 | - * | |
129 | - */ | |
130 | - | |
131 | - | |
132 | -getOld: | |
133 | - function() { | |
134 | - $('.loading').show(); | |
135 | - $.ajax({ | |
136 | - type: "GET", | |
137 | - url: this.notes_path, | |
138 | - data: "first_id=" + this.first_id + this.target_params, | |
139 | - complete: function(){ $('.status').removeClass("loading")}, | |
140 | - beforeSend: function() { $('.status').addClass("loading") }, | |
141 | - dataType: "script"}); | |
142 | - }, | |
143 | - | |
144 | -append: | |
145 | - function(id, html) { | |
146 | - if(this.first_id == id) { | |
147 | - this.disable = true; | |
148 | - } else { | |
149 | - this.first_id = id; | |
150 | - $("#notes-list").append(html); | |
151 | - } | |
152 | - }, | |
153 | - | |
122 | + }, | |
123 | + | |
124 | + | |
125 | + /** | |
126 | + * Paging for old notes when scroll to bottom: | |
127 | + * 1. Init scroll events with 'initLoadMore' | |
128 | + * 2. Load onlder notes with 'getOld' method | |
129 | + * 3. append old notes to bottom of list with 'append' | |
130 | + * | |
131 | + */ | |
132 | + getOld: | |
133 | + function() { | |
134 | + $('.loading').show(); | |
135 | + $.ajax({ | |
136 | + type: "GET", | |
137 | + url: this.notes_path, | |
138 | + data: "first_id=" + this.first_id + this.target_params, | |
139 | + complete: function(){ $('.status').removeClass("loading")}, | |
140 | + beforeSend: function() { $('.status').addClass("loading") }, | |
141 | + dataType: "script"}); | |
142 | + }, | |
143 | + | |
144 | + append: | |
145 | + function(id, html) { | |
146 | + if(this.first_id == id) { | |
147 | + this.disable = true; | |
148 | + } else { | |
149 | + this.first_id = id; | |
150 | + $("#notes-list").append(html); | |
151 | + } | |
152 | + }, | |
154 | 153 | |
155 | -initLoadMore: | |
156 | - function() { | |
157 | - $(document).endlessScroll({ | |
158 | - bottomPixels: 400, | |
154 | + initLoadMore: | |
155 | + function() { | |
156 | + $(document).endlessScroll({ | |
157 | + bottomPixels: 400, | |
159 | 158 | fireDelay: 1000, |
160 | 159 | fireOnce:true, |
161 | 160 | ceaseFire: function() { |
... | ... | @@ -164,6 +163,20 @@ initLoadMore: |
164 | 163 | callback: function(i) { |
165 | 164 | NoteList.getOld(); |
166 | 165 | } |
167 | - }); | |
168 | - } | |
166 | + }); | |
167 | + } | |
168 | +}; | |
169 | + | |
170 | +var PerLineNotes = { | |
171 | + init: | |
172 | + function() { | |
173 | + $(".line_note_link, .line_note_reply_link").live("click", function(e) { | |
174 | + var form = $(".per_line_form"); | |
175 | + $(this).closest("tr").after(form); | |
176 | + form.find("#note_line_code").val($(this).attr("line_code")); | |
177 | + form.show(); | |
178 | + return false; | |
179 | + }); | |
180 | + disableButtonIfEmtpyField(".line-note-text", ".submit_inline_note"); | |
181 | + } | |
169 | 182 | } | ... | ... |
app/assets/javascripts/projects.js
... | ... | @@ -7,8 +7,10 @@ function Projects() { |
7 | 7 | |
8 | 8 | $('.new_project, .edit_project').live('ajax:before', function() { |
9 | 9 | $('.project_new_holder, .project_edit_holder').hide(); |
10 | - $('.ajax_loader').show(); | |
10 | + $('.save-project-loader').show(); | |
11 | 11 | }); |
12 | 12 | |
13 | 13 | $('form #project_default_branch').chosen(); |
14 | + | |
15 | + disableButtonIfEmtpyField("#project_name", ".project-submit") | |
14 | 16 | } | ... | ... |
app/assets/stylesheets/common.scss
1 | -.diff_file_header a, | |
2 | -.file_stats a { | |
3 | - color:$style_color; | |
4 | -} | |
5 | - | |
6 | - | |
7 | 1 | /** LAYOUT **/ |
8 | 2 | |
3 | +body { | |
4 | + margin-bottom:20px; | |
5 | +} | |
6 | + | |
9 | 7 | .container { |
10 | 8 | padding-top:0; |
11 | 9 | z-index:5; |
... | ... | @@ -40,30 +38,6 @@ |
40 | 38 | color: $link_color; |
41 | 39 | } |
42 | 40 | |
43 | -.widget { | |
44 | - @include shade; | |
45 | - padding:20px; | |
46 | - margin-bottom:20px; | |
47 | - border: 1px solid #DDD; | |
48 | - border-radius: 5px; | |
49 | - background:#fafafa; | |
50 | - | |
51 | - .link_holder { | |
52 | - background:#eee; | |
53 | - position:relative; | |
54 | - left:-20px; | |
55 | - top:20px; | |
56 | - padding:10px 20px; | |
57 | - width:100%; | |
58 | - border-top:1px solid #ccc; | |
59 | - | |
60 | - a { | |
61 | - font-size:14px; | |
62 | - color:#666; | |
63 | - } | |
64 | - } | |
65 | -} | |
66 | - | |
67 | 41 | .help li { color:#111 } |
68 | 42 | |
69 | 43 | .back_link { |
... | ... | @@ -88,16 +62,6 @@ |
88 | 62 | padding-left:20px; |
89 | 63 | } |
90 | 64 | |
91 | -.number { | |
92 | - border-radius: 4px; | |
93 | - text-shadow: none; | |
94 | - background: rgba(0,0,0,.12); | |
95 | - text-align: center; | |
96 | - padding: 2px 4px; | |
97 | - line-height:18px; | |
98 | - margin-left:2px; | |
99 | -} | |
100 | - | |
101 | 65 | table a code { |
102 | 66 | position: relative; |
103 | 67 | top: -2px; |
... | ... | @@ -129,26 +93,18 @@ table a code { |
129 | 93 | border-bottom:1px solid #ccc; |
130 | 94 | |
131 | 95 | h4 { |
132 | - color:#444; | |
133 | - font-size:22px; | |
96 | + color:#666; | |
97 | + font-size:18px; | |
98 | + line-height:38px; | |
134 | 99 | padding-top:5px; |
135 | 100 | margin:2px; |
101 | + font-weight:normal; | |
136 | 102 | } |
137 | 103 | } |
138 | 104 | |
139 | 105 | .git_url_wrapper { |
140 | 106 | margin-right:50px |
141 | 107 | } |
142 | -.file_stats { | |
143 | - span { | |
144 | - img { | |
145 | - width:14px; | |
146 | - float:left; | |
147 | - margin-right:6px; | |
148 | - padding:2px 0; | |
149 | - } | |
150 | - } | |
151 | -} | |
152 | 108 | |
153 | 109 | .handle:hover { |
154 | 110 | cursor:move; |
... | ... | @@ -172,10 +128,6 @@ span.update-author { |
172 | 128 | display:block; |
173 | 129 | } |
174 | 130 | /** END UPDATE ITEM **/ |
175 | -.ajax-tab-loading { | |
176 | - padding:40px; | |
177 | - display:none; | |
178 | -} | |
179 | 131 | .dashboard-loader { |
180 | 132 | float:left; |
181 | 133 | margin:10px; |
... | ... | @@ -186,15 +138,110 @@ span.update-author { |
186 | 138 | font-weight:bold; |
187 | 139 | } |
188 | 140 | |
189 | -a.project-update.titled { | |
190 | - position:relative; | |
191 | - padding-left:35% !important; | |
192 | - .title-block { | |
193 | - padding:10px; | |
194 | - width:35%; | |
195 | - position:absolute; | |
196 | - left:0; | |
197 | - top:0; | |
141 | +.neib { | |
142 | + margin-right:10px; | |
143 | +} | |
144 | + | |
145 | +.label { | |
146 | + background-color: #474D57; | |
147 | + | |
148 | + &.label-issue { | |
149 | + background-color: #eee; | |
150 | + border: 1px solid #ccc; | |
151 | + padding:4px 6px; | |
152 | + color:#444; | |
153 | + text-shadow:0 0 1px #fff; | |
154 | + | |
155 | + &.grouped { | |
156 | + float: left; | |
157 | + margin-right: 6px; | |
158 | + padding: 6px; | |
159 | + } | |
160 | + } | |
161 | +} | |
162 | + | |
163 | +.event_label { | |
164 | + @extend .label; | |
165 | + background-color: #999; | |
166 | + | |
167 | + &.pushed { | |
168 | + background-color: #4A97BD; | |
169 | + } | |
170 | + | |
171 | + &.opened { | |
172 | + background-color: #469847; | |
173 | + } | |
174 | + | |
175 | + &.closed { | |
176 | + background-color: #B94A48; | |
177 | + } | |
178 | + | |
179 | + &.merged { | |
180 | + background-color: #2A2; | |
181 | + } | |
182 | +} | |
183 | + | |
184 | +form { | |
185 | + @extend .form-horizontal; | |
186 | + | |
187 | + .actions { | |
188 | + @extend .form-actions; | |
189 | + } | |
190 | + | |
191 | + .clearfix { | |
192 | + @extend .control-group; | |
193 | + } | |
194 | + | |
195 | + .input { | |
196 | + @extend .controls; | |
197 | + } | |
198 | + | |
199 | + label { | |
200 | + @extend .control-label; | |
201 | + } | |
202 | + .xlarge { | |
203 | + @extend .input-xlarge; | |
204 | + } | |
205 | + .xxlarge { | |
206 | + @extend .input-xxlarge; | |
207 | + } | |
208 | +} | |
209 | + | |
210 | + | |
211 | +.field_with_errors { | |
212 | + display:inline; | |
213 | +} | |
214 | + | |
215 | +ul.breadcrumb { | |
216 | + background:white; | |
217 | + border:none; | |
218 | + li { | |
219 | + display: inline; | |
220 | + text-shadow: 0 1px 0 white | |
221 | + } | |
222 | + | |
223 | + a { | |
224 | + color:#474D57; | |
225 | + font-weight:bold; | |
226 | + font-size:14px; | |
227 | + } | |
228 | + | |
229 | + .arrow { | |
230 | + background: url("images.png") no-repeat -85px -77px; | |
231 | + width: 19px; | |
232 | + height: 16px; | |
233 | + float: left; | |
234 | + position: relative; | |
235 | + left: -10px; | |
236 | + padding:0; | |
237 | + margin:0; | |
238 | + } | |
239 | +} | |
240 | + | |
241 | +input[type=text] { | |
242 | + &.large_text { | |
243 | + padding:6px; | |
244 | + font-size:16px; | |
198 | 245 | } |
199 | 246 | } |
200 | 247 | |
... | ... | @@ -270,40 +317,6 @@ p.time { |
270 | 317 | } |
271 | 318 | |
272 | 319 | |
273 | -/** | |
274 | - * Dashboard page | |
275 | - * | |
276 | - */ | |
277 | -.dashboard_category { | |
278 | - margin-bottom:30px; | |
279 | - h3 a { | |
280 | - color:#474D57; | |
281 | - &:hover { | |
282 | - text-decoration:underline; | |
283 | - } | |
284 | - } | |
285 | - | |
286 | - .dashboard_block { | |
287 | - .dash_project_item { | |
288 | - margin-bottom:10px; | |
289 | - border:none; | |
290 | - padding:0px 5px; | |
291 | - .project_link { | |
292 | - color:#888; | |
293 | - &:hover { | |
294 | - color:#111; | |
295 | - .ico.project { | |
296 | - background-position:-209px -21px; | |
297 | - } | |
298 | - } | |
299 | - } | |
300 | - h4 { | |
301 | - color:#666; | |
302 | - } | |
303 | - } | |
304 | - } | |
305 | -} | |
306 | - | |
307 | 320 | .styled_image { |
308 | 321 | border:2px solid #ddd; |
309 | 322 | } |
... | ... | @@ -393,39 +406,6 @@ p.time { |
393 | 406 | } |
394 | 407 | } |
395 | 408 | |
396 | -.btn { | |
397 | - &.very_small { | |
398 | - font-size:11px; | |
399 | - padding:2px 6px; | |
400 | - margin:2px; | |
401 | - } | |
402 | - | |
403 | - &.grouped { | |
404 | - margin-right:7px; | |
405 | - float:left; | |
406 | - } | |
407 | - | |
408 | - &.padded { | |
409 | - margin-right:3px; | |
410 | - padding:4px 10px 4px; | |
411 | - } | |
412 | -} | |
413 | - | |
414 | - | |
415 | -.prettyprint { | |
416 | - background-color: #fefbf3; | |
417 | - padding: 9px; | |
418 | - border: 1px solid rgba(0,0,0,.2); | |
419 | - -webkit-box-shadow: 0 1px 2px rgba(0,0,0,.1); | |
420 | - -moz-box-shadow: 0 1px 2px rgba(0,0,0,.1); | |
421 | - box-shadow: 0 1px 2px rgba(0,0,0,.1); | |
422 | -} | |
423 | - | |
424 | -.hint { | |
425 | - font-style: italic; | |
426 | - color: #999; | |
427 | -} | |
428 | - | |
429 | 409 | .upvotes { |
430 | 410 | font-size: 14px; |
431 | 411 | font-weight: bold; |
... | ... | @@ -549,14 +529,6 @@ li.note { |
549 | 529 | } |
550 | 530 | |
551 | 531 | |
552 | -/** | |
553 | - * Milestones list | |
554 | - * | |
555 | - */ | |
556 | - | |
557 | -.milestone { | |
558 | - @extend .wll; | |
559 | -} | |
560 | 532 | |
561 | 533 | /** |
562 | 534 | * Admin area |
... | ... | @@ -603,11 +575,10 @@ li.note { |
603 | 575 | * |
604 | 576 | */ |
605 | 577 | .event_lp { |
606 | - @extend .alert-info; | |
578 | + @extend .ui-box; | |
579 | + color:#777; | |
607 | 580 | margin-bottom:20px; |
608 | 581 | padding:8px; |
609 | - border-style: solid; | |
610 | - border-width: 1px; | |
611 | 582 | @include border-radius(4px); |
612 | 583 | min-height:22px; |
613 | 584 | |
... | ... | @@ -621,88 +592,19 @@ li.note { |
621 | 592 | cursor:pointer; |
622 | 593 | } |
623 | 594 | |
624 | -/** | |
625 | - * Issues, MRs legend | |
626 | - * | |
627 | - */ | |
628 | - | |
629 | -.list_legend { | |
630 | - float:left; | |
631 | - margin-right:20px; | |
632 | - .icon { | |
633 | - width:12px; | |
634 | - height:12px; | |
635 | - float:left; | |
636 | - margin-right:5px; | |
637 | - margin-top: 2px; | |
638 | - @include border-radius(4px); | |
639 | - &.today{ | |
640 | - background: #ADA; | |
641 | - border:1px solid #8B8; | |
642 | - } | |
643 | - &.closed { | |
644 | - background: #DDD; | |
645 | - border:1px solid #BBB; | |
646 | - } | |
647 | - &.yours { | |
648 | - background: #AAD; | |
649 | - border:1px solid #88B; | |
650 | - } | |
651 | - &.merged { | |
652 | - background: #DAD; | |
653 | - border:1px solid #B8B; | |
654 | - } | |
655 | - } | |
656 | - .text { | |
657 | - padding-bottom: 10px; | |
658 | - float:left; | |
659 | - } | |
660 | -} | |
661 | - | |
662 | 595 | .merge_request, |
663 | 596 | .issue { |
664 | - .list_legend { | |
665 | - margin-right: 5px; | |
666 | - margin-top: 14px; | |
667 | - .icon { | |
668 | - width:8px; | |
669 | - height:8px; | |
670 | - float:left; | |
671 | - margin-right:5px; | |
672 | - @include border-radius(4px); | |
673 | - border:1px solid #ddd; | |
674 | - } | |
675 | - } | |
676 | - | |
677 | 597 | &.today{ |
678 | 598 | background: #EFE; |
679 | 599 | border-color:#CEC; |
680 | - .icon { | |
681 | - background: #ADA; | |
682 | - border:1px solid #8B8; | |
683 | - } | |
684 | 600 | } |
685 | 601 | &.closed { |
686 | 602 | background: #F5f5f5; |
687 | 603 | border-color:#E5E5E5; |
688 | - .icon { | |
689 | - background: #DDD; | |
690 | - border:1px solid #BBB; | |
691 | - } | |
692 | - } | |
693 | - &.yours { | |
694 | - .icon { | |
695 | - background: #AAD; | |
696 | - border:1px solid #88B; | |
697 | - } | |
698 | 604 | } |
699 | 605 | &.merged { |
700 | 606 | background: #F5f5f5; |
701 | 607 | border-color:#E5E5E5; |
702 | - .icon { | |
703 | - background: #DAD; | |
704 | - border:1px solid #B8B; | |
705 | - } | |
706 | 608 | } |
707 | 609 | } |
708 | 610 | |
... | ... | @@ -735,3 +637,11 @@ li.note { |
735 | 637 | font-size: 12px; |
736 | 638 | } |
737 | 639 | } |
640 | + | |
641 | +.error_message { | |
642 | + @extend .cred; | |
643 | + border-bottom: 1px solid #D21; | |
644 | + padding-bottom:20px; | |
645 | + text-align:center; | |
646 | + margin-bottom:10px; | |
647 | +} | ... | ... |
app/assets/stylesheets/gitlab_bootstrap.scss
... | ... | @@ -1,818 +0,0 @@ |
1 | -body { | |
2 | - margin-bottom:20px; | |
3 | -} | |
4 | -a { | |
5 | - outline: none; | |
6 | - color: $link_color; | |
7 | - &:hover { | |
8 | - text-decoration:none; | |
9 | - color: $blue_link; | |
10 | - } | |
11 | - | |
12 | - &.btn { | |
13 | - color: $style_color; | |
14 | - } | |
15 | - | |
16 | - &.dark { | |
17 | - color: $style_color; | |
18 | - } | |
19 | - | |
20 | - &.lined { | |
21 | - text-decoration:underline; | |
22 | - &:hover { text-decoration:underline; } | |
23 | - } | |
24 | - | |
25 | - &.gray { | |
26 | - color:gray; | |
27 | - } | |
28 | - | |
29 | - &.supp_diff_link { | |
30 | - text-align:center; | |
31 | - padding:20px 0; | |
32 | - background:#f1f1f1; | |
33 | - width:100%; | |
34 | - float:left; | |
35 | - } | |
36 | - | |
37 | - &.neib { | |
38 | - margin-right:15px; | |
39 | - } | |
40 | -} | |
41 | - | |
42 | -.neib { | |
43 | - margin-right:10px; | |
44 | -} | |
45 | - | |
46 | -.alert-message { | |
47 | - @extend .alert; | |
48 | - | |
49 | - &.success { | |
50 | - @extend .alert-success; | |
51 | - } | |
52 | - | |
53 | - &.error { | |
54 | - @extend .alert-error; | |
55 | - } | |
56 | -} | |
57 | - | |
58 | -.alert { | |
59 | - &.alert-well { | |
60 | - background:#ddd; | |
61 | - border:1px solid #ccc; | |
62 | - background-image: -webkit-gradient(linear, 0 0, 0 30, color-stop(0.066, #ddd), to(#dfdfdf)); | |
63 | - background-image: -webkit-linear-gradient(#ddd 6.6%, #dfdfdf); | |
64 | - background-image: -moz-linear-gradient(#ddd 6.6%, #dfdfdf); | |
65 | - background-image: -o-linear-gradient(#ddd 6.6%, #dfdfdf); | |
66 | - color:#111; | |
67 | - } | |
68 | -} | |
69 | - | |
70 | -h3, h4, h5, h6 { | |
71 | - line-height: 36px; | |
72 | -} | |
73 | - | |
74 | -h5 { | |
75 | - font-size:14px; | |
76 | -} | |
77 | - | |
78 | - | |
79 | -table { | |
80 | - width:100%; | |
81 | - th { | |
82 | - padding-top: 9px; | |
83 | - font-weight: bold; | |
84 | - vertical-align: middle; | |
85 | - } | |
86 | - th, td { | |
87 | - padding: 10px 10px 9px; | |
88 | - line-height: 18px; | |
89 | - text-align: left; | |
90 | - } | |
91 | - | |
92 | - &.bordered-table { | |
93 | - border: 1px solid #DDD; | |
94 | - border-collapse: separate; | |
95 | - -webkit-border-radius: 4px; | |
96 | - -moz-border-radius: 4px; | |
97 | - border-radius: 4px; | |
98 | - } | |
99 | - | |
100 | - &.zebra-striped { | |
101 | - @extend .table-striped; | |
102 | - } | |
103 | -} | |
104 | - | |
105 | -.btn { | |
106 | - background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#f1f1f1), color-stop(25%, #f1f1f1), to(#e6e6e6)); | |
107 | - background-image: -webkit-linear-gradient(#f1f1f1, #f1f1f1 25%, #e6e6e6); | |
108 | - background-image: -moz-linear-gradient(top, #f1f1f1, #f1f1f1 25%, #e6e6e6); | |
109 | - background-image: -ms-linear-gradient(#f1f1f1, #f1f1f1 25%, #e6e6e6); | |
110 | - background-image: -o-linear-gradient(#f1f1f1, #f1f1f1 25%, #e6e6e6); | |
111 | - background-image: linear-gradient(#f1f1f1, #f1f1f1 25%, #e6e6e6); | |
112 | - | |
113 | - &:hover { | |
114 | - } | |
115 | - | |
116 | - &.btn-primary { | |
117 | - background:$link_color; | |
118 | - border-color: #2A79A3; | |
119 | - &:hover { | |
120 | - background:$blue_link; | |
121 | - } | |
122 | - } | |
123 | - &.primary { | |
124 | - @extend .btn-primary; | |
125 | - } | |
126 | - | |
127 | - &.success { | |
128 | - color: #fff; | |
129 | - text-shadow: 0 0 1px #111; | |
130 | - background: #5bb75b;; | |
131 | - font-weight: bold; | |
132 | - | |
133 | - &:hover { | |
134 | - background-color: #51a351; | |
135 | - color: #fff; | |
136 | - } | |
137 | - } | |
138 | - | |
139 | - &.danger, | |
140 | - &.btn-danger { | |
141 | - color:#fff; | |
142 | - background: #DA4E49; | |
143 | - border-color: #BD362F; | |
144 | - | |
145 | - &:hover { | |
146 | - color:#fff; | |
147 | - background: #EE4E49; | |
148 | - } | |
149 | - } | |
150 | - | |
151 | - &.danger { | |
152 | - @extend .btn-danger; | |
153 | - } | |
154 | - | |
155 | - &.small { | |
156 | - @extend .btn-small; | |
157 | - } | |
158 | - | |
159 | - &.active { | |
160 | - border-color:#aaa; | |
161 | - background-color:#ccc; | |
162 | - } | |
163 | -} | |
164 | - | |
165 | -a:focus { | |
166 | - outline: none; | |
167 | -} | |
168 | - | |
169 | -.nav-pills a:hover { | |
170 | - background-color:#888; | |
171 | -} | |
172 | - | |
173 | -.nav-pills .active a { | |
174 | - background-color: $style_color; | |
175 | -} | |
176 | - | |
177 | -.label { | |
178 | - background-color: #474D57; | |
179 | - &.label-important { | |
180 | - background-color: #B94A48; | |
181 | - } | |
182 | - | |
183 | - &.label-issue { | |
184 | - background-color: #eee; | |
185 | - border: 1px solid #ccc; | |
186 | - padding:4px 6px; | |
187 | - color:#444; | |
188 | - text-shadow:0 0 1px #fff; | |
189 | - | |
190 | - &.grouped { | |
191 | - float: left; | |
192 | - margin-right: 6px; | |
193 | - padding: 6px; | |
194 | - } | |
195 | - } | |
196 | -} | |
197 | - | |
198 | -.nav-tabs > li > a, .nav-pills > li > a { | |
199 | - color:$style_color; | |
200 | -} | |
201 | - | |
202 | -.nav-tabs > .active > a { | |
203 | - font-weight:bold; | |
204 | -} | |
205 | - | |
206 | -/** COLORS **/ | |
207 | -.cgray { color:gray; } | |
208 | -.cred { color:#D12F19; } | |
209 | -.cgreen { color:#44aa22; } | |
210 | -.cblack { color:#111; } | |
211 | -.cdark { color:#444 } | |
212 | -.cwhite { color:#fff !important } | |
213 | -.bgred { background: #F2DEDE !important} | |
214 | - | |
215 | -/** COMMON STYLES **/ | |
216 | -.left { | |
217 | - float:left; | |
218 | -} | |
219 | -.right { | |
220 | - float:right !important; | |
221 | -} | |
222 | -.width-50p{ | |
223 | - width:50%; | |
224 | -} | |
225 | -.width-49p{ | |
226 | - width:49%; | |
227 | -} | |
228 | -.width-30p{ | |
229 | - width:30%; | |
230 | -} | |
231 | -.width-65p{ | |
232 | - width:65%; | |
233 | -} | |
234 | -.width-100p{ | |
235 | - width:100%; | |
236 | -} | |
237 | -.append-bottom-10 { | |
238 | - margin-bottom:10px; | |
239 | -} | |
240 | -.append-bottom-20 { | |
241 | - margin-bottom:20px; | |
242 | -} | |
243 | -.prepend-top-10 { | |
244 | - margin-top:10px; | |
245 | -} | |
246 | - | |
247 | -.prepend-top-20 { | |
248 | - margin-top:20px; | |
249 | -} | |
250 | - | |
251 | -.padded { | |
252 | - padding:20px; | |
253 | -} | |
254 | - | |
255 | -.ipadded { | |
256 | - padding:20px !important; | |
257 | -} | |
258 | -.lborder { | |
259 | - border-left:1px solid #eee; | |
260 | -} | |
261 | - | |
262 | -.borders { | |
263 | - border: 1px solid #ccc; | |
264 | - @include shade; | |
265 | -} | |
266 | -.no-borders { | |
267 | - border:none; | |
268 | -} | |
269 | -table.no-borders { | |
270 | - border:none; | |
271 | - tr, td { border:none } | |
272 | -} | |
273 | -.no-padding { | |
274 | - padding:0 !important; | |
275 | -} | |
276 | -.underlined { | |
277 | - border-bottom: 1px solid $border_color; | |
278 | -} | |
279 | -.vlink { | |
280 | - color: $link_color !important; | |
281 | -} | |
282 | - | |
283 | -.pretty_label { | |
284 | - @include round-borders-all(4px); | |
285 | - padding:2px 4px; | |
286 | - background-image: -webkit-gradient(linear, 0 0, 0 26, color-stop(0.076, #fefefe), to(#F6F7F8)); | |
287 | - background-image: -webkit-linear-gradient(#fefefe 7.6%, #F6F7F8); | |
288 | - background-image: -moz-linear-gradient(#fefefe 7.6%, #F6F7F8); | |
289 | - background-image: -o-linear-gradient(#fefefe 7.6%, #F6F7F8); | |
290 | - color: #777; | |
291 | - border: 1px solid #DEDFE1; | |
292 | - | |
293 | - &.branch { | |
294 | - border:none; | |
295 | - font-size:13px; | |
296 | - background: #474D57; | |
297 | - color:#fff; | |
298 | - font-weight:bold; | |
299 | - font-family: monospace; | |
300 | - } | |
301 | -} | |
302 | - | |
303 | -.event_label { | |
304 | - @extend .label; | |
305 | - background-color: #999; | |
306 | - | |
307 | - &.pushed { | |
308 | - background-color: #3A87AD; | |
309 | - } | |
310 | - | |
311 | - &.opened { | |
312 | - background-color: #468847; | |
313 | - } | |
314 | - | |
315 | - &.closed { | |
316 | - background-color: #B94A48; | |
317 | - } | |
318 | - | |
319 | - &.merged { | |
320 | - background-color: #2A2; | |
321 | - } | |
322 | -} | |
323 | - | |
324 | -img.avatar { | |
325 | - float:left; | |
326 | - margin-right:15px; | |
327 | - width:40px; | |
328 | - border:2px solid #ddd; | |
329 | - | |
330 | - &.s16 { | |
331 | - width:16px; | |
332 | - } | |
333 | - &.s24 { | |
334 | - width:24px; | |
335 | - } | |
336 | - &.s32 { | |
337 | - width:32px; | |
338 | - } | |
339 | -} | |
340 | - | |
341 | -img.lil_av { | |
342 | - padding-left: 4px; | |
343 | - padding-right:3px; | |
344 | -} | |
345 | - | |
346 | -form { | |
347 | - @extend .form-horizontal; | |
348 | - | |
349 | - .actions { | |
350 | - @extend .form-actions; | |
351 | - } | |
352 | - | |
353 | - .clearfix { | |
354 | - @extend .control-group; | |
355 | - } | |
356 | - | |
357 | - .input { | |
358 | - @extend .controls; | |
359 | - } | |
360 | - | |
361 | - label { | |
362 | - @extend .control-label; | |
363 | - } | |
364 | - .xlarge { | |
365 | - @extend .input-xlarge; | |
366 | - } | |
367 | - .xxlarge { | |
368 | - @extend .input-xxlarge; | |
369 | - } | |
370 | -} | |
371 | - | |
372 | -/** | |
373 | - * List li block element #1 | |
374 | - * | |
375 | - */ | |
376 | -.wll { | |
377 | - background-color: #FFF; | |
378 | - padding: 10px 5px; | |
379 | - min-height: 20px; | |
380 | - border-bottom: 1px solid #eee; | |
381 | - border-bottom: 1px solid rgba(0, 0, 0, 0.05); | |
382 | - &.smoke { | |
383 | - background-color:#f5f5f5; | |
384 | - } | |
385 | - &:hover { | |
386 | - background:$hover; | |
387 | - } | |
388 | - &:last-child { border:none } | |
389 | - p { padding-top:5px; margin:0; color:$style_color;} | |
390 | - .author { color: #999; } | |
391 | - p { | |
392 | - color:#222; | |
393 | - margin-bottom: 0; | |
394 | - img { | |
395 | - position:relative; | |
396 | - top:3px; | |
397 | - } | |
398 | - } | |
399 | -} | |
400 | - | |
401 | - | |
402 | -/** | |
403 | - * Block element #2 | |
404 | - * | |
405 | - */ | |
406 | -.entry { | |
407 | - position: relative; | |
408 | - padding: 7px 15px; | |
409 | - margin-bottom: 18px; | |
410 | - color: #404040; | |
411 | - filter:none; | |
412 | - | |
413 | - text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); | |
414 | - text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); | |
415 | - | |
416 | - -webkit-border-radius: 4px; | |
417 | - -moz-border-radius: 4px; | |
418 | - border-radius: 4px; | |
419 | - | |
420 | - -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25); | |
421 | - -moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25); | |
422 | - box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25); | |
423 | - | |
424 | - background:#F1F1F1; | |
425 | - border: 1px solid #ccc; | |
426 | - | |
427 | - | |
428 | - p { | |
429 | - color:$style_color; | |
430 | - margin-bottom: 0; | |
431 | - img { | |
432 | - position:relative; | |
433 | - top:3px; | |
434 | - } | |
435 | - } | |
436 | -} | |
437 | - | |
438 | - | |
439 | -/** | |
440 | - * Big UI Block for show page content | |
441 | - * | |
442 | - */ | |
443 | -.ui-box { | |
444 | - background:#F9F9F9; | |
445 | - margin-bottom: 25px; | |
446 | - @include round-borders-all(4px); | |
447 | - border-color: #CCC; | |
448 | - @include solid_shade; | |
449 | - | |
450 | - ul { | |
451 | - margin:0; | |
452 | - } | |
453 | - | |
454 | - h5, .title { | |
455 | - padding: 0 10px; | |
456 | - @include round-borders-top(4px); | |
457 | - border-bottom: 1px solid #bbb; | |
458 | - background:#eee; | |
459 | - background-image: -webkit-gradient(linear, 0 0, 0 30, color-stop(0.066, #eee), to(#dfdfdf)); | |
460 | - background-image: -webkit-linear-gradient(#eee 6.6%, #dfdfdf); | |
461 | - background-image: -moz-linear-gradient(#eee 6.6%, #dfdfdf); | |
462 | - background-image: -o-linear-gradient(#eee 6.6%, #dfdfdf); | |
463 | - | |
464 | - &.small { | |
465 | - line-height: 28px; | |
466 | - font-size: 14px; | |
467 | - line-height:28px; | |
468 | - text-shadow: 0 1px 1px white; | |
469 | - } | |
470 | - | |
471 | - form { | |
472 | - padding:9px 0; | |
473 | - margin:0px; | |
474 | - } | |
475 | - | |
476 | - .nav-pills { | |
477 | - li { | |
478 | - padding:3px 0; | |
479 | - &.active a { background-color:$style_color; } | |
480 | - a { | |
481 | - border-radius:7px; | |
482 | - } | |
483 | - } | |
484 | - } | |
485 | - } | |
486 | - | |
487 | - .bottom { | |
488 | - background-image: -webkit-gradient(linear, 0 0, 0 30, color-stop(0.066, #eee), to(#dfdfdf)); | |
489 | - background-image: -webkit-linear-gradient(#eee 6.6%, #dfdfdf); | |
490 | - background-image: -moz-linear-gradient(#eee 6.6%, #dfdfdf); | |
491 | - background-image: -o-linear-gradient(#eee 6.6%, #dfdfdf); | |
492 | - @include round-borders-bottom(4px); | |
493 | - border-bottom:none; | |
494 | - border-top: 1px solid #bbb; | |
495 | - } | |
496 | - | |
497 | - &.padded { | |
498 | - h5, .title { | |
499 | - margin: -20px; | |
500 | - margin-bottom: 0; | |
501 | - padding: 5px 20px; | |
502 | - } | |
503 | - .middle_title { | |
504 | - background:#f5f5f5; | |
505 | - margin:20px -20px; | |
506 | - padding: 0 20px; | |
507 | - border-top:1px solid #eee; | |
508 | - border-bottom:1px solid #eee; | |
509 | - font-size:14px; | |
510 | - color:#777; | |
511 | - } | |
512 | - } | |
513 | - .row_title { | |
514 | - font-weight:bold; | |
515 | - color:#444; | |
516 | - &:hover { | |
517 | - color:#444; | |
518 | - text-decoration:underline; | |
519 | - } | |
520 | - } | |
521 | - | |
522 | - li, .wll { | |
523 | - padding:10px; | |
524 | - &:first-child { | |
525 | - @include round-borders-top(4px); | |
526 | - border-top:none; | |
527 | - } | |
528 | - | |
529 | - &:last-child { | |
530 | - @include round-borders-bottom(4px); | |
531 | - border:none; | |
532 | - } | |
533 | - } | |
534 | - | |
535 | -} | |
536 | - | |
537 | -table.admin-table { | |
538 | - @extend .table-bordered; | |
539 | - @extend .zebra-striped; | |
540 | - @include solid_shade; | |
541 | - th { | |
542 | - border-color: #CCC; | |
543 | - border-bottom: 1px solid #bbb; | |
544 | - background:#eee; | |
545 | - background-image: -webkit-gradient(linear, 0 0, 0 30, color-stop(0.066, #eee), to(#dfdfdf)); | |
546 | - background-image: -webkit-linear-gradient(#eee 6.6%, #dfdfdf); | |
547 | - background-image: -moz-linear-gradient(#eee 6.6%, #dfdfdf); | |
548 | - background-image: -o-linear-gradient(#eee 6.6%, #dfdfdf); | |
549 | - } | |
550 | -} | |
551 | - | |
552 | -.field_with_errors { | |
553 | - display:inline; | |
554 | -} | |
555 | - | |
556 | -ul.breadcrumb { | |
557 | - background:white; | |
558 | - border:none; | |
559 | - li { | |
560 | - display: inline; | |
561 | - text-shadow: 0 1px 0 white | |
562 | - } | |
563 | - | |
564 | - a { | |
565 | - color:#474D57; | |
566 | - font-weight:bold; | |
567 | - font-size:14px; | |
568 | - } | |
569 | - | |
570 | - .arrow { | |
571 | - background: url("images.png") no-repeat -85px -77px; | |
572 | - width: 19px; | |
573 | - height: 16px; | |
574 | - float: left; | |
575 | - position: relative; | |
576 | - left: -10px; | |
577 | - padding:0; | |
578 | - margin:0; | |
579 | - } | |
580 | -} | |
581 | - | |
582 | -.nothing_here_message { | |
583 | - text-align:center; | |
584 | - padding:20px; | |
585 | - color:#777; | |
586 | -} | |
587 | - | |
588 | -/** | |
589 | - * UI box element | |
590 | - * contains top, middle, bottom blocks | |
591 | - * | |
592 | - */ | |
593 | -.main_box { | |
594 | - @extend .borders; | |
595 | - @extend .prepend-top-20; | |
596 | - @extend .append-bottom-20; | |
597 | - border-width:1px; | |
598 | - @include solid_shade; | |
599 | - | |
600 | - | |
601 | - img { max-width: 100%; } | |
602 | - | |
603 | - pre { | |
604 | - code { | |
605 | - background: none !important; | |
606 | - } | |
607 | - } | |
608 | - | |
609 | - .top_box_content, | |
610 | - .middle_box_content, | |
611 | - .bottom_box_content { | |
612 | - padding:15px; | |
613 | - | |
614 | - pre { | |
615 | - background: none !important; | |
616 | - margin:0; | |
617 | - border:none; | |
618 | - padding:0; | |
619 | - } | |
620 | - } | |
621 | - | |
622 | - .middle_box_content { | |
623 | - border-radius:0; | |
624 | - border:none; | |
625 | - font-size:12px; | |
626 | - background-color:#f5f5f5; | |
627 | - border:none; | |
628 | - border-top:1px solid #eee; | |
629 | - } | |
630 | - | |
631 | - .bottom_box_content { | |
632 | - border-top:1px solid #eee; | |
633 | - } | |
634 | -} | |
635 | - | |
636 | -input[type=text] { | |
637 | - &.large_text { | |
638 | - padding:6px; | |
639 | - font-size:16px; | |
640 | - } | |
641 | -} | |
642 | - | |
643 | -p { | |
644 | - &.slead { | |
645 | - color:#456; | |
646 | - font-size:16px; | |
647 | - margin-bottom: 12px; | |
648 | - font-weight: 200; | |
649 | - line-height: 24px; | |
650 | - } | |
651 | -} | |
652 | - | |
653 | -h3.page_title { | |
654 | - color:#456; | |
655 | - font-size:20px; | |
656 | - font-weight: normal; | |
657 | - line-height: 28px; | |
658 | -} | |
659 | - | |
660 | -/** | |
661 | - * File content holder | |
662 | - * | |
663 | - */ | |
664 | -.file_holder { | |
665 | - border:1px solid #CCC; | |
666 | - margin-bottom:1em; | |
667 | - @include solid_shade; | |
668 | - | |
669 | - .file_title { | |
670 | - border-bottom: 1px solid #bbb; | |
671 | - background:#eee; | |
672 | - background-image: -webkit-gradient(linear, 0 0, 0 30, color-stop(0.066, #eee), to(#dfdfdf)); | |
673 | - background-image: -webkit-linear-gradient(#eee 6.6%, #dfdfdf); | |
674 | - background-image: -moz-linear-gradient(#eee 6.6%, #dfdfdf); | |
675 | - background-image: -o-linear-gradient(#eee 6.6%, #dfdfdf); | |
676 | - margin: 0; | |
677 | - font-weight: normal; | |
678 | - font-weight: bold; | |
679 | - text-align: left; | |
680 | - color: #666; | |
681 | - padding: 9px 10px; | |
682 | - height:18px; | |
683 | - | |
684 | - .options { | |
685 | - float:right; | |
686 | - margin-top: -5px; | |
687 | - } | |
688 | - | |
689 | - .file_name { | |
690 | - color:$style_color; | |
691 | - font-size:14px; | |
692 | - text-shadow: 0 1px 1px #fff; | |
693 | - small { | |
694 | - color:#999; | |
695 | - font-size:13px; | |
696 | - } | |
697 | - } | |
698 | - } | |
699 | - .file_content { | |
700 | - background:#fff; | |
701 | - font-size: 11px; | |
702 | - | |
703 | - &.wiki { | |
704 | - font-size: 13px; | |
705 | - code { | |
706 | - padding:0 4px; | |
707 | - } | |
708 | - padding:20px; | |
709 | - h1, h2 { | |
710 | - line-height: 46px; | |
711 | - } | |
712 | - h3, h4 { | |
713 | - line-height: 40px; | |
714 | - } | |
715 | - } | |
716 | - | |
717 | - &.image_file { | |
718 | - background:#eee; | |
719 | - text-align:center; | |
720 | - img { | |
721 | - padding:100px; | |
722 | - max-width:300px; | |
723 | - } | |
724 | - } | |
725 | - | |
726 | - &.blob_file { | |
727 | - | |
728 | - } | |
729 | - | |
730 | - /** | |
731 | - * Blame file | |
732 | - */ | |
733 | - &.blame { | |
734 | - tr { | |
735 | - border-bottom: 1px solid #eee; | |
736 | - } | |
737 | - td { | |
738 | - padding:5px; | |
739 | - } | |
740 | - .author, | |
741 | - .blame_commit { | |
742 | - background:#f5f5f5; | |
743 | - vertical-align:top; | |
744 | - } | |
745 | - .lines { | |
746 | - pre { | |
747 | - padding:0; | |
748 | - margin:0; | |
749 | - background:none; | |
750 | - border:none; | |
751 | - } | |
752 | - } | |
753 | - } | |
754 | - | |
755 | - &.logs { | |
756 | - background:#eee; | |
757 | - max-height: 700px; | |
758 | - overflow-y: auto; | |
759 | - | |
760 | - ol { | |
761 | - margin-left:40px; | |
762 | - padding: 10px 0; | |
763 | - border-left: 1px solid #CCC; | |
764 | - margin-bottom:0; | |
765 | - background: white; | |
766 | - li { | |
767 | - color:#888; | |
768 | - p { | |
769 | - margin:0; | |
770 | - color:#333; | |
771 | - line-height:24px; | |
772 | - padding-left: 10px; | |
773 | - } | |
774 | - | |
775 | - &:hover { | |
776 | - background:$hover; | |
777 | - } | |
778 | - } | |
779 | - } | |
780 | - } | |
781 | - | |
782 | - /** | |
783 | - * Code file | |
784 | - */ | |
785 | - &.code { | |
786 | - padding:0; | |
787 | - td.code { | |
788 | - width: 100%; | |
789 | - .highlight { | |
790 | - margin-left: 55px; | |
791 | - overflow:auto; | |
792 | - overflow-y:hidden; | |
793 | - } | |
794 | - } | |
795 | - .highlight pre { | |
796 | - white-space: pre; | |
797 | - word-wrap:normal; | |
798 | - } | |
799 | - | |
800 | - table.highlighttable { | |
801 | - border: none; | |
802 | - } | |
803 | - body.project-page table.highlighttable td { border: none } | |
804 | - table.highlighttable tr:hover { background:none;} | |
805 | - | |
806 | - table.highlighttable pre{ | |
807 | - line-height:16px !important; | |
808 | - font-size:12px !important; | |
809 | - } | |
810 | - | |
811 | - table.highlighttable .linenodiv pre { | |
812 | - text-align: right; | |
813 | - padding-right: 4px; | |
814 | - color:#666; | |
815 | - } | |
816 | - } | |
817 | - } | |
818 | -} |
... | ... | @@ -0,0 +1,145 @@ |
1 | +/** | |
2 | + * =================================== | |
3 | + * Contain 3 main UI block elements: | |
4 | + * .main_box - for show pages | |
5 | + * .ui-box - for simple block & widgets | |
6 | + * =================================== | |
7 | + */ | |
8 | + | |
9 | +/** | |
10 | + * UI box element | |
11 | + * contains top, middle, bottom blocks | |
12 | + * | |
13 | + */ | |
14 | +.main_box { | |
15 | + @extend .borders; | |
16 | + @extend .prepend-top-20; | |
17 | + @extend .append-bottom-20; | |
18 | + border-width:1px; | |
19 | + @include solid_shade; | |
20 | + | |
21 | + | |
22 | + img { max-width: 100%; } | |
23 | + | |
24 | + pre { | |
25 | + code { | |
26 | + background: none !important; | |
27 | + } | |
28 | + } | |
29 | + | |
30 | + .top_box_content, | |
31 | + .middle_box_content, | |
32 | + .bottom_box_content { | |
33 | + padding:15px; | |
34 | + | |
35 | + pre { | |
36 | + background: none !important; | |
37 | + margin:0; | |
38 | + border:none; | |
39 | + padding:0; | |
40 | + } | |
41 | + } | |
42 | + | |
43 | + .middle_box_content { | |
44 | + border-radius:0; | |
45 | + border:none; | |
46 | + font-size:12px; | |
47 | + background-color:#f5f5f5; | |
48 | + border:none; | |
49 | + border-top:1px solid #eee; | |
50 | + } | |
51 | + | |
52 | + .bottom_box_content { | |
53 | + border-top:1px solid #eee; | |
54 | + } | |
55 | +} | |
56 | + | |
57 | +/** | |
58 | + * Big UI Block for show page content | |
59 | + * | |
60 | + */ | |
61 | +.ui-box { | |
62 | + background:#F9F9F9; | |
63 | + margin-bottom: 25px; | |
64 | + @include round-borders-all(4px); | |
65 | + border-color: #CCC; | |
66 | + @include solid_shade; | |
67 | + | |
68 | + ul { | |
69 | + margin:0; | |
70 | + } | |
71 | + | |
72 | + h5, .title { | |
73 | + padding: 0 10px; | |
74 | + @include round-borders-top(4px); | |
75 | + @include bg-gray-gradient; | |
76 | + border-bottom: 1px solid #bbb; | |
77 | + | |
78 | + &.small { | |
79 | + line-height: 28px; | |
80 | + font-size: 14px; | |
81 | + line-height:28px; | |
82 | + text-shadow: 0 1px 1px white; | |
83 | + } | |
84 | + | |
85 | + form { | |
86 | + padding:9px 0; | |
87 | + margin:0px; | |
88 | + } | |
89 | + | |
90 | + .nav-pills { | |
91 | + li { | |
92 | + padding:3px 0; | |
93 | + &.active a { background-color:$style_color; } | |
94 | + a { | |
95 | + border-radius:7px; | |
96 | + } | |
97 | + } | |
98 | + } | |
99 | + } | |
100 | + | |
101 | + .bottom { | |
102 | + @include bg-gray-gradient; | |
103 | + @include round-borders-bottom(4px); | |
104 | + border-bottom:none; | |
105 | + border-top: 1px solid #bbb; | |
106 | + } | |
107 | + | |
108 | + &.padded { | |
109 | + h5, .title { | |
110 | + margin: -20px; | |
111 | + margin-bottom: 0; | |
112 | + padding: 5px 20px; | |
113 | + } | |
114 | + .middle_title { | |
115 | + background:#f5f5f5; | |
116 | + margin:20px -20px; | |
117 | + padding: 0 20px; | |
118 | + border-top:1px solid #eee; | |
119 | + border-bottom:1px solid #eee; | |
120 | + font-size:14px; | |
121 | + color:#777; | |
122 | + } | |
123 | + } | |
124 | + .row_title { | |
125 | + font-weight:bold; | |
126 | + color:#444; | |
127 | + &:hover { | |
128 | + color:#444; | |
129 | + text-decoration:underline; | |
130 | + } | |
131 | + } | |
132 | + | |
133 | + li, .wll { | |
134 | + padding:10px; | |
135 | + &:first-child { | |
136 | + @include round-borders-top(4px); | |
137 | + border-top:none; | |
138 | + } | |
139 | + | |
140 | + &:last-child { | |
141 | + @include round-borders-bottom(4px); | |
142 | + border:none; | |
143 | + } | |
144 | + } | |
145 | +} | ... | ... |
... | ... | @@ -0,0 +1,105 @@ |
1 | +.btn { | |
2 | + background-image: -webkit-gradient(linear, 0 0, 0 26, color-stop(0.076, #f7f7f7), to(#d5d5d5)); | |
3 | + background-image: -webkit-linear-gradient(#f7f7f7 7.6%, #d5d5d5); | |
4 | + background-image: -moz-linear-gradient(#f7f7f7 7.6%, #d5d5d5); | |
5 | + background-image: -o-linear-gradient(#f7f7f7 7.6%, #d5d5d5); | |
6 | + border-color:#aaa; | |
7 | + &:hover { | |
8 | + @include bg-gray-gradient; | |
9 | + border-color:#bbb; | |
10 | + color:#333; | |
11 | + } | |
12 | + | |
13 | + &.primary { | |
14 | + background:#2a79A3; | |
15 | + border-color: #2A79A3; | |
16 | + background-image: -webkit-linear-gradient(#47A7b7 7.6%, #2585b5); | |
17 | + background-image: -moz-linear-gradient(#47A7b7 7.6%, #2585b5); | |
18 | + background-image: -o-linear-gradient(#47A7b7 7.6%, #2585b5); | |
19 | + color:#fff; | |
20 | + text-shadow: 0 1px 1px #268; | |
21 | + &:hover { | |
22 | + background:$blue_link; | |
23 | + color:#fff; | |
24 | + } | |
25 | + | |
26 | + &.disabled { | |
27 | + color:#fff; | |
28 | + background:#29B; | |
29 | + } | |
30 | + } | |
31 | + | |
32 | + &.success { | |
33 | + border-color: #4A4; | |
34 | + background-image: -webkit-linear-gradient(#82D482 7.6%, #22B442); | |
35 | + background-image: -moz-linear-gradient(#82D482 7.6%, #22B442); | |
36 | + background-image: -o-linear-gradient(#82D482 7.6%, #22B442); | |
37 | + color: #fff; | |
38 | + text-shadow: 0 1px 1px #141; | |
39 | + | |
40 | + &:hover { | |
41 | + background: #6C6; | |
42 | + color: #fff; | |
43 | + } | |
44 | + | |
45 | + &.disabled { | |
46 | + color:#fff; | |
47 | + background:#2b2; | |
48 | + } | |
49 | + } | |
50 | + | |
51 | + &.save-btn { | |
52 | + @extend .wide; | |
53 | + @extend .primary; | |
54 | + } | |
55 | + | |
56 | + &.cancel-btn { | |
57 | + float:right; | |
58 | + } | |
59 | + | |
60 | + &.wide { | |
61 | + padding-left:30px; | |
62 | + padding-right:30px; | |
63 | + } | |
64 | + | |
65 | + &.danger, | |
66 | + &.btn-danger { | |
67 | + color:#fff; | |
68 | + background: #DA4E49; | |
69 | + border-color: #BD362F; | |
70 | + | |
71 | + &:hover { | |
72 | + color:#fff; | |
73 | + background: #EE4E49; | |
74 | + } | |
75 | + } | |
76 | + | |
77 | + &.danger { | |
78 | + @extend .btn-danger; | |
79 | + } | |
80 | + | |
81 | + &.small { | |
82 | + @extend .btn-small; | |
83 | + } | |
84 | + | |
85 | + &.active { | |
86 | + border-color:#aaa; | |
87 | + background-color:#ccc; | |
88 | + } | |
89 | + | |
90 | + &.very_small { | |
91 | + font-size:11px; | |
92 | + padding:2px 6px; | |
93 | + margin:2px; | |
94 | + } | |
95 | + | |
96 | + &.grouped { | |
97 | + margin-right:7px; | |
98 | + float:left; | |
99 | + } | |
100 | + | |
101 | + &.padded { | |
102 | + margin-right:3px; | |
103 | + padding:4px 10px 4px; | |
104 | + } | |
105 | +} | ... | ... |
... | ... | @@ -0,0 +1,52 @@ |
1 | +/** COLORS **/ | |
2 | +.cgray { color:gray } | |
3 | +.cred { color:#D12F19 } | |
4 | +.cgreen { color:#4a2 } | |
5 | +.cblack { color:#111 } | |
6 | +.cdark { color:#444 } | |
7 | +.cwhite { color:#fff!important } | |
8 | +.bgred { background:#F2DEDE!important } | |
9 | + | |
10 | +/** COMMON CLASSES **/ | |
11 | +.left { float:left } | |
12 | +.right { float:right!important } | |
13 | +.width-50p { width:50% } | |
14 | +.width-49p { width:49% } | |
15 | +.width-30p { width:30% } | |
16 | +.width-65p { width:65% } | |
17 | +.width-100p { width:100% } | |
18 | +.append-bottom-10 { margin-bottom:10px } | |
19 | +.append-bottom-20 { margin-bottom:20px } | |
20 | +.prepend-top-10 { margin-top:10px } | |
21 | +.prepend-top-20 { margin-top:20px } | |
22 | +.padded { padding:20px } | |
23 | +.ipadded { padding:20px!important } | |
24 | +.lborder { border-left:1px solid #eee } | |
25 | +.no-padding { padding:0 !important; } | |
26 | +.underlined { border-bottom: 1px solid #CCC; } | |
27 | +.no-borders { border:none; } | |
28 | +.vlink { color: $link_color !important; } | |
29 | +.borders { border: 1px solid #ccc; @include shade; } | |
30 | +.hint { font-style: italic; color: #999; } | |
31 | + | |
32 | +/** PILLS & TABS**/ | |
33 | +.nav-pills a:hover { background-color:#888; } | |
34 | +.nav-pills .active a { background-color: $style_color; } | |
35 | +.nav-tabs > li > a, .nav-pills > li > a { color:$style_color; } | |
36 | +.nav-tabs > .active > a { font-weight:bold; } | |
37 | + | |
38 | +/** ALERT MESSAGES **/ | |
39 | +.alert-message { @extend .alert; } | |
40 | +.alert-messag.success { @extend .alert-success; } | |
41 | +.alert-message.error { @extend .alert-error; } | |
42 | + | |
43 | +/** AVATARS **/ | |
44 | +img.avatar { float:left; margin-right:15px; width:40px; border:1px solid #ddd; padding:1px; } | |
45 | +img.avatar.s16 { width:16px; height:16px; } | |
46 | +img.avatar.s24 { width:24px; height:24px; } | |
47 | +img.avatar.s32 { width:32px; height:32px; } | |
48 | +img.lil_av { padding-left: 4px; padding-right:3px; } | |
49 | + | |
50 | +/** HELPERS **/ | |
51 | +.nothing_here_message { text-align:center; padding:20px; color:#777; } | |
52 | +p.slead { color:#456; font-size:16px; margin-bottom: 12px; font-weight: 200; line-height: 24px; } | ... | ... |
... | ... | @@ -0,0 +1,156 @@ |
1 | +/** | |
2 | + * File content holder | |
3 | + * | |
4 | + */ | |
5 | +.file_holder { | |
6 | + border:1px solid #CCC; | |
7 | + margin-bottom:1em; | |
8 | + @include solid_shade; | |
9 | + | |
10 | + .file_title { | |
11 | + border-bottom: 1px solid #bbb; | |
12 | + @include bg-gray-gradient; | |
13 | + margin: 0; | |
14 | + font-weight: normal; | |
15 | + font-weight: bold; | |
16 | + text-align: left; | |
17 | + color: #666; | |
18 | + padding: 9px 10px; | |
19 | + height:18px; | |
20 | + | |
21 | + .options { | |
22 | + float:right; | |
23 | + margin-top: -5px; | |
24 | + } | |
25 | + | |
26 | + .file_name { | |
27 | + color:$style_color; | |
28 | + font-size:14px; | |
29 | + text-shadow: 0 1px 1px #fff; | |
30 | + small { | |
31 | + color:#999; | |
32 | + font-size:13px; | |
33 | + } | |
34 | + } | |
35 | + } | |
36 | + .file_content { | |
37 | + background:#fff; | |
38 | + font-size: 11px; | |
39 | + | |
40 | + &.wiki { | |
41 | + font-size: 13px; | |
42 | + code { | |
43 | + padding:0 4px; | |
44 | + } | |
45 | + padding:20px; | |
46 | + h1, h2 { | |
47 | + line-height: 46px; | |
48 | + } | |
49 | + h3, h4 { | |
50 | + line-height: 40px; | |
51 | + } | |
52 | + } | |
53 | + | |
54 | + &.image_file { | |
55 | + background:#eee; | |
56 | + text-align:center; | |
57 | + img { | |
58 | + padding:100px; | |
59 | + max-width:300px; | |
60 | + } | |
61 | + } | |
62 | + | |
63 | + &.blob_file { | |
64 | + | |
65 | + } | |
66 | + | |
67 | + /** | |
68 | + * Blame file | |
69 | + */ | |
70 | + &.blame { | |
71 | + tr { | |
72 | + border-bottom: 1px solid #eee; | |
73 | + } | |
74 | + td { | |
75 | + padding:5px; | |
76 | + } | |
77 | + .author, | |
78 | + .blame_commit { | |
79 | + background:#f5f5f5; | |
80 | + vertical-align:top; | |
81 | + } | |
82 | + .lines { | |
83 | + pre { | |
84 | + padding:0; | |
85 | + margin:0; | |
86 | + background:none; | |
87 | + border:none; | |
88 | + } | |
89 | + } | |
90 | + } | |
91 | + | |
92 | + &.logs { | |
93 | + background:#eee; | |
94 | + max-height: 700px; | |
95 | + overflow-y: auto; | |
96 | + | |
97 | + ol { | |
98 | + margin-left:40px; | |
99 | + padding: 10px 0; | |
100 | + border-left: 1px solid #CCC; | |
101 | + margin-bottom:0; | |
102 | + background: white; | |
103 | + li { | |
104 | + color:#888; | |
105 | + p { | |
106 | + margin:0; | |
107 | + color:#333; | |
108 | + line-height:24px; | |
109 | + padding-left: 10px; | |
110 | + } | |
111 | + | |
112 | + &:hover { | |
113 | + background:$hover; | |
114 | + } | |
115 | + } | |
116 | + } | |
117 | + } | |
118 | + | |
119 | + /** | |
120 | + * Code file | |
121 | + */ | |
122 | + &.code { | |
123 | + padding:0; | |
124 | + td.code { | |
125 | + width: 100%; | |
126 | + .highlight { | |
127 | + margin-left: 55px; | |
128 | + overflow:auto; | |
129 | + overflow-y:hidden; | |
130 | + } | |
131 | + } | |
132 | + .highlight pre { | |
133 | + white-space: pre; | |
134 | + word-wrap:normal; | |
135 | + } | |
136 | + | |
137 | + table.highlighttable { | |
138 | + border: none; | |
139 | + } | |
140 | + body.project-page table.highlighttable td { border: none } | |
141 | + table.highlighttable tr:hover { background:none;} | |
142 | + | |
143 | + table.highlighttable pre{ | |
144 | + line-height:16px !important; | |
145 | + font-size:12px !important; | |
146 | + } | |
147 | + | |
148 | + table.highlighttable .linenodiv pre { | |
149 | + text-align: right; | |
150 | + padding-right: 4px; | |
151 | + color:#666; | |
152 | + } | |
153 | + } | |
154 | + } | |
155 | +} | |
156 | + | ... | ... |
... | ... | @@ -0,0 +1,30 @@ |
1 | +/** LISTS **/ | |
2 | + | |
3 | +ul { | |
4 | + /** | |
5 | + * List li block element #1 | |
6 | + * | |
7 | + */ | |
8 | + .wll { | |
9 | + background-color: #FFF; | |
10 | + padding: 10px 5px; | |
11 | + min-height: 20px; | |
12 | + border-bottom: 1px solid #eee; | |
13 | + border-bottom: 1px solid rgba(0, 0, 0, 0.05); | |
14 | + | |
15 | + &.smoke { background-color:#f5f5f5; } | |
16 | + &:hover { background:$hover; } | |
17 | + &:last-child { border:none } | |
18 | + .author { color: #999; } | |
19 | + | |
20 | + p { | |
21 | + padding-top:5px; | |
22 | + margin:0; | |
23 | + color:#222; | |
24 | + img { | |
25 | + position:relative; | |
26 | + top:3px; | |
27 | + } | |
28 | + } | |
29 | + } | |
30 | +} | ... | ... |
... | ... | @@ -0,0 +1,41 @@ |
1 | +table { | |
2 | + width:100%; | |
3 | + th { | |
4 | + padding-top: 9px; | |
5 | + font-weight: bold; | |
6 | + vertical-align: middle; | |
7 | + } | |
8 | + th, td { | |
9 | + padding: 10px 10px 9px; | |
10 | + line-height: 18px; | |
11 | + text-align: left; | |
12 | + } | |
13 | + | |
14 | + &.bordered-table { | |
15 | + border: 1px solid #DDD; | |
16 | + border-collapse: separate; | |
17 | + -webkit-border-radius: 4px; | |
18 | + -moz-border-radius: 4px; | |
19 | + border-radius: 4px; | |
20 | + } | |
21 | + | |
22 | + &.zebra-striped { | |
23 | + @extend .table-striped; | |
24 | + } | |
25 | +} | |
26 | + | |
27 | +table.admin-table { | |
28 | + @extend .table-bordered; | |
29 | + @extend .zebra-striped; | |
30 | + @include solid_shade; | |
31 | + th { | |
32 | + border-color: #CCC; | |
33 | + border-bottom: 1px solid #bbb; | |
34 | + @include bg-gray-gradient; | |
35 | + } | |
36 | +} | |
37 | + | |
38 | +table.no-borders { | |
39 | + border:none; | |
40 | + tr, td { border:none } | |
41 | +} | ... | ... |
... | ... | @@ -0,0 +1,71 @@ |
1 | +/** | |
2 | + * Headers | |
3 | + * | |
4 | + */ | |
5 | +h3, h4, h5, h6 { line-height: 36px; } | |
6 | +h5 { font-size:14px; } | |
7 | +h3.page_title { | |
8 | + color:#456; | |
9 | + font-size:20px; | |
10 | + font-weight: normal; | |
11 | + line-height: 28px; | |
12 | +} | |
13 | + | |
14 | +/** CODE **/ | |
15 | +pre { | |
16 | + font-family:'Menlo', 'Liberation Mono', 'Consolas', 'Courier New', 'andale mono','lucida console',monospace; | |
17 | + | |
18 | + &.dark { | |
19 | + background: #333; | |
20 | + color:#f5f5f5; | |
21 | + } | |
22 | +} | |
23 | + | |
24 | +/** | |
25 | + * Links | |
26 | + * | |
27 | + */ | |
28 | +a { | |
29 | + outline: none; | |
30 | + color: $link_color; | |
31 | + &:hover { | |
32 | + text-decoration:none; | |
33 | + color: $blue_link; | |
34 | + } | |
35 | + | |
36 | + &.btn { | |
37 | + color: $style_color; | |
38 | + &:hover { | |
39 | + color: $style_color; | |
40 | + } | |
41 | + } | |
42 | + | |
43 | + &.dark { | |
44 | + color: $style_color; | |
45 | + } | |
46 | + | |
47 | + &.lined { | |
48 | + text-decoration:underline; | |
49 | + &:hover { text-decoration:underline; } | |
50 | + } | |
51 | + | |
52 | + &.gray { | |
53 | + color:gray; | |
54 | + } | |
55 | + | |
56 | + &.supp_diff_link { | |
57 | + text-align:center; | |
58 | + padding:20px 0; | |
59 | + background:#f1f1f1; | |
60 | + width:100%; | |
61 | + float:left; | |
62 | + } | |
63 | + | |
64 | + &.neib { | |
65 | + margin-right:15px; | |
66 | + } | |
67 | +} | |
68 | + | |
69 | +a:focus { | |
70 | + outline: none; | |
71 | +} | ... | ... |
app/assets/stylesheets/main.scss
... | ... | @@ -2,29 +2,13 @@ |
2 | 2 | @import "bootstrap-responsive"; |
3 | 3 | |
4 | 4 | /** GITLAB colors **/ |
5 | -$text_color:#222; | |
6 | -$lite_text_color: #666; | |
7 | -$link_color:#2A79A3; | |
8 | -$active_link_color:#2FA0BB; | |
9 | -$active_bg_color:#79C3E0; | |
10 | -$active_bd_color: #2FA0BB; | |
11 | -$border_color:#CCC; | |
12 | -$lite_border_color:#EEE; | |
13 | -$min_app_width:980px; | |
14 | -$max_app_width:980px; | |
15 | -$app_padding:20px; | |
16 | -$bg_color: #FFF; | |
17 | -$styled_border_color: #2FA0BB; | |
18 | -$color: "#4BB8D2"; | |
5 | +$link_color:#3A89A3; | |
19 | 6 | $blue_link: #2fa0bb; |
20 | - | |
21 | - | |
22 | -/** Style colors **/ | |
23 | -$style_color: #474D57; | |
24 | -$hover: #FDF5D9; | |
7 | +$style_color: #474d57; | |
8 | +$hover: #fdf5d9; | |
25 | 9 | |
26 | 10 | /** GITLAB Fonts **/ |
27 | -@font-face { font-family: Korolev; src: url('korolev-medium-compressed.otf'); } | |
11 | +@font-face { font-family: Korolev; src: url('korolev-medium-compressed.otf'); } | |
28 | 12 | |
29 | 13 | /** MIXINS **/ |
30 | 14 | @mixin shade { |
... | ... | @@ -72,7 +56,20 @@ $hover: #FDF5D9; |
72 | 56 | border-radius: $radius; |
73 | 57 | } |
74 | 58 | |
59 | +@mixin bg-gray-gradient { | |
60 | + background:#eee; | |
61 | + background-image: -webkit-gradient(linear, 0 0, 0 30, color-stop(0.066, #eee), to(#dfdfdf)); | |
62 | + background-image: -webkit-linear-gradient(#eee 6.6%, #dfdfdf); | |
63 | + background-image: -moz-linear-gradient(#eee 6.6%, #dfdfdf); | |
64 | + background-image: -o-linear-gradient(#eee 6.6%, #dfdfdf); | |
65 | +} | |
75 | 66 | |
67 | +@mixin bg-dark-gray-gradient { | |
68 | + background:#eee; | |
69 | + background-image: -webkit-linear-gradient(#e9e9e9, #d7d7d7); | |
70 | + background-image: -moz-linear-gradient(#e9e9e9, #d7d7d7); | |
71 | + background-image: -o-linear-gradient(#e9e9e9, #d7d7d7); | |
72 | +} | |
76 | 73 | |
77 | 74 | /** |
78 | 75 | * Header of application. |
... | ... | @@ -113,7 +110,13 @@ $hover: #FDF5D9; |
113 | 110 | * Overrides some styles of twitter bootstrap. |
114 | 111 | * Also give some common classes for gitlab app |
115 | 112 | */ |
116 | -@import "gitlab_bootstrap.scss"; | |
113 | +@import "gitlab_bootstrap/common.scss"; | |
114 | +@import "gitlab_bootstrap/typography.scss"; | |
115 | +@import "gitlab_bootstrap/buttons.scss"; | |
116 | +@import "gitlab_bootstrap/blocks.scss"; | |
117 | +@import "gitlab_bootstrap/files.scss"; | |
118 | +@import "gitlab_bootstrap/tables.scss"; | |
119 | +@import "gitlab_bootstrap/lists.scss"; | |
117 | 120 | |
118 | 121 | |
119 | 122 | /** | ... | ... |
app/assets/stylesheets/projects.css.scss
... | ... | @@ -1,385 +0,0 @@ |
1 | -.git_url_wrapper { margin-right:50px } | |
2 | - | |
3 | -.sidebar aside a{ | |
4 | - display: block; | |
5 | - position: relative; | |
6 | - padding: 15px 10px; | |
7 | - margin: 10px 0 0 0; | |
8 | - | |
9 | - font-size:13px; | |
10 | - font-weight:bold; | |
11 | - color:#333; | |
12 | - | |
13 | - &.current { | |
14 | - color: white; | |
15 | - background: $active_bg_color; | |
16 | - border: 1px solid $active_bd_color; | |
17 | - border-radius:5px; | |
18 | - | |
19 | - -webkit-border-top-right-radius: 0; | |
20 | - -webkit-border-bottom-right-radius: 0; | |
21 | - -moz-border-radius-topright: 0px; | |
22 | - -moz-border-radius-bottomright: 0px; | |
23 | - border-top-right-radius: 0; | |
24 | - border-bottom-right-radius: 0; | |
25 | - margin-right: -1px; | |
26 | - } | |
27 | -} | |
28 | - | |
29 | -body table .commit a{color: #{$blue_link}} | |
30 | -body table th, body table td{ border-bottom: 1px solid #DEE2E3;} | |
31 | -body .fixed{position: fixed; } | |
32 | - | |
33 | -/** File stat **/ | |
34 | -.file_stats { | |
35 | - span { | |
36 | - img { | |
37 | - width:14px; | |
38 | - float:left; | |
39 | - margin-right: 6px; | |
40 | - padding:2px 0; | |
41 | - } | |
42 | - } | |
43 | -} | |
44 | - | |
45 | -.round-borders { | |
46 | - @include round-borders-all(4px); | |
47 | - padding: 4px 0px; | |
48 | -} | |
49 | - | |
50 | -table.round-borders { | |
51 | - float:left; | |
52 | - text-align: left; | |
53 | -} | |
54 | - | |
55 | - | |
56 | - | |
57 | -/** PROJECTS **/ | |
58 | -input.ssh_project_url { | |
59 | - padding:5px; | |
60 | - margin:0px; | |
61 | - float:right; | |
62 | - width:400px; | |
63 | - text-align:center; | |
64 | -} | |
65 | - | |
66 | -#projects-list .project { | |
67 | - height:50px; | |
68 | -} | |
69 | - | |
70 | -#tree-slider .tree-item, | |
71 | -#projects-list .project, | |
72 | -#snippets-table .snippet, | |
73 | -#issues-table .issue{ | |
74 | - cursor:pointer; | |
75 | -} | |
76 | - | |
77 | -.clear { | |
78 | - clear: both; | |
79 | -} | |
80 | - | |
81 | - | |
82 | - | |
83 | -#user_projects_limit{ | |
84 | - width: 60px; | |
85 | -} | |
86 | - | |
87 | -.handle:hover{ | |
88 | - cursor: move; | |
89 | -} | |
90 | - | |
91 | -.project-refs-form { | |
92 | - span { | |
93 | - background: none !important; | |
94 | - position:static !important; | |
95 | - width:auto !important; | |
96 | - height: auto !important; | |
97 | - } | |
98 | -} | |
99 | - | |
100 | -.project-refs-select { | |
101 | - width:200px; | |
102 | -} | |
103 | - | |
104 | -.filter .left { margin-right:15px; } | |
105 | - | |
106 | -body table .commit { | |
107 | - a.tree-commit-link { | |
108 | - color:#444; | |
109 | - &:hover { | |
110 | - text-decoration:underline; | |
111 | - } | |
112 | - } | |
113 | -} | |
114 | - | |
115 | -/** NEW PROJECT **/ | |
116 | -.new-project-hodler { | |
117 | - .icon span { background-position: -31px -70px; } | |
118 | - td { border-bottom: 1px solid #DEE2E3; } | |
119 | -} | |
120 | - | |
121 | -/** Feed entry **/ | |
122 | -.commit, | |
123 | -.snippet, | |
124 | -.message { | |
125 | - .title { | |
126 | - color:#666; | |
127 | - a { color:#666 !important; } | |
128 | - p { margin-top:0px; } | |
129 | - } | |
130 | - .author { color: #999 } | |
131 | -} | |
132 | - | |
133 | -/** JQuery UI **/ | |
134 | -.ui-autocomplete { @include round-borders-all(5px); } | |
135 | -.ui-menu-item { cursor: pointer } | |
136 | -.ui-selectmenu{ | |
137 | - @include round-borders-all(4px); | |
138 | - margin-right:10px; | |
139 | - font-size:1.5em; | |
140 | - height:auto; | |
141 | - font-weight:bold; | |
142 | - .ui-selectmenu-status { | |
143 | - padding:3px 10px; | |
144 | - } | |
145 | -} | |
146 | - | |
147 | -#holder { | |
148 | - background:#FAFAFA; | |
149 | - border: 1px solid #EEE; | |
150 | - cursor: move; | |
151 | - height: 70%; | |
152 | - overflow: hidden; | |
153 | -} | |
154 | - | |
155 | -/* Project Dashboard Page */ | |
156 | -html, body { height: 100%; } | |
157 | - | |
158 | -.news-feed h2{float: left;} | |
159 | -.news-feed .project-updates {margin-bottom: 20px; display: block; width: 100%;} | |
160 | -.news-feed .project-updates .data{ padding: 0} | |
161 | -.news-feed .project-updates a.project-update {padding: 10px; border-bottom: 1px solid #eee; overflow: hidden; display: block;} | |
162 | -.news-feed .project-updates a.project-update:last-child{border-bottom: 0} | |
163 | -.news-feed .project-updates a.project-update img{float: left; margin-right: 10px;} | |
164 | -.news-feed .project-updates a.project-update span.update-title, .dashboard-page .news-feed .project-updates li a span.update-author{display: block;} | |
165 | -.news-feed .project-updates a.project-update span.update-title{margin-bottom: 10px} | |
166 | -.news-feed .project-updates a.project-update span.update-author{color: #999; font-weight: normal; font-style: italic;} | |
167 | -.news-feed .project-updates a.project-update span.update-author strong{font-weight: bold; font-style: normal;} | |
168 | -/* eo Dashboard Page */ | |
169 | - | |
170 | - | |
171 | -/** Update entry **/ | |
172 | -.update-data { padding: 0 } | |
173 | -.update-data { width:100%; } | |
174 | -.update-data.ui-box .data { padding:0; } | |
175 | -a.update-item {padding: 10px; border-bottom: 1px solid #eee; overflow: hidden; display: block;} | |
176 | -a.update-item:last-child{border-bottom: 0} | |
177 | -a.update-item img{float: left; margin-right: 10px;} | |
178 | -a.update-item span.update-title, .dashboard-page .news-feed .project-updates li a span.update-author{display: block;} | |
179 | -a.update-item span.update-title{margin-bottom: 10px} | |
180 | -a.update-item span.update-author{color: #999; font-weight: normal; font-style: italic;} | |
181 | -a.update-item span.update-author strong{font-weight: bold; font-style: normal;} | |
182 | - | |
183 | - | |
184 | -body .team_member_new .span-6, .team_member_edit .span-6{ padding:10px 0; } | |
185 | - | |
186 | -body.projects-page input.text.git-url.project_list_url { width:165px; } | |
187 | - | |
188 | - | |
189 | -body table.no-borders th { | |
190 | - background:none; | |
191 | - border-bottom:1px solid #CCC; | |
192 | - color:#333; | |
193 | -} | |
194 | - | |
195 | -body table.no-borders tr, | |
196 | -body table.no-borders td{ | |
197 | - border:none; | |
198 | -} | |
199 | - | |
200 | -.ajax-tab-loading { | |
201 | - padding:40px; | |
202 | - display:none; | |
203 | -} | |
204 | - | |
205 | -#tree-content-holder { float:left; width:100%; } | |
206 | - | |
207 | -#tree-readme-holder { | |
208 | - float:left; | |
209 | - width:100%; | |
210 | - | |
211 | - .readme { | |
212 | - @include round-borders-all(4px); | |
213 | - padding: 4px 15px; | |
214 | - background:#F7F7F7; | |
215 | - } | |
216 | -} | |
217 | - | |
218 | - | |
219 | - | |
220 | -/* Commit Page */ | |
221 | -.entity-info {float: right;} | |
222 | -.entity-button{ | |
223 | - background-image: -webkit-gradient(linear, 0 0, 0 26, color-stop(0.192, #fff), to(#f4f4f4)); | |
224 | - background-image: -webkit-linear-gradient(#fff 19.2%, #f4f4f4); | |
225 | - background-image: -moz-linear-gradient(#fff 19.2%, #f4f4f4); | |
226 | - background-image: -o-linear-gradient(#fff 19.2%, #f4f4f4); | |
227 | - box-shadow: 0 -1px 0 white inset; | |
228 | - display: block; | |
229 | - border: 1px solid #eee; | |
230 | - border-radius: 5px; | |
231 | - margin-bottom: 2px; | |
232 | - position: relative; | |
233 | - padding: 4px 10px; | |
234 | - font-size: 11px; | |
235 | - padding-right: 20px; | |
236 | -} | |
237 | - | |
238 | -.entity-button i{ | |
239 | - background: url('images.png') no-repeat -138px -27px; | |
240 | - width: 6px; | |
241 | - height: 9px; | |
242 | - float: right; | |
243 | - position: absolute; | |
244 | - top: 6px; | |
245 | - right: 5px; | |
246 | -} | |
247 | -.box-arrow{float: right; background: #E3E5EA; padding: 10px; border-radius: 5px; margin-top: 2px; text-shadow: none; color: #999; margin: 1.5em 0;} | |
248 | - | |
249 | -h4.dash-tabs { | |
250 | - margin: 0; | |
251 | - border-bottom: 1px solid #ccc; | |
252 | - padding: 10px 10px; | |
253 | - font-size: 11px; | |
254 | - padding-left:20px; | |
255 | - font-weight: bold; text-transform: uppercase; | |
256 | - background: #F7F7F7; | |
257 | - margin-bottom:20px; | |
258 | - height:13px; | |
259 | - | |
260 | -} | |
261 | - | |
262 | -.dash-button { | |
263 | - border-right: 1px solid #ddd; | |
264 | - background:none; | |
265 | - padding: 10px 15px; | |
266 | - float:left; | |
267 | - position:relative; | |
268 | - top:-10px; | |
269 | - left:0px; | |
270 | - height:13px; | |
271 | - | |
272 | - &:first-child { | |
273 | - border-left: 1px solid #ddd; | |
274 | - } | |
275 | - &.active { | |
276 | - background: #eaeaea; | |
277 | - } | |
278 | -} | |
279 | - | |
280 | - | |
281 | -.dashboard-loader { | |
282 | - float:right; | |
283 | - margin-right:30px; | |
284 | - display:none; | |
285 | -} | |
286 | - | |
287 | - | |
288 | -.merge-tabs { | |
289 | - margin: 0; | |
290 | - border: 1px solid #ccc; | |
291 | - padding: 5px; | |
292 | - font-size: 12px; | |
293 | - background: #F7F7F7; | |
294 | - margin-bottom:20px; | |
295 | - height:26px; | |
296 | - | |
297 | - -moz-border-radius: 4px; | |
298 | - -webkit-border-radius: 4px; | |
299 | - border-radius: 4px; | |
300 | - | |
301 | - .tab { | |
302 | - font-weight: bold; | |
303 | - border-right: 1px solid #ddd; | |
304 | - background:none; | |
305 | - padding: 10px; | |
306 | - min-width:60px; | |
307 | - float:left; | |
308 | - position:relative; | |
309 | - top:-5px; | |
310 | - left:-5px; | |
311 | - height:16px; | |
312 | - padding-left:34px; | |
313 | - | |
314 | - span { | |
315 | - width: 20px; | |
316 | - height: 20px; | |
317 | - display: inline-block; | |
318 | - position: absolute; | |
319 | - left: 8px; | |
320 | - top: 8px; | |
321 | - } | |
322 | - | |
323 | - &.active { | |
324 | - background: #eaeaea; | |
325 | - } | |
326 | - } | |
327 | -} | |
328 | -.merge-tabs.repository .tab span{ background: url("images.png") no-repeat -38px -77px; } | |
329 | -.activities-tab span { background: url("images.png") no-repeat -161px -1px; } | |
330 | -.stat-tab span, | |
331 | -.team-tab span, | |
332 | -.snippets-tab span { background: url("images.png") no-repeat -38px -77px; } | |
333 | -.files-tab span { background: url("images.png") no-repeat -112px -23px; } | |
334 | - | |
335 | -.merge-notes-tab span { background: url("images.png") no-repeat -161px -1px; } | |
336 | -.merge-commits-tab span { background: url("images.png") no-repeat -86px 1px; } | |
337 | -.merge-diffs-tab span { background: url("images.png") no-repeat -118px 1px; } | |
338 | -.merge-tabs .dashboard-loader { padding:8px; } | |
339 | - | |
340 | -.user-mention { | |
341 | - color: #2FA0BB; | |
342 | - font-weight: bold; | |
343 | -} | |
344 | - | |
345 | -.author { | |
346 | - color: #999; | |
347 | -} | |
348 | - | |
349 | - | |
350 | - | |
351 | - | |
352 | -.dark_scheme_box { | |
353 | - padding:20px 0; | |
354 | - | |
355 | - label { | |
356 | - float:left; | |
357 | - box-shadow: 0 0px 5px rgba(0,0,0,.3); | |
358 | - | |
359 | - img { | |
360 | - } | |
361 | - } | |
362 | -} | |
363 | - | |
364 | -a.project-update.titled { | |
365 | - position: relative; | |
366 | - padding-left: 235px !important; | |
367 | - | |
368 | - .title-block { | |
369 | - padding: 10px; | |
370 | - width: 205px; | |
371 | - position: absolute; | |
372 | - left: 0; | |
373 | - top: 0; | |
374 | - } | |
375 | -} | |
376 | - | |
377 | -.add_new { | |
378 | - float: right; | |
379 | - background: #A6B807; | |
380 | - color: white; | |
381 | - padding: 4px 10px; | |
382 | - @include round-borders-all(4px); | |
383 | - font-size:11px; | |
384 | - margin: 10px 0; | |
385 | -} |
app/assets/stylesheets/ref_select.scss
app/assets/stylesheets/sections/commits.scss
... | ... | @@ -206,4 +206,24 @@ |
206 | 206 | min-width:65px; |
207 | 207 | font-family: 'Menlo', 'Liberation Mono', 'Consolas', 'Courier New', 'andale mono','lucida console',monospace; |
208 | 208 | } |
209 | + | |
210 | + .commit-author-name { | |
211 | + color: #777; | |
212 | + } | |
213 | +} | |
214 | + | |
215 | +.diff_file_header a, | |
216 | +.file_stats a { | |
217 | + color:$style_color; | |
218 | +} | |
219 | + | |
220 | +.file_stats { | |
221 | + span { | |
222 | + img { | |
223 | + width:14px; | |
224 | + float:left; | |
225 | + margin-right:6px; | |
226 | + padding:2px 0; | |
227 | + } | |
228 | + } | |
209 | 229 | } | ... | ... |
app/assets/stylesheets/sections/graph.scss
... | ... | @@ -6,11 +6,7 @@ |
6 | 6 | h4 { |
7 | 7 | padding:0 10px; |
8 | 8 | border-bottom: 1px solid #bbb; |
9 | - background:#eee; | |
10 | - background-image: -webkit-gradient(linear, 0 0, 0 30, color-stop(0.066, #eee), to(#dfdfdf)); | |
11 | - background-image: -webkit-linear-gradient(#eee 6.6%, #dfdfdf); | |
12 | - background-image: -moz-linear-gradient(#eee 6.6%, #dfdfdf); | |
13 | - background-image: -o-linear-gradient(#eee 6.6%, #dfdfdf); | |
9 | + @include bg-gray-gradient; | |
14 | 10 | } |
15 | 11 | |
16 | 12 | .graph { | ... | ... |
app/assets/stylesheets/sections/issues.scss
... | ... | @@ -65,6 +65,11 @@ input.check_all_issues { |
65 | 65 | } |
66 | 66 | } |
67 | 67 | |
68 | +@media (min-width: 800px) { .issues_filters select { width:160px; } } | |
69 | +@media (min-width: 1000px) { .issues_filters select { width:200px; } } | |
70 | +@media (min-width: 1200px) { .issues_filters select { width:220px; } } | |
71 | + | |
72 | + | |
68 | 73 | #issues-table-holder { |
69 | 74 | .issues_filters { |
70 | 75 | form { |
... | ... | @@ -99,3 +104,11 @@ input.check_all_issues { |
99 | 104 | #update_status { |
100 | 105 | width:100px; |
101 | 106 | } |
107 | + | |
108 | +/** | |
109 | + * Milestones list | |
110 | + * | |
111 | + */ | |
112 | +.milestone { | |
113 | + @extend .wll; | |
114 | +} | ... | ... |
app/assets/stylesheets/sections/merge_requests.scss
... | ... | @@ -11,23 +11,6 @@ |
11 | 11 | background:#f1f1f1; |
12 | 12 | } |
13 | 13 | |
14 | - .commit { | |
15 | - margin:0; | |
16 | - padding:0; | |
17 | - padding: 5px; | |
18 | - margin-bottom: 5px; | |
19 | - | |
20 | - .committed_ago { | |
21 | - display:none; | |
22 | - } | |
23 | - .browse_code_link_holder { | |
24 | - display:none; | |
25 | - } | |
26 | - list-style:none; | |
27 | - &:hover { | |
28 | - background:none; | |
29 | - } | |
30 | - } | |
31 | 14 | } |
32 | 15 | |
33 | 16 | /** |
... | ... | @@ -55,6 +38,7 @@ |
55 | 38 | background: #CEB; |
56 | 39 | |
57 | 40 | .accept_merge_request { |
41 | + font-size:13px; | |
58 | 42 | float:left; |
59 | 43 | } |
60 | 44 | .remove_branch_holder { |
... | ... | @@ -99,3 +83,42 @@ li.merge_request { |
99 | 83 | @extend .padded; |
100 | 84 | @extend .append-bottom-10; |
101 | 85 | } |
86 | + | |
87 | +.label_branch { | |
88 | + @include round-borders-all(4px); | |
89 | + padding:2px 4px; | |
90 | + border:none; | |
91 | + font-size:13px; | |
92 | + background: #474D57; | |
93 | + color:#fff; | |
94 | + font-weight:bold; | |
95 | + font-family: monospace; | |
96 | +} | |
97 | + | |
98 | +.mr_source_commit, | |
99 | +.mr_target_commit { | |
100 | + .commit { | |
101 | + margin:0; | |
102 | + padding:0; | |
103 | + padding: 5px; | |
104 | + margin-bottom: 5px; | |
105 | + .avatar { position:relative } | |
106 | + .row_title { | |
107 | + color:#444; | |
108 | + } | |
109 | + .commit-author-name, | |
110 | + .dash, | |
111 | + .committed_ago, | |
112 | + .browse_code_link_holder { | |
113 | + display:none; | |
114 | + } | |
115 | + list-style:none; | |
116 | + &:hover { | |
117 | + background:none; | |
118 | + } | |
119 | + } | |
120 | +} | |
121 | + | |
122 | +.mr_direction_tip { | |
123 | + margin-top:40px | |
124 | +} | ... | ... |
app/assets/stylesheets/sections/nav.scss
... | ... | @@ -6,13 +6,9 @@ ul.main_menu { |
6 | 6 | border-radius: 4px; |
7 | 7 | margin: auto; |
8 | 8 | margin:30px 0; |
9 | - background:#eee; | |
10 | - border:1px solid #bbb; | |
9 | + border:1px solid #AAA; | |
11 | 10 | height:37px; |
12 | - background-image: -webkit-gradient(linear, 0 0, 0 30, color-stop(0.066, #eee), to(#dfdfdf)); | |
13 | - background-image: -webkit-linear-gradient(#eee 6.6%, #dfdfdf); | |
14 | - background-image: -moz-linear-gradient(#eee 6.6%, #dfdfdf); | |
15 | - background-image: -o-linear-gradient(#eee 6.6%, #dfdfdf); | |
11 | + @include bg-gray-gradient; | |
16 | 12 | position:relative; |
17 | 13 | overflow:hidden; |
18 | 14 | @include shade; |
... | ... | @@ -89,7 +85,7 @@ ul.main_menu { |
89 | 85 | line-height:36px; |
90 | 86 | color: $style_color; |
91 | 87 | text-shadow:0 1px 1px white; |
92 | - | |
88 | + padding:0 10px; | |
93 | 89 | } |
94 | 90 | } |
95 | 91 | /* | ... | ... |
app/assets/stylesheets/sections/notes.scss
... | ... | @@ -2,7 +2,7 @@ |
2 | 2 | * Notes |
3 | 3 | * |
4 | 4 | */ |
5 | -#notes-list, | |
5 | +#notes-list, | |
6 | 6 | #new_notes_list { |
7 | 7 | display:block; |
8 | 8 | list-style:none; |
... | ... | @@ -10,7 +10,7 @@ |
10 | 10 | padding:0px; |
11 | 11 | } |
12 | 12 | |
13 | -#new_notes_list li:last-child{ | |
13 | +#new_notes_list li:last-child{ | |
14 | 14 | border-bottom:1px solid #aaa; |
15 | 15 | } |
16 | 16 | |
... | ... | @@ -30,16 +30,24 @@ |
30 | 30 | } |
31 | 31 | |
32 | 32 | #new_note { |
33 | - #note_note { | |
34 | - height:25px; | |
33 | + .note-text { | |
34 | + height:40px; | |
35 | 35 | } |
36 | 36 | .attach_holder { |
37 | 37 | display:none; |
38 | 38 | } |
39 | 39 | } |
40 | 40 | |
41 | -.note { | |
42 | - padding: 8px 0; | |
41 | +.preview_note { | |
42 | + margin: 2px; | |
43 | + border: 1px solid #ddd; | |
44 | + padding: 10px; | |
45 | + min-height: 60px; | |
46 | + background:#f5f5f5; | |
47 | +} | |
48 | + | |
49 | +.note { | |
50 | + padding: 8px 0; | |
43 | 51 | border-bottom: 1px solid #eee; |
44 | 52 | overflow: hidden; |
45 | 53 | display: block; |
... | ... | @@ -49,16 +57,16 @@ |
49 | 57 | .note-author { color: $style_color;} |
50 | 58 | |
51 | 59 | .note-title { margin-left:45px; padding-top: 5px;} |
52 | - .avatar { | |
60 | + .avatar { | |
53 | 61 | margin-top:3px; |
54 | 62 | } |
55 | 63 | |
56 | - .delete-note { | |
57 | - display:none; | |
64 | + .delete-note { | |
65 | + display:none; | |
58 | 66 | float:right; |
59 | 67 | } |
60 | 68 | |
61 | - &:hover { | |
69 | + &:hover { | |
62 | 70 | .delete-note { display:block; } |
63 | 71 | } |
64 | 72 | } |
... | ... | @@ -72,18 +80,18 @@ p.notify_controls span{ |
72 | 80 | font-weight: 700; |
73 | 81 | } |
74 | 82 | |
75 | -tr.line_notes_row { | |
83 | +tr.line_notes_row { | |
76 | 84 | border-bottom:1px solid #DDD; |
77 | 85 | border-left: 7px solid #2A79A3; |
78 | 86 | |
79 | - &.reply { | |
87 | + &.reply { | |
80 | 88 | background:#eee; |
81 | 89 | border-left: 7px solid #2A79A3; |
82 | 90 | border-top:1px solid #ddd; |
83 | - td { | |
91 | + td { | |
84 | 92 | padding:7px 10px; |
85 | 93 | } |
86 | - a.line_note_reply_link { | |
94 | + a.line_note_reply_link { | |
87 | 95 | @include round-borders-all(4px); |
88 | 96 | padding: 3px 10px; |
89 | 97 | margin-left:5px; |
... | ... | @@ -92,9 +100,9 @@ tr.line_notes_row { |
92 | 100 | border-color: #2A79A3; |
93 | 101 | } |
94 | 102 | } |
95 | - ul { | |
103 | + ul { | |
96 | 104 | margin:0; |
97 | - li { | |
105 | + li { | |
98 | 106 | padding:0; |
99 | 107 | border:none; |
100 | 108 | } |
... | ... | @@ -103,26 +111,26 @@ tr.line_notes_row { |
103 | 111 | |
104 | 112 | .line_notes_row, .per_line_form { font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; } |
105 | 113 | |
106 | -.per_line_form { | |
114 | +.per_line_form { | |
107 | 115 | background:#f5f5f5; |
108 | 116 | border-top:1px solid #eee; |
109 | 117 | form { margin: 0; } |
110 | - td { | |
118 | + td { | |
111 | 119 | border-bottom:1px solid #ddd; |
112 | 120 | } |
113 | - .note_actions { | |
121 | + .note_actions { | |
114 | 122 | margin:0; |
115 | 123 | padding-top: 10px; |
116 | 124 | |
117 | - .buttons { | |
125 | + .buttons { | |
118 | 126 | float:left; |
119 | 127 | width:300px; |
120 | 128 | } |
121 | - .options { | |
122 | - .labels { | |
129 | + .options { | |
130 | + .labels { | |
123 | 131 | float:left; |
124 | 132 | padding-left:10px; |
125 | - label { | |
133 | + label { | |
126 | 134 | padding: 6px 0; |
127 | 135 | margin: 0; |
128 | 136 | width:120px; |
... | ... | @@ -132,7 +140,7 @@ tr.line_notes_row { |
132 | 140 | } |
133 | 141 | } |
134 | 142 | |
135 | -td .line_note_link { | |
143 | +td .line_note_link { | |
136 | 144 | position:absolute; |
137 | 145 | margin-left:-70px; |
138 | 146 | margin-top:-10px; |
... | ... | @@ -144,14 +152,14 @@ td .line_note_link { |
144 | 152 | opacity: 0.0; |
145 | 153 | filter: alpha(opacity=0); |
146 | 154 | |
147 | - &:hover { | |
155 | + &:hover { | |
148 | 156 | opacity: 1.0; |
149 | 157 | filter: alpha(opacity=100); |
150 | 158 | } |
151 | 159 | } |
152 | 160 | |
153 | 161 | .diff_file_content tr.line_holder:hover > td { background: $hover !important; } |
154 | -.diff_file_content tr.line_holder:hover > td .line_note_link { | |
162 | +.diff_file_content tr.line_holder:hover > td .line_note_link { | |
155 | 163 | opacity: 1.0; |
156 | 164 | filter: alpha(opacity=100); |
157 | 165 | } |
... | ... | @@ -169,8 +177,8 @@ td .line_note_link { |
169 | 177 | margin: 0; |
170 | 178 | } |
171 | 179 | |
172 | - .note_advanced_opts { | |
173 | - h6 { | |
180 | + .note_advanced_opts { | |
181 | + h6 { | |
174 | 182 | line-height: 32px; |
175 | 183 | padding-right: 15px; |
176 | 184 | } |
... | ... | @@ -183,7 +191,7 @@ td .line_note_link { |
183 | 191 | overflow:hidden; |
184 | 192 | margin:0 0 5px !important; |
185 | 193 | |
186 | - .input_file { | |
194 | + .input_file { | |
187 | 195 | .file_upload { |
188 | 196 | position: absolute; |
189 | 197 | right:14px; |
... | ... | @@ -196,7 +204,7 @@ td .line_note_link { |
196 | 204 | height:28px; |
197 | 205 | overflow:hidden; |
198 | 206 | } |
199 | - .input-file { | |
207 | + .input-file { | |
200 | 208 | width: 260px; |
201 | 209 | height: 41px; |
202 | 210 | float: right; |
... | ... | @@ -204,3 +212,8 @@ td .line_note_link { |
204 | 212 | } |
205 | 213 | } |
206 | 214 | } |
215 | + | |
216 | +.note-text { | |
217 | + border: 1px solid #aaa; | |
218 | + box-shadow:none; | |
219 | +} | ... | ... |
app/assets/stylesheets/sections/projects.scss
1 | -.projects { | |
1 | +.projects { | |
2 | 2 | @extend .row; |
3 | 3 | .activities { |
4 | 4 | } |
5 | 5 | |
6 | - .side { | |
6 | + .side { | |
7 | 7 | @extend .span4; |
8 | 8 | @extend .right; |
9 | 9 | |
10 | - .projects_box { | |
11 | - h5 { | |
10 | + .projects_box { | |
11 | + h5 { | |
12 | 12 | color:$style_color; |
13 | 13 | font-size:16px; |
14 | 14 | text-shadow: 0 1px 1px #fff; |
15 | + padding: 2px 10px; | |
16 | + } | |
17 | + ul { | |
18 | + li { | |
19 | + padding:0; | |
20 | + a { | |
21 | + display:block; | |
22 | + .project_name { | |
23 | + color:#4fa2bd; | |
24 | + font-size:14px; | |
25 | + line-height:18px; | |
26 | + } | |
27 | + .arrow { | |
28 | + float:right; | |
29 | + padding:10px; | |
30 | + margin:0; | |
31 | + } | |
32 | + .last_activity { | |
33 | + padding-top:5px; | |
34 | + display:block; | |
35 | + span, strong { | |
36 | + font-size:12px; | |
37 | + color:#666; | |
38 | + } | |
39 | + } | |
40 | + } | |
41 | + } | |
15 | 42 | } |
16 | 43 | @extend .leftbar; |
17 | 44 | @extend .ui-box; |
... | ... | @@ -19,21 +46,47 @@ |
19 | 46 | } |
20 | 47 | } |
21 | 48 | |
22 | -.new_project, | |
23 | -.edit_project { | |
24 | - .project_name_holder { | |
49 | +.new_project, | |
50 | +.edit_project { | |
51 | + .project_name_holder { | |
25 | 52 | input, |
26 | - label { | |
53 | + label { | |
27 | 54 | font-size:16px; |
28 | 55 | line-height:20px; |
29 | 56 | padding:8px; |
30 | 57 | } |
31 | - label { | |
58 | + label { | |
32 | 59 | color:#888; |
33 | 60 | } |
34 | - .btn { | |
35 | - padding:6px; | |
61 | + .btn { | |
62 | + padding:6px 10px; | |
36 | 63 | margin-left:10px; |
64 | + margin-bottom:8px; | |
37 | 65 | } |
38 | 66 | } |
67 | + .adv_settings { | |
68 | + h6 { margin-left:40px; } | |
69 | + } | |
70 | +} | |
71 | + | |
72 | +.project_clone_panel { | |
73 | + @include border-radius(4px); | |
74 | + @include bg-gray-gradient; | |
75 | + padding: 4px 7px; | |
76 | + border: 1px solid #CCC; | |
77 | + margin-bottom:5px; | |
78 | + input[type=text] { | |
79 | + border: 1px solid #BBB; | |
80 | + } | |
81 | +} | |
82 | + | |
83 | +.save-project-loader { | |
84 | + img { | |
85 | + margin-top:50px; | |
86 | + margin-bottom:50px; | |
87 | + } | |
88 | + h3 { | |
89 | + @extend .page_title; | |
90 | + } | |
91 | + | |
39 | 92 | } | ... | ... |
app/assets/stylesheets/sections/tree.scss
... | ... | @@ -72,11 +72,7 @@ |
72 | 72 | th { |
73 | 73 | border-color: #CCC; |
74 | 74 | border-bottom: 1px solid #bbb; |
75 | - background:#eee; | |
76 | - background-image: -webkit-gradient(linear, 0 0, 0 30, color-stop(0.066, #eee), to(#dfdfdf)); | |
77 | - background-image: -webkit-linear-gradient(#eee 6.6%, #dfdfdf); | |
78 | - background-image: -moz-linear-gradient(#eee 6.6%, #dfdfdf); | |
79 | - background-image: -o-linear-gradient(#eee 6.6%, #dfdfdf); | |
75 | + @include bg-gray-gradient; | |
80 | 76 | } |
81 | 77 | } |
82 | 78 | ... | ... |
app/assets/stylesheets/themes/ui_mars.scss
... | ... | @@ -20,6 +20,10 @@ |
20 | 20 | |
21 | 21 | .fbtn { |
22 | 22 | .btn { |
23 | + i { | |
24 | + position: relative; | |
25 | + top: 1px; | |
26 | + } | |
23 | 27 | margin-left:8px; |
24 | 28 | background-image: -webkit-gradient(linear, 0 0, 0 30, color-stop(0.066, #595D63), to(#31363E)); |
25 | 29 | background-image: -webkit-linear-gradient(#595D63 6.6%, #31363E); |
... | ... | @@ -32,6 +36,10 @@ |
32 | 36 | background-image: -moz-linear-gradient(#595D63 6.6%, #202227); |
33 | 37 | background-image: -o-linear-gradient(#595D63 6.6%, #202227); |
34 | 38 | background-position:0 0; |
39 | + color:#fff; | |
40 | + i { | |
41 | + @extend .icon-white; | |
42 | + } | |
35 | 43 | } |
36 | 44 | |
37 | 45 | border: 1px solid #31363E; | ... | ... |
app/contexts/merge_requests_load.rb
1 | 1 | class MergeRequestsLoad < BaseContext |
2 | 2 | def execute |
3 | - type = params[:f].to_i | |
3 | + type = params[:f] | |
4 | 4 | |
5 | 5 | merge_requests = project.merge_requests |
6 | 6 | |
7 | 7 | merge_requests = case type |
8 | - when 1 then merge_requests | |
9 | - when 2 then merge_requests.closed | |
10 | - when 3 then merge_requests.opened.assigned(current_user) | |
8 | + when 'all' then merge_requests | |
9 | + when 'closed' then merge_requests.closed | |
10 | + when 'assigned-to-me' then merge_requests.opened.assigned(current_user) | |
11 | 11 | else merge_requests.opened |
12 | 12 | end.page(params[:page]).per(20) |
13 | 13 | ... | ... |
app/controllers/application_controller.rb
... | ... | @@ -14,6 +14,10 @@ class ApplicationController < ActionController::Base |
14 | 14 | render "errors/gitolite", layout: "error" |
15 | 15 | end |
16 | 16 | |
17 | + rescue_from Gitlab::Gitolite::InvalidKey do |exception| | |
18 | + render "errors/invalid_ssh_key", layout: "error" | |
19 | + end | |
20 | + | |
17 | 21 | rescue_from Encoding::CompatibilityError do |exception| |
18 | 22 | render "errors/encoding", layout: "error", status: 404 |
19 | 23 | end | ... | ... |
app/controllers/issues_controller.rb
... | ... | @@ -60,7 +60,13 @@ class IssuesController < ApplicationController |
60 | 60 | @issue.save |
61 | 61 | |
62 | 62 | respond_to do |format| |
63 | - format.html { redirect_to project_issue_path(@project, @issue) } | |
63 | + format.html do | |
64 | + if @issue.valid? | |
65 | + redirect_to project_issue_path(@project, @issue) | |
66 | + else | |
67 | + render :new | |
68 | + end | |
69 | + end | |
64 | 70 | format.js |
65 | 71 | end |
66 | 72 | end |
... | ... | @@ -162,10 +168,10 @@ class IssuesController < ApplicationController |
162 | 168 | |
163 | 169 | def issues_filter |
164 | 170 | { |
165 | - all: "1", | |
166 | - closed: "2", | |
167 | - to_me: "3", | |
168 | - open: "0" | |
171 | + all: "all", | |
172 | + closed: "closed", | |
173 | + to_me: "assigned-to-me", | |
174 | + open: "open" | |
169 | 175 | } |
170 | 176 | end |
171 | 177 | end | ... | ... |
... | ... | @@ -0,0 +1,25 @@ |
1 | +class LabelsController < ApplicationController | |
2 | + before_filter :authenticate_user! | |
3 | + before_filter :project | |
4 | + before_filter :module_enabled | |
5 | + | |
6 | + layout "project" | |
7 | + | |
8 | + # Authorize | |
9 | + before_filter :add_project_abilities | |
10 | + | |
11 | + # Allow read any issue | |
12 | + before_filter :authorize_read_issue! | |
13 | + | |
14 | + respond_to :js, :html | |
15 | + | |
16 | + def index | |
17 | + @labels = @project.issues.tag_counts_on(:labels).order('count DESC') | |
18 | + end | |
19 | + | |
20 | + protected | |
21 | + | |
22 | + def module_enabled | |
23 | + return render_404 unless @project.issues_enabled | |
24 | + end | |
25 | +end | ... | ... |
app/controllers/merge_requests_controller.rb
... | ... | @@ -103,10 +103,12 @@ class MergeRequestsController < ApplicationController |
103 | 103 | |
104 | 104 | def branch_from |
105 | 105 | @commit = project.commit(params[:ref]) |
106 | + @commit = CommitDecorator.decorate(@commit) | |
106 | 107 | end |
107 | 108 | |
108 | 109 | def branch_to |
109 | 110 | @commit = project.commit(params[:ref]) |
111 | + @commit = CommitDecorator.decorate(@commit) | |
110 | 112 | end |
111 | 113 | |
112 | 114 | protected | ... | ... |
app/controllers/milestones_controller.rb
... | ... | @@ -17,8 +17,8 @@ class MilestonesController < ApplicationController |
17 | 17 | respond_to :html |
18 | 18 | |
19 | 19 | def index |
20 | - @milestones = case params[:f].to_i | |
21 | - when 1; @project.milestones | |
20 | + @milestones = case params[:f] | |
21 | + when 'all'; @project.milestones | |
22 | 22 | else @project.milestones.active |
23 | 23 | end |
24 | 24 | ... | ... |
app/controllers/omniauth_callbacks_controller.rb
... | ... | @@ -12,8 +12,7 @@ class OmniauthCallbacksController < Devise::OmniauthCallbacksController |
12 | 12 | |
13 | 13 | def ldap |
14 | 14 | # We only find ourselves here if the authentication to LDAP was successful. |
15 | - info = request.env["omniauth.auth"]["info"] | |
16 | - @user = User.find_for_ldap_auth(info) | |
15 | + @user = User.find_for_ldap_auth(request.env["omniauth.auth"], current_user) | |
17 | 16 | if @user.persisted? |
18 | 17 | @user.remember_me = true |
19 | 18 | end | ... | ... |
app/controllers/team_members_controller.rb
app/decorators/application_decorator.rb
app/helpers/application_helper.rb
... | ... | @@ -2,10 +2,13 @@ require 'digest/md5' |
2 | 2 | module ApplicationHelper |
3 | 3 | |
4 | 4 | def gravatar_icon(user_email = '', size = 40) |
5 | - return unless user_email | |
6 | - gravatar_host = request.ssl? ? "https://secure.gravatar.com" : "http://www.gravatar.com" | |
7 | - user_email.strip! | |
8 | - "#{gravatar_host}/avatar/#{Digest::MD5.hexdigest(user_email.downcase)}?s=#{size}&d=identicon" | |
5 | + if Gitlab.config.disable_gravatar? || user_email.blank? | |
6 | + 'no_avatar.png' | |
7 | + else | |
8 | + gravatar_prefix = request.ssl? ? "https://secure" : "http://www" | |
9 | + user_email.strip! | |
10 | + "#{gravatar_prefix}.gravatar.com/avatar/#{Digest::MD5.hexdigest(user_email.downcase)}?s=#{size}&d=identicon" | |
11 | + end | |
9 | 12 | end |
10 | 13 | |
11 | 14 | def request_protocol |
... | ... | @@ -75,16 +78,16 @@ module ApplicationHelper |
75 | 78 | end |
76 | 79 | |
77 | 80 | def show_last_push_widget?(event) |
78 | - event && | |
81 | + event && | |
79 | 82 | event.last_push_to_non_root? && |
80 | 83 | !event.rm_ref? && |
81 | - event.project && | |
84 | + event.project && | |
82 | 85 | event.project.merge_requests_enabled |
83 | 86 | end |
84 | 87 | |
85 | 88 | def tab_class(tab_key) |
86 | 89 | active = case tab_key |
87 | - | |
90 | + | |
88 | 91 | # Project Area |
89 | 92 | when :wall; wall_tab? |
90 | 93 | when :wiki; controller.controller_name == "wikis" |
... | ... | @@ -123,4 +126,13 @@ module ApplicationHelper |
123 | 126 | def hexdigest(string) |
124 | 127 | Digest::SHA1.hexdigest string |
125 | 128 | end |
129 | + | |
130 | + def project_last_activity project | |
131 | + activity = project.last_activity | |
132 | + if activity && activity.created_at | |
133 | + time_ago_in_words(activity.created_at) + " ago" | |
134 | + else | |
135 | + "Never" | |
136 | + end | |
137 | + end | |
126 | 138 | end | ... | ... |
app/helpers/gitlab_markdown_helper.rb
1 | 1 | module GitlabMarkdownHelper |
2 | + # Replaces references (i.e. @abc, #123, !456, ...) in the text with links to | |
3 | + # the appropriate items in Gitlab. | |
4 | + # | |
5 | + # text - the source text | |
6 | + # html_options - extra options for the reference links as given to link_to | |
7 | + # | |
8 | + # note: reference links will only be generated if @project is set | |
9 | + # | |
10 | + # see Gitlab::Markdown for details on the supported syntax | |
2 | 11 | def gfm(text, html_options = {}) |
3 | 12 | return text if text.nil? |
4 | 13 | return text if @project.nil? |
5 | 14 | |
6 | - # Extract pre blocks | |
15 | + # Extract pre blocks so they are not altered | |
7 | 16 | # from http://github.github.com/github-flavored-markdown/ |
8 | 17 | extractions = {} |
9 | 18 | text.gsub!(%r{<pre>.*?</pre>|<code>.*?</code>}m) do |match| |
... | ... | @@ -22,10 +31,18 @@ module GitlabMarkdownHelper |
22 | 31 | extractions[$1] |
23 | 32 | end |
24 | 33 | |
25 | - text.html_safe | |
34 | + sanitize text.html_safe, attributes: ActionView::Base.sanitized_allowed_attributes + %w(id class ) | |
26 | 35 | end |
27 | 36 | |
28 | - # circumvents nesting links, which will behave bad in browsers | |
37 | + # Use this in places where you would normally use link_to(gfm(...), ...). | |
38 | + # | |
39 | + # It solves a problem occurring with nested links (i.e. | |
40 | + # "<a>outer text <a>gfm ref</a> more outer text</a>"). This will not be | |
41 | + # interpreted as intended. Browsers will parse something like | |
42 | + # "<a>outer text </a><a>gfm ref</a> more outer text" (notice the last part is | |
43 | + # not linked any more). link_to_gfm corrects that. It wraps all parts to | |
44 | + # explicitly produce the correct linking behavior (i.e. | |
45 | + # "<a>outer text </a><a>gfm ref</a><a> more outer text</a>"). | |
29 | 46 | def link_to_gfm(body, url, html_options = {}) |
30 | 47 | gfm_body = gfm(body, html_options) |
31 | 48 | |
... | ... | @@ -37,17 +54,24 @@ module GitlabMarkdownHelper |
37 | 54 | end |
38 | 55 | |
39 | 56 | def markdown(text) |
40 | - @__renderer ||= Redcarpet::Markdown.new(Redcarpet::Render::GitlabHTML.new(self, filter_html: true, with_toc_data: true), { | |
41 | - no_intra_emphasis: true, | |
42 | - tables: true, | |
43 | - fenced_code_blocks: true, | |
44 | - autolink: true, | |
45 | - strikethrough: true, | |
46 | - lax_html_blocks: true, | |
47 | - space_after_headers: true, | |
48 | - superscript: true | |
49 | - }) | |
50 | - | |
51 | - @__renderer.render(text).html_safe | |
57 | + unless @markdown | |
58 | + gitlab_renderer = Redcarpet::Render::GitlabHTML.new(self, | |
59 | + # see https://github.com/vmg/redcarpet#darling-i-packed-you-a-couple-renderers-for-lunch- | |
60 | + filter_html: true, | |
61 | + with_toc_data: true, | |
62 | + hard_wrap: true) | |
63 | + @markdown ||= Redcarpet::Markdown.new(gitlab_renderer, | |
64 | + # see https://github.com/vmg/redcarpet#and-its-like-really-simple-to-use | |
65 | + no_intra_emphasis: true, | |
66 | + tables: true, | |
67 | + fenced_code_blocks: true, | |
68 | + autolink: true, | |
69 | + strikethrough: true, | |
70 | + lax_html_blocks: true, | |
71 | + space_after_headers: true, | |
72 | + superscript: true) | |
73 | + end | |
74 | + | |
75 | + @markdown.render(text).html_safe | |
52 | 76 | end |
53 | 77 | end | ... | ... |
app/mailers/notify.rb
... | ... | @@ -12,74 +12,117 @@ class Notify < ActionMailer::Base |
12 | 12 | def new_user_email(user_id, password) |
13 | 13 | @user = User.find(user_id) |
14 | 14 | @password = password |
15 | - mail(to: @user.email, subject: "gitlab | Account was created for you") | |
15 | + mail(to: @user.email, subject: subject("Account was created for you")) | |
16 | 16 | end |
17 | 17 | |
18 | 18 | def new_issue_email(issue_id) |
19 | 19 | @issue = Issue.find(issue_id) |
20 | 20 | @project = @issue.project |
21 | - mail(to: @issue.assignee_email, subject: "gitlab | new issue ##{@issue.id} | #{@issue.title} | #{@project.name}") | |
21 | + mail(to: @issue.assignee_email, subject: subject("new issue ##{@issue.id}", @issue.title)) | |
22 | 22 | end |
23 | 23 | |
24 | 24 | def note_wall_email(recipient_id, note_id) |
25 | - recipient = User.find(recipient_id) | |
26 | 25 | @note = Note.find(note_id) |
27 | 26 | @project = @note.project |
28 | - mail(to: recipient.email, subject: "gitlab | #{@project.name}") | |
27 | + mail(to: recipient(recipient_id), subject: subject) | |
29 | 28 | end |
30 | 29 | |
31 | 30 | def note_commit_email(recipient_id, note_id) |
32 | - recipient = User.find(recipient_id) | |
33 | 31 | @note = Note.find(note_id) |
34 | 32 | @commit = @note.target |
35 | 33 | @commit = CommitDecorator.decorate(@commit) |
36 | 34 | @project = @note.project |
37 | - mail(to: recipient.email, subject: "gitlab | note for commit #{@commit.short_id} | #{@commit.title} | #{@project.name}") | |
35 | + mail(to: recipient(recipient_id), subject: subject("note for commit #{@commit.short_id}", @commit.title)) | |
38 | 36 | end |
39 | 37 | |
40 | 38 | def note_merge_request_email(recipient_id, note_id) |
41 | - recipient = User.find(recipient_id) | |
42 | 39 | @note = Note.find(note_id) |
43 | 40 | @merge_request = @note.noteable |
44 | 41 | @project = @note.project |
45 | - mail(to: recipient.email, subject: "gitlab | note for merge request !#{@merge_request.id} | #{@project.name}") | |
42 | + mail(to: recipient(recipient_id), subject: subject("note for merge request !#{@merge_request.id}")) | |
46 | 43 | end |
47 | 44 | |
48 | 45 | def note_issue_email(recipient_id, note_id) |
49 | - recipient = User.find(recipient_id) | |
50 | 46 | @note = Note.find(note_id) |
51 | 47 | @issue = @note.noteable |
52 | 48 | @project = @note.project |
53 | - mail(to: recipient.email, subject: "gitlab | note for issue ##{@issue.id} | #{@project.name}") | |
49 | + mail(to: recipient(recipient_id), subject: subject("note for issue ##{@issue.id}")) | |
54 | 50 | end |
55 | 51 | |
56 | 52 | def note_wiki_email(recipient_id, note_id) |
57 | - recipient = User.find(recipient_id) | |
58 | 53 | @note = Note.find(note_id) |
59 | 54 | @wiki = @note.noteable |
60 | 55 | @project = @note.project |
61 | - mail(to: recipient.email, subject: "gitlab | note for wiki | #{@project.name}") | |
56 | + mail(to: recipient(recipient_id), subject: subject("note for wiki")) | |
62 | 57 | end |
63 | 58 | |
64 | 59 | def new_merge_request_email(merge_request_id) |
65 | 60 | @merge_request = MergeRequest.find(merge_request_id) |
66 | 61 | @project = @merge_request.project |
67 | - mail(to: @merge_request.assignee_email, subject: "gitlab | new merge request !#{@merge_request.id} | #{@merge_request.title} | #{@project.name}") | |
62 | + mail(to: @merge_request.assignee_email, subject: subject("new merge request !#{@merge_request.id}", @merge_request.title)) | |
68 | 63 | end |
69 | 64 | |
70 | 65 | def reassigned_merge_request_email(recipient_id, merge_request_id, previous_assignee_id) |
71 | - recipient = User.find(recipient_id) | |
72 | 66 | @merge_request = MergeRequest.find(merge_request_id) |
73 | 67 | @previous_assignee ||= User.find(previous_assignee_id) |
74 | 68 | @project = @merge_request.project |
75 | - mail(to: recipient.email, subject: "gitlab | changed merge request !#{@merge_request.id} | #{@merge_request.title} | #{@project.name}") | |
69 | + mail(to: recipient(recipient_id), subject: subject("changed merge request !#{@merge_request.id}", @merge_request.title)) | |
76 | 70 | end |
77 | 71 | |
78 | 72 | def reassigned_issue_email(recipient_id, issue_id, previous_assignee_id) |
79 | - recipient = User.find(recipient_id) | |
80 | 73 | @issue = Issue.find(issue_id) |
81 | 74 | @previous_assignee ||= User.find(previous_assignee_id) |
82 | 75 | @project = @issue.project |
83 | - mail(to: recipient.email, subject: "gitlab | changed issue ##{@issue.id} | #{@issue.title} | #{@project.name}") | |
76 | + mail(to: recipient(recipient_id), subject: subject("changed issue ##{@issue.id}", @issue.title)) | |
77 | + end | |
78 | + | |
79 | + def project_access_granted_email(user_project_id) | |
80 | + @users_project = UsersProject.find user_project_id | |
81 | + @project = @users_project.project | |
82 | + mail(to: @users_project.user.email, | |
83 | + subject: subject("access to project was granted")) | |
84 | + end | |
85 | + | |
86 | + def issue_status_changed_email(recipient_id, issue_id, status, updated_by_user_id) | |
87 | + @issue = Issue.find issue_id | |
88 | + @issue_status = status | |
89 | + @updated_by = User.find updated_by_user_id | |
90 | + mail(to: recipient(recipient_id), | |
91 | + subject: subject("changed issue ##{@issue.id}", @issue.title)) | |
92 | + end | |
93 | + | |
94 | + private | |
95 | + | |
96 | + # Look up a User by their ID and return their email address | |
97 | + # | |
98 | + # recipient_id - User ID | |
99 | + # | |
100 | + # Returns a String containing the User's email address. | |
101 | + def recipient(recipient_id) | |
102 | + if recipient = User.find(recipient_id) | |
103 | + recipient.email | |
104 | + end | |
105 | + end | |
106 | + | |
107 | + # Formats arguments into a String suitable for use as an email subject | |
108 | + # | |
109 | + # extra - Extra Strings to be inserted into the subject | |
110 | + # | |
111 | + # Examples | |
112 | + # | |
113 | + # >> subject('Lorem ipsum') | |
114 | + # => "gitlab | Lorem ipsum" | |
115 | + # | |
116 | + # # Automatically inserts Project name when @project is set | |
117 | + # >> @project = Project.last | |
118 | + # => #<Project id: 1, name: "Ruby on Rails", path: "ruby_on_rails", ...> | |
119 | + # >> subject('Lorem ipsum') | |
120 | + # => "gitlab | Lorem ipsum | Ruby on Rails" | |
121 | + # | |
122 | + # # Accepts multiple arguments | |
123 | + # >> subject('Lorem ipsum', 'Dolor sit amet') | |
124 | + # => "gitlab | Lorem ipsum | Dolor sit amet" | |
125 | + def subject(*extra) | |
126 | + "gitlab | " << extra.join(' | ') << (@project ? " | #{@project.name}" : "") | |
84 | 127 | end |
85 | 128 | end | ... | ... |
app/models/key.rb
1 | 1 | require 'digest/md5' |
2 | 2 | |
3 | 3 | class Key < ActiveRecord::Base |
4 | - include SshKey | |
5 | 4 | belongs_to :user |
6 | 5 | belongs_to :project |
7 | 6 | |
7 | + attr_protected :user_id | |
8 | + | |
8 | 9 | validates :title, |
9 | 10 | presence: true, |
10 | 11 | length: { within: 0..255 } |
11 | 12 | |
12 | 13 | validates :key, |
13 | 14 | presence: true, |
15 | + format: { :with => /ssh-.{3} / }, | |
14 | 16 | length: { within: 0..5000 } |
15 | 17 | |
16 | 18 | before_save :set_identifier |
... | ... | @@ -50,6 +52,10 @@ class Key < ActiveRecord::Base |
50 | 52 | user.projects |
51 | 53 | end |
52 | 54 | end |
55 | + | |
56 | + def last_deploy? | |
57 | + Key.where(identifier: identifier).count == 0 | |
58 | + end | |
53 | 59 | end |
54 | 60 | # == Schema Information |
55 | 61 | # | ... | ... |
app/models/merge_request.rb
... | ... | @@ -88,8 +88,11 @@ class MergeRequest < ActiveRecord::Base |
88 | 88 | end |
89 | 89 | |
90 | 90 | def unmerged_diffs |
91 | - commits = project.repo.commits_between(target_branch, source_branch).map {|c| Commit.new(c)} | |
92 | - diffs = project.repo.diff(commits.first.prev_commit.id, commits.last.id) rescue [] | |
91 | + # Only show what is new in the source branch compared to the target branch, not the other way around. | |
92 | + # The linex below with merge_base is equivalent to diff with three dots (git diff branch1...branch2) | |
93 | + # From the git documentation: "git diff A...B" is equivalent to "git diff $(git-merge-base A B) B" | |
94 | + common_commit = project.repo.git.native(:merge_base, {}, [target_branch, source_branch]).strip | |
95 | + diffs = project.repo.diff(common_commit, source_branch) | |
93 | 96 | end |
94 | 97 | |
95 | 98 | def last_commit | ... | ... |
app/models/milestone.rb
... | ... | @@ -28,17 +28,9 @@ class Milestone < ActiveRecord::Base |
28 | 28 | end |
29 | 29 | |
30 | 30 | def percent_complete |
31 | - @percent_complete ||= begin | |
32 | - total_i = self.issues.count | |
33 | - closed_i = self.issues.closed.count | |
34 | - if total_i > 0 | |
35 | - (closed_i * 100) / total_i | |
36 | - else | |
37 | - 100 | |
38 | - end | |
39 | - rescue => ex | |
40 | - 0 | |
41 | - end | |
31 | + ((self.issues.closed.count * 100) / self.issues.count).abs | |
32 | + rescue ZeroDivisionError | |
33 | + 100 | |
42 | 34 | end |
43 | 35 | |
44 | 36 | def expires_at | ... | ... |
app/models/project.rb
... | ... | @@ -2,13 +2,13 @@ require "grit" |
2 | 2 | |
3 | 3 | class Project < ActiveRecord::Base |
4 | 4 | include Repository |
5 | - include ProjectPush | |
5 | + include PushObserver | |
6 | 6 | include Authority |
7 | 7 | include Team |
8 | 8 | |
9 | 9 | # |
10 | 10 | # Relations |
11 | - # | |
11 | + # | |
12 | 12 | belongs_to :owner, class_name: "User" |
13 | 13 | has_many :users, through: :users_projects |
14 | 14 | has_many :events, dependent: :destroy |
... | ... | @@ -25,12 +25,12 @@ class Project < ActiveRecord::Base |
25 | 25 | |
26 | 26 | attr_accessor :error_code |
27 | 27 | |
28 | - # | |
28 | + # | |
29 | 29 | # Protected attributes |
30 | 30 | # |
31 | 31 | attr_protected :private_flag, :owner_id |
32 | 32 | |
33 | - # | |
33 | + # | |
34 | 34 | # Scopes |
35 | 35 | # |
36 | 36 | scope :public_only, where(private_flag: false) |
... | ... | @@ -158,7 +158,7 @@ class Project < ActiveRecord::Base |
158 | 158 | end |
159 | 159 | |
160 | 160 | def last_activity |
161 | - events.last || nil | |
161 | + events.order("created_at ASC").last | |
162 | 162 | end |
163 | 163 | |
164 | 164 | def last_activity_date | ... | ... |
app/models/protected_branch.rb
1 | 1 | class ProtectedBranch < ActiveRecord::Base |
2 | + include GitHost | |
3 | + | |
2 | 4 | belongs_to :project |
3 | 5 | validates_presence_of :project_id |
4 | 6 | validates_presence_of :name |
... | ... | @@ -7,7 +9,7 @@ class ProtectedBranch < ActiveRecord::Base |
7 | 9 | after_destroy :update_repository |
8 | 10 | |
9 | 11 | def update_repository |
10 | - Gitlab::GitHost.system.update_project(project.path, project) | |
12 | + git_host.update_repository(project) | |
11 | 13 | end |
12 | 14 | |
13 | 15 | def commit | ... | ... |
app/models/user.rb
... | ... | @@ -7,7 +7,7 @@ class User < ActiveRecord::Base |
7 | 7 | |
8 | 8 | attr_accessible :email, :password, :password_confirmation, :remember_me, :bio, |
9 | 9 | :name, :projects_limit, :skype, :linkedin, :twitter, :dark_scheme, |
10 | - :theme_id, :force_random_password | |
10 | + :theme_id, :force_random_password, :extern_uid, :provider | |
11 | 11 | |
12 | 12 | attr_accessor :force_random_password |
13 | 13 | |
... | ... | @@ -54,6 +54,8 @@ class User < ActiveRecord::Base |
54 | 54 | |
55 | 55 | validates :bio, length: { within: 0..255 } |
56 | 56 | |
57 | + validates :extern_uid, :allow_blank => true, :uniqueness => {:scope => :provider} | |
58 | + | |
57 | 59 | before_save :ensure_authentication_token |
58 | 60 | alias_attribute :private_token, :authentication_token |
59 | 61 | |
... | ... | @@ -84,21 +86,31 @@ class User < ActiveRecord::Base |
84 | 86 | where('id NOT IN (SELECT DISTINCT(user_id) FROM users_projects)') |
85 | 87 | end |
86 | 88 | |
87 | - def self.find_for_ldap_auth(omniauth_info) | |
88 | - name = omniauth_info.name.force_encoding("utf-8") | |
89 | - email = omniauth_info.email.downcase unless omniauth_info.email.nil? | |
90 | - raise OmniAuth::Error, "LDAP accounts must provide an email address" if email.nil? | |
89 | + def self.find_for_ldap_auth(auth, signed_in_resource=nil) | |
90 | + uid = auth.info.uid | |
91 | + provider = auth.provider | |
92 | + name = auth.info.name.force_encoding("utf-8") | |
93 | + email = auth.info.email.downcase unless auth.info.email.nil? | |
94 | + raise OmniAuth::Error, "LDAP accounts must provide an uid and email address" if uid.nil? or email.nil? | |
91 | 95 | |
92 | - if @user = User.find_by_email(email) | |
96 | + if @user = User.find_by_extern_uid_and_provider(uid, provider) | |
97 | + @user | |
98 | + # workaround for backward compatibility | |
99 | + elsif @user = User.find_by_email(email) | |
100 | + logger.info "Updating legacy LDAP user #{email} with extern_uid => #{uid}" | |
101 | + @user.update_attributes(:extern_uid => uid, :provider => provider) | |
93 | 102 | @user |
94 | 103 | else |
104 | + logger.info "Creating user from LDAP login {uid => #{uid}, name => #{name}, email => #{email}}" | |
95 | 105 | password = Devise.friendly_token[0, 8].downcase |
96 | 106 | @user = User.create( |
97 | - name: name, | |
98 | - email: email, | |
99 | - password: password, | |
100 | - password_confirmation: password, | |
101 | - projects_limit: Gitlab.config.default_projects_limit | |
107 | + :extern_uid => uid, | |
108 | + :provider => provider, | |
109 | + :name => name, | |
110 | + :email => email, | |
111 | + :password => password, | |
112 | + :password_confirmation => password, | |
113 | + :projects_limit => Gitlab.config.default_projects_limit | |
102 | 114 | ) |
103 | 115 | end |
104 | 116 | end | ... | ... |
app/models/users_project.rb
1 | 1 | class UsersProject < ActiveRecord::Base |
2 | + include GitHost | |
3 | + | |
2 | 4 | GUEST = 10 |
3 | 5 | REPORTER = 20 |
4 | 6 | DEVELOPER = 30 |
... | ... | @@ -58,9 +60,7 @@ class UsersProject < ActiveRecord::Base |
58 | 60 | end |
59 | 61 | |
60 | 62 | def update_repository |
61 | - Gitlab::GitHost.system.new.configure do |c| | |
62 | - c.update_project(project.path, project) | |
63 | - end | |
63 | + git_host.update_repository(project) | |
64 | 64 | end |
65 | 65 | |
66 | 66 | def project_access_human | ... | ... |
app/observers/issue_observer.rb
... | ... | @@ -9,8 +9,16 @@ class IssueObserver < ActiveRecord::Observer |
9 | 9 | |
10 | 10 | def after_update(issue) |
11 | 11 | send_reassigned_email(issue) if issue.is_being_reassigned? |
12 | - Note.create_status_change_note(issue, current_user, 'closed') if issue.is_being_closed? | |
13 | - Note.create_status_change_note(issue, current_user, 'reopened') if issue.is_being_reopened? | |
12 | + | |
13 | + status = nil | |
14 | + status = 'closed' if issue.is_being_closed? | |
15 | + status = 'reopened' if issue.is_being_reopened? | |
16 | + if status | |
17 | + Note.create_status_change_note(issue, current_user, status) | |
18 | + [issue.author, issue.assignee].compact.each do |recipient| | |
19 | + Notify.issue_status_changed_email(recipient.id, issue.id, status, current_user) | |
20 | + end | |
21 | + end | |
14 | 22 | end |
15 | 23 | |
16 | 24 | protected | ... | ... |
app/observers/key_observer.rb
1 | 1 | class KeyObserver < ActiveRecord::Observer |
2 | + include GitHost | |
3 | + | |
2 | 4 | def after_save(key) |
3 | - key.update_repository | |
5 | + git_host.set_key(key.identifier, key.key, key.projects) | |
4 | 6 | end |
5 | 7 | |
6 | 8 | def after_destroy(key) |
7 | - key.repository_delete_key | |
9 | + return if key.is_deploy_key && !key.last_deploy? | |
10 | + git_host.remove_key(key.identifier, key.projects) | |
8 | 11 | end |
9 | 12 | end | ... | ... |
... | ... | @@ -0,0 +1,9 @@ |
1 | +class UsersProjectObserver < ActiveRecord::Observer | |
2 | + def after_create(users_project) | |
3 | + Notify.project_access_granted_email(users_project.id).deliver | |
4 | + end | |
5 | + | |
6 | + def after_update(users_project) | |
7 | + Notify.project_access_granted_email(users_project.id).deliver | |
8 | + end | |
9 | +end | ... | ... |
app/roles/git_merge.rb
app/roles/project_push.rb
... | ... | @@ -1,105 +0,0 @@ |
1 | -module ProjectPush | |
2 | - def observe_push(oldrev, newrev, ref, user) | |
3 | - data = post_receive_data(oldrev, newrev, ref, user) | |
4 | - | |
5 | - Event.create( | |
6 | - project: self, | |
7 | - action: Event::Pushed, | |
8 | - data: data, | |
9 | - author_id: data[:user_id] | |
10 | - ) | |
11 | - end | |
12 | - | |
13 | - def update_merge_requests(oldrev, newrev, ref, user) | |
14 | - return true unless ref =~ /heads/ | |
15 | - branch_name = ref.gsub("refs/heads/", "") | |
16 | - c_ids = self.commits_between(oldrev, newrev).map(&:id) | |
17 | - | |
18 | - # Update code for merge requests | |
19 | - mrs = self.merge_requests.opened.find_all_by_branch(branch_name).all | |
20 | - mrs.each { |merge_request| merge_request.reload_code; merge_request.mark_as_unchecked } | |
21 | - | |
22 | - # Close merge requests | |
23 | - mrs = self.merge_requests.opened.where(target_branch: branch_name).all | |
24 | - mrs = mrs.select(&:last_commit).select { |mr| c_ids.include?(mr.last_commit.id) } | |
25 | - mrs.each { |merge_request| merge_request.merge!(user.id) } | |
26 | - | |
27 | - true | |
28 | - end | |
29 | - | |
30 | - def execute_hooks(oldrev, newrev, ref, user) | |
31 | - ref_parts = ref.split('/') | |
32 | - | |
33 | - # Return if this is not a push to a branch (e.g. new commits) | |
34 | - return if ref_parts[1] !~ /heads/ || oldrev == "00000000000000000000000000000000" | |
35 | - | |
36 | - data = post_receive_data(oldrev, newrev, ref, user) | |
37 | - | |
38 | - hooks.each { |hook| hook.execute(data) } | |
39 | - end | |
40 | - | |
41 | - def post_receive_data(oldrev, newrev, ref, user) | |
42 | - | |
43 | - push_commits = commits_between(oldrev, newrev) | |
44 | - | |
45 | - # Total commits count | |
46 | - push_commits_count = push_commits.size | |
47 | - | |
48 | - # Get latest 20 commits ASC | |
49 | - push_commits_limited = push_commits.last(20) | |
50 | - | |
51 | - # Hash to be passed as post_receive_data | |
52 | - data = { | |
53 | - before: oldrev, | |
54 | - after: newrev, | |
55 | - ref: ref, | |
56 | - user_id: user.id, | |
57 | - user_name: user.name, | |
58 | - repository: { | |
59 | - name: name, | |
60 | - url: web_url, | |
61 | - description: description, | |
62 | - homepage: web_url, | |
63 | - }, | |
64 | - commits: [], | |
65 | - total_commits_count: push_commits_count | |
66 | - } | |
67 | - | |
68 | - # For perfomance purposes maximum 20 latest commits | |
69 | - # will be passed as post receive hook data. | |
70 | - # | |
71 | - push_commits_limited.each do |commit| | |
72 | - data[:commits] << { | |
73 | - id: commit.id, | |
74 | - message: commit.safe_message, | |
75 | - timestamp: commit.date.xmlschema, | |
76 | - url: "#{Gitlab.config.url}/#{code}/commits/#{commit.id}", | |
77 | - author: { | |
78 | - name: commit.author_name, | |
79 | - email: commit.author_email | |
80 | - } | |
81 | - } | |
82 | - end | |
83 | - | |
84 | - data | |
85 | - end | |
86 | - | |
87 | - | |
88 | - # This method will be called after each post receive | |
89 | - # and only if user present in gitlab. | |
90 | - # All callbacks for post receive should be placed here | |
91 | - # | |
92 | - def trigger_post_receive(oldrev, newrev, ref, user) | |
93 | - # Create push event | |
94 | - self.observe_push(oldrev, newrev, ref, user) | |
95 | - | |
96 | - # Close merged MR | |
97 | - self.update_merge_requests(oldrev, newrev, ref, user) | |
98 | - | |
99 | - # Execute web hooks | |
100 | - self.execute_hooks(oldrev, newrev, ref, user) | |
101 | - | |
102 | - # Create satellite | |
103 | - self.satellite.create unless self.satellite.exists? | |
104 | - end | |
105 | -end |
... | ... | @@ -0,0 +1,105 @@ |
1 | +module PushObserver | |
2 | + def observe_push(oldrev, newrev, ref, user) | |
3 | + data = post_receive_data(oldrev, newrev, ref, user) | |
4 | + | |
5 | + Event.create( | |
6 | + project: self, | |
7 | + action: Event::Pushed, | |
8 | + data: data, | |
9 | + author_id: data[:user_id] | |
10 | + ) | |
11 | + end | |
12 | + | |
13 | + def update_merge_requests(oldrev, newrev, ref, user) | |
14 | + return true unless ref =~ /heads/ | |
15 | + branch_name = ref.gsub("refs/heads/", "") | |
16 | + c_ids = self.commits_between(oldrev, newrev).map(&:id) | |
17 | + | |
18 | + # Update code for merge requests | |
19 | + mrs = self.merge_requests.opened.find_all_by_branch(branch_name).all | |
20 | + mrs.each { |merge_request| merge_request.reload_code; merge_request.mark_as_unchecked } | |
21 | + | |
22 | + # Close merge requests | |
23 | + mrs = self.merge_requests.opened.where(target_branch: branch_name).all | |
24 | + mrs = mrs.select(&:last_commit).select { |mr| c_ids.include?(mr.last_commit.id) } | |
25 | + mrs.each { |merge_request| merge_request.merge!(user.id) } | |
26 | + | |
27 | + true | |
28 | + end | |
29 | + | |
30 | + def execute_hooks(oldrev, newrev, ref, user) | |
31 | + ref_parts = ref.split('/') | |
32 | + | |
33 | + # Return if this is not a push to a branch (e.g. new commits) | |
34 | + return if ref_parts[1] !~ /heads/ || oldrev == "00000000000000000000000000000000" | |
35 | + | |
36 | + data = post_receive_data(oldrev, newrev, ref, user) | |
37 | + | |
38 | + hooks.each { |hook| hook.execute(data) } | |
39 | + end | |
40 | + | |
41 | + def post_receive_data(oldrev, newrev, ref, user) | |
42 | + | |
43 | + push_commits = commits_between(oldrev, newrev) | |
44 | + | |
45 | + # Total commits count | |
46 | + push_commits_count = push_commits.size | |
47 | + | |
48 | + # Get latest 20 commits ASC | |
49 | + push_commits_limited = push_commits.last(20) | |
50 | + | |
51 | + # Hash to be passed as post_receive_data | |
52 | + data = { | |
53 | + before: oldrev, | |
54 | + after: newrev, | |
55 | + ref: ref, | |
56 | + user_id: user.id, | |
57 | + user_name: user.name, | |
58 | + repository: { | |
59 | + name: name, | |
60 | + url: web_url, | |
61 | + description: description, | |
62 | + homepage: web_url, | |
63 | + }, | |
64 | + commits: [], | |
65 | + total_commits_count: push_commits_count | |
66 | + } | |
67 | + | |
68 | + # For perfomance purposes maximum 20 latest commits | |
69 | + # will be passed as post receive hook data. | |
70 | + # | |
71 | + push_commits_limited.each do |commit| | |
72 | + data[:commits] << { | |
73 | + id: commit.id, | |
74 | + message: commit.safe_message, | |
75 | + timestamp: commit.date.xmlschema, | |
76 | + url: "#{Gitlab.config.url}/#{code}/commits/#{commit.id}", | |
77 | + author: { | |
78 | + name: commit.author_name, | |
79 | + email: commit.author_email | |
80 | + } | |
81 | + } | |
82 | + end | |
83 | + | |
84 | + data | |
85 | + end | |
86 | + | |
87 | + | |
88 | + # This method will be called after each post receive | |
89 | + # and only if user present in gitlab. | |
90 | + # All callbacks for post receive should be placed here | |
91 | + # | |
92 | + def trigger_post_receive(oldrev, newrev, ref, user) | |
93 | + # Create push event | |
94 | + self.observe_push(oldrev, newrev, ref, user) | |
95 | + | |
96 | + # Close merged MR | |
97 | + self.update_merge_requests(oldrev, newrev, ref, user) | |
98 | + | |
99 | + # Execute web hooks | |
100 | + self.execute_hooks(oldrev, newrev, ref, user) | |
101 | + | |
102 | + # Create satellite | |
103 | + self.satellite.create unless self.satellite.exists? | |
104 | + end | |
105 | +end | ... | ... |
app/roles/repository.rb
1 | 1 | module Repository |
2 | + include GitHost | |
3 | + | |
2 | 4 | def valid_repo? |
3 | 5 | repo |
4 | 6 | rescue |
... | ... | @@ -30,26 +32,10 @@ module Repository |
30 | 32 | Commit.commits_between(repo, from, to) |
31 | 33 | end |
32 | 34 | |
33 | - def write_hooks | |
34 | - %w(post-receive).each do |hook| | |
35 | - write_hook(hook, File.read(File.join(Rails.root, 'lib', "#{hook}-hook"))) | |
36 | - end | |
37 | - end | |
38 | - | |
39 | 35 | def satellite |
40 | 36 | @satellite ||= Gitlab::Satellite.new(self) |
41 | 37 | end |
42 | 38 | |
43 | - def write_hook(name, content) | |
44 | - hook_file = File.join(path_to_repo, 'hooks', name) | |
45 | - | |
46 | - File.open(hook_file, 'w') do |f| | |
47 | - f.write(content) | |
48 | - end | |
49 | - | |
50 | - File.chmod(0775, hook_file) | |
51 | - end | |
52 | - | |
53 | 39 | def has_post_receive_file? |
54 | 40 | hook_file = File.join(path_to_repo, 'hooks', 'post-receive') |
55 | 41 | File.exists?(hook_file) |
... | ... | @@ -64,7 +50,7 @@ module Repository |
64 | 50 | end |
65 | 51 | |
66 | 52 | def url_to_repo |
67 | - Gitlab::GitHost.url_to_repo(path) | |
53 | + git_host.url_to_repo(path) | |
68 | 54 | end |
69 | 55 | |
70 | 56 | def path_to_repo |
... | ... | @@ -72,13 +58,11 @@ module Repository |
72 | 58 | end |
73 | 59 | |
74 | 60 | def update_repository |
75 | - Gitlab::GitHost.system.update_project(path, self) | |
76 | - | |
77 | - write_hooks if File.exists?(path_to_repo) | |
61 | + git_host.update_repository(self) | |
78 | 62 | end |
79 | 63 | |
80 | 64 | def destroy_repository |
81 | - Gitlab::GitHost.system.destroy_project(self) | |
65 | + git_host.remove_repository(self) | |
82 | 66 | end |
83 | 67 | |
84 | 68 | def repo_exists? |
... | ... | @@ -133,10 +117,13 @@ module Repository |
133 | 117 | storage_path = File.join(Rails.root, "tmp", "repositories", self.code) |
134 | 118 | file_path = File.join(storage_path, file_name) |
135 | 119 | |
120 | + # Put files into a directory before archiving | |
121 | + prefix = self.code + "/" | |
122 | + | |
136 | 123 | # Create file if not exists |
137 | 124 | unless File.exists?(file_path) |
138 | 125 | FileUtils.mkdir_p storage_path |
139 | - file = self.repo.archive_to_file(ref, nil, file_path) | |
126 | + file = self.repo.archive_to_file(ref, prefix, file_path) | |
140 | 127 | end |
141 | 128 | |
142 | 129 | file_path | ... | ... |
app/roles/ssh_key.rb
... | ... | @@ -1,18 +0,0 @@ |
1 | -module SshKey | |
2 | - def update_repository | |
3 | - Gitlab::GitHost.system.new.configure do |c| | |
4 | - c.update_keys(identifier, key) | |
5 | - c.update_projects(projects) | |
6 | - end | |
7 | - end | |
8 | - | |
9 | - def repository_delete_key | |
10 | - Gitlab::GitHost.system.new.configure do |c| | |
11 | - #delete key file is there is no identically deploy keys | |
12 | - if !is_deploy_key || Key.where(identifier: identifier).count() == 0 | |
13 | - c.delete_key(identifier) | |
14 | - end | |
15 | - c.update_projects(projects) | |
16 | - end | |
17 | - end | |
18 | -end |
app/views/admin/dashboard/index.html.haml
... | ... | @@ -35,11 +35,13 @@ |
35 | 35 | %h3 Latest projects |
36 | 36 | %hr |
37 | 37 | - @projects.each do |project| |
38 | - %h5 | |
38 | + %p | |
39 | 39 | = link_to project.name, [:admin, project] |
40 | 40 | .span6 |
41 | 41 | %h3 Latest users |
42 | 42 | %hr |
43 | 43 | - @users.each do |user| |
44 | - %h5 | |
45 | - = link_to user.name, [:admin, user] | |
44 | + %p | |
45 | + = link_to [:admin, user] do | |
46 | + = user.name | |
47 | + %small= user.email | ... | ... |
app/views/admin/hooks/index.html.haml
... | ... | @@ -5,7 +5,7 @@ |
5 | 5 | Read more about system hooks |
6 | 6 | %strong #{link_to "here", help_system_hooks_path, class: "vlink"} |
7 | 7 | |
8 | -= form_for @hook, as: :hook, url: admin_hooks_path do |f| | |
8 | += form_for @hook, as: :hook, url: admin_hooks_path, html: { class: 'form-inline' } do |f| | |
9 | 9 | -if @hook.errors.any? |
10 | 10 | .alert-message.block-message.error |
11 | 11 | - @hook.errors.full_messages.each do |msg| | ... | ... |
app/views/admin/projects/_form.html.haml
... | ... | @@ -10,19 +10,17 @@ |
10 | 10 | Project name is |
11 | 11 | .input |
12 | 12 | = f.text_field :name, placeholder: "Example Project", class: "xxlarge" |
13 | - = f.submit project.new_record? ? 'Create project' : 'Save Project', class: "btn primary" | |
14 | 13 | |
15 | 14 | %hr |
16 | - .alert.alert-info | |
17 | - %h5 Advanced settings: | |
15 | + .adv_settings | |
16 | + %h6 Advanced settings: | |
18 | 17 | .clearfix |
19 | 18 | = f.label :path do |
20 | - Git Clone | |
19 | + Path | |
21 | 20 | .input |
22 | 21 | .input-prepend |
23 | - %span.add-on= Gitlab.config.ssh_path | |
24 | - = f.text_field :path, placeholder: "example_project", disabled: !!project.id | |
25 | - %span.add-on= ".git" | |
22 | + %strong | |
23 | + = text_field_tag :ppath, @admin_project.path_to_repo, class: "xlarge", disabled: true | |
26 | 24 | .clearfix |
27 | 25 | = f.label :code do |
28 | 26 | URL |
... | ... | @@ -42,8 +40,9 @@ |
42 | 40 | .input= f.select(:default_branch, project.heads.map(&:name), {}, style: "width:210px;") |
43 | 41 | |
44 | 42 | - unless project.new_record? |
45 | - .alert.alert-info | |
46 | - %h5 Features: | |
43 | + %hr | |
44 | + .adv_settings | |
45 | + %h6 Features: | |
47 | 46 | |
48 | 47 | .clearfix |
49 | 48 | = f.label :issues_enabled, "Issues" |
... | ... | @@ -63,7 +62,8 @@ |
63 | 62 | |
64 | 63 | - unless project.new_record? |
65 | 64 | .actions |
66 | - = f.submit 'Save Project', class: "btn primary" | |
65 | + = f.submit 'Save Project', class: "btn save-btn" | |
66 | + = link_to 'Cancel', admin_projects_path, class: "btn cancel-btn" | |
67 | 67 | |
68 | 68 | |
69 | 69 | ... | ... |
... | ... | @@ -0,0 +1,29 @@ |
1 | += form_for [:admin, @admin_project] do |f| | |
2 | + - if @admin_project.errors.any? | |
3 | + .alert-message.block-message.error | |
4 | + %span= @admin_project.errors.full_messages.first | |
5 | + .clearfix.project_name_holder | |
6 | + = f.label :name do | |
7 | + Project name is | |
8 | + .input | |
9 | + = f.text_field :name, placeholder: "Example Project", class: "xxlarge" | |
10 | + = f.submit 'Create project', class: "btn primary project-submit" | |
11 | + | |
12 | + %hr | |
13 | + %div.adv_settings | |
14 | + %h6 Advanced settings: | |
15 | + .clearfix | |
16 | + = f.label :path do | |
17 | + Git Clone | |
18 | + .input | |
19 | + .input-prepend | |
20 | + %span.add-on= Gitlab.config.ssh_path | |
21 | + = f.text_field :path, placeholder: "example_project", disabled: !@admin_project.new_record? | |
22 | + %span.add-on= ".git" | |
23 | + .clearfix | |
24 | + = f.label :code do | |
25 | + URL | |
26 | + .input | |
27 | + .input-prepend | |
28 | + %span.add-on= web_app_url | |
29 | + = f.text_field :code, placeholder: "example" | ... | ... |
app/views/admin/projects/index.html.haml
1 | -%h3 | |
1 | +%h3.page_title | |
2 | 2 | Projects |
3 | 3 | = link_to 'New Project', new_admin_project_path, class: "btn small right" |
4 | 4 | %br |
5 | -= form_tag admin_projects_path, method: :get do | |
5 | += form_tag admin_projects_path, method: :get, class: 'form-inline' do | |
6 | 6 | = text_field_tag :name, params[:name], class: "xlarge" |
7 | 7 | = submit_tag "Search", class: "btn submit primary" |
8 | 8 | ... | ... |
app/views/admin/projects/new.html.haml
1 | -%h3.page_title New project | |
2 | -%hr | |
3 | -= render 'form', project: @admin_project | |
1 | +.project_new_holder | |
2 | + %h3.page_title | |
3 | + New Project | |
4 | + %hr | |
5 | + = render 'new_form' | |
6 | +%div.save-project-loader.hide | |
7 | + %center | |
8 | + = image_tag "ajax_loader.gif" | |
9 | + %h3 Creating project & repository. Please wait a few minutes | |
10 | + | |
11 | +:javascript | |
12 | + $(function(){ new Projects(); }); | ... | ... |
app/views/admin/users/_form.html.haml
... | ... | @@ -2,71 +2,79 @@ |
2 | 2 | = form_for [:admin, @admin_user] do |f| |
3 | 3 | -if @admin_user.errors.any? |
4 | 4 | #error_explanation |
5 | - %ul | |
5 | + %ul.unstyled.alert.alert-error | |
6 | 6 | - @admin_user.errors.full_messages.each do |msg| |
7 | 7 | %li= msg |
8 | 8 | |
9 | 9 | .row |
10 | - .span6 | |
11 | - .clearfix | |
12 | - = f.label :name | |
13 | - .input | |
14 | - = f.text_field :name | |
15 | - %span.help-inline * required | |
16 | - .clearfix | |
17 | - = f.label :email | |
18 | - .input | |
19 | - = f.text_field :email | |
20 | - %span.help-inline * required | |
21 | - %hr | |
22 | - | |
23 | - -if f.object.new_record? | |
24 | - .clearfix | |
25 | - = f.label :admin, class: "checkbox" do | |
26 | - = f.check_box :force_random_password, {}, true, nil | |
27 | - %span Generate random password | |
28 | - | |
29 | - %div.password-fields | |
10 | + .span7 | |
11 | + .ui-box | |
12 | + %br | |
30 | 13 | .clearfix |
31 | - = f.label :password | |
32 | - .input= f.password_field :password, disabled: f.object.force_random_password | |
14 | + = f.label :name | |
15 | + .input | |
16 | + = f.text_field :name | |
17 | + %span.help-inline * required | |
33 | 18 | .clearfix |
34 | - = f.label :password_confirmation | |
35 | - .input= f.password_field :password_confirmation, disabled: f.object.force_random_password | |
36 | - %hr | |
37 | - .clearfix | |
38 | - = f.label :skype | |
39 | - .input= f.text_field :skype | |
40 | - .clearfix | |
41 | - = f.label :linkedin | |
42 | - .input= f.text_field :linkedin | |
43 | - .clearfix | |
44 | - = f.label :twitter | |
45 | - .input= f.text_field :twitter | |
46 | - .span6 | |
47 | - .clearfix | |
48 | - = f.label :projects_limit | |
49 | - .input= f.text_field :projects_limit, class: "small_input" | |
19 | + = f.label :email | |
20 | + .input | |
21 | + = f.text_field :email | |
22 | + %span.help-inline * required | |
23 | + %hr | |
24 | + -if f.object.new_record? | |
25 | + .clearfix | |
26 | + = f.label :force_random_password do | |
27 | + %span Generate random password | |
28 | + .input= f.check_box :force_random_password, {}, true, nil | |
29 | + | |
30 | + %div.password-fields | |
31 | + .clearfix | |
32 | + = f.label :password | |
33 | + .input= f.password_field :password, disabled: f.object.force_random_password | |
34 | + .clearfix | |
35 | + = f.label :password_confirmation | |
36 | + .input= f.password_field :password_confirmation, disabled: f.object.force_random_password | |
37 | + %hr | |
38 | + .clearfix | |
39 | + = f.label :skype | |
40 | + .input= f.text_field :skype | |
41 | + .clearfix | |
42 | + = f.label :linkedin | |
43 | + .input= f.text_field :linkedin | |
44 | + .clearfix | |
45 | + = f.label :twitter | |
46 | + .input= f.text_field :twitter | |
47 | + .span5 | |
48 | + .ui-box | |
49 | + %br | |
50 | + .clearfix | |
51 | + = f.label :projects_limit | |
52 | + .input= f.number_field :projects_limit | |
50 | 53 | |
51 | - .alert | |
52 | 54 | .clearfix |
53 | - %p Make the user a GitLab administrator. | |
54 | - = f.label :admin, class: "checkbox" do | |
55 | - = f.check_box :admin | |
56 | - %span Administrator | |
57 | - - unless @admin_user.new_record? | |
58 | - .alert.alert-error | |
59 | - - if @admin_user.blocked | |
60 | - %span | |
61 | - = link_to 'Unblock', unblock_admin_user_path(@admin_user), method: :put, class: "btn small" | |
62 | - This user is blocked and is not able to login to GitLab | |
63 | - - else | |
64 | - %span | |
65 | - = link_to 'Block', block_admin_user_path(@admin_user), confirm: 'USER WILL BE BLOCKED! Are you sure?', method: :put, class: "btn small danger" | |
66 | - Blocked users will be removed from all projects & will not be able to login to GitLab. | |
55 | + = f.label :admin do | |
56 | + %strong.cred Administrator | |
57 | + .input= f.check_box :admin | |
58 | + - unless @admin_user.new_record? | |
59 | + %hr | |
60 | + .padded.cred | |
61 | + - if @admin_user.blocked | |
62 | + %span | |
63 | + This user is blocked and is not able to login to GitLab | |
64 | + .clearfix | |
65 | + = link_to 'Unblock User', unblock_admin_user_path(@admin_user), method: :put, class: "btn small right" | |
66 | + - else | |
67 | + %span | |
68 | + Blocked users will be removed from all projects & will not be able to login to GitLab. | |
69 | + .clearfix | |
70 | + = link_to 'Block User', block_admin_user_path(@admin_user), confirm: 'USER WILL BE BLOCKED! Are you sure?', method: :put, class: "btn small right danger" | |
71 | + | |
72 | + .row | |
73 | + .span6 | |
74 | + .span6 | |
67 | 75 | .actions |
68 | - = f.submit 'Save', class: "btn primary" | |
76 | + = f.submit 'Save', class: "btn save-btn" | |
69 | 77 | - if @admin_user.new_record? |
70 | - = link_to 'Cancel', admin_users_path, class: "btn" | |
78 | + = link_to 'Cancel', admin_users_path, class: "btn cancel-btn" | |
71 | 79 | - else |
72 | - = link_to 'Cancel', admin_user_path(@admin_user), class: "btn" | |
80 | + = link_to 'Cancel', admin_user_path(@admin_user), class: "btn cancel-btn" | ... | ... |
app/views/admin/users/edit.html.haml
app/views/admin/users/index.html.haml
1 | -%h3 | |
1 | +%h3.page_title | |
2 | 2 | Users |
3 | 3 | = link_to 'New User', new_admin_user_path, class: "btn small right" |
4 | 4 | %br |
5 | 5 | |
6 | -= form_tag admin_users_path, method: :get do | |
6 | += form_tag admin_users_path, method: :get, class: 'form-inline' do | |
7 | 7 | = text_field_tag :name, params[:name], class: "xlarge" |
8 | 8 | = submit_tag "Search", class: "btn submit primary" |
9 | 9 | %ul.nav.nav-pills | ... | ... |
app/views/admin/users/new.html.haml
app/views/commits/_commit.html.haml
... | ... | @@ -4,8 +4,8 @@ |
4 | 4 | %strong= link_to "Browse Code »", tree_project_ref_path(@project, commit.id), class: "right" |
5 | 5 | %p |
6 | 6 | = link_to commit.short_id(8), project_commit_path(@project, id: commit.id), class: "commit_short_id" |
7 | - %strong.cgray= commit.author_name | |
8 | - – | |
7 | + %strong.commit-author-name= commit.author_name | |
8 | + %span.dash – | |
9 | 9 | = image_tag gravatar_icon(commit.author_email), class: "avatar", width: 16 |
10 | 10 | = link_to_gfm truncate(commit.title, length: 50), project_commit_path(@project, id: commit.id), class: "row_title" |
11 | 11 | ... | ... |
app/views/commits/compare.html.haml
app/views/commits/show.html.haml
... | ... | @@ -5,12 +5,6 @@ |
5 | 5 | |
6 | 6 | |
7 | 7 | :javascript |
8 | - $(document).ready(function(){ | |
9 | - $(".line_note_link, .line_note_reply_link").live("click", function(e) { | |
10 | - var form = $(".per_line_form"); | |
11 | - $(this).parent().parent().after(form); | |
12 | - form.find("#note_line_code").val($(this).attr("line_code")); | |
13 | - form.show(); | |
14 | - return false; | |
15 | - }); | |
8 | + $(function(){ | |
9 | + PerLineNotes.init(); | |
16 | 10 | }); | ... | ... |
app/views/dashboard/index.html.haml
1 | 1 | - if @projects.any? |
2 | 2 | .projects |
3 | 3 | .activities.span8 |
4 | - - if current_user.require_ssh_key? | |
5 | - .alert.alert-error.padded | |
6 | - %span | |
7 | - You wont be able to pull/push project code unless you | |
8 | - %strong | |
9 | - = link_to new_key_path, class: "vlink" do | |
10 | - add new key | |
11 | - to your profile | |
4 | + = render 'shared/no_ssh' | |
12 | 5 | - if @events.any? |
13 | 6 | .content_list= render @events |
14 | 7 | - else |
... | ... | @@ -26,13 +19,16 @@ |
26 | 19 | = link_to new_project_path, class: "btn very_small info" do |
27 | 20 | %i.icon-plus |
28 | 21 | New Project |
29 | - - @projects.each do |project| | |
30 | - = link_to project_path(project), class: dom_class(project) do | |
31 | - %h4 | |
32 | - %span.ico.project | |
33 | - = truncate(project.name, length: 25) | |
34 | - %span.right | |
35 | - → | |
22 | + %ul.unstyled | |
23 | + - @projects.each do |project| | |
24 | + %li.wll | |
25 | + = link_to project_path(project), class: dom_class(project) do | |
26 | + %strong.project_name= truncate(project.name, length: 25) | |
27 | + %span.arrow | |
28 | + → | |
29 | + %span.last_activity | |
30 | + %strong Last activity: | |
31 | + %span= project_last_activity(project) | |
36 | 32 | .bottom= paginate @projects, theme: "gitlab" |
37 | 33 | |
38 | 34 | %hr |
... | ... | @@ -57,5 +53,5 @@ |
57 | 53 | If you will be added to project - it will be displayed here |
58 | 54 | |
59 | 55 | |
60 | -:javascript | |
56 | +:javascript | |
61 | 57 | $(function(){ Pager.init(20); }); | ... | ... |
app/views/errors/gitolite.html.haml
... | ... | @@ -21,7 +21,5 @@ |
21 | 21 | Permissions: |
22 | 22 | %pre |
23 | 23 | = preserve do |
24 | - sudo chmod -R 770 /home/git/repositories/ | |
25 | - sudo chown -R git:git /home/git/repositories/ | |
26 | - sudo chown gitlab:gitlab /home/git/repositories/**/hooks/post-receive | |
27 | - | |
24 | + sudo chmod -R 770 #{Gitlab.config.git_base_path} | |
25 | + sudo chown -R git:git #{Gitlab.config.git_base_path} | ... | ... |
app/views/events/_event_last_push.html.haml
... | ... | @@ -9,5 +9,5 @@ |
9 | 9 | at |
10 | 10 | %strong= link_to event.project.name, event.project |
11 | 11 | |
12 | - = link_to new_mr_path_from_push_event(event), title: "New Merge Request", class: "btn very_small primary" do | |
12 | + = link_to new_mr_path_from_push_event(event), title: "New Merge Request", class: "btn very_small" do | |
13 | 13 | Create Merge Request | ... | ... |
app/views/help/api.html.haml
... | ... | @@ -10,6 +10,8 @@ |
10 | 10 | %li |
11 | 11 | %a{href: "#projects"} Projects |
12 | 12 | %li |
13 | + %a{href: "#snippets"} Snippets | |
14 | + %li | |
13 | 15 | %a{href: "#users"} Users |
14 | 16 | %li |
15 | 17 | %a{href: "#issues"} Issues |
... | ... | @@ -34,6 +36,16 @@ |
34 | 36 | |
35 | 37 | %br |
36 | 38 | |
39 | +.file_holder#snippets | |
40 | + .file_title | |
41 | + %i.icon-file | |
42 | + Projects Snippets | |
43 | + .file_content.wiki | |
44 | + = preserve do | |
45 | + = markdown File.read(Rails.root.join("doc", "api", "snippets.md")) | |
46 | + | |
47 | +%br | |
48 | + | |
37 | 49 | .file_holder#users |
38 | 50 | .file_title |
39 | 51 | %i.icon-file |
... | ... | @@ -51,3 +63,13 @@ |
51 | 63 | .file_content.wiki |
52 | 64 | = preserve do |
53 | 65 | = markdown File.read(Rails.root.join("doc", "api", "issues.md")) |
66 | + | |
67 | +%br | |
68 | + | |
69 | +.file_holder#milestones | |
70 | + .file_title | |
71 | + %i.icon-file | |
72 | + Milestones | |
73 | + .file_content.wiki | |
74 | + = preserve do | |
75 | + = markdown File.read(Rails.root.join("doc", "api", "milestones.md")) | ... | ... |
app/views/help/index.html.haml
app/views/help/markdown.html.haml
1 | -- bash_lexer = Pygments::Lexer[:bash] | |
2 | -%h3.page_title Gitlab Markdown | |
1 | +%h3.page_title Gitlab Flavored Markdown | |
3 | 2 | .back_link |
4 | 3 | = link_to help_path do |
5 | 4 | ← to index |
6 | 5 | %hr |
7 | 6 | |
8 | -%p.slead We extend Markdown with some GITLAB specific syntax. It allows you to link to: | |
7 | +.row | |
8 | + .span8 | |
9 | + %p | |
10 | + For Gitlab we developed something we call "Gitlab Flavored Markdown" (GFM). | |
11 | + It extends the standard Markdown in a few significant ways adds some useful functionality. | |
9 | 12 | |
10 | -%ul | |
11 | - %li issues (#123) | |
12 | - %li merge request (!123) | |
13 | - %li commits (1234567) | |
14 | - %li team members (@foo) | |
15 | - %li snippets ($123) | |
13 | + %p You can use GFM in: | |
14 | + %ul | |
15 | + %li commit messages | |
16 | + %li comments | |
17 | + %li wall posts | |
18 | + %li issues | |
19 | + %li merge requests | |
20 | + %li milestones | |
21 | + %li wiki pages | |
16 | 22 | |
17 | -%p.slead in | |
23 | + %h3 Differences from traditional Markdown | |
18 | 24 | |
19 | -%ul | |
20 | - %li commit messages | |
21 | - %li notes/comments/wall posts | |
22 | - %li issues | |
23 | - %li merge requests | |
24 | - %li milestones | |
25 | - %li wiki pages | |
25 | + %h4 Newlines | |
26 | + | |
27 | + %p | |
28 | + The biggest difference that GFM introduces is in the handling of linebreaks. | |
29 | + With traditional Markdown you can hard wrap paragraphs of text and they will be combined into a single paragraph. We find this to be the cause of a huge number of unintentional formatting errors. | |
30 | + GFM treats newlines in paragraph-like content as real line breaks, which is probably what you intended. | |
31 | + | |
32 | + | |
33 | + %p The next paragraph contains two phrases separated by a single newline character: | |
34 | + %pre= "Roses are red\nViolets are blue" | |
35 | + %p becomes | |
36 | + = markdown "Roses are red\nViolets are blue" | |
37 | + | |
38 | + %h4 Multiple underscores in words | |
39 | + | |
40 | + %p | |
41 | + It is not reasonable to italicize just <em>part</em> of a word, especially when you're dealing with code and names often appear with multiple underscores. | |
42 | + Therefore, GFM ignores multiple underscores in words. | |
43 | + | |
44 | + %pre= "perform_complicated_task\ndo_this_and_do_that_and_another_thing" | |
45 | + %p becomes | |
46 | + = markdown "perform_complicated_task\ndo_this_and_do_that_and_another_thing" | |
47 | + | |
48 | + %h4 URL autolinking | |
49 | + | |
50 | + %p | |
51 | + GFM will autolink standard URLs you copy and paste into your text. | |
52 | + So if you want to link to a URL (instead of a textual link), you can simply put the URL in verbatim and it will be turned into a link to that URL. | |
53 | + | |
54 | + %h4 Fenced code blocks | |
55 | + | |
56 | + %p | |
57 | + Markdown converts text with four spaces at the front of each line to code blocks. | |
58 | + GFM supports that, but we also support fenced blocks. | |
59 | + Just wrap your code blocks in <code>```</code> and you won't need to indent manually to trigger a code block. | |
60 | + | |
61 | + %pre= %Q{```ruby\nrequire 'redcarpet'\nmarkdown = Redcarpet.new("Hello World!")\nputs markdown.to_html\n```} | |
62 | + %p becomes | |
63 | + = markdown %Q{```ruby\nrequire 'redcarpet'\nmarkdown = Redcarpet.new("Hello World!")\nputs markdown.to_html\n```} | |
64 | + | |
65 | + %h4 Special Gitlab references | |
66 | + | |
67 | + %p | |
68 | + GFM recognizes special references. | |
69 | + You can easily reference e.g. a team member, an issue or a commit within a project. | |
70 | + GFM will turn that reference into a link so you can navigate between them easily. | |
71 | + | |
72 | + %p GFM will recognize the following references: | |
73 | + %ul | |
74 | + %li | |
75 | + %code @foo | |
76 | + for team members | |
77 | + %li | |
78 | + %code #123 | |
79 | + for issues | |
80 | + %li | |
81 | + %code !123 | |
82 | + for merge request | |
83 | + %li | |
84 | + %code $123 | |
85 | + for snippets | |
86 | + %li | |
87 | + %code 1234567 | |
88 | + for commits | |
89 | + | |
90 | + -# this example will only be shown if the user has a project with at least one issue | |
91 | + - if @project = current_user.projects.first | |
92 | + - if issue = @project.issues.first | |
93 | + %p For example in your #{link_to @project.name, project_path(@project)} project something like | |
94 | + %pre= "This is related to ##{issue.id}. @#{current_user.name} is working on solving it." | |
95 | + %p becomes | |
96 | + = markdown "This is related to ##{issue.id}. @#{current_user.name} is working on solving it." | |
97 | + | |
98 | + | |
99 | + | |
100 | + .span4.right | |
101 | + .alert.alert-info | |
102 | + %p | |
103 | + If you're not already familiar with Markdown, you should spend 15 minutes and go over the excellent | |
104 | + %strong= link_to "Markdown Syntax Guide", "http://daringfireball.net/projects/markdown/syntax" | |
105 | + at Daring Fireball. | ... | ... |
app/views/help/permissions.html.haml
... | ... | @@ -0,0 +1,25 @@ |
1 | +%h3.page_title SSH Keys | |
2 | +.back_link | |
3 | + = link_to help_path do | |
4 | + ← to index | |
5 | +%hr | |
6 | + | |
7 | +%p.slead | |
8 | + SSH key allows you to establish a secure connection between your computer and Gitlab | |
9 | + | |
10 | +%p.slead | |
11 | + To generate a new SSH key just open your terminal and use code below. | |
12 | + | |
13 | +%pre.dark | |
14 | + ssh-keygen -t rsa -C "#{current_user.email}" | |
15 | + | |
16 | + \# Creates a new ssh key using the provided email | |
17 | + \# Generating public/private rsa key pair... | |
18 | + | |
19 | +%p.slead | |
20 | + Next just use code below to dump your public key and add to GITLAB SSH Keys | |
21 | + | |
22 | +%pre.dark | |
23 | + cat ~/.ssh/id_rsa.pub | |
24 | + | |
25 | + \# ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC6eNtGpNGwstc.... | ... | ... |
app/views/help/system_hooks.html.haml
1 | 1 | %h3 System hooks |
2 | 2 | .back_link |
3 | - = link_to :back do | |
3 | + = link_to :back do | |
4 | 4 | ← back |
5 | 5 | %hr |
6 | 6 | |
7 | -%p.slead | |
7 | +%p.slead | |
8 | 8 | Your Gitlab instance can perform HTTP POST request on next event: create_project, delete_project, create_user, delete_user, change_team_member. |
9 | 9 | %br |
10 | 10 | System Hooks can be used for logging or change information in LDAP server. | ... | ... |
app/views/help/web_hooks.html.haml
1 | -%h3 Web hooks | |
1 | +%h3.page_title Web hooks | |
2 | 2 | .back_link |
3 | - = link_to help_path do | |
3 | + = link_to help_path do | |
4 | 4 | ← to index |
5 | 5 | %hr |
6 | 6 | |
7 | -%p.slead | |
8 | - Every Gitlab project can trigger a web server whenever the repo is pushed to. | |
7 | +%p.slead | |
8 | + Every Gitlab project can trigger a web server whenever the repo is pushed to. | |
9 | 9 | %br |
10 | 10 | Web Hooks can be used to update an external issue tracker, trigger CI builds, update a backup mirror, or even deploy to your production server. |
11 | 11 | %br | ... | ... |
app/views/help/workflow.html.haml
1 | -- bash_lexer = Pygments::Lexer[:bash] | |
2 | -%h3 Workflow | |
1 | +%h3.page_title Workflow | |
3 | 2 | .back_link |
4 | - = link_to help_path do | |
3 | + = link_to help_path do | |
5 | 4 | ← to index |
6 | 5 | %hr |
7 | 6 | |
... | ... | @@ -9,25 +8,25 @@ |
9 | 8 | %li |
10 | 9 | %p Clone project |
11 | 10 | .bash |
12 | - %pre | |
11 | + %pre.dark | |
13 | 12 | git clone git@example.com:project-name.git |
14 | 13 | |
15 | 14 | %li |
16 | 15 | %p Create branch with your feature |
17 | 16 | .bash |
18 | - %pre | |
17 | + %pre.dark | |
19 | 18 | git checkout -b $feature_name |
20 | 19 | |
21 | 20 | %li |
22 | 21 | %p Write code. Commit changes |
23 | 22 | .bash |
24 | - %pre | |
23 | + %pre.dark | |
25 | 24 | git commit -am "My feature is ready" |
26 | 25 | |
27 | 26 | %li |
28 | 27 | %p Push your branch to gitlabhq |
29 | 28 | .bash |
30 | - %pre | |
29 | + %pre.dark | |
31 | 30 | git push origin $feature_name |
32 | 31 | |
33 | 32 | %li | ... | ... |
app/views/hooks/_data_ex.html.erb
app/views/hooks/index.html.haml
... | ... | @@ -8,7 +8,7 @@ |
8 | 8 | Read more about web hooks |
9 | 9 | %strong #{link_to "here", help_web_hooks_path, class: "vlink"} |
10 | 10 | |
11 | -= form_for [@project, @hook], as: :hook, url: project_hooks_path(@project) do |f| | |
11 | += form_for [@project, @hook], as: :hook, url: project_hooks_path(@project), html: { class: 'form-inline' } do |f| | |
12 | 12 | -if @hook.errors.any? |
13 | 13 | .alert-message.block-message.error |
14 | 14 | - @hook.errors.full_messages.each do |msg| | ... | ... |
app/views/issues/_form.html.haml
... | ... | @@ -38,19 +38,20 @@ |
38 | 38 | = f.label :description, "Details" |
39 | 39 | .input |
40 | 40 | = f.text_area :description, maxlength: 2000, class: "xxlarge", rows: 14 |
41 | - %p.hint Markdown is enabled. | |
41 | + %p.hint Issues are parsed with #{link_to "Gitlab Flavored Markdown", help_markdown_path, target: '_blank'}. | |
42 | 42 | |
43 | 43 | |
44 | 44 | .actions |
45 | 45 | - if @issue.new_record? |
46 | - = f.submit 'Submit new issue', class: "primary btn" | |
46 | + = f.submit 'Submit new issue', class: "btn save-btn" | |
47 | 47 | -else |
48 | - = f.submit 'Save changes', class: "primary btn" | |
48 | + = f.submit 'Save changes', class: "save-btn btn" | |
49 | 49 | |
50 | + - cancel_class = 'btn cancel-btn' | |
50 | 51 | - if request.xhr? |
51 | - = link_to "Cancel", "#back", onclick: "backToIssues();", class: "btn" | |
52 | + = link_to "Cancel", "#back", onclick: "backToIssues();", class: cancel_class | |
52 | 53 | - else |
53 | 54 | - if @issue.new_record? |
54 | - = link_to "Cancel", project_issues_path(@project), class: "btn" | |
55 | + = link_to "Cancel", project_issues_path(@project), class: cancel_class | |
55 | 56 | - else |
56 | - = link_to "Cancel", project_issue_path(@project, @issue), class: "btn" | |
57 | + = link_to "Cancel", project_issue_path(@project, @issue), class: cancel_class | ... | ... |
app/views/issues/_head.html.haml
... | ... | @@ -5,6 +5,9 @@ |
5 | 5 | %li{class: "#{'active' if current_page?(project_milestones_path(@project))}"} |
6 | 6 | = link_to project_milestones_path(@project), class: "tab" do |
7 | 7 | Milestones |
8 | + %li{class: "#{'active' if current_page?(project_labels_path(@project))}"} | |
9 | + = link_to project_labels_path(@project), class: "tab" do | |
10 | + Labels | |
8 | 11 | %li.right |
9 | 12 | %span.rss-icon |
10 | 13 | = link_to project_issues_path(@project, :atom, { private_token: current_user.private_token }) do | ... | ... |
app/views/issues/index.html.haml
... | ... | @@ -6,7 +6,7 @@ |
6 | 6 | .right |
7 | 7 | .span5 |
8 | 8 | - if can? current_user, :write_issue, @project |
9 | - = link_to new_project_issue_path(@project), class: "right btn small", title: "New Issue", remote: true do | |
9 | + = link_to new_project_issue_path(@project), class: "right btn", title: "New Issue", remote: true do | |
10 | 10 | %i.icon-plus |
11 | 11 | New Issue |
12 | 12 | = form_tag search_project_issues_path(@project), method: :get, remote: true, id: "issue_search_form", class: :right do | ... | ... |
app/views/keys/_form.html.haml
... | ... | @@ -11,8 +11,14 @@ |
11 | 11 | .input= f.text_field :title |
12 | 12 | .clearfix |
13 | 13 | = f.label :key |
14 | - .input= f.text_area :key, class: [:xxlarge, :thin_area] | |
14 | + .input | |
15 | + = f.text_area :key, class: [:xxlarge, :thin_area] | |
16 | + %p.hint | |
17 | + Paste your public key here. Read more about how generate it | |
18 | + = link_to "here", help_ssh_path | |
19 | + | |
20 | + | |
15 | 21 | .actions |
16 | - = f.submit 'Save', class: "primary btn" | |
17 | - = link_to "Cancel", keys_path, class: "btn" | |
22 | + = f.submit 'Save', class: "btn save-btn" | |
23 | + = link_to "Cancel", keys_path, class: "btn cancel-btn" | |
18 | 24 | ... | ... |
app/views/keys/index.html.haml
app/views/keys/new.html.haml
... | ... | @@ -0,0 +1,14 @@ |
1 | += render "issues/head" | |
2 | + | |
3 | +%h3.page_title | |
4 | + Labels | |
5 | +%br | |
6 | +%div.ui-box | |
7 | + %ul.unstyled.labels-table | |
8 | + - @labels.each do |label| | |
9 | + = render 'label', label: label | |
10 | + | |
11 | + - unless @labels.present? | |
12 | + %li | |
13 | + %h3.nothing_here_message Nothing to show here | |
14 | + | ... | ... |
app/views/merge_requests/_form.html.haml
... | ... | @@ -9,7 +9,7 @@ |
9 | 9 | %br |
10 | 10 | |
11 | 11 | .row |
12 | - .span6 | |
12 | + .span5 | |
13 | 13 | .mr_branch_box |
14 | 14 | %h5 From (Head Branch) |
15 | 15 | .body |
... | ... | @@ -17,10 +17,11 @@ |
17 | 17 | = f.label :source_branch, "From", class: "control-label" |
18 | 18 | .controls |
19 | 19 | = f.select(:source_branch, @project.heads.map(&:name), { include_blank: "Select branch" }, style: "width:250px") |
20 | - .bottom_commit | |
21 | - .mr_source_commit | |
20 | + .mr_source_commit | |
22 | 21 | |
23 | - .span6 | |
22 | + .span2 | |
23 | + %center= image_tag "merge.png", class: 'mr_direction_tip' | |
24 | + .span5 | |
24 | 25 | .mr_branch_box |
25 | 26 | %h5 To (Base Branch) |
26 | 27 | .body |
... | ... | @@ -28,8 +29,7 @@ |
28 | 29 | = f.label :target_branch, "To", class: "control-label" |
29 | 30 | .controls |
30 | 31 | = f.select(:target_branch, @project.heads.map(&:name), { include_blank: "Select branch" }, style: "width:250px") |
31 | - .bottom_commit | |
32 | - .mr_target_commit | |
32 | + .mr_target_commit | |
33 | 33 | |
34 | 34 | %h4.cdark 2. Fill info |
35 | 35 | |
... | ... | @@ -48,18 +48,19 @@ |
48 | 48 | .control-group |
49 | 49 | |
50 | 50 | .form-actions |
51 | - = f.submit 'Save', class: "btn-primary btn" | |
51 | + = f.submit 'Save', class: "btn save-btn" | |
52 | 52 | - if @merge_request.new_record? |
53 | - = link_to project_merge_requests_path(@project), class: "btn" do | |
53 | + = link_to project_merge_requests_path(@project), class: "btn cancel-btn" do | |
54 | 54 | Cancel |
55 | 55 | - else |
56 | - = link_to project_merge_request_path(@project, @merge_request), class: "btn" do | |
56 | + = link_to project_merge_request_path(@project, @merge_request), class: "btn cancel-btn" do | |
57 | 57 | Cancel |
58 | 58 | |
59 | 59 | |
60 | 60 | |
61 | 61 | :javascript |
62 | 62 | $(function(){ |
63 | + disableButtonIfEmtpyField("#merge_request_title", ".save-btn"); | |
63 | 64 | $('select#merge_request_assignee_id').chosen(); |
64 | 65 | $('select#merge_request_source_branch').chosen(); |
65 | 66 | $('select#merge_request_target_branch').chosen(); | ... | ... |
app/views/merge_requests/index.html.haml
1 | 1 | %h3.page_title |
2 | 2 | Merge Requests |
3 | 3 | - if can? current_user, :write_issue, @project |
4 | - = link_to new_project_merge_request_path(@project), class: "right btn small", title: "New Merge Request" do | |
4 | + = link_to new_project_merge_request_path(@project), class: "right btn", title: "New Merge Request" do | |
5 | 5 | New Merge Request |
6 | 6 | |
7 | 7 | %br |
... | ... | @@ -10,17 +10,17 @@ |
10 | 10 | .ui-box |
11 | 11 | .title |
12 | 12 | %ul.nav.nav-pills |
13 | - %li{class: ("active" if (params[:f] == "0" || !params[:f]))} | |
14 | - = link_to project_merge_requests_path(@project, f: 0) do | |
13 | + %li{class: ("active" if (params[:f] == 'open' || !params[:f]))} | |
14 | + = link_to project_merge_requests_path(@project, f: 'open') do | |
15 | 15 | Open |
16 | - %li{class: ("active" if params[:f] == "2")} | |
17 | - = link_to project_merge_requests_path(@project, f: 2) do | |
16 | + %li{class: ("active" if params[:f] == "closed")} | |
17 | + = link_to project_merge_requests_path(@project, f: "closed") do | |
18 | 18 | Closed |
19 | - %li{class: ("active" if params[:f] == "3")} | |
20 | - = link_to project_merge_requests_path(@project, f: 3) do | |
19 | + %li{class: ("active" if params[:f] == 'assigned-to-me')} | |
20 | + = link_to project_merge_requests_path(@project, f: 'assigned-to-me') do | |
21 | 21 | To Me |
22 | - %li{class: ("active" if params[:f] == "1")} | |
23 | - = link_to project_merge_requests_path(@project, f: 1) do | |
22 | + %li{class: ("active" if params[:f] == 'all')} | |
23 | + = link_to project_merge_requests_path(@project, f: 'all') do | |
24 | 24 | All |
25 | 25 | |
26 | 26 | %ul.unstyled | ... | ... |
app/views/merge_requests/show/_how_to_merge.html.haml
... | ... | @@ -3,13 +3,12 @@ |
3 | 3 | %a.close{href: "#"} × |
4 | 4 | %h3 How To Merge |
5 | 5 | .modal-body |
6 | - %pre | |
6 | + %pre.dark | |
7 | 7 | = preserve do |
8 | - :erb | |
9 | - git checkout <%= @merge_request.target_branch %> | |
10 | - git fetch origin | |
11 | - git merge origin/<%= @merge_request.source_branch %> | |
12 | - git push origin <%= @merge_request.target_branch %> | |
8 | + git checkout #{@merge_request.target_branch} | |
9 | + git fetch origin | |
10 | + git merge origin/#{@merge_request.source_branch} | |
11 | + git push origin #{@merge_request.target_branch} | |
13 | 12 | |
14 | 13 | |
15 | 14 | :javascript | ... | ... |
app/views/merge_requests/show/_mr_title.html.haml
1 | 1 | %h3.page_title |
2 | 2 | = "Merge Request ##{@merge_request.id}:" |
3 | 3 | |
4 | - %span.pretty_label.branch= @merge_request.source_branch | |
4 | + %span.label_branch= @merge_request.source_branch | |
5 | 5 | → |
6 | - %span.pretty_label.branch= @merge_request.target_branch | |
6 | + %span.label_branch= @merge_request.target_branch | |
7 | 7 | |
8 | 8 | %span.right |
9 | 9 | - if @merge_request.merged? | ... | ... |