Commit 63c2c2cc23eeacfda0f15c339dbaf854e7de1199
Exists in
master
and in
4 other branches
Merge branch 'dev'
Showing
59 changed files
with
2086 additions
and
350 deletions
Show diff stats
Gemfile
@@ -21,6 +21,8 @@ gem "git" | @@ -21,6 +21,8 @@ gem "git" | ||
21 | gem "acts_as_list" | 21 | gem "acts_as_list" |
22 | gem 'rdiscount' | 22 | gem 'rdiscount' |
23 | 23 | ||
24 | +gem 'acts-as-taggable-on', '~>2.1.0' | ||
25 | + | ||
24 | group :assets do | 26 | group :assets do |
25 | gem 'sass-rails', " ~> 3.1.0" | 27 | gem 'sass-rails', " ~> 3.1.0" |
26 | gem 'coffee-rails', "~> 3.1.0" | 28 | gem 'coffee-rails', "~> 3.1.0" |
Gemfile.lock
@@ -54,6 +54,8 @@ GEM | @@ -54,6 +54,8 @@ GEM | ||
54 | activesupport (= 3.1.0) | 54 | activesupport (= 3.1.0) |
55 | activesupport (3.1.0) | 55 | activesupport (3.1.0) |
56 | multi_json (~> 1.0) | 56 | multi_json (~> 1.0) |
57 | + acts-as-taggable-on (2.1.1) | ||
58 | + rails | ||
57 | acts_as_list (0.1.4) | 59 | acts_as_list (0.1.4) |
58 | addressable (2.2.6) | 60 | addressable (2.2.6) |
59 | ansi (1.3.0) | 61 | ansi (1.3.0) |
@@ -246,6 +248,7 @@ PLATFORMS | @@ -246,6 +248,7 @@ PLATFORMS | ||
246 | ruby | 248 | ruby |
247 | 249 | ||
248 | DEPENDENCIES | 250 | DEPENDENCIES |
251 | + acts-as-taggable-on (~> 2.1.0) | ||
249 | acts_as_list | 252 | acts_as_list |
250 | annotate! | 253 | annotate! |
251 | autotest | 254 | autotest |
app/assets/images/ajax-loader.gif
396 Bytes
app/assets/javascripts/application.js
@@ -8,6 +8,7 @@ | @@ -8,6 +8,7 @@ | ||
8 | //= require jquery-ui | 8 | //= require jquery-ui |
9 | //= require jquery_ujs | 9 | //= require jquery_ujs |
10 | //= require jquery.ui.selectmenu | 10 | //= require jquery.ui.selectmenu |
11 | +//= require jquery.tagify | ||
11 | //= require jquery.cookie | 12 | //= require jquery.cookie |
12 | //= require_tree . | 13 | //= require_tree . |
13 | 14 | ||
@@ -20,6 +21,6 @@ $(function(){ | @@ -20,6 +21,6 @@ $(function(){ | ||
20 | $('select#tag').selectmenu({style:'popup', width:200}); | 21 | $('select#tag').selectmenu({style:'popup', width:200}); |
21 | }); | 22 | }); |
22 | 23 | ||
23 | -function updatePage(){ | ||
24 | - $.ajax({type: "GET", url: location.href, dataType: "script"}); | 24 | +function updatePage(data){ |
25 | + $.ajax({type: "GET", url: location.href, data: data, dataType: "script"}); | ||
25 | } | 26 | } |
@@ -0,0 +1,901 @@ | @@ -0,0 +1,901 @@ | ||
1 | +// Chosen, a Select Box Enhancer for jQuery and Protoype | ||
2 | +// by Patrick Filler for Harvest, http://getharvest.com | ||
3 | +// | ||
4 | +// Version 0.9.5 | ||
5 | +// Full source at https://github.com/harvesthq/chosen | ||
6 | +// Copyright (c) 2011 Harvest http://getharvest.com | ||
7 | + | ||
8 | +// MIT License, https://github.com/harvesthq/chosen/blob/master/LICENSE.md | ||
9 | +// This file is generated by `cake build`, do not edit it by hand. | ||
10 | +(function() { | ||
11 | + var SelectParser; | ||
12 | + SelectParser = (function() { | ||
13 | + function SelectParser() { | ||
14 | + this.options_index = 0; | ||
15 | + this.parsed = []; | ||
16 | + } | ||
17 | + SelectParser.prototype.add_node = function(child) { | ||
18 | + if (child.nodeName === "OPTGROUP") { | ||
19 | + return this.add_group(child); | ||
20 | + } else { | ||
21 | + return this.add_option(child); | ||
22 | + } | ||
23 | + }; | ||
24 | + SelectParser.prototype.add_group = function(group) { | ||
25 | + var group_position, option, _i, _len, _ref, _results; | ||
26 | + group_position = this.parsed.length; | ||
27 | + this.parsed.push({ | ||
28 | + array_index: group_position, | ||
29 | + group: true, | ||
30 | + label: group.label, | ||
31 | + children: 0, | ||
32 | + disabled: group.disabled | ||
33 | + }); | ||
34 | + _ref = group.childNodes; | ||
35 | + _results = []; | ||
36 | + for (_i = 0, _len = _ref.length; _i < _len; _i++) { | ||
37 | + option = _ref[_i]; | ||
38 | + _results.push(this.add_option(option, group_position, group.disabled)); | ||
39 | + } | ||
40 | + return _results; | ||
41 | + }; | ||
42 | + SelectParser.prototype.add_option = function(option, group_position, group_disabled) { | ||
43 | + if (option.nodeName === "OPTION") { | ||
44 | + if (option.text !== "") { | ||
45 | + if (group_position != null) { | ||
46 | + this.parsed[group_position].children += 1; | ||
47 | + } | ||
48 | + this.parsed.push({ | ||
49 | + array_index: this.parsed.length, | ||
50 | + options_index: this.options_index, | ||
51 | + value: option.value, | ||
52 | + text: option.text, | ||
53 | + html: option.innerHTML, | ||
54 | + selected: option.selected, | ||
55 | + disabled: group_disabled === true ? group_disabled : option.disabled, | ||
56 | + group_array_index: group_position, | ||
57 | + classes: option.className, | ||
58 | + style: option.style.cssText | ||
59 | + }); | ||
60 | + } else { | ||
61 | + this.parsed.push({ | ||
62 | + array_index: this.parsed.length, | ||
63 | + options_index: this.options_index, | ||
64 | + empty: true | ||
65 | + }); | ||
66 | + } | ||
67 | + return this.options_index += 1; | ||
68 | + } | ||
69 | + }; | ||
70 | + return SelectParser; | ||
71 | + })(); | ||
72 | + SelectParser.select_to_array = function(select) { | ||
73 | + var child, parser, _i, _len, _ref; | ||
74 | + parser = new SelectParser(); | ||
75 | + _ref = select.childNodes; | ||
76 | + for (_i = 0, _len = _ref.length; _i < _len; _i++) { | ||
77 | + child = _ref[_i]; | ||
78 | + parser.add_node(child); | ||
79 | + } | ||
80 | + return parser.parsed; | ||
81 | + }; | ||
82 | + this.SelectParser = SelectParser; | ||
83 | +}).call(this); | ||
84 | +(function() { | ||
85 | + /* | ||
86 | + Chosen source: generate output using 'cake build' | ||
87 | + Copyright (c) 2011 by Harvest | ||
88 | + */ | ||
89 | + var AbstractChosen, root; | ||
90 | + var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }; | ||
91 | + root = this; | ||
92 | + AbstractChosen = (function() { | ||
93 | + function AbstractChosen(form_field, options) { | ||
94 | + this.form_field = form_field; | ||
95 | + this.options = options != null ? options : {}; | ||
96 | + this.set_default_values(); | ||
97 | + this.is_multiple = this.form_field.multiple; | ||
98 | + this.default_text_default = this.is_multiple ? "Select Some Options" : "Select an Option"; | ||
99 | + this.setup(); | ||
100 | + this.set_up_html(); | ||
101 | + this.register_observers(); | ||
102 | + this.finish_setup(); | ||
103 | + } | ||
104 | + AbstractChosen.prototype.set_default_values = function() { | ||
105 | + this.click_test_action = __bind(function(evt) { | ||
106 | + return this.test_active_click(evt); | ||
107 | + }, this); | ||
108 | + this.activate_action = __bind(function(evt) { | ||
109 | + return this.activate_field(evt); | ||
110 | + }, this); | ||
111 | + this.active_field = false; | ||
112 | + this.mouse_on_container = false; | ||
113 | + this.results_showing = false; | ||
114 | + this.result_highlighted = null; | ||
115 | + this.result_single_selected = null; | ||
116 | + this.allow_single_deselect = (this.options.allow_single_deselect != null) && this.form_field.options[0].text === "" ? this.options.allow_single_deselect : false; | ||
117 | + this.disable_search_threshold = this.options.disable_search_threshold || 0; | ||
118 | + this.choices = 0; | ||
119 | + return this.results_none_found = this.options.no_results_text || "No results match"; | ||
120 | + }; | ||
121 | + AbstractChosen.prototype.mouse_enter = function() { | ||
122 | + return this.mouse_on_container = true; | ||
123 | + }; | ||
124 | + AbstractChosen.prototype.mouse_leave = function() { | ||
125 | + return this.mouse_on_container = false; | ||
126 | + }; | ||
127 | + AbstractChosen.prototype.input_focus = function(evt) { | ||
128 | + if (!this.active_field) { | ||
129 | + return setTimeout((__bind(function() { | ||
130 | + return this.container_mousedown(); | ||
131 | + }, this)), 50); | ||
132 | + } | ||
133 | + }; | ||
134 | + AbstractChosen.prototype.input_blur = function(evt) { | ||
135 | + if (!this.mouse_on_container) { | ||
136 | + this.active_field = false; | ||
137 | + return setTimeout((__bind(function() { | ||
138 | + return this.blur_test(); | ||
139 | + }, this)), 100); | ||
140 | + } | ||
141 | + }; | ||
142 | + AbstractChosen.prototype.result_add_option = function(option) { | ||
143 | + var classes, style; | ||
144 | + if (!option.disabled) { | ||
145 | + option.dom_id = this.container_id + "_o_" + option.array_index; | ||
146 | + classes = option.selected && this.is_multiple ? [] : ["active-result"]; | ||
147 | + if (option.selected) { | ||
148 | + classes.push("result-selected"); | ||
149 | + } | ||
150 | + if (option.group_array_index != null) { | ||
151 | + classes.push("group-option"); | ||
152 | + } | ||
153 | + if (option.classes !== "") { | ||
154 | + classes.push(option.classes); | ||
155 | + } | ||
156 | + style = option.style.cssText !== "" ? " style=\"" + option.style + "\"" : ""; | ||
157 | + return '<li id="' + option.dom_id + '" class="' + classes.join(' ') + '"' + style + '>' + option.html + '</li>'; | ||
158 | + } else { | ||
159 | + return ""; | ||
160 | + } | ||
161 | + }; | ||
162 | + AbstractChosen.prototype.results_update_field = function() { | ||
163 | + this.result_clear_highlight(); | ||
164 | + this.result_single_selected = null; | ||
165 | + return this.results_build(); | ||
166 | + }; | ||
167 | + AbstractChosen.prototype.results_toggle = function() { | ||
168 | + if (this.results_showing) { | ||
169 | + return this.results_hide(); | ||
170 | + } else { | ||
171 | + return this.results_show(); | ||
172 | + } | ||
173 | + }; | ||
174 | + AbstractChosen.prototype.results_search = function(evt) { | ||
175 | + if (this.results_showing) { | ||
176 | + return this.winnow_results(); | ||
177 | + } else { | ||
178 | + return this.results_show(); | ||
179 | + } | ||
180 | + }; | ||
181 | + AbstractChosen.prototype.keyup_checker = function(evt) { | ||
182 | + var stroke, _ref; | ||
183 | + stroke = (_ref = evt.which) != null ? _ref : evt.keyCode; | ||
184 | + this.search_field_scale(); | ||
185 | + switch (stroke) { | ||
186 | + case 8: | ||
187 | + if (this.is_multiple && this.backstroke_length < 1 && this.choices > 0) { | ||
188 | + return this.keydown_backstroke(); | ||
189 | + } else if (!this.pending_backstroke) { | ||
190 | + this.result_clear_highlight(); | ||
191 | + return this.results_search(); | ||
192 | + } | ||
193 | + break; | ||
194 | + case 13: | ||
195 | + evt.preventDefault(); | ||
196 | + if (this.results_showing) { | ||
197 | + return this.result_select(evt); | ||
198 | + } | ||
199 | + break; | ||
200 | + case 27: | ||
201 | + if (this.results_showing) { | ||
202 | + return this.results_hide(); | ||
203 | + } | ||
204 | + break; | ||
205 | + case 9: | ||
206 | + case 38: | ||
207 | + case 40: | ||
208 | + case 16: | ||
209 | + case 91: | ||
210 | + case 17: | ||
211 | + break; | ||
212 | + default: | ||
213 | + return this.results_search(); | ||
214 | + } | ||
215 | + }; | ||
216 | + AbstractChosen.prototype.generate_field_id = function() { | ||
217 | + var new_id; | ||
218 | + new_id = this.generate_random_id(); | ||
219 | + this.form_field.id = new_id; | ||
220 | + return new_id; | ||
221 | + }; | ||
222 | + AbstractChosen.prototype.generate_random_char = function() { | ||
223 | + var chars, newchar, rand; | ||
224 | + chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZ"; | ||
225 | + rand = Math.floor(Math.random() * chars.length); | ||
226 | + return newchar = chars.substring(rand, rand + 1); | ||
227 | + }; | ||
228 | + return AbstractChosen; | ||
229 | + })(); | ||
230 | + root.AbstractChosen = AbstractChosen; | ||
231 | +}).call(this); | ||
232 | +(function() { | ||
233 | + /* | ||
234 | + Chosen source: generate output using 'cake build' | ||
235 | + Copyright (c) 2011 by Harvest | ||
236 | + */ | ||
237 | + var $, Chosen, get_side_border_padding, root; | ||
238 | + var __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) { | ||
239 | + for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } | ||
240 | + function ctor() { this.constructor = child; } | ||
241 | + ctor.prototype = parent.prototype; | ||
242 | + child.prototype = new ctor; | ||
243 | + child.__super__ = parent.prototype; | ||
244 | + return child; | ||
245 | + }, __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }; | ||
246 | + root = this; | ||
247 | + $ = jQuery; | ||
248 | + $.fn.extend({ | ||
249 | + chosen: function(options) { | ||
250 | + if ($.browser.msie && ($.browser.version === "6.0" || $.browser.version === "7.0")) { | ||
251 | + return this; | ||
252 | + } | ||
253 | + return $(this).each(function(input_field) { | ||
254 | + if (!($(this)).hasClass("chzn-done")) { | ||
255 | + return new Chosen(this, options); | ||
256 | + } | ||
257 | + }); | ||
258 | + } | ||
259 | + }); | ||
260 | + Chosen = (function() { | ||
261 | + __extends(Chosen, AbstractChosen); | ||
262 | + function Chosen() { | ||
263 | + Chosen.__super__.constructor.apply(this, arguments); | ||
264 | + } | ||
265 | + Chosen.prototype.setup = function() { | ||
266 | + this.form_field_jq = $(this.form_field); | ||
267 | + return this.is_rtl = this.form_field_jq.hasClass("chzn-rtl"); | ||
268 | + }; | ||
269 | + Chosen.prototype.finish_setup = function() { | ||
270 | + return this.form_field_jq.addClass("chzn-done"); | ||
271 | + }; | ||
272 | + Chosen.prototype.set_up_html = function() { | ||
273 | + var container_div, dd_top, dd_width, sf_width; | ||
274 | + this.container_id = this.form_field.id.length ? this.form_field.id.replace(/(:|\.)/g, '_') : this.generate_field_id(); | ||
275 | + this.container_id += "_chzn"; | ||
276 | + this.f_width = this.form_field_jq.outerWidth(); | ||
277 | + this.default_text = this.form_field_jq.data('placeholder') ? this.form_field_jq.data('placeholder') : this.default_text_default; | ||
278 | + container_div = $("<div />", { | ||
279 | + id: this.container_id, | ||
280 | + "class": "chzn-container" + (this.is_rtl ? ' chzn-rtl' : ''), | ||
281 | + style: 'width: ' + this.f_width + 'px;' | ||
282 | + }); | ||
283 | + if (this.is_multiple) { | ||
284 | + container_div.html('<ul class="chzn-choices"><li class="search-field"><input type="text" value="' + this.default_text + '" class="default" autocomplete="off" style="width:25px;" /></li></ul><div class="chzn-drop" style="left:-9000px;"><ul class="chzn-results"></ul></div>'); | ||
285 | + } else { | ||
286 | + container_div.html('<a href="javascript:void(0)" class="chzn-single"><span>' + this.default_text + '</span><div><b></b></div></a><div class="chzn-drop" style="left:-9000px;"><div class="chzn-search"><input type="text" autocomplete="off" /></div><ul class="chzn-results"></ul></div>'); | ||
287 | + } | ||
288 | + this.form_field_jq.hide().after(container_div); | ||
289 | + this.container = $('#' + this.container_id); | ||
290 | + this.container.addClass("chzn-container-" + (this.is_multiple ? "multi" : "single")); | ||
291 | + this.dropdown = this.container.find('div.chzn-drop').first(); | ||
292 | + dd_top = this.container.height(); | ||
293 | + dd_width = this.f_width - get_side_border_padding(this.dropdown); | ||
294 | + this.dropdown.css({ | ||
295 | + "width": dd_width + "px", | ||
296 | + "top": dd_top + "px" | ||
297 | + }); | ||
298 | + this.search_field = this.container.find('input').first(); | ||
299 | + this.search_results = this.container.find('ul.chzn-results').first(); | ||
300 | + this.search_field_scale(); | ||
301 | + this.search_no_results = this.container.find('li.no-results').first(); | ||
302 | + if (this.is_multiple) { | ||
303 | + this.search_choices = this.container.find('ul.chzn-choices').first(); | ||
304 | + this.search_container = this.container.find('li.search-field').first(); | ||
305 | + } else { | ||
306 | + this.search_container = this.container.find('div.chzn-search').first(); | ||
307 | + this.selected_item = this.container.find('.chzn-single').first(); | ||
308 | + sf_width = dd_width - get_side_border_padding(this.search_container) - get_side_border_padding(this.search_field); | ||
309 | + this.search_field.css({ | ||
310 | + "width": sf_width + "px" | ||
311 | + }); | ||
312 | + } | ||
313 | + this.results_build(); | ||
314 | + this.set_tab_index(); | ||
315 | + return this.form_field_jq.trigger("liszt:ready", { | ||
316 | + chosen: this | ||
317 | + }); | ||
318 | + }; | ||
319 | + Chosen.prototype.register_observers = function() { | ||
320 | + this.container.mousedown(__bind(function(evt) { | ||
321 | + return this.container_mousedown(evt); | ||
322 | + }, this)); | ||
323 | + this.container.mouseup(__bind(function(evt) { | ||
324 | + return this.container_mouseup(evt); | ||
325 | + }, this)); | ||
326 | + this.container.mouseenter(__bind(function(evt) { | ||
327 | + return this.mouse_enter(evt); | ||
328 | + }, this)); | ||
329 | + this.container.mouseleave(__bind(function(evt) { | ||
330 | + return this.mouse_leave(evt); | ||
331 | + }, this)); | ||
332 | + this.search_results.mouseup(__bind(function(evt) { | ||
333 | + return this.search_results_mouseup(evt); | ||
334 | + }, this)); | ||
335 | + this.search_results.mouseover(__bind(function(evt) { | ||
336 | + return this.search_results_mouseover(evt); | ||
337 | + }, this)); | ||
338 | + this.search_results.mouseout(__bind(function(evt) { | ||
339 | + return this.search_results_mouseout(evt); | ||
340 | + }, this)); | ||
341 | + this.form_field_jq.bind("liszt:updated", __bind(function(evt) { | ||
342 | + return this.results_update_field(evt); | ||
343 | + }, this)); | ||
344 | + this.search_field.blur(__bind(function(evt) { | ||
345 | + return this.input_blur(evt); | ||
346 | + }, this)); | ||
347 | + this.search_field.keyup(__bind(function(evt) { | ||
348 | + return this.keyup_checker(evt); | ||
349 | + }, this)); | ||
350 | + this.search_field.keydown(__bind(function(evt) { | ||
351 | + return this.keydown_checker(evt); | ||
352 | + }, this)); | ||
353 | + if (this.is_multiple) { | ||
354 | + this.search_choices.click(__bind(function(evt) { | ||
355 | + return this.choices_click(evt); | ||
356 | + }, this)); | ||
357 | + return this.search_field.focus(__bind(function(evt) { | ||
358 | + return this.input_focus(evt); | ||
359 | + }, this)); | ||
360 | + } | ||
361 | + }; | ||
362 | + Chosen.prototype.search_field_disabled = function() { | ||
363 | + this.is_disabled = this.form_field_jq[0].disabled; | ||
364 | + if (this.is_disabled) { | ||
365 | + this.container.addClass('chzn-disabled'); | ||
366 | + this.search_field[0].disabled = true; | ||
367 | + if (!this.is_multiple) { | ||
368 | + this.selected_item.unbind("focus", this.activate_action); | ||
369 | + } | ||
370 | + return this.close_field(); | ||
371 | + } else { | ||
372 | + this.container.removeClass('chzn-disabled'); | ||
373 | + this.search_field[0].disabled = false; | ||
374 | + if (!this.is_multiple) { | ||
375 | + return this.selected_item.bind("focus", this.activate_action); | ||
376 | + } | ||
377 | + } | ||
378 | + }; | ||
379 | + Chosen.prototype.container_mousedown = function(evt) { | ||
380 | + var target_closelink; | ||
381 | + if (!this.is_disabled) { | ||
382 | + target_closelink = evt != null ? ($(evt.target)).hasClass("search-choice-close") : false; | ||
383 | + if (evt && evt.type === "mousedown") { | ||
384 | + evt.stopPropagation(); | ||
385 | + } | ||
386 | + if (!this.pending_destroy_click && !target_closelink) { | ||
387 | + if (!this.active_field) { | ||
388 | + if (this.is_multiple) { | ||
389 | + this.search_field.val(""); | ||
390 | + } | ||
391 | + $(document).click(this.click_test_action); | ||
392 | + this.results_show(); | ||
393 | + } else if (!this.is_multiple && evt && ($(evt.target) === this.selected_item || $(evt.target).parents("a.chzn-single").length)) { | ||
394 | + evt.preventDefault(); | ||
395 | + this.results_toggle(); | ||
396 | + } | ||
397 | + return this.activate_field(); | ||
398 | + } else { | ||
399 | + return this.pending_destroy_click = false; | ||
400 | + } | ||
401 | + } | ||
402 | + }; | ||
403 | + Chosen.prototype.container_mouseup = function(evt) { | ||
404 | + if (evt.target.nodeName === "ABBR") { | ||
405 | + return this.results_reset(evt); | ||
406 | + } | ||
407 | + }; | ||
408 | + Chosen.prototype.blur_test = function(evt) { | ||
409 | + if (!this.active_field && this.container.hasClass("chzn-container-active")) { | ||
410 | + return this.close_field(); | ||
411 | + } | ||
412 | + }; | ||
413 | + Chosen.prototype.close_field = function() { | ||
414 | + $(document).unbind("click", this.click_test_action); | ||
415 | + if (!this.is_multiple) { | ||
416 | + this.selected_item.attr("tabindex", this.search_field.attr("tabindex")); | ||
417 | + this.search_field.attr("tabindex", -1); | ||
418 | + } | ||
419 | + this.active_field = false; | ||
420 | + this.results_hide(); | ||
421 | + this.container.removeClass("chzn-container-active"); | ||
422 | + this.winnow_results_clear(); | ||
423 | + this.clear_backstroke(); | ||
424 | + this.show_search_field_default(); | ||
425 | + return this.search_field_scale(); | ||
426 | + }; | ||
427 | + Chosen.prototype.activate_field = function() { | ||
428 | + if (!this.is_multiple && !this.active_field) { | ||
429 | + this.search_field.attr("tabindex", this.selected_item.attr("tabindex")); | ||
430 | + this.selected_item.attr("tabindex", -1); | ||
431 | + } | ||
432 | + this.container.addClass("chzn-container-active"); | ||
433 | + this.active_field = true; | ||
434 | + this.search_field.val(this.search_field.val()); | ||
435 | + return this.search_field.focus(); | ||
436 | + }; | ||
437 | + Chosen.prototype.test_active_click = function(evt) { | ||
438 | + if ($(evt.target).parents('#' + this.container_id).length) { | ||
439 | + return this.active_field = true; | ||
440 | + } else { | ||
441 | + return this.close_field(); | ||
442 | + } | ||
443 | + }; | ||
444 | + Chosen.prototype.results_build = function() { | ||
445 | + var content, data, startTime, _i, _len, _ref; | ||
446 | + startTime = new Date(); | ||
447 | + this.parsing = true; | ||
448 | + this.results_data = root.SelectParser.select_to_array(this.form_field); | ||
449 | + if (this.is_multiple && this.choices > 0) { | ||
450 | + this.search_choices.find("li.search-choice").remove(); | ||
451 | + this.choices = 0; | ||
452 | + } else if (!this.is_multiple) { | ||
453 | + this.selected_item.find("span").text(this.default_text); | ||
454 | + if (this.form_field.options.length <= this.disable_search_threshold) { | ||
455 | + this.container.addClass("chzn-container-single-nosearch"); | ||
456 | + } else { | ||
457 | + this.container.removeClass("chzn-container-single-nosearch"); | ||
458 | + } | ||
459 | + } | ||
460 | + content = ''; | ||
461 | + _ref = this.results_data; | ||
462 | + for (_i = 0, _len = _ref.length; _i < _len; _i++) { | ||
463 | + data = _ref[_i]; | ||
464 | + if (data.group) { | ||
465 | + content += this.result_add_group(data); | ||
466 | + } else if (!data.empty) { | ||
467 | + content += this.result_add_option(data); | ||
468 | + if (data.selected && this.is_multiple) { | ||
469 | + this.choice_build(data); | ||
470 | + } else if (data.selected && !this.is_multiple) { | ||
471 | + this.selected_item.find("span").text(data.text); | ||
472 | + if (this.allow_single_deselect) { | ||
473 | + this.single_deselect_control_build(); | ||
474 | + } | ||
475 | + } | ||
476 | + } | ||
477 | + } | ||
478 | + this.search_field_disabled(); | ||
479 | + this.show_search_field_default(); | ||
480 | + this.search_field_scale(); | ||
481 | + this.search_results.html(content); | ||
482 | + return this.parsing = false; | ||
483 | + }; | ||
484 | + Chosen.prototype.result_add_group = function(group) { | ||
485 | + if (!group.disabled) { | ||
486 | + group.dom_id = this.container_id + "_g_" + group.array_index; | ||
487 | + return '<li id="' + group.dom_id + '" class="group-result">' + $("<div />").text(group.label).html() + '</li>'; | ||
488 | + } else { | ||
489 | + return ""; | ||
490 | + } | ||
491 | + }; | ||
492 | + Chosen.prototype.result_do_highlight = function(el) { | ||
493 | + var high_bottom, high_top, maxHeight, visible_bottom, visible_top; | ||
494 | + if (el.length) { | ||
495 | + this.result_clear_highlight(); | ||
496 | + this.result_highlight = el; | ||
497 | + this.result_highlight.addClass("highlighted"); | ||
498 | + maxHeight = parseInt(this.search_results.css("maxHeight"), 10); | ||
499 | + visible_top = this.search_results.scrollTop(); | ||
500 | + visible_bottom = maxHeight + visible_top; | ||
501 | + high_top = this.result_highlight.position().top + this.search_results.scrollTop(); | ||
502 | + high_bottom = high_top + this.result_highlight.outerHeight(); | ||
503 | + if (high_bottom >= visible_bottom) { | ||
504 | + return this.search_results.scrollTop((high_bottom - maxHeight) > 0 ? high_bottom - maxHeight : 0); | ||
505 | + } else if (high_top < visible_top) { | ||
506 | + return this.search_results.scrollTop(high_top); | ||
507 | + } | ||
508 | + } | ||
509 | + }; | ||
510 | + Chosen.prototype.result_clear_highlight = function() { | ||
511 | + if (this.result_highlight) { | ||
512 | + this.result_highlight.removeClass("highlighted"); | ||
513 | + } | ||
514 | + return this.result_highlight = null; | ||
515 | + }; | ||
516 | + Chosen.prototype.results_show = function() { | ||
517 | + var dd_top; | ||
518 | + if (!this.is_multiple) { | ||
519 | + this.selected_item.addClass("chzn-single-with-drop"); | ||
520 | + if (this.result_single_selected) { | ||
521 | + this.result_do_highlight(this.result_single_selected); | ||
522 | + } | ||
523 | + } | ||
524 | + dd_top = this.is_multiple ? this.container.height() : this.container.height() - 1; | ||
525 | + this.dropdown.css({ | ||
526 | + "top": dd_top + "px", | ||
527 | + "left": 0 | ||
528 | + }); | ||
529 | + this.results_showing = true; | ||
530 | + this.search_field.focus(); | ||
531 | + this.search_field.val(this.search_field.val()); | ||
532 | + return this.winnow_results(); | ||
533 | + }; | ||
534 | + Chosen.prototype.results_hide = function() { | ||
535 | + if (!this.is_multiple) { | ||
536 | + this.selected_item.removeClass("chzn-single-with-drop"); | ||
537 | + } | ||
538 | + this.result_clear_highlight(); | ||
539 | + this.dropdown.css({ | ||
540 | + "left": "-9000px" | ||
541 | + }); | ||
542 | + return this.results_showing = false; | ||
543 | + }; | ||
544 | + Chosen.prototype.set_tab_index = function(el) { | ||
545 | + var ti; | ||
546 | + if (this.form_field_jq.attr("tabindex")) { | ||
547 | + ti = this.form_field_jq.attr("tabindex"); | ||
548 | + this.form_field_jq.attr("tabindex", -1); | ||
549 | + if (this.is_multiple) { | ||
550 | + return this.search_field.attr("tabindex", ti); | ||
551 | + } else { | ||
552 | + this.selected_item.attr("tabindex", ti); | ||
553 | + return this.search_field.attr("tabindex", -1); | ||
554 | + } | ||
555 | + } | ||
556 | + }; | ||
557 | + Chosen.prototype.show_search_field_default = function() { | ||
558 | + if (this.is_multiple && this.choices < 1 && !this.active_field) { | ||
559 | + this.search_field.val(this.default_text); | ||
560 | + return this.search_field.addClass("default"); | ||
561 | + } else { | ||
562 | + this.search_field.val(""); | ||
563 | + return this.search_field.removeClass("default"); | ||
564 | + } | ||
565 | + }; | ||
566 | + Chosen.prototype.search_results_mouseup = function(evt) { | ||
567 | + var target; | ||
568 | + target = $(evt.target).hasClass("active-result") ? $(evt.target) : $(evt.target).parents(".active-result").first(); | ||
569 | + if (target.length) { | ||
570 | + this.result_highlight = target; | ||
571 | + return this.result_select(evt); | ||
572 | + } | ||
573 | + }; | ||
574 | + Chosen.prototype.search_results_mouseover = function(evt) { | ||
575 | + var target; | ||
576 | + target = $(evt.target).hasClass("active-result") ? $(evt.target) : $(evt.target).parents(".active-result").first(); | ||
577 | + if (target) { | ||
578 | + return this.result_do_highlight(target); | ||
579 | + } | ||
580 | + }; | ||
581 | + Chosen.prototype.search_results_mouseout = function(evt) { | ||
582 | + if ($(evt.target).hasClass("active-result" || $(evt.target).parents('.active-result').first())) { | ||
583 | + return this.result_clear_highlight(); | ||
584 | + } | ||
585 | + }; | ||
586 | + Chosen.prototype.choices_click = function(evt) { | ||
587 | + evt.preventDefault(); | ||
588 | + if (this.active_field && !($(evt.target).hasClass("search-choice" || $(evt.target).parents('.search-choice').first)) && !this.results_showing) { | ||
589 | + return this.results_show(); | ||
590 | + } | ||
591 | + }; | ||
592 | + Chosen.prototype.choice_build = function(item) { | ||
593 | + var choice_id, link; | ||
594 | + choice_id = this.container_id + "_c_" + item.array_index; | ||
595 | + this.choices += 1; | ||
596 | + this.search_container.before('<li class="search-choice" id="' + choice_id + '"><span>' + item.html + '</span><a href="javascript:void(0)" class="search-choice-close" rel="' + item.array_index + '"></a></li>'); | ||
597 | + link = $('#' + choice_id).find("a").first(); | ||
598 | + return link.click(__bind(function(evt) { | ||
599 | + return this.choice_destroy_link_click(evt); | ||
600 | + }, this)); | ||
601 | + }; | ||
602 | + Chosen.prototype.choice_destroy_link_click = function(evt) { | ||
603 | + evt.preventDefault(); | ||
604 | + if (!this.is_disabled) { | ||
605 | + this.pending_destroy_click = true; | ||
606 | + return this.choice_destroy($(evt.target)); | ||
607 | + } else { | ||
608 | + return evt.stopPropagation; | ||
609 | + } | ||
610 | + }; | ||
611 | + Chosen.prototype.choice_destroy = function(link) { | ||
612 | + this.choices -= 1; | ||
613 | + this.show_search_field_default(); | ||
614 | + if (this.is_multiple && this.choices > 0 && this.search_field.val().length < 1) { | ||
615 | + this.results_hide(); | ||
616 | + } | ||
617 | + this.result_deselect(link.attr("rel")); | ||
618 | + return link.parents('li').first().remove(); | ||
619 | + }; | ||
620 | + Chosen.prototype.results_reset = function(evt) { | ||
621 | + this.form_field.options[0].selected = true; | ||
622 | + this.selected_item.find("span").text(this.default_text); | ||
623 | + this.show_search_field_default(); | ||
624 | + $(evt.target).remove(); | ||
625 | + this.form_field_jq.trigger("change"); | ||
626 | + if (this.active_field) { | ||
627 | + return this.results_hide(); | ||
628 | + } | ||
629 | + }; | ||
630 | + Chosen.prototype.result_select = function(evt) { | ||
631 | + var high, high_id, item, position; | ||
632 | + if (this.result_highlight) { | ||
633 | + high = this.result_highlight; | ||
634 | + high_id = high.attr("id"); | ||
635 | + this.result_clear_highlight(); | ||
636 | + if (this.is_multiple) { | ||
637 | + this.result_deactivate(high); | ||
638 | + } else { | ||
639 | + this.search_results.find(".result-selected").removeClass("result-selected"); | ||
640 | + this.result_single_selected = high; | ||
641 | + } | ||
642 | + high.addClass("result-selected"); | ||
643 | + position = high_id.substr(high_id.lastIndexOf("_") + 1); | ||
644 | + item = this.results_data[position]; | ||
645 | + item.selected = true; | ||
646 | + this.form_field.options[item.options_index].selected = true; | ||
647 | + if (this.is_multiple) { | ||
648 | + this.choice_build(item); | ||
649 | + } else { | ||
650 | + this.selected_item.find("span").first().text(item.text); | ||
651 | + if (this.allow_single_deselect) { | ||
652 | + this.single_deselect_control_build(); | ||
653 | + } | ||
654 | + } | ||
655 | + if (!(evt.metaKey && this.is_multiple)) { | ||
656 | + this.results_hide(); | ||
657 | + } | ||
658 | + this.search_field.val(""); | ||
659 | + this.form_field_jq.trigger("change"); | ||
660 | + return this.search_field_scale(); | ||
661 | + } | ||
662 | + }; | ||
663 | + Chosen.prototype.result_activate = function(el) { | ||
664 | + return el.addClass("active-result"); | ||
665 | + }; | ||
666 | + Chosen.prototype.result_deactivate = function(el) { | ||
667 | + return el.removeClass("active-result"); | ||
668 | + }; | ||
669 | + Chosen.prototype.result_deselect = function(pos) { | ||
670 | + var result, result_data; | ||
671 | + result_data = this.results_data[pos]; | ||
672 | + result_data.selected = false; | ||
673 | + this.form_field.options[result_data.options_index].selected = false; | ||
674 | + result = $("#" + this.container_id + "_o_" + pos); | ||
675 | + result.removeClass("result-selected").addClass("active-result").show(); | ||
676 | + this.result_clear_highlight(); | ||
677 | + this.winnow_results(); | ||
678 | + this.form_field_jq.trigger("change"); | ||
679 | + return this.search_field_scale(); | ||
680 | + }; | ||
681 | + Chosen.prototype.single_deselect_control_build = function() { | ||
682 | + if (this.allow_single_deselect && this.selected_item.find("abbr").length < 1) { | ||
683 | + return this.selected_item.find("span").first().after("<abbr class=\"search-choice-close\"></abbr>"); | ||
684 | + } | ||
685 | + }; | ||
686 | + Chosen.prototype.winnow_results = function() { | ||
687 | + var found, option, part, parts, regex, result_id, results, searchText, startTime, startpos, text, zregex, _i, _j, _len, _len2, _ref; | ||
688 | + startTime = new Date(); | ||
689 | + this.no_results_clear(); | ||
690 | + results = 0; | ||
691 | + searchText = this.search_field.val() === this.default_text ? "" : $('<div/>').text($.trim(this.search_field.val())).html(); | ||
692 | + regex = new RegExp('^' + searchText.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"), 'i'); | ||
693 | + zregex = new RegExp(searchText.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"), 'i'); | ||
694 | + _ref = this.results_data; | ||
695 | + for (_i = 0, _len = _ref.length; _i < _len; _i++) { | ||
696 | + option = _ref[_i]; | ||
697 | + if (!option.disabled && !option.empty) { | ||
698 | + if (option.group) { | ||
699 | + $('#' + option.dom_id).hide(); | ||
700 | + } else if (!(this.is_multiple && option.selected)) { | ||
701 | + found = false; | ||
702 | + result_id = option.dom_id; | ||
703 | + if (regex.test(option.html)) { | ||
704 | + found = true; | ||
705 | + results += 1; | ||
706 | + } else if (option.html.indexOf(" ") >= 0 || option.html.indexOf("[") === 0) { | ||
707 | + parts = option.html.replace(/\[|\]/g, "").split(" "); | ||
708 | + if (parts.length) { | ||
709 | + for (_j = 0, _len2 = parts.length; _j < _len2; _j++) { | ||
710 | + part = parts[_j]; | ||
711 | + if (regex.test(part)) { | ||
712 | + found = true; | ||
713 | + results += 1; | ||
714 | + } | ||
715 | + } | ||
716 | + } | ||
717 | + } | ||
718 | + if (found) { | ||
719 | + if (searchText.length) { | ||
720 | + startpos = option.html.search(zregex); | ||
721 | + text = option.html.substr(0, startpos + searchText.length) + '</em>' + option.html.substr(startpos + searchText.length); | ||
722 | + text = text.substr(0, startpos) + '<em>' + text.substr(startpos); | ||
723 | + } else { | ||
724 | + text = option.html; | ||
725 | + } | ||
726 | + if ($("#" + result_id).html !== text) { | ||
727 | + $("#" + result_id).html(text); | ||
728 | + } | ||
729 | + this.result_activate($("#" + result_id)); | ||
730 | + if (option.group_array_index != null) { | ||
731 | + $("#" + this.results_data[option.group_array_index].dom_id).show(); | ||
732 | + } | ||
733 | + } else { | ||
734 | + if (this.result_highlight && result_id === this.result_highlight.attr('id')) { | ||
735 | + this.result_clear_highlight(); | ||
736 | + } | ||
737 | + this.result_deactivate($("#" + result_id)); | ||
738 | + } | ||
739 | + } | ||
740 | + } | ||
741 | + } | ||
742 | + if (results < 1 && searchText.length) { | ||
743 | + return this.no_results(searchText); | ||
744 | + } else { | ||
745 | + return this.winnow_results_set_highlight(); | ||
746 | + } | ||
747 | + }; | ||
748 | + Chosen.prototype.winnow_results_clear = function() { | ||
749 | + var li, lis, _i, _len, _results; | ||
750 | + this.search_field.val(""); | ||
751 | + lis = this.search_results.find("li"); | ||
752 | + _results = []; | ||
753 | + for (_i = 0, _len = lis.length; _i < _len; _i++) { | ||
754 | + li = lis[_i]; | ||
755 | + li = $(li); | ||
756 | + _results.push(li.hasClass("group-result") ? li.show() : !this.is_multiple || !li.hasClass("result-selected") ? this.result_activate(li) : void 0); | ||
757 | + } | ||
758 | + return _results; | ||
759 | + }; | ||
760 | + Chosen.prototype.winnow_results_set_highlight = function() { | ||
761 | + var do_high, selected_results; | ||
762 | + if (!this.result_highlight) { | ||
763 | + selected_results = !this.is_multiple ? this.search_results.find(".result-selected.active-result") : []; | ||
764 | + do_high = selected_results.length ? selected_results.first() : this.search_results.find(".active-result").first(); | ||
765 | + if (do_high != null) { | ||
766 | + return this.result_do_highlight(do_high); | ||
767 | + } | ||
768 | + } | ||
769 | + }; | ||
770 | + Chosen.prototype.no_results = function(terms) { | ||
771 | + var no_results_html; | ||
772 | + no_results_html = $('<li class="no-results">' + this.results_none_found + ' "<span></span>"</li>'); | ||
773 | + no_results_html.find("span").first().html(terms); | ||
774 | + return this.search_results.append(no_results_html); | ||
775 | + }; | ||
776 | + Chosen.prototype.no_results_clear = function() { | ||
777 | + return this.search_results.find(".no-results").remove(); | ||
778 | + }; | ||
779 | + Chosen.prototype.keydown_arrow = function() { | ||
780 | + var first_active, next_sib; | ||
781 | + if (!this.result_highlight) { | ||
782 | + first_active = this.search_results.find("li.active-result").first(); | ||
783 | + if (first_active) { | ||
784 | + this.result_do_highlight($(first_active)); | ||
785 | + } | ||
786 | + } else if (this.results_showing) { | ||
787 | + next_sib = this.result_highlight.nextAll("li.active-result").first(); | ||
788 | + if (next_sib) { | ||
789 | + this.result_do_highlight(next_sib); | ||
790 | + } | ||
791 | + } | ||
792 | + if (!this.results_showing) { | ||
793 | + return this.results_show(); | ||
794 | + } | ||
795 | + }; | ||
796 | + Chosen.prototype.keyup_arrow = function() { | ||
797 | + var prev_sibs; | ||
798 | + if (!this.results_showing && !this.is_multiple) { | ||
799 | + return this.results_show(); | ||
800 | + } else if (this.result_highlight) { | ||
801 | + prev_sibs = this.result_highlight.prevAll("li.active-result"); | ||
802 | + if (prev_sibs.length) { | ||
803 | + return this.result_do_highlight(prev_sibs.first()); | ||
804 | + } else { | ||
805 | + if (this.choices > 0) { | ||
806 | + this.results_hide(); | ||
807 | + } | ||
808 | + return this.result_clear_highlight(); | ||
809 | + } | ||
810 | + } | ||
811 | + }; | ||
812 | + Chosen.prototype.keydown_backstroke = function() { | ||
813 | + if (this.pending_backstroke) { | ||
814 | + this.choice_destroy(this.pending_backstroke.find("a").first()); | ||
815 | + return this.clear_backstroke(); | ||
816 | + } else { | ||
817 | + this.pending_backstroke = this.search_container.siblings("li.search-choice").last(); | ||
818 | + return this.pending_backstroke.addClass("search-choice-focus"); | ||
819 | + } | ||
820 | + }; | ||
821 | + Chosen.prototype.clear_backstroke = function() { | ||
822 | + if (this.pending_backstroke) { | ||
823 | + this.pending_backstroke.removeClass("search-choice-focus"); | ||
824 | + } | ||
825 | + return this.pending_backstroke = null; | ||
826 | + }; | ||
827 | + Chosen.prototype.keydown_checker = function(evt) { | ||
828 | + var stroke, _ref; | ||
829 | + stroke = (_ref = evt.which) != null ? _ref : evt.keyCode; | ||
830 | + this.search_field_scale(); | ||
831 | + if (stroke !== 8 && this.pending_backstroke) { | ||
832 | + this.clear_backstroke(); | ||
833 | + } | ||
834 | + switch (stroke) { | ||
835 | + case 8: | ||
836 | + this.backstroke_length = this.search_field.val().length; | ||
837 | + break; | ||
838 | + case 9: | ||
839 | + if (this.results_showing && !this.is_multiple) { | ||
840 | + this.result_select(evt); | ||
841 | + } | ||
842 | + this.mouse_on_container = false; | ||
843 | + break; | ||
844 | + case 13: | ||
845 | + evt.preventDefault(); | ||
846 | + break; | ||
847 | + case 38: | ||
848 | + evt.preventDefault(); | ||
849 | + this.keyup_arrow(); | ||
850 | + break; | ||
851 | + case 40: | ||
852 | + this.keydown_arrow(); | ||
853 | + break; | ||
854 | + } | ||
855 | + }; | ||
856 | + Chosen.prototype.search_field_scale = function() { | ||
857 | + var dd_top, div, h, style, style_block, styles, w, _i, _len; | ||
858 | + if (this.is_multiple) { | ||
859 | + h = 0; | ||
860 | + w = 0; | ||
861 | + style_block = "position:absolute; left: -1000px; top: -1000px; display:none;"; | ||
862 | + styles = ['font-size', 'font-style', 'font-weight', 'font-family', 'line-height', 'text-transform', 'letter-spacing']; | ||
863 | + for (_i = 0, _len = styles.length; _i < _len; _i++) { | ||
864 | + style = styles[_i]; | ||
865 | + style_block += style + ":" + this.search_field.css(style) + ";"; | ||
866 | + } | ||
867 | + div = $('<div />', { | ||
868 | + 'style': style_block | ||
869 | + }); | ||
870 | + div.text(this.search_field.val()); | ||
871 | + $('body').append(div); | ||
872 | + w = div.width() + 25; | ||
873 | + div.remove(); | ||
874 | + if (w > this.f_width - 10) { | ||
875 | + w = this.f_width - 10; | ||
876 | + } | ||
877 | + this.search_field.css({ | ||
878 | + 'width': w + 'px' | ||
879 | + }); | ||
880 | + dd_top = this.container.height(); | ||
881 | + return this.dropdown.css({ | ||
882 | + "top": dd_top + "px" | ||
883 | + }); | ||
884 | + } | ||
885 | + }; | ||
886 | + Chosen.prototype.generate_random_id = function() { | ||
887 | + var string; | ||
888 | + string = "sel" + this.generate_random_char() + this.generate_random_char() + this.generate_random_char(); | ||
889 | + while ($("#" + string).length > 0) { | ||
890 | + string += this.generate_random_char(); | ||
891 | + } | ||
892 | + return string; | ||
893 | + }; | ||
894 | + return Chosen; | ||
895 | + })(); | ||
896 | + get_side_border_padding = function(elmt) { | ||
897 | + var side_border_padding; | ||
898 | + return side_border_padding = elmt.outerWidth() - elmt.width(); | ||
899 | + }; | ||
900 | + root.get_side_border_padding = get_side_border_padding; | ||
901 | +}).call(this); |
app/assets/javascripts/commits.js
@@ -7,3 +7,51 @@ $(document).ready(function(){ | @@ -7,3 +7,51 @@ $(document).ready(function(){ | ||
7 | } | 7 | } |
8 | }); | 8 | }); |
9 | }); | 9 | }); |
10 | + | ||
11 | + | ||
12 | + | ||
13 | +var CommitsList = { | ||
14 | + | ||
15 | +ref:null, | ||
16 | +limit:0, | ||
17 | +offset:0, | ||
18 | + | ||
19 | +init: | ||
20 | + function(ref, limit) { | ||
21 | + this.ref=ref; | ||
22 | + this.limit=limit; | ||
23 | + this.offset=limit; | ||
24 | + this.initLoadMore(); | ||
25 | + $('.loading').show(); | ||
26 | + }, | ||
27 | + | ||
28 | +getOld: | ||
29 | + function() { | ||
30 | + $('.loading').show(); | ||
31 | + $.ajax({ | ||
32 | + type: "GET", | ||
33 | + url: location.href, | ||
34 | + data: "limit=" + this.limit + "&offset=" + this.offset + "&ref=" + this.ref, | ||
35 | + complete: function(){ $('.loading').hide()}, | ||
36 | + dataType: "script"}); | ||
37 | + }, | ||
38 | + | ||
39 | +append: | ||
40 | + function(count, html) { | ||
41 | + $("#commits_list").append(html); | ||
42 | + if(count > 0) { | ||
43 | + this.offset += count; | ||
44 | + this.initLoadMore(); | ||
45 | + } | ||
46 | + }, | ||
47 | + | ||
48 | +initLoadMore: | ||
49 | + function() { | ||
50 | + $(window).bind('scroll', function(){ | ||
51 | + if($(window).scrollTop() == $(document).height() - $(window).height()){ | ||
52 | + $(window).unbind('scroll'); | ||
53 | + CommitsList.getOld(); | ||
54 | + } | ||
55 | + }); | ||
56 | + } | ||
57 | +} |
@@ -0,0 +1,87 @@ | @@ -0,0 +1,87 @@ | ||
1 | +var NoteList = { | ||
2 | + | ||
3 | +first_id: 0, | ||
4 | +last_id: 0, | ||
5 | +resource_name: null, | ||
6 | + | ||
7 | +init: | ||
8 | + function(resource_name, first_id, last_id) { | ||
9 | + this.resource_name = resource_name; | ||
10 | + this.first_id = first_id; | ||
11 | + this.last_id = last_id; | ||
12 | + this.initRefresh(); | ||
13 | + this.initLoadMore(); | ||
14 | + }, | ||
15 | + | ||
16 | +getOld: | ||
17 | + function() { | ||
18 | + $('.loading').show(); | ||
19 | + $.ajax({ | ||
20 | + type: "GET", | ||
21 | + url: location.href, | ||
22 | + data: "first_id=" + this.first_id, | ||
23 | + complete: function(){ $('.loading').hide()}, | ||
24 | + dataType: "script"}); | ||
25 | + }, | ||
26 | + | ||
27 | +append: | ||
28 | + function(id, html) { | ||
29 | + this.first_id = id; | ||
30 | + $("#notes-list").append(html); | ||
31 | + this.initLoadMore(); | ||
32 | + }, | ||
33 | + | ||
34 | +replace: | ||
35 | + function(fid, lid, html) { | ||
36 | + this.first_id = fid; | ||
37 | + this.last_id = lid; | ||
38 | + $("#notes-list").html(html); | ||
39 | + this.initLoadMore(); | ||
40 | + }, | ||
41 | + | ||
42 | + | ||
43 | +prepend: | ||
44 | + function(id, html) { | ||
45 | + this.last_id = id; | ||
46 | + $("#notes-list").prepend(html); | ||
47 | + }, | ||
48 | + | ||
49 | +getNew: | ||
50 | + function() { | ||
51 | + // refersh notes list | ||
52 | + $.ajax({ | ||
53 | + type: "GET", | ||
54 | + url: location.href, | ||
55 | + data: "last_id=" + this.last_id, | ||
56 | + dataType: "script"}); | ||
57 | + }, | ||
58 | + | ||
59 | +refresh: | ||
60 | + function() { | ||
61 | + // refersh notes list | ||
62 | + $.ajax({ | ||
63 | + type: "GET", | ||
64 | + url: location.href, | ||
65 | + data: "first_id=" + this.first_id + "&last_id=" + this.last_id, | ||
66 | + dataType: "script"}); | ||
67 | + }, | ||
68 | + | ||
69 | + | ||
70 | + | ||
71 | +initRefresh: | ||
72 | + function() { | ||
73 | + // init timer | ||
74 | + var intNew = setInterval("NoteList.getNew()", 15000); | ||
75 | + var intRefresh = setInterval("NoteList.refresh()", 90000); | ||
76 | + }, | ||
77 | + | ||
78 | +initLoadMore: | ||
79 | + function() { | ||
80 | + $(window).bind('scroll', function(){ | ||
81 | + if($(window).scrollTop() == $(document).height() - $(window).height()){ | ||
82 | + $(window).unbind('scroll'); | ||
83 | + NoteList.getOld(); | ||
84 | + } | ||
85 | + }); | ||
86 | + } | ||
87 | +} |
app/assets/stylesheets/application.css
@@ -4,6 +4,7 @@ | @@ -4,6 +4,7 @@ | ||
4 | * the top of the compiled file, but it's generally better to create a new file per style scope. | 4 | * the top of the compiled file, but it's generally better to create a new file per style scope. |
5 | *= require jquery-ui/jquery-ui | 5 | *= require jquery-ui/jquery-ui |
6 | *= require jquery-ui/jquery.ui.selectmenu | 6 | *= require jquery-ui/jquery.ui.selectmenu |
7 | + *= require jquery-ui/jquery.tagify | ||
7 | *= require_self | 8 | *= require_self |
8 | *= require_tree . | 9 | *= require_tree . |
9 | */ | 10 | */ |
@@ -0,0 +1,367 @@ | @@ -0,0 +1,367 @@ | ||
1 | +/* @group Base */ | ||
2 | +.chzn-container { | ||
3 | + font-size: 13px; | ||
4 | + position: relative; | ||
5 | + display: inline-block; | ||
6 | + zoom: 1; | ||
7 | + *display: inline; | ||
8 | +} | ||
9 | +.chzn-container .chzn-drop { | ||
10 | + background: #fff; | ||
11 | + border: 1px solid #aaa; | ||
12 | + border-top: 0; | ||
13 | + position: absolute; | ||
14 | + top: 29px; | ||
15 | + left: 0; | ||
16 | + -webkit-box-shadow: 0 4px 5px rgba(0,0,0,.15); | ||
17 | + -moz-box-shadow : 0 4px 5px rgba(0,0,0,.15); | ||
18 | + -o-box-shadow : 0 4px 5px rgba(0,0,0,.15); | ||
19 | + box-shadow : 0 4px 5px rgba(0,0,0,.15); | ||
20 | + z-index: 999; | ||
21 | +} | ||
22 | +/* @end */ | ||
23 | + | ||
24 | +/* @group Single Chosen */ | ||
25 | +.chzn-container-single .chzn-single { | ||
26 | + background-color: #fff; | ||
27 | + background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0, #eeeeee), color-stop(0.5, white)); | ||
28 | + background-image: -webkit-linear-gradient(center bottom, #eeeeee 0%, white 50%); | ||
29 | + background-image: -moz-linear-gradient(center bottom, #eeeeee 0%, white 50%); | ||
30 | + background-image: -o-linear-gradient(top, #eeeeee 0%,#ffffff 50%); | ||
31 | + background-image: -ms-linear-gradient(top, #eeeeee 0%,#ffffff 50%); | ||
32 | + filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#eeeeee', endColorstr='#ffffff',GradientType=0 ); | ||
33 | + background-image: linear-gradient(top, #eeeeee 0%,#ffffff 50%); | ||
34 | + -webkit-border-radius: 4px; | ||
35 | + -moz-border-radius : 4px; | ||
36 | + border-radius : 4px; | ||
37 | + -moz-background-clip : padding; | ||
38 | + -webkit-background-clip: padding-box; | ||
39 | + background-clip : padding-box; | ||
40 | + border: 1px solid #aaa; | ||
41 | + display: block; | ||
42 | + overflow: hidden; | ||
43 | + white-space: nowrap; | ||
44 | + position: relative; | ||
45 | + height: 26px; | ||
46 | + line-height: 26px; | ||
47 | + padding: 0 0 0 8px; | ||
48 | + color: #444; | ||
49 | + text-decoration: none; | ||
50 | +} | ||
51 | +.chzn-container-single .chzn-single span { | ||
52 | + margin-right: 26px; | ||
53 | + display: block; | ||
54 | + overflow: hidden; | ||
55 | + white-space: nowrap; | ||
56 | + -o-text-overflow: ellipsis; | ||
57 | + -ms-text-overflow: ellipsis; | ||
58 | + text-overflow: ellipsis; | ||
59 | +} | ||
60 | +.chzn-container-single .chzn-single abbr { | ||
61 | + display: block; | ||
62 | + position: absolute; | ||
63 | + right: 26px; | ||
64 | + top: 8px; | ||
65 | + width: 12px; | ||
66 | + height: 13px; | ||
67 | + font-size: 1px; | ||
68 | + background: url(chosen-sprite.png) right top no-repeat; | ||
69 | +} | ||
70 | +.chzn-container-single .chzn-single abbr:hover { | ||
71 | + background-position: right -11px; | ||
72 | +} | ||
73 | +.chzn-container-single .chzn-single div { | ||
74 | + -webkit-border-radius: 0 4px 4px 0; | ||
75 | + -moz-border-radius : 0 4px 4px 0; | ||
76 | + border-radius : 0 4px 4px 0; | ||
77 | + -moz-background-clip : padding; | ||
78 | + -webkit-background-clip: padding-box; | ||
79 | + background-clip : padding-box; | ||
80 | + background: #ccc; | ||
81 | + background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0, #ccc), color-stop(0.6, #eee)); | ||
82 | + background-image: -webkit-linear-gradient(center bottom, #ccc 0%, #eee 60%); | ||
83 | + background-image: -moz-linear-gradient(center bottom, #ccc 0%, #eee 60%); | ||
84 | + background-image: -o-linear-gradient(bottom, #ccc 0%, #eee 60%); | ||
85 | + background-image: -ms-linear-gradient(top, #cccccc 0%,#eeeeee 60%); | ||
86 | + filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#cccccc', endColorstr='#eeeeee',GradientType=0 ); | ||
87 | + background-image: linear-gradient(top, #cccccc 0%,#eeeeee 60%); | ||
88 | + border-left: 1px solid #aaa; | ||
89 | + position: absolute; | ||
90 | + right: 0; | ||
91 | + top: 0; | ||
92 | + display: block; | ||
93 | + height: 100%; | ||
94 | + width: 18px; | ||
95 | +} | ||
96 | +.chzn-container-single .chzn-single div b { | ||
97 | + background: url('chosen-sprite.png') no-repeat 0 1px; | ||
98 | + display: block; | ||
99 | + width: 100%; | ||
100 | + height: 100%; | ||
101 | +} | ||
102 | +.chzn-container-single .chzn-search { | ||
103 | + padding: 3px 4px; | ||
104 | + position: relative; | ||
105 | + margin: 0; | ||
106 | + white-space: nowrap; | ||
107 | + z-index: 1010; | ||
108 | +} | ||
109 | +.chzn-container-single .chzn-search input { | ||
110 | + background: #fff url('chosen-sprite.png') no-repeat 100% -22px; | ||
111 | + background: url('chosen-sprite.png') no-repeat 100% -22px, -webkit-gradient(linear, left bottom, left top, color-stop(0.85, white), color-stop(0.99, #eeeeee)); | ||
112 | + background: url('chosen-sprite.png') no-repeat 100% -22px, -webkit-linear-gradient(center bottom, white 85%, #eeeeee 99%); | ||
113 | + background: url('chosen-sprite.png') no-repeat 100% -22px, -moz-linear-gradient(center bottom, white 85%, #eeeeee 99%); | ||
114 | + background: url('chosen-sprite.png') no-repeat 100% -22px, -o-linear-gradient(bottom, white 85%, #eeeeee 99%); | ||
115 | + background: url('chosen-sprite.png') no-repeat 100% -22px, -ms-linear-gradient(top, #ffffff 85%,#eeeeee 99%); | ||
116 | + background: url('chosen-sprite.png') no-repeat 100% -22px, linear-gradient(top, #ffffff 85%,#eeeeee 99%); | ||
117 | + margin: 1px 0; | ||
118 | + padding: 4px 20px 4px 5px; | ||
119 | + outline: 0; | ||
120 | + border: 1px solid #aaa; | ||
121 | + font-family: sans-serif; | ||
122 | + font-size: 1em; | ||
123 | +} | ||
124 | +.chzn-container-single .chzn-drop { | ||
125 | + -webkit-border-radius: 0 0 4px 4px; | ||
126 | + -moz-border-radius : 0 0 4px 4px; | ||
127 | + border-radius : 0 0 4px 4px; | ||
128 | + -moz-background-clip : padding; | ||
129 | + -webkit-background-clip: padding-box; | ||
130 | + background-clip : padding-box; | ||
131 | +} | ||
132 | +/* @end */ | ||
133 | + | ||
134 | +.chzn-container-single-nosearch .chzn-search input { | ||
135 | + position: absolute; | ||
136 | + left: -9000px; | ||
137 | +} | ||
138 | + | ||
139 | +/* @group Multi Chosen */ | ||
140 | +.chzn-container-multi .chzn-choices { | ||
141 | + background-color: #fff; | ||
142 | + background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0.85, white), color-stop(0.99, #eeeeee)); | ||
143 | + background-image: -webkit-linear-gradient(center bottom, white 85%, #eeeeee 99%); | ||
144 | + background-image: -moz-linear-gradient(center bottom, white 85%, #eeeeee 99%); | ||
145 | + background-image: -o-linear-gradient(bottom, white 85%, #eeeeee 99%); | ||
146 | + background-image: -ms-linear-gradient(top, #ffffff 85%,#eeeeee 99%); | ||
147 | + filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffffff', endColorstr='#eeeeee',GradientType=0 ); | ||
148 | + background-image: linear-gradient(top, #ffffff 85%,#eeeeee 99%); | ||
149 | + border: 1px solid #aaa; | ||
150 | + margin: 0; | ||
151 | + padding: 0; | ||
152 | + cursor: text; | ||
153 | + overflow: hidden; | ||
154 | + height: auto !important; | ||
155 | + height: 1%; | ||
156 | + position: relative; | ||
157 | +} | ||
158 | +.chzn-container-multi .chzn-choices li { | ||
159 | + float: left; | ||
160 | + list-style: none; | ||
161 | +} | ||
162 | +.chzn-container-multi .chzn-choices .search-field { | ||
163 | + white-space: nowrap; | ||
164 | + margin: 0; | ||
165 | + padding: 0; | ||
166 | +} | ||
167 | +.chzn-container-multi .chzn-choices .search-field input { | ||
168 | + color: #666; | ||
169 | + background: transparent !important; | ||
170 | + border: 0 !important; | ||
171 | + padding: 5px; | ||
172 | + margin: 1px 0; | ||
173 | + outline: 0; | ||
174 | + -webkit-box-shadow: none; | ||
175 | + -moz-box-shadow : none; | ||
176 | + -o-box-shadow : none; | ||
177 | + box-shadow : none; | ||
178 | +} | ||
179 | +.chzn-container-multi .chzn-choices .search-field .default { | ||
180 | + color: #999; | ||
181 | +} | ||
182 | +.chzn-container-multi .chzn-choices .search-choice { | ||
183 | + -webkit-border-radius: 3px; | ||
184 | + -moz-border-radius : 3px; | ||
185 | + border-radius : 3px; | ||
186 | + -moz-background-clip : padding; | ||
187 | + -webkit-background-clip: padding-box; | ||
188 | + background-clip : padding-box; | ||
189 | + background-color: #e4e4e4; | ||
190 | + background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0, #e4e4e4), color-stop(0.7, #eeeeee)); | ||
191 | + background-image: -webkit-linear-gradient(center bottom, #e4e4e4 0%, #eeeeee 70%); | ||
192 | + background-image: -moz-linear-gradient(center bottom, #e4e4e4 0%, #eeeeee 70%); | ||
193 | + background-image: -o-linear-gradient(bottom, #e4e4e4 0%, #eeeeee 70%); | ||
194 | + background-image: -ms-linear-gradient(top, #e4e4e4 0%,#eeeeee 70%); | ||
195 | + filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#e4e4e4', endColorstr='#eeeeee',GradientType=0 ); | ||
196 | + background-image: linear-gradient(top, #e4e4e4 0%,#eeeeee 70%); | ||
197 | + color: #333; | ||
198 | + border: 1px solid #b4b4b4; | ||
199 | + line-height: 13px; | ||
200 | + padding: 3px 19px 3px 6px; | ||
201 | + margin: 3px 0 3px 5px; | ||
202 | + position: relative; | ||
203 | +} | ||
204 | +.chzn-container-multi .chzn-choices .search-choice span { | ||
205 | + cursor: default; | ||
206 | +} | ||
207 | +.chzn-container-multi .chzn-choices .search-choice-focus { | ||
208 | + background: #d4d4d4; | ||
209 | +} | ||
210 | +.chzn-container-multi .chzn-choices .search-choice .search-choice-close { | ||
211 | + display: block; | ||
212 | + position: absolute; | ||
213 | + right: 3px; | ||
214 | + top: 4px; | ||
215 | + width: 12px; | ||
216 | + height: 13px; | ||
217 | + font-size: 1px; | ||
218 | + background: url(chosen-sprite.png) right top no-repeat; | ||
219 | +} | ||
220 | +.chzn-container-multi .chzn-choices .search-choice .search-choice-close:hover { | ||
221 | + background-position: right -11px; | ||
222 | +} | ||
223 | +.chzn-container-multi .chzn-choices .search-choice-focus .search-choice-close { | ||
224 | + background-position: right -11px; | ||
225 | +} | ||
226 | +/* @end */ | ||
227 | + | ||
228 | +/* @group Results */ | ||
229 | +.chzn-container .chzn-results { | ||
230 | + margin: 0 4px 4px 0; | ||
231 | + max-height: 190px; | ||
232 | + padding: 0 0 0 4px; | ||
233 | + position: relative; | ||
234 | + overflow-x: hidden; | ||
235 | + overflow-y: auto; | ||
236 | +} | ||
237 | +.chzn-container-multi .chzn-results { | ||
238 | + margin: -1px 0 0; | ||
239 | + padding: 0; | ||
240 | +} | ||
241 | +.chzn-container .chzn-results li { | ||
242 | + display: none; | ||
243 | + line-height: 80%; | ||
244 | + padding: 7px 7px 8px; | ||
245 | + margin: 0; | ||
246 | + list-style: none; | ||
247 | +} | ||
248 | +.chzn-container .chzn-results .active-result { | ||
249 | + cursor: pointer; | ||
250 | + display: list-item; | ||
251 | +} | ||
252 | +.chzn-container .chzn-results .highlighted { | ||
253 | + background: #3875d7; | ||
254 | + color: #fff; | ||
255 | +} | ||
256 | +.chzn-container .chzn-results li em { | ||
257 | + background: #feffde; | ||
258 | + font-style: normal; | ||
259 | +} | ||
260 | +.chzn-container .chzn-results .highlighted em { | ||
261 | + background: transparent; | ||
262 | +} | ||
263 | +.chzn-container .chzn-results .no-results { | ||
264 | + background: #f4f4f4; | ||
265 | + display: list-item; | ||
266 | +} | ||
267 | +.chzn-container .chzn-results .group-result { | ||
268 | + cursor: default; | ||
269 | + color: #999; | ||
270 | + font-weight: bold; | ||
271 | +} | ||
272 | +.chzn-container .chzn-results .group-option { | ||
273 | + padding-left: 20px; | ||
274 | +} | ||
275 | +.chzn-container-multi .chzn-drop .result-selected { | ||
276 | + display: none; | ||
277 | +} | ||
278 | +/* @end */ | ||
279 | + | ||
280 | +/* @group Active */ | ||
281 | +.chzn-container-active .chzn-single { | ||
282 | + -webkit-box-shadow: 0 0 5px rgba(0,0,0,.3); | ||
283 | + -moz-box-shadow : 0 0 5px rgba(0,0,0,.3); | ||
284 | + -o-box-shadow : 0 0 5px rgba(0,0,0,.3); | ||
285 | + box-shadow : 0 0 5px rgba(0,0,0,.3); | ||
286 | + border: 1px solid #5897fb; | ||
287 | +} | ||
288 | +.chzn-container-active .chzn-single-with-drop { | ||
289 | + border: 1px solid #aaa; | ||
290 | + -webkit-box-shadow: 0 1px 0 #fff inset; | ||
291 | + -moz-box-shadow : 0 1px 0 #fff inset; | ||
292 | + -o-box-shadow : 0 1px 0 #fff inset; | ||
293 | + box-shadow : 0 1px 0 #fff inset; | ||
294 | + background-color: #eee; | ||
295 | + background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0, white), color-stop(0.5, #eeeeee)); | ||
296 | + background-image: -webkit-linear-gradient(center bottom, white 0%, #eeeeee 50%); | ||
297 | + background-image: -moz-linear-gradient(center bottom, white 0%, #eeeeee 50%); | ||
298 | + background-image: -o-linear-gradient(bottom, white 0%, #eeeeee 50%); | ||
299 | + background-image: -ms-linear-gradient(top, #ffffff 0%,#eeeeee 50%); | ||
300 | + filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffffff', endColorstr='#eeeeee',GradientType=0 ); | ||
301 | + background-image: linear-gradient(top, #ffffff 0%,#eeeeee 50%); | ||
302 | + -webkit-border-bottom-left-radius : 0; | ||
303 | + -webkit-border-bottom-right-radius: 0; | ||
304 | + -moz-border-radius-bottomleft : 0; | ||
305 | + -moz-border-radius-bottomright: 0; | ||
306 | + border-bottom-left-radius : 0; | ||
307 | + border-bottom-right-radius: 0; | ||
308 | +} | ||
309 | +.chzn-container-active .chzn-single-with-drop div { | ||
310 | + background: transparent; | ||
311 | + border-left: none; | ||
312 | +} | ||
313 | +.chzn-container-active .chzn-single-with-drop div b { | ||
314 | + background-position: -18px 1px; | ||
315 | +} | ||
316 | +.chzn-container-active .chzn-choices { | ||
317 | + -webkit-box-shadow: 0 0 5px rgba(0,0,0,.3); | ||
318 | + -moz-box-shadow : 0 0 5px rgba(0,0,0,.3); | ||
319 | + -o-box-shadow : 0 0 5px rgba(0,0,0,.3); | ||
320 | + box-shadow : 0 0 5px rgba(0,0,0,.3); | ||
321 | + border: 1px solid #5897fb; | ||
322 | +} | ||
323 | +.chzn-container-active .chzn-choices .search-field input { | ||
324 | + color: #111 !important; | ||
325 | +} | ||
326 | +/* @end */ | ||
327 | + | ||
328 | +/* @group Disabled Support */ | ||
329 | +.chzn-disabled { | ||
330 | + cursor: default; | ||
331 | + opacity:0.5 !important; | ||
332 | +} | ||
333 | +.chzn-disabled .chzn-single { | ||
334 | + cursor: default; | ||
335 | +} | ||
336 | +.chzn-disabled .chzn-choices .search-choice .search-choice-close { | ||
337 | + cursor: default; | ||
338 | +} | ||
339 | + | ||
340 | +/* @group Right to Left */ | ||
341 | +.chzn-rtl { direction:rtl;text-align: right; } | ||
342 | +.chzn-rtl .chzn-single { padding-left: 0; padding-right: 8px; } | ||
343 | +.chzn-rtl .chzn-single span { margin-left: 26px; margin-right: 0; } | ||
344 | +.chzn-rtl .chzn-single div { | ||
345 | + left: 0; right: auto; | ||
346 | + border-left: none; border-right: 1px solid #aaaaaa; | ||
347 | + -webkit-border-radius: 4px 0 0 4px; | ||
348 | + -moz-border-radius : 4px 0 0 4px; | ||
349 | + border-radius : 4px 0 0 4px; | ||
350 | +} | ||
351 | +.chzn-rtl .chzn-choices li { float: right; } | ||
352 | +.chzn-rtl .chzn-choices .search-choice { padding: 3px 6px 3px 19px; margin: 3px 5px 3px 0; } | ||
353 | +.chzn-rtl .chzn-choices .search-choice .search-choice-close { left: 5px; right: auto; background-position: right top;} | ||
354 | +.chzn-rtl.chzn-container-single .chzn-results { margin-left: 4px; margin-right: 0; padding-left: 0; padding-right: 4px; } | ||
355 | +.chzn-rtl .chzn-results .group-option { padding-left: 0; padding-right: 20px; } | ||
356 | +.chzn-rtl.chzn-container-active .chzn-single-with-drop div { border-right: none; } | ||
357 | +.chzn-rtl .chzn-search input { | ||
358 | + background: url('chosen-sprite.png') no-repeat -38px -22px, #ffffff; | ||
359 | + background: url('chosen-sprite.png') no-repeat -38px -22px, -webkit-gradient(linear, left bottom, left top, color-stop(0.85, white), color-stop(0.99, #eeeeee)); | ||
360 | + background: url('chosen-sprite.png') no-repeat -38px -22px, -webkit-linear-gradient(center bottom, white 85%, #eeeeee 99%); | ||
361 | + background: url('chosen-sprite.png') no-repeat -38px -22px, -moz-linear-gradient(center bottom, white 85%, #eeeeee 99%); | ||
362 | + background: url('chosen-sprite.png') no-repeat -38px -22px, -o-linear-gradient(bottom, white 85%, #eeeeee 99%); | ||
363 | + background: url('chosen-sprite.png') no-repeat -38px -22px, -ms-linear-gradient(top, #ffffff 85%,#eeeeee 99%); | ||
364 | + background: url('chosen-sprite.png') no-repeat -38px -22px, linear-gradient(top, #ffffff 85%,#eeeeee 99%); | ||
365 | + padding: 4px 5px 4px 20px; | ||
366 | +} | ||
367 | +/* @end */ |
app/assets/stylesheets/projects.css.scss
@@ -52,7 +52,8 @@ | @@ -52,7 +52,8 @@ | ||
52 | background: #eee; | 52 | background: #eee; |
53 | } | 53 | } |
54 | .diff_file_content { | 54 | .diff_file_content { |
55 | - overflow-x: scroll; | 55 | + overflow:auto; |
56 | + overflow-y:hidden; | ||
56 | background:#fff; | 57 | background:#fff; |
57 | color:#333; | 58 | color:#333; |
58 | font-size: 12px; | 59 | font-size: 12px; |
@@ -162,10 +163,6 @@ table.round-borders { | @@ -162,10 +163,6 @@ table.round-borders { | ||
162 | padding:20px; | 163 | padding:20px; |
163 | } | 164 | } |
164 | 165 | ||
165 | -//body { | ||
166 | - //background: #eaeaea; | ||
167 | -//} | ||
168 | - | ||
169 | a { | 166 | a { |
170 | color: #111; | 167 | color: #111; |
171 | } | 168 | } |
@@ -174,9 +171,9 @@ a { | @@ -174,9 +171,9 @@ a { | ||
174 | .old_line, .new_line { | 171 | .old_line, .new_line { |
175 | background:#ECECEC; | 172 | background:#ECECEC; |
176 | color:#777; | 173 | color:#777; |
177 | - width:15px; | 174 | + width:30px; |
178 | float:left; | 175 | float:left; |
179 | - padding: 0px 10px; | 176 | + padding: 0px 5px; |
180 | border-right: 1px solid #ccc; | 177 | border-right: 1px solid #ccc; |
181 | } | 178 | } |
182 | } | 179 | } |
@@ -231,43 +228,15 @@ input.ssh_project_url { | @@ -231,43 +228,15 @@ input.ssh_project_url { | ||
231 | text-align:center; | 228 | text-align:center; |
232 | } | 229 | } |
233 | 230 | ||
234 | -.day-commits-table li.commit { | ||
235 | - cursor:pointer; | ||
236 | - | ||
237 | - &:hover { | ||
238 | - @include hover-color; | ||
239 | - } | ||
240 | -} | ||
241 | - | ||
242 | -/* | ||
243 | -#FFF6BF | ||
244 | -#FFD324 | ||
245 | -*/ | ||
246 | -#tree-slider tr.tree-item { | ||
247 | - cursor:pointer; | ||
248 | - | ||
249 | - &:hover { | ||
250 | - @include hover-color; | ||
251 | - td { | ||
252 | - @include hover-color; | ||
253 | - } | ||
254 | - } | ||
255 | -} | ||
256 | #projects-list .project { | 231 | #projects-list .project { |
257 | height:50px; | 232 | height:50px; |
258 | } | 233 | } |
259 | 234 | ||
235 | +#tree-slider .tree-item, | ||
260 | #projects-list .project, | 236 | #projects-list .project, |
261 | #snippets-table .snippet, | 237 | #snippets-table .snippet, |
262 | #issues-table .issue{ | 238 | #issues-table .issue{ |
263 | cursor:pointer; | 239 | cursor:pointer; |
264 | - | ||
265 | - &:hover { | ||
266 | - @include hover-color; | ||
267 | - td { | ||
268 | - @include hover-color; | ||
269 | - } | ||
270 | - } | ||
271 | } | 240 | } |
272 | 241 | ||
273 | .clear { | 242 | .clear { |
@@ -421,31 +390,6 @@ input.ssh_project_url { | @@ -421,31 +390,6 @@ input.ssh_project_url { | ||
421 | list-style:none; | 390 | list-style:none; |
422 | margin:0px; | 391 | margin:0px; |
423 | padding:0px; | 392 | padding:0px; |
424 | - | ||
425 | - li { | ||
426 | - display:list-item; | ||
427 | - padding:8px; | ||
428 | - margin:0px; | ||
429 | - background: #F7FBFC; | ||
430 | - border-top: 1px solid #E2EAEE; | ||
431 | - | ||
432 | - &:first-child { | ||
433 | - border-top: none; | ||
434 | - } | ||
435 | - &:nth-child(2n+1) { | ||
436 | - background: white; | ||
437 | - } | ||
438 | - p { | ||
439 | - margin-bottom: 4px; | ||
440 | - font-size: 13px; | ||
441 | - color:#111; | ||
442 | - } | ||
443 | - } | ||
444 | - cite { | ||
445 | - &.ago { | ||
446 | - color:#666; | ||
447 | - } | ||
448 | - } | ||
449 | } | 393 | } |
450 | 394 | ||
451 | .notes_count { | 395 | .notes_count { |
@@ -460,14 +404,6 @@ input.ssh_project_url { | @@ -460,14 +404,6 @@ input.ssh_project_url { | ||
460 | right: 6px; | 404 | right: 6px; |
461 | top: 6px; | 405 | top: 6px; |
462 | } | 406 | } |
463 | -.note_author { | ||
464 | - float:left; | ||
465 | - width:60px; | ||
466 | -} | ||
467 | -.note_content { | ||
468 | - float:left; | ||
469 | - width:650px; | ||
470 | -} | ||
471 | 407 | ||
472 | .issue_notes { | 408 | .issue_notes { |
473 | .note_content { | 409 | .note_content { |
@@ -556,8 +492,7 @@ input.ssh_project_url { | @@ -556,8 +492,7 @@ input.ssh_project_url { | ||
556 | 492 | ||
557 | } | 493 | } |
558 | .commit, | 494 | .commit, |
559 | -.message, | ||
560 | -#notes-list{ | 495 | +.message{ |
561 | .author { | 496 | .author { |
562 | background: #eaeaea; | 497 | background: #eaeaea; |
563 | color: #333; | 498 | color: #333; |
@@ -574,7 +509,7 @@ input.ssh_project_url { | @@ -574,7 +509,7 @@ input.ssh_project_url { | ||
574 | font-size:14px; | 509 | font-size:14px; |
575 | } | 510 | } |
576 | 511 | ||
577 | -.wall_page { | 512 | +#new_note { |
578 | #note_note { | 513 | #note_note { |
579 | height:25px; | 514 | height:25px; |
580 | } | 515 | } |
@@ -596,6 +531,7 @@ input.ssh_project_url { | @@ -596,6 +531,7 @@ input.ssh_project_url { | ||
596 | @include round-borders-all(4px); | 531 | @include round-borders-all(4px); |
597 | padding:2px 4px; | 532 | padding:2px 4px; |
598 | border:none; | 533 | border:none; |
534 | + text-shadow:none; | ||
599 | 535 | ||
600 | &.high { | 536 | &.high { |
601 | background: #D12F19; | 537 | background: #D12F19; |
@@ -706,3 +642,44 @@ table.highlighttable pre{ | @@ -706,3 +642,44 @@ table.highlighttable pre{ | ||
706 | line-height:16px !important; | 642 | line-height:16px !important; |
707 | font-size:12px !important; | 643 | font-size:12px !important; |
708 | } | 644 | } |
645 | + | ||
646 | +.project-refs-form { | ||
647 | + span { | ||
648 | + background: none !important; | ||
649 | + position:static !important; | ||
650 | + width:auto !important; | ||
651 | + height: auto !important; | ||
652 | + } | ||
653 | +} | ||
654 | + | ||
655 | +.project-refs-select { | ||
656 | + width:200px; | ||
657 | +} | ||
658 | + | ||
659 | +.issues_filter { | ||
660 | + margin-top:10px; | ||
661 | + .left { | ||
662 | + margin-right:15px; | ||
663 | + } | ||
664 | +} | ||
665 | + | ||
666 | +.cgray { color:gray; } | ||
667 | +.cred { color:#D12F19; } | ||
668 | +.cgreen { color:#44aa22; } | ||
669 | + | ||
670 | +body.project-page table .commit { | ||
671 | + a.tree-commit-link { | ||
672 | + color:gray; | ||
673 | + &:hover { | ||
674 | + text-decoration:underline; | ||
675 | + } | ||
676 | + } | ||
677 | +} | ||
678 | + | ||
679 | +body.project-page #notes-list .note {padding: 10px; border-bottom: 1px solid #eee; overflow: hidden; display: block;} | ||
680 | +body.project-page #notes-list .note {padding: 10px; border-bottom: 1px solid #eee; overflow: hidden; display: block;} | ||
681 | +body.project-page #notes-list .note img{float: left; margin-right: 10px;} | ||
682 | +body.project-page #notes-list .note span.note-title{display: block;} | ||
683 | +body.project-page #notes-list .note span.note-title{margin-bottom: 10px} | ||
684 | +body.project-page #notes-list .note span.note-author{color: #999; font-weight: normal; font-style: italic;} | ||
685 | +body.project-page #notes-list .note span.note-author strong{font-weight: bold; font-style: normal;} |
app/assets/stylesheets/style.scss
@@ -292,7 +292,7 @@ body.login-page{background-color: #f1f1f1; padding-top: 10%} | @@ -292,7 +292,7 @@ body.login-page{background-color: #f1f1f1; padding-top: 10%} | ||
292 | 292 | ||
293 | /* General */ | 293 | /* General */ |
294 | #container{background-color: white; overflow: hidden;} | 294 | #container{background-color: white; overflow: hidden;} |
295 | -/*#container{margin: auto; width: 980px; border: 1px solid rgba(0,0,0,.22); border-top: 0; box-shadow: 0 0 0px 4px rgba(0,0,0,.04)}*/ | 295 | +body.collapsed #container{margin: auto; width: 980px; border: 1px solid rgba(0,0,0,.22); border-top: 0; box-shadow: 0 0 0px 4px rgba(0,0,0,.04)} |
296 | 296 | ||
297 | 297 | ||
298 | 298 | ||
@@ -323,6 +323,7 @@ header nav{border-radius: 4px; box-shadow: 0 1px 2px black; width: 294px; margin | @@ -323,6 +323,7 @@ header nav{border-radius: 4px; box-shadow: 0 1px 2px black; width: 294px; margin | ||
323 | background-image: -moz-linear-gradient(#595d63 6.6%, #31363e); | 323 | background-image: -moz-linear-gradient(#595d63 6.6%, #31363e); |
324 | background-image: -o-linear-gradient(#595d63 6.6%, #31363e); | 324 | background-image: -o-linear-gradient(#595d63 6.6%, #31363e); |
325 | margin-top: 2px; | 325 | margin-top: 2px; |
326 | + height:30px | ||
326 | } | 327 | } |
327 | header nav a{padding: 8px 12px 8px 34px; display: inline-block; color: #D6DADF; border-right: 1px solid #31363E; position: relative; box-shadow: 1px 0 0 rgba(255,255,255,.1); margin: 0} | 328 | header nav a{padding: 8px 12px 8px 34px; display: inline-block; color: #D6DADF; border-right: 1px solid #31363E; position: relative; box-shadow: 1px 0 0 rgba(255,255,255,.1); margin: 0} |
328 | header nav a span{width: 20px; height: 20px; display: inline-block; background: red; position: absolute; left: 8px; top: 6px;} | 329 | header nav a span{width: 20px; height: 20px; display: inline-block; background: red; position: absolute; left: 8px; top: 6px;} |
@@ -0,0 +1,30 @@ | @@ -0,0 +1,30 @@ | ||
1 | +.tags-list { | ||
2 | + padding : 0px 10px 10px 10px; | ||
3 | + | ||
4 | +} | ||
5 | + | ||
6 | +.tags-list a { | ||
7 | + display: inline-block; | ||
8 | + padding: 8px 11px 8px 11px; | ||
9 | + margin: 1px 5px 0px 0px; | ||
10 | + border-radius: 4px; | ||
11 | + border: 1px solid #72bbdf; | ||
12 | + background-color: #72bbdf; | ||
13 | + color: #0f326d; | ||
14 | + font-weight: bold; | ||
15 | + font-size: 14px; | ||
16 | +} | ||
17 | + | ||
18 | + | ||
19 | +.small-tags a{ | ||
20 | + font-size: 9px; | ||
21 | + | ||
22 | + display: inline-block; | ||
23 | + padding: 2px 3px 1px 3px; | ||
24 | + margin: 0px 3px 0px 0px; | ||
25 | + border-radius: 2px; | ||
26 | + background-color: #72bbdf; | ||
27 | + color: #FFF; | ||
28 | + text-shadow: none; | ||
29 | + font-weight: bold; | ||
30 | +} | ||
0 | \ No newline at end of file | 31 | \ No newline at end of file |
app/controllers/application_controller.rb
1 | class ApplicationController < ActionController::Base | 1 | class ApplicationController < ActionController::Base |
2 | before_filter :authenticate_user! | 2 | before_filter :authenticate_user! |
3 | + before_filter :view_style | ||
4 | + | ||
3 | protect_from_forgery | 5 | protect_from_forgery |
4 | 6 | ||
5 | helper_method :abilities, :can? | 7 | helper_method :abilities, :can? |
@@ -57,19 +59,13 @@ class ApplicationController < ActionController::Base | @@ -57,19 +59,13 @@ class ApplicationController < ActionController::Base | ||
57 | end | 59 | end |
58 | 60 | ||
59 | def load_refs | 61 | def load_refs |
60 | - @branch = unless params[:branch].blank? | ||
61 | - params[:branch] | ||
62 | - else | ||
63 | - nil | ||
64 | - end | ||
65 | - | ||
66 | - @tag = unless params[:tag].blank? | ||
67 | - params[:tag] | ||
68 | - else | ||
69 | - nil | ||
70 | - end | ||
71 | - | ||
72 | - @ref = @branch || @tag || "master" | 62 | + unless params[:ref].blank? |
63 | + @ref = params[:ref] | ||
64 | + else | ||
65 | + @branch = params[:branch].blank? ? nil : params[:branch] | ||
66 | + @tag = params[:tag].blank? ? nil : params[:tag] | ||
67 | + @ref = @branch || @tag || "master" | ||
68 | + end | ||
73 | end | 69 | end |
74 | 70 | ||
75 | def render_404 | 71 | def render_404 |
@@ -79,4 +75,30 @@ class ApplicationController < ActionController::Base | @@ -79,4 +75,30 @@ class ApplicationController < ActionController::Base | ||
79 | def require_non_empty_project | 75 | def require_non_empty_project |
80 | redirect_to @project unless @project.repo_exists? | 76 | redirect_to @project unless @project.repo_exists? |
81 | end | 77 | end |
78 | + | ||
79 | + def view_style | ||
80 | + if params[:view_style] == "collapsed" | ||
81 | + cookies[:view_style] = "collapsed" | ||
82 | + elsif params[:view_style] == "fluid" | ||
83 | + cookies[:view_style] = "" | ||
84 | + end | ||
85 | + | ||
86 | + @view_mode = if cookies[:view_style] == "collapsed" | ||
87 | + :fixed | ||
88 | + else | ||
89 | + :fluid | ||
90 | + end | ||
91 | + end | ||
92 | + | ||
93 | + def respond_with_notes | ||
94 | + if params[:last_id] && params[:first_id] | ||
95 | + @notes = @notes.where("id >= ?", params[:first_id]) | ||
96 | + elsif params[:last_id] | ||
97 | + @notes = @notes.where("id > ?", params[:last_id]) | ||
98 | + elsif params[:first_id] | ||
99 | + @notes = @notes.where("id < ?", params[:first_id]) | ||
100 | + else | ||
101 | + nil | ||
102 | + end | ||
103 | + end | ||
82 | end | 104 | end |
app/controllers/commits_controller.rb
@@ -13,11 +13,12 @@ class CommitsController < ApplicationController | @@ -13,11 +13,12 @@ class CommitsController < ApplicationController | ||
13 | load_refs # load @branch, @tag & @ref | 13 | load_refs # load @branch, @tag & @ref |
14 | 14 | ||
15 | @repo = project.repo | 15 | @repo = project.repo |
16 | + limit, offset = (params[:limit] || 20), (params[:offset] || 0) | ||
16 | 17 | ||
17 | if params[:path] | 18 | if params[:path] |
18 | - @commits = @repo.log(@ref, params[:path], :max_count => params[:limit] || 100, :skip => params[:offset] || 0) | 19 | + @commits = @repo.log(@ref, params[:path], :max_count => limit, :skip => offset) |
19 | else | 20 | else |
20 | - @commits = @repo.commits(@ref, params[:limit] || 100, params[:offset] || 0) | 21 | + @commits = @repo.commits(@ref, limit, offset) |
21 | end | 22 | end |
22 | 23 | ||
23 | respond_to do |format| | 24 | respond_to do |format| |
@@ -28,12 +29,12 @@ class CommitsController < ApplicationController | @@ -28,12 +29,12 @@ class CommitsController < ApplicationController | ||
28 | 29 | ||
29 | def show | 30 | def show |
30 | @commit = project.repo.commits(params[:id]).first | 31 | @commit = project.repo.commits(params[:id]).first |
31 | - @notes = project.notes.where(:noteable_id => @commit.id, :noteable_type => "Commit") | 32 | + @notes = project.notes.where(:noteable_id => @commit.id, :noteable_type => "Commit").order("created_at DESC").limit(20) |
32 | @note = @project.notes.new(:noteable_id => @commit.id, :noteable_type => "Commit") | 33 | @note = @project.notes.new(:noteable_id => @commit.id, :noteable_type => "Commit") |
33 | 34 | ||
34 | - respond_to do |format| | ||
35 | - format.html # show.html.erb | ||
36 | - format.js | 35 | + respond_to do |format| |
36 | + format.html | ||
37 | + format.js { respond_with_notes } | ||
37 | end | 38 | end |
38 | end | 39 | end |
39 | end | 40 | end |
app/controllers/issues_controller.rb
@@ -35,8 +35,13 @@ class IssuesController < ApplicationController | @@ -35,8 +35,13 @@ class IssuesController < ApplicationController | ||
35 | end | 35 | end |
36 | 36 | ||
37 | def show | 37 | def show |
38 | - @notes = @issue.notes.order("created_at ASC") | 38 | + @notes = @issue.notes.order("created_at DESC").limit(20) |
39 | @note = @project.notes.new(:noteable => @issue) | 39 | @note = @project.notes.new(:noteable => @issue) |
40 | + | ||
41 | + respond_to do |format| | ||
42 | + format.html | ||
43 | + format.js { respond_with_notes } | ||
44 | + end | ||
40 | end | 45 | end |
41 | 46 | ||
42 | def create | 47 | def create |
app/controllers/projects_controller.rb
@@ -10,7 +10,9 @@ class ProjectsController < ApplicationController | @@ -10,7 +10,9 @@ class ProjectsController < ApplicationController | ||
10 | before_filter :require_non_empty_project, :only => [:blob, :tree] | 10 | before_filter :require_non_empty_project, :only => [:blob, :tree] |
11 | 11 | ||
12 | def index | 12 | def index |
13 | - @projects = current_user.projects.all | 13 | + source = current_user.projects |
14 | + source = source.tagged_with(params[:tag]) unless params[:tag].blank? | ||
15 | + @projects = source.all | ||
14 | end | 16 | end |
15 | 17 | ||
16 | def new | 18 | def new |
@@ -86,13 +88,12 @@ class ProjectsController < ApplicationController | @@ -86,13 +88,12 @@ class ProjectsController < ApplicationController | ||
86 | def wall | 88 | def wall |
87 | @note = Note.new | 89 | @note = Note.new |
88 | @notes = @project.common_notes.order("created_at DESC") | 90 | @notes = @project.common_notes.order("created_at DESC") |
91 | + @notes = @notes.fresh.limit(20) | ||
89 | 92 | ||
90 | - @notes = case params[:view] | ||
91 | - when "week" then @notes.since((Date.today - 7.days).at_beginning_of_day) | ||
92 | - when "all" then @notes.all | ||
93 | - when "day" then @notes.since(Date.today.at_beginning_of_day) | ||
94 | - else @notes.fresh.limit(10) | ||
95 | - end | 93 | + respond_to do |format| |
94 | + format.html | ||
95 | + format.js { respond_with_notes } | ||
96 | + end | ||
96 | end | 97 | end |
97 | 98 | ||
98 | # | 99 | # |
@@ -0,0 +1,11 @@ | @@ -0,0 +1,11 @@ | ||
1 | +class TagsController < ApplicationController | ||
2 | + def index | ||
3 | + @tags = Project.tag_counts.order('count DESC') | ||
4 | + @tags = @tags.where('name like ?', "%#{params[:term]}%") unless params[:term].blank? | ||
5 | + | ||
6 | + respond_to do |format| | ||
7 | + format.html | ||
8 | + format.json { render json: @tags.limit(8).map {|t| t.name}} | ||
9 | + end | ||
10 | + end | ||
11 | +end |
app/helpers/application_helper.rb
@@ -4,6 +4,18 @@ module ApplicationHelper | @@ -4,6 +4,18 @@ module ApplicationHelper | ||
4 | "http://www.gravatar.com/avatar/#{Digest::MD5.hexdigest(user_email)}?s=40&d=identicon" | 4 | "http://www.gravatar.com/avatar/#{Digest::MD5.hexdigest(user_email)}?s=40&d=identicon" |
5 | end | 5 | end |
6 | 6 | ||
7 | + def fixed_mode? | ||
8 | + @view_mode == :fixed | ||
9 | + end | ||
10 | + | ||
11 | + def body_class(default_class = nil) | ||
12 | + main = content_for(:body_class).blank? ? | ||
13 | + default_class : | ||
14 | + content_for(:body_class) | ||
15 | + | ||
16 | + [main, cookies[:view_style]].join(" ") | ||
17 | + end | ||
18 | + | ||
7 | def commit_name(project, commit) | 19 | def commit_name(project, commit) |
8 | if project.commit.id == commit.id | 20 | if project.commit.id == commit.id |
9 | "master" | 21 | "master" |
@@ -32,6 +44,15 @@ module ApplicationHelper | @@ -32,6 +44,15 @@ module ApplicationHelper | ||
32 | "Never" | 44 | "Never" |
33 | end | 45 | end |
34 | 46 | ||
47 | + def grouped_options_refs | ||
48 | + options = [ | ||
49 | + ["Branch", @repo.heads.map(&:name) ], | ||
50 | + [ "Tag", @project.tags ] | ||
51 | + ] | ||
52 | + | ||
53 | + grouped_options_for_select(options, @ref) | ||
54 | + end | ||
55 | + | ||
35 | def markdown(text) | 56 | def markdown(text) |
36 | RDiscount.new(text, :autolink, :no_pseudo_protocols, :safelink, :smart, :filter_html).to_html.html_safe | 57 | RDiscount.new(text, :autolink, :no_pseudo_protocols, :safelink, :smart, :filter_html).to_html.html_safe |
37 | end | 58 | end |
app/models/key.rb
@@ -8,7 +8,7 @@ class Key < ActiveRecord::Base | @@ -8,7 +8,7 @@ class Key < ActiveRecord::Base | ||
8 | validates :key, | 8 | validates :key, |
9 | :presence => true, | 9 | :presence => true, |
10 | :uniqueness => true, | 10 | :uniqueness => true, |
11 | - :length => { :within => 0..1024 } | 11 | + :length => { :within => 0..1600 } |
12 | 12 | ||
13 | before_save :set_identifier | 13 | before_save :set_identifier |
14 | after_save :update_gitosis | 14 | after_save :update_gitosis |
app/models/project.rb
@@ -9,6 +9,8 @@ class Project < ActiveRecord::Base | @@ -9,6 +9,8 @@ class Project < ActiveRecord::Base | ||
9 | has_many :notes, :dependent => :destroy | 9 | has_many :notes, :dependent => :destroy |
10 | has_many :snippets, :dependent => :destroy | 10 | has_many :snippets, :dependent => :destroy |
11 | 11 | ||
12 | + acts_as_taggable | ||
13 | + | ||
12 | validates :name, | 14 | validates :name, |
13 | :uniqueness => true, | 15 | :uniqueness => true, |
14 | :presence => true, | 16 | :presence => true, |
@@ -48,6 +50,11 @@ class Project < ActiveRecord::Base | @@ -48,6 +50,11 @@ class Project < ActiveRecord::Base | ||
48 | code | 50 | code |
49 | end | 51 | end |
50 | 52 | ||
53 | + def team_member_by_name_or_email(email = nil, name = nil) | ||
54 | + user = users.where("email like ? or name like ?", email, name).first | ||
55 | + users_projects.find_by_user_id(user.id) if user | ||
56 | + end | ||
57 | + | ||
51 | def common_notes | 58 | def common_notes |
52 | notes.where(:noteable_type => ["", nil]) | 59 | notes.where(:noteable_type => ["", nil]) |
53 | end | 60 | end |
app/views/commits/_commits.html.haml
@@ -17,9 +17,8 @@ | @@ -17,9 +17,8 @@ | ||
17 | = image_tag "no_avatar.png", :class => "left", :width => 40, :style => "padding-right:5px;" | 17 | = image_tag "no_avatar.png", :class => "left", :width => 40, :style => "padding-right:5px;" |
18 | %span.commit-title | 18 | %span.commit-title |
19 | %strong | 19 | %strong |
20 | - = truncate(commit.safe_message, :length => 60) | 20 | + = truncate(commit.safe_message, :length => fixed_mode? ? 60 : 120) |
21 | %span.commit-author | 21 | %span.commit-author |
22 | %strong= commit.author_name | 22 | %strong= commit.author_name |
23 | = time_ago_in_words(commit.committed_date) | 23 | = time_ago_in_words(commit.committed_date) |
24 | ago | 24 | ago |
25 | -= more_commits_link if @commits.size > 99 |
app/views/commits/index.html.haml
1 | - content_for(:body_class, "project-page commits-page") | 1 | - content_for(:body_class, "project-page commits-page") |
2 | 2 | ||
3 | -.left | ||
4 | - = form_tag project_commits_path(@project), :method => :get do | ||
5 | - = select_tag "branch", options_for_select(@repo.heads.map(&:name), @branch), :onchange => "this.form.submit();", :class => "", :prompt => "Branches" | ||
6 | -.left | ||
7 | - = form_tag project_commits_path(@project), :method => :get do | ||
8 | - = select_tag "tag", options_for_select(@project.tags, @tag), :onchange => "this.form.submit();", :class => "", :prompt => "Tags" | ||
9 | -.clear | ||
10 | - | ||
11 | -%br | ||
12 | - | ||
13 | - | ||
14 | -#%a.right.button{:href => "#"} Download | 3 | -#%a.right.button{:href => "#"} Download |
15 | -#-if can? current_user, :admin_project, @project | 4 | -#-if can? current_user, :admin_project, @project |
16 | %a.right.button.blue{:href => "#"} EDIT | 5 | %a.right.button.blue{:href => "#"} EDIT |
17 | %h2.icon | 6 | %h2.icon |
18 | %span | 7 | %span |
19 | - %a.project-name{:href => "#"} | ||
20 | - %i.arrow> | ||
21 | - Project | ||
22 | - | ||
23 | %d | 8 | %d |
24 | - %a{:href => "#"} | ||
25 | - = @ref | ||
26 | - - if params[:path] | ||
27 | - | ||
28 | - %d | 9 | + = link_to project_commits_path(@project) do |
10 | + = @project.name | ||
11 | + - if params[:path] | ||
12 | + \/ | ||
29 | %a{:href => "#"}= params[:path].split("/").join(" / ") | 13 | %a{:href => "#"}= params[:path].split("/").join(" / ") |
30 | 14 | ||
15 | +.right= render :partial => "projects/refs", :locals => { :destination => project_commits_path(@project) } | ||
31 | 16 | ||
32 | %div{:id => dom_id(@project)} | 17 | %div{:id => dom_id(@project)} |
33 | - = render "commits" | 18 | + #commits_list= render "commits" |
19 | +.clear | ||
20 | +.loading{ :style => "display:none;"} | ||
21 | + %center= image_tag "ajax-loader.gif" | ||
22 | + | ||
23 | + | ||
24 | + | ||
25 | +:javascript | ||
26 | + $(function(){ | ||
27 | + CommitsList.init("#{@ref}", 20); | ||
28 | + }); |
app/views/commits/index.js.erb
app/views/commits/show.html.haml
1 | %h3 | 1 | %h3 |
2 | - = "[ #{@commit.committer} ] #{truncate(@commit.safe_message)}" | 2 | + = "[ #{@commit.author_name} ] #{truncate(@commit.safe_message, :length => 70)}" |
3 | -#= link_to 'Back', project_commits_path(@project), :class => "button" | 3 | -#= link_to 'Back', project_commits_path(@project), :class => "button" |
4 | %table.round-borders | 4 | %table.round-borders |
5 | %tr | 5 | %tr |
@@ -9,11 +9,8 @@ | @@ -9,11 +9,8 @@ | ||
9 | %td Author | 9 | %td Author |
10 | %td= @commit.author_name | 10 | %td= @commit.author_name |
11 | %tr | 11 | %tr |
12 | - %td Commiter | ||
13 | - %td= @commit.committer | ||
14 | - %tr | ||
15 | %td Commited Date | 12 | %td Commited Date |
16 | - %td= @commit.committed_date | 13 | + %td= @commit.committed_date.stamp("21 Aug 2011, 11:15pm") |
17 | %tr | 14 | %tr |
18 | %td Message | 15 | %td Message |
19 | %td | 16 | %td |
@@ -24,18 +21,7 @@ | @@ -24,18 +21,7 @@ | ||
24 | %td= link_to 'Browse Code', tree_project_path(@project, :commit_id => @commit.id) | 21 | %td= link_to 'Browse Code', tree_project_path(@project, :commit_id => @commit.id) |
25 | .clear | 22 | .clear |
26 | 23 | ||
27 | -#tabs | ||
28 | - %ul | ||
29 | - %li | ||
30 | - %a{ :href => "#tabs-1" } Diff | ||
31 | - %li | ||
32 | - %a{ :href => "#tabs-2" } Comments | ||
33 | - %span{ :class => "notes_count" }= @notes.count | ||
34 | - %hr | ||
35 | - #tabs-1 | ||
36 | - = render "commits/diff" | ||
37 | - #tabs-2 | ||
38 | - = render "notes/notes" | 24 | +%br |
39 | 25 | ||
40 | -:javascript | ||
41 | - $(function() { $( "#tabs" ).tabs(); }); | 26 | += render "commits/diff" |
27 | += render "notes/notes" |
app/views/commits/show.js.haml
1 | --#:plain | ||
2 | - $("#side-commit-preview").remove(); | ||
3 | - var side = $("<div id='side-commit-preview'></div>"); | ||
4 | - side.html("#{escape_javascript(render "commits/show")}"); | ||
5 | - $("##{dom_id(@project)}").parent().append(side); | ||
6 | - $("##{dom_id(@project)}").addClass("span-14"); | ||
7 | -:plain | ||
8 | - $("#notes-list").html("#{escape_javascript(render(:partial => 'notes/notes_list'))}"); | 1 | += render "notes/load" |
app/views/issues/_issues.html.haml
@@ -6,7 +6,6 @@ | @@ -6,7 +6,6 @@ | ||
6 | %th ID | 6 | %th ID |
7 | %th Title | 7 | %th Title |
8 | %th Closed? | 8 | %th Closed? |
9 | - %th | ||
10 | 9 | ||
11 | - @issues.critical.each do |issue| | 10 | - @issues.critical.each do |issue| |
12 | = render(:partial => 'show', :locals => {:issue => issue}) | 11 | = render(:partial => 'show', :locals => {:issue => issue}) |
app/views/issues/_show.html.haml
@@ -4,15 +4,24 @@ | @@ -4,15 +4,24 @@ | ||
4 | = image_tag "move.png" , :class => [:handle, :left] | 4 | = image_tag "move.png" , :class => [:handle, :left] |
5 | %td | 5 | %td |
6 | = image_tag gravatar_icon(issue.assignee.email), :class => "left", :width => 40, :style => "padding:0 5px;" | 6 | = image_tag gravatar_icon(issue.assignee.email), :class => "left", :width => 40, :style => "padding:0 5px;" |
7 | - = truncate issue.assignee.name, :lenght => 20 | 7 | + = issue.assignee.name |
8 | %td ##{issue.id} | 8 | %td ##{issue.id} |
9 | %td | 9 | %td |
10 | - = truncate(html_escape(issue.title), :length => 60) | 10 | + = truncate(html_escape(issue.title), :length => 200) |
11 | + %br | ||
11 | %br | 12 | %br |
12 | - if issue.critical | 13 | - if issue.critical |
13 | %span.tag.high critical | 14 | %span.tag.high critical |
14 | - if issue.today? | 15 | - if issue.today? |
15 | %span.tag.today today | 16 | %span.tag.today today |
17 | + | ||
18 | + .right | ||
19 | + - if can?(current_user, :admin_issue, @project) || issue.author == current_user | ||
20 | + = link_to 'Edit', edit_project_issue_path(@project, issue), :class => "cgray", :remote => true | ||
21 | + - if can?(current_user, :admin_issue, @project) || issue.author == current_user | ||
22 | + | ||
23 | + = link_to 'Destroy', [@project, issue], :confirm => 'Are you sure?', :method => :delete, :remote => true, :class => "cred delete-issue negative", :id => "destroy_issue_#{issue.id}" | ||
24 | + | ||
16 | -#- if issue.author == current_user | 25 | -#- if issue.author == current_user |
17 | -#%span.tag.yours yours | 26 | -#%span.tag.yours yours |
18 | -#- if issue.notes.count > 0 | 27 | -#- if issue.notes.count > 0 |
@@ -26,8 +35,3 @@ | @@ -26,8 +35,3 @@ | ||
26 | = hidden_field_tag :status_only, true | 35 | = hidden_field_tag :status_only, true |
27 | - else | 36 | - else |
28 | = check_box_tag "closed", 1, issue.closed, :disabled => true | 37 | = check_box_tag "closed", 1, issue.closed, :disabled => true |
29 | - %td | ||
30 | - - if can?(current_user, :admin_issue, @project) || issue.author == current_user | ||
31 | - = link_to 'Edit', edit_project_issue_path(@project, issue), :class => "lbutton positive", :remote => true | ||
32 | - - if can?(current_user, :admin_issue, @project) || issue.author == current_user | ||
33 | - = link_to 'Destroy', [@project, issue], :confirm => 'Are you sure?', :method => :delete, :remote => true, :class => "lbutton delete-issue negative", :id => "destroy_issue_#{issue.id}" |
app/views/issues/index.html.haml
@@ -7,18 +7,18 @@ | @@ -7,18 +7,18 @@ | ||
7 | = hidden_field_tag :project_id, @project.id, { :id => 'project_id' } | 7 | = hidden_field_tag :project_id, @project.id, { :id => 'project_id' } |
8 | = search_field_tag :issue_search, nil, { :placeholder => 'Search', :class => 'issue_search' } | 8 | = search_field_tag :issue_search, nil, { :placeholder => 'Search', :class => 'issue_search' } |
9 | 9 | ||
10 | - .right | 10 | + .right.issues_filter |
11 | = form_tag project_issues_path(@project), :method => :get do | 11 | = form_tag project_issues_path(@project), :method => :get do |
12 | - .span-2 | 12 | + .left |
13 | = radio_button_tag :f, 0, (params[:f] || "0") == "0", :onclick => "this.form.submit()", :id => "open_issues", :class => "status" | 13 | = radio_button_tag :f, 0, (params[:f] || "0") == "0", :onclick => "this.form.submit()", :id => "open_issues", :class => "status" |
14 | = label_tag "open_issues","Open" | 14 | = label_tag "open_issues","Open" |
15 | - .span-2 | 15 | + .left |
16 | = radio_button_tag :f, 2, params[:f] == "2", :onclick => "this.form.submit()", :id => "closed_issues", :class => "status" | 16 | = radio_button_tag :f, 2, params[:f] == "2", :onclick => "this.form.submit()", :id => "closed_issues", :class => "status" |
17 | = label_tag "closed_issues","Closed" | 17 | = label_tag "closed_issues","Closed" |
18 | - .span-2 | 18 | + .left |
19 | = radio_button_tag :f, 3, params[:f] == "3", :onclick => "this.form.submit()", :id => "my_issues", :class => "status" | 19 | = radio_button_tag :f, 3, params[:f] == "3", :onclick => "this.form.submit()", :id => "my_issues", :class => "status" |
20 | = label_tag "my_issues","To Me" | 20 | = label_tag "my_issues","To Me" |
21 | - .span-2 | 21 | + .left |
22 | = radio_button_tag :f, 1, params[:f] == "1", :onclick => "this.form.submit()", :id => "all_issues", :class => "status" | 22 | = radio_button_tag :f, 1, params[:f] == "1", :onclick => "this.form.submit()", :id => "all_issues", :class => "status" |
23 | = label_tag "all_issues","All" | 23 | = label_tag "all_issues","All" |
24 | 24 |
app/views/issues/show.html.haml
1 | %h2 | 1 | %h2 |
2 | - = "Issue ##{@issue.id} - #{html_escape(@issue.title)}" | 2 | + %strong |
3 | + Issue | ||
4 | + = "##{@issue.id}" | ||
5 | + – | ||
6 | + = html_escape(@issue.title) | ||
3 | .left.width-65p | 7 | .left.width-65p |
4 | - -#= simple_format html_escape(@issue.content) | ||
5 | .issue_notes= render "notes/notes" | 8 | .issue_notes= render "notes/notes" |
9 | + | ||
10 | + .loading{ :style => "display:none;"} | ||
11 | + %center= image_tag "ajax-loader.gif" | ||
6 | .right.width-30p | 12 | .right.width-30p |
7 | .span-8 | 13 | .span-8 |
8 | - - if @issue.closed | ||
9 | - %center.success Closed | ||
10 | - - else | ||
11 | - %center.error Open | ||
12 | %table.round-borders | 14 | %table.round-borders |
13 | %tr | 15 | %tr |
14 | - %td Title: | ||
15 | - %td | ||
16 | - = truncate html_escape(@issue.title) | ||
17 | - %tr | ||
18 | - %td Project | ||
19 | - %td | ||
20 | - %strong= @issue.project.name | ||
21 | - %tr | ||
22 | %td Author: | 16 | %td Author: |
23 | %td | 17 | %td |
24 | = image_tag gravatar_icon(@issue.author.email), :class => "left", :width => 40, :style => "padding:0 5px;" | 18 | = image_tag gravatar_icon(@issue.author.email), :class => "left", :width => 40, :style => "padding:0 5px;" |
@@ -41,7 +35,7 @@ | @@ -41,7 +35,7 @@ | ||
41 | %tr | 35 | %tr |
42 | %td Closed? | 36 | %td Closed? |
43 | %td | 37 | %td |
44 | - - if can? current_user, :write_issue, @project | 38 | + - if can? current_user, :write_issue, @issue |
45 | = form_for([@project, @issue]) do |f| | 39 | = form_for([@project, @issue]) do |f| |
46 | = f.check_box :closed, :onclick => "$(this).parent().submit();" | 40 | = f.check_box :closed, :onclick => "$(this).parent().submit();" |
47 | = hidden_field_tag :status_only, true | 41 | = hidden_field_tag :status_only, true |
@@ -49,9 +43,9 @@ | @@ -49,9 +43,9 @@ | ||
49 | = check_box_tag "closed", 1, @issue.closed, :disabled => true | 43 | = check_box_tag "closed", 1, @issue.closed, :disabled => true |
50 | 44 | ||
51 | 45 | ||
52 | - - if can?(current_user, :admin_issue, @issue) | 46 | + - if can?(current_user, :write_issue, @issue) |
53 | .clear | 47 | .clear |
54 | - = link_to 'Edit', edit_project_issue_path(@project, @issue), :class => "lbutton positive", :remote => true | ||
55 | - .right= link_to 'Destroy', [@project, @issue], :confirm => 'Are you sure?', :method => :delete, :class => "lbutton delete-issue negative", :id => "destroy_issue_#{@issue.id}" | 48 | + %br |
49 | + = link_to 'Edit', edit_project_issue_path(@project, @issue), :class => "lbutton positive", :remote => true | ||
50 | + .right= link_to 'Destroy', [@project, @issue], :confirm => 'Are you sure?', :method => :delete, :class => "lbutton delete-issue negative", :id => "destroy_issue_#{@issue.id}" | ||
56 | .clear | 51 | .clear |
57 | - |
app/views/issues/show.js.haml
app/views/layouts/_head_panel.html.erb
1 | <!-- Page Header --> | 1 | <!-- Page Header --> |
2 | <header> | 2 | <header> |
3 | -<h1 class="logo"> | ||
4 | - <a href="/">GITLAB</a></h1> | ||
5 | - <div class="login-top"> | ||
6 | - <%= link_to profile_path, :class => "pic" do %> | ||
7 | - <%= image_tag gravatar_icon(current_user.email) %> | ||
8 | - <% end %> | ||
9 | - <%= link_to profile_path, :class => "username" do %> | ||
10 | - <%= current_user.name %> | ||
11 | - <% end %> | ||
12 | - <%= link_to 'Logout', destroy_user_session_path, :class => "logout", :method => :delete %> | 3 | + <h1 class="logo"> |
4 | + <a href="/">GITLAB</a> | ||
5 | + </h1> | ||
6 | + <div class="account-box"> | ||
7 | + <%= link_to profile_path, :class => "pic" do %> | ||
8 | + <%= image_tag gravatar_icon(current_user.email) %> | ||
9 | + <% end %> | ||
10 | + | ||
11 | + <a href="#" class="arrow-up"></a> | ||
12 | + | ||
13 | + <div class="account-links"> | ||
14 | + <%= link_to profile_path, :class => "username" do %> | ||
15 | + <%#= current_user.name %> | ||
16 | + Your profile | ||
17 | + <% end %> | ||
18 | + <%= link_to "Fluid layout", url_for( :view_style => 'fluid' ) if cookies[:view_style] == "collapsed"%> | ||
19 | + <%= link_to "Fixed layout", url_for( :view_style => 'collapsed' ) unless cookies[:view_style] == "collapsed"%> | ||
20 | + <%= link_to 'Logout', destroy_user_session_path, :class => "logout", :method => :delete %> | ||
13 | </div> | 21 | </div> |
14 | - <div class="search"> | ||
15 | - <%= text_field_tag "search", nil, :placeholder => "Search", :class => "search-input" %> | ||
16 | - </div> | 22 | + </div><!-- .account-box --> |
23 | + | ||
24 | + <div class="search"> | ||
25 | + <%= text_field_tag "search", nil, :placeholder => "Search", :class => "search-input" %> | ||
26 | + </div> | ||
17 | <!-- .login-top --> | 27 | <!-- .login-top --> |
18 | <nav> | 28 | <nav> |
19 | <%= link_to dashboard_path, :class => current_page?(root_path) ? "current dashboard" : "dashboard" do %> | 29 | <%= link_to dashboard_path, :class => current_page?(root_path) ? "current dashboard" : "dashboard" do %> |
@@ -26,23 +36,10 @@ | @@ -26,23 +36,10 @@ | ||
26 | <span></span>Admin | 36 | <span></span>Admin |
27 | <% end %> | 37 | <% end %> |
28 | </nav> | 38 | </nav> |
39 | + | ||
29 | </header> | 40 | </header> |
30 | <!-- eo Page Header --> | 41 | <!-- eo Page Header --> |
31 | 42 | ||
32 | -<div id="header-panel" style="display:none"> | ||
33 | - <div class="container"> | ||
34 | - <div class="span-24"> | ||
35 | - <div class="span-10"> | ||
36 | - <span class="search-holder"> | ||
37 | - </span> | ||
38 | - </div> | ||
39 | - <div class="right"> | ||
40 | - <%= link_to truncate(@project.name, :length => 20), project_path(@project), :class => "current button" if @project && !@project.new_record? %> | ||
41 | - </div> | ||
42 | - </div> | ||
43 | - </div> | ||
44 | -</div> | ||
45 | - | ||
46 | <% if current_user %> | 43 | <% if current_user %> |
47 | <%= javascript_tag do %> | 44 | <%= javascript_tag do %> |
48 | $(function() { | 45 | $(function() { |
app/views/layouts/admin.html.haml
@@ -6,11 +6,10 @@ | @@ -6,11 +6,10 @@ | ||
6 | = stylesheet_link_tag "application" | 6 | = stylesheet_link_tag "application" |
7 | = javascript_include_tag "application" | 7 | = javascript_include_tag "application" |
8 | = csrf_meta_tags | 8 | = csrf_meta_tags |
9 | - %link{:href => "/assets/favicon.png", :rel => "icon", :type => "image/png"}/ | ||
10 | = javascript_tag do | 9 | = javascript_tag do |
11 | REQ_URI = "#{request.env["REQUEST_URI"]}"; | 10 | REQ_URI = "#{request.env["REQUEST_URI"]}"; |
12 | REQ_REFFER = "#{request.env["HTTP_REFERER"]}"; | 11 | REQ_REFFER = "#{request.env["HTTP_REFERER"]}"; |
13 | - %body{ :class => content_for?(:body_class) ? yield(:body_class) : 'project-page', :id => yield(:boyd_id)} | 12 | + %body{ :class => body_class('project-page'), :id => yield(:boyd_id)} |
14 | #container | 13 | #container |
15 | = render :partial => "layouts/flash" | 14 | = render :partial => "layouts/flash" |
16 | = render :partial => "layouts/head_panel" | 15 | = render :partial => "layouts/head_panel" |
app/views/layouts/application.html.haml
@@ -2,22 +2,16 @@ | @@ -2,22 +2,16 @@ | ||
2 | %html | 2 | %html |
3 | %head | 3 | %head |
4 | %title | 4 | %title |
5 | - GitLab #{" - #{@project.name}" if @project && !@project.new_record?} | ||
6 | - -#= stylesheet_link_tag 'blueprint/screen', :media => "screen, projection" | ||
7 | - -#= stylesheet_link_tag 'blueprint/print', :media => "print" | ||
8 | - -#= stylesheet_link_tag 'blueprint/plugins/buttons/screen', :media => "screen, projection" | ||
9 | - -#= stylesheet_link_tag 'blueprint/plugins/link-icons/screen', :media => "screen, projection" | 5 | + GitLab |
10 | = stylesheet_link_tag "application" | 6 | = stylesheet_link_tag "application" |
11 | = javascript_include_tag "application" | 7 | = javascript_include_tag "application" |
12 | = csrf_meta_tags | 8 | = csrf_meta_tags |
13 | - %link{:href => "/assets/favicon.png", :rel => "icon", :type => "image/png"}/ | ||
14 | = javascript_tag do | 9 | = javascript_tag do |
15 | REQ_URI = "#{request.env["REQUEST_URI"]}"; | 10 | REQ_URI = "#{request.env["REQUEST_URI"]}"; |
16 | REQ_REFFER = "#{request.env["HTTP_REFERER"]}"; | 11 | REQ_REFFER = "#{request.env["HTTP_REFERER"]}"; |
17 | - %body{ :class => yield(:body_class), :id => yield(:boyd_id)} | 12 | + %body{ :class => body_class, :id => yield(:boyd_id)} |
18 | #container | 13 | #container |
19 | = render :partial => "layouts/flash" | 14 | = render :partial => "layouts/flash" |
20 | = render :partial => "layouts/head_panel" | 15 | = render :partial => "layouts/head_panel" |
21 | - %div{ :id => "main", :role => "main", :class => "container_4" } | ||
22 | - = render :partial => "layouts/page_title" | ||
23 | - = yield | 16 | + = render :partial => "layouts/page_title" |
17 | + = yield |
app/views/layouts/devise.html.haml
@@ -6,7 +6,6 @@ | @@ -6,7 +6,6 @@ | ||
6 | = stylesheet_link_tag "application" | 6 | = stylesheet_link_tag "application" |
7 | = javascript_include_tag "application" | 7 | = javascript_include_tag "application" |
8 | = csrf_meta_tags | 8 | = csrf_meta_tags |
9 | - %link{:href => "/assets/favicon.png", :rel => "icon", :type => "image/png"}/ | ||
10 | = javascript_tag do | 9 | = javascript_tag do |
11 | REQ_URI = "#{request.env["REQUEST_URI"]}"; | 10 | REQ_URI = "#{request.env["REQUEST_URI"]}"; |
12 | REQ_REFFER = "#{request.env["HTTP_REFERER"]}"; | 11 | REQ_REFFER = "#{request.env["HTTP_REFERER"]}"; |
app/views/layouts/profile.html.haml
@@ -6,11 +6,10 @@ | @@ -6,11 +6,10 @@ | ||
6 | = stylesheet_link_tag "application" | 6 | = stylesheet_link_tag "application" |
7 | = javascript_include_tag "application" | 7 | = javascript_include_tag "application" |
8 | = csrf_meta_tags | 8 | = csrf_meta_tags |
9 | - %link{:href => "/assets/favicon.png", :rel => "icon", :type => "image/png"}/ | ||
10 | = javascript_tag do | 9 | = javascript_tag do |
11 | REQ_URI = "#{request.env["REQUEST_URI"]}"; | 10 | REQ_URI = "#{request.env["REQUEST_URI"]}"; |
12 | REQ_REFFER = "#{request.env["HTTP_REFERER"]}"; | 11 | REQ_REFFER = "#{request.env["HTTP_REFERER"]}"; |
13 | - %body{ :class => content_for?(:body_class) ? yield(:body_class) : 'project-page', :id => yield(:boyd_id)} | 12 | + %body{ :class => body_class('project-page'), :id => yield(:boyd_id)} |
14 | #container | 13 | #container |
15 | = render :partial => "layouts/flash" | 14 | = render :partial => "layouts/flash" |
16 | = render :partial => "layouts/head_panel" | 15 | = render :partial => "layouts/head_panel" |
app/views/layouts/project.html.haml
@@ -6,40 +6,39 @@ | @@ -6,40 +6,39 @@ | ||
6 | = stylesheet_link_tag "application" | 6 | = stylesheet_link_tag "application" |
7 | = javascript_include_tag "application" | 7 | = javascript_include_tag "application" |
8 | = csrf_meta_tags | 8 | = csrf_meta_tags |
9 | - %link{:href => "/assets/favicon.png", :rel => "icon", :type => "image/png"}/ | ||
10 | = javascript_tag do | 9 | = javascript_tag do |
11 | REQ_URI = "#{request.env["REQUEST_URI"]}"; | 10 | REQ_URI = "#{request.env["REQUEST_URI"]}"; |
12 | REQ_REFFER = "#{request.env["HTTP_REFERER"]}"; | 11 | REQ_REFFER = "#{request.env["HTTP_REFERER"]}"; |
13 | - %body{ :class => content_for?(:body_class) ? yield(:body_class) : 'project-page', :id => yield(:boyd_id)} | 12 | + %body{ :class => body_class('project-page'), :id => yield(:boyd_id)} |
14 | #container | 13 | #container |
15 | = render :partial => "layouts/flash" | 14 | = render :partial => "layouts/flash" |
16 | = render :partial => "layouts/head_panel" | 15 | = render :partial => "layouts/head_panel" |
17 | .project-container | 16 | .project-container |
18 | .project-sidebar | 17 | .project-sidebar |
19 | .fixed | 18 | .fixed |
20 | - %input.git-url.text{:id => "", :name => "", :readonly => "", :type => "text", :value => @project.url_to_repo} | ||
21 | - %aside | ||
22 | - = link_to "History", project_path(@project), :class => current_page?(:controller => "projects", :action => "show", :id => @project) ? "current" : nil | ||
23 | - = link_to "Tree", tree_project_path(@project), :class => current_page?(:controller => "projects", :action => "tree", :id => @project) ? "current" : nil | ||
24 | - = link_to "Commits", project_commits_path(@project), :class => current_page?(:controller => "commits", :action => "index", :project_id => @project) ? "current" : nil | ||
25 | - = link_to team_project_path(@project), :class => (current_page?(:controller => "projects", :action => "team", :id => @project) || controller.controller_name == "team_members") ? "current" : nil do | ||
26 | - Team | ||
27 | - - if @project.users_projects.count > 0 | ||
28 | - %span{ :class => "number" }= @project.users_projects.count | ||
29 | - = link_to project_issues_path(@project), :class => (controller.controller_name == "issues") ? "current" : nil do | ||
30 | - Issues | ||
31 | - - if @project.issues.opened.count > 0 | ||
32 | - %span{ :class => "number" }= @project.issues.opened.count | ||
33 | - = link_to wall_project_path(@project), :class => current_page?(:controller => "projects", :action => "wall", :id => @project) ? "current" : nil do | ||
34 | - Wall | ||
35 | - - if @project.common_notes.count > 0 | ||
36 | - %span{ :class => "number" }= @project.common_notes.count | ||
37 | - = link_to project_snippets_path(@project), :class => (controller.controller_name == "snippets") ? "current" : nil do | ||
38 | - Snippets | ||
39 | - - if @project.snippets.count > 0 | ||
40 | - %span{ :class => "number" }= @project.snippets.non_expired.count | ||
41 | - - if @commit | ||
42 | - = link_to truncate(commit_name(@project,@commit), :length => 15), project_commit_path(@project, :id => @commit.id), :class => current_page?(:controller => "commits", :action => "show", :project_id => @project, :id => @commit.id) ? "current" : nil | 19 | + %input.git-url.text{:id => "", :name => "", :readonly => "", :type => "text", :value => @project.url_to_repo, :class => "one_click_select"} |
20 | + %aside | ||
21 | + = link_to "History", project_path(@project), :class => current_page?(:controller => "projects", :action => "show", :id => @project) ? "current" : nil | ||
22 | + = link_to "Tree", tree_project_path(@project), :class => current_page?(:controller => "projects", :action => "tree", :id => @project) ? "current" : nil | ||
23 | + = link_to "Commits", project_commits_path(@project), :class => current_page?(:controller => "commits", :action => "index", :project_id => @project) ? "current" : nil | ||
24 | + = link_to team_project_path(@project), :class => (current_page?(:controller => "projects", :action => "team", :id => @project) || controller.controller_name == "team_members") ? "current" : nil do | ||
25 | + Team | ||
26 | + - if @project.users_projects.count > 0 | ||
27 | + %span{ :class => "number" }= @project.users_projects.count | ||
28 | + = link_to project_issues_path(@project), :class => (controller.controller_name == "issues") ? "current" : nil do | ||
29 | + Issues | ||
30 | + - if @project.issues.opened.count > 0 | ||
31 | + %span{ :class => "number" }= @project.issues.opened.count | ||
32 | + = link_to wall_project_path(@project), :class => current_page?(:controller => "projects", :action => "wall", :id => @project) ? "current" : nil do | ||
33 | + Wall | ||
34 | + - if @project.common_notes.count > 0 | ||
35 | + %span{ :class => "number" }= @project.common_notes.count | ||
36 | + = link_to project_snippets_path(@project), :class => (controller.controller_name == "snippets") ? "current" : nil do | ||
37 | + Snippets | ||
38 | + - if @project.snippets.count > 0 | ||
39 | + %span{ :class => "number" }= @project.snippets.non_expired.count | ||
40 | + - if @commit | ||
41 | + = link_to truncate(commit_name(@project,@commit), :length => 15), project_commit_path(@project, :id => @commit.id), :class => current_page?(:controller => "commits", :action => "show", :project_id => @project, :id => @commit.id) ? "current" : nil | ||
43 | 42 | ||
44 | .project-content | 43 | .project-content |
45 | = yield | 44 | = yield |
@@ -0,0 +1,17 @@ | @@ -0,0 +1,17 @@ | ||
1 | +- unless @notes.blank? | ||
2 | + | ||
3 | + - if params[:last_id] && params[:first_id] | ||
4 | + :plain | ||
5 | + NoteList.replace(#{@notes.last.id}, #{@notes.first.id}, "#{escape_javascript(render(:partial => 'notes/notes_list'))}"); | ||
6 | + | ||
7 | + | ||
8 | + - elsif params[:last_id] | ||
9 | + :plain | ||
10 | + NoteList.prepend(#{@notes.first.id}, "#{escape_javascript(render(:partial => 'notes/notes_list'))}"); | ||
11 | + | ||
12 | + - elsif params[:first_id] | ||
13 | + :plain | ||
14 | + NoteList.append(#{@notes.last.id}, "#{escape_javascript(render(:partial => 'notes/notes_list'))}"); | ||
15 | + | ||
16 | + - else | ||
17 | + :plain |
app/views/notes/_notes.html.haml
1 | -- if controller.action_name == "wall" | ||
2 | - %ul#notes-list= render "notes/notes_list" | ||
3 | - | ||
4 | -- else | ||
5 | - %ul#notes-list= render "notes/notes_list" | ||
6 | - %br | ||
7 | - %br | ||
8 | - - if can? current_user, :write_note, @project | ||
9 | - = render "notes/form" | 1 | +- if can? current_user, :write_note, @project |
2 | + = render "notes/form" | ||
3 | +.clear | ||
4 | +%hr | ||
5 | +%ul#notes-list= render "notes/notes_list" | ||
10 | 6 | ||
11 | :javascript | 7 | :javascript |
12 | $('.delete-note').live('ajax:success', function() { | 8 | $('.delete-note').live('ajax:success', function() { |
@@ -20,8 +16,11 @@ | @@ -20,8 +16,11 @@ | ||
20 | $("#submit_note").removeAttr("disabled"); | 16 | $("#submit_note").removeAttr("disabled"); |
21 | }) | 17 | }) |
22 | 18 | ||
23 | -- if ["issues", "projects"].include?(controller.controller_name) | ||
24 | - :javascript | ||
25 | - $(function(){ | ||
26 | - var int =self.setInterval("updatePage()", 20000); | 19 | + $(function(){ |
20 | + $("#note_note").live("click", function(){ | ||
21 | + $(this).css("height", "100px"); | ||
22 | + $('.attach_holder').show(); | ||
27 | }); | 23 | }); |
24 | + | ||
25 | + NoteList.init("wall", #{@notes.last.try(:id) || 0}, #{@notes.first.try(:id) || 0}); | ||
26 | + }); |
app/views/notes/_show.html.haml
1 | -%li{:id => dom_id(note)} | ||
2 | - %div.note_author | ||
3 | - = image_tag gravatar_icon(note.author.email), :class => "left", :width => 40, :style => "padding-right:5px;" | ||
4 | - %div.note_content.left | ||
5 | - = markdown(note.note) | ||
6 | - - if note.attachment.url | ||
7 | - Attachment: | ||
8 | - = link_to note.attachment_identifier, note.attachment.url, :target => "_blank" | ||
9 | - %br | ||
10 | - %span.author= note.author.name | ||
11 | - %cite.ago | 1 | +%li{:id => dom_id(note), :class => "note"} |
2 | + = image_tag gravatar_icon(note.author.email), :class => "left", :width => 40, :style => "padding-right:5px;" | ||
3 | + %div.note-author | ||
4 | + %strong= note.author_name | ||
5 | + %cite.cgray | ||
12 | = time_ago_in_words(note.updated_at) | 6 | = time_ago_in_words(note.updated_at) |
13 | ago | 7 | ago |
14 | - %br | ||
15 | - - if(note.author_id == current_user.id) || can?(current_user, :admin_note, @project) | ||
16 | - = link_to 'Remove', [@project, note], :confirm => 'Are you sure?', :method => :delete, :remote => true, :class => "lbutton delete-note right negative" | 8 | + - if(note.author_id == current_user.id) || can?(current_user, :admin_note, @project) |
9 | + = link_to "Remove", [@project, note], :confirm => 'Are you sure?', :method => :delete, :remote => true, :class => "cred delete-note right" | ||
10 | + | ||
11 | + %div.note-title | ||
12 | + = markdown(note.note) | ||
13 | + - if note.attachment.url | ||
14 | + .right | ||
15 | + %span.file | ||
16 | + = link_to note.attachment_identifier, note.attachment.url, :target => "_blank" | ||
17 | .clear | 17 | .clear |
app/views/notes/create.js.haml
1 | - if @note.valid? | 1 | - if @note.valid? |
2 | :plain | 2 | :plain |
3 | $("#new_note .errors").remove(); | 3 | $("#new_note .errors").remove(); |
4 | - updatePage(); | ||
5 | $('#note_note').val(""); | 4 | $('#note_note').val(""); |
5 | + NoteList.prepend(#{@note.id}, "#{escape_javascript(render :partial => "notes/show", :locals => {:note => @note})}"); | ||
6 | - else | 6 | - else |
7 | :plain | 7 | :plain |
8 | $("#new_note").replaceWith("#{escape_javascript(render('form'))}"); | 8 | $("#new_note").replaceWith("#{escape_javascript(render('form'))}"); |
app/views/projects/_form.html.haml
@@ -25,6 +25,11 @@ | @@ -25,6 +25,11 @@ | ||
25 | .left= f.label :code | 25 | .left= f.label :code |
26 | %cite.right http://yourserver/ | 26 | %cite.right http://yourserver/ |
27 | %td= f.text_field :code, :placeholder => "example" | 27 | %td= f.text_field :code, :placeholder => "example" |
28 | + | ||
29 | + %tr | ||
30 | + %td= f.label :tag_list | ||
31 | + %td= f.text_area :tag_list, :placeholder => "project tags", :style => "height:50px", :id => :tag_field | ||
32 | + | ||
28 | .field | 33 | .field |
29 | = f.label :description | 34 | = f.label :description |
30 | %br/ | 35 | %br/ |
@@ -41,8 +46,25 @@ | @@ -41,8 +46,25 @@ | ||
41 | %h3.prepend-top Creating project & repository. Please wait for few minutes | 46 | %h3.prepend-top Creating project & repository. Please wait for few minutes |
42 | - else | 47 | - else |
43 | %h3.prepend-top Updating project & repository. Please wait for few minutes | 48 | %h3.prepend-top Updating project & repository. Please wait for few minutes |
49 | + | ||
44 | :javascript | 50 | :javascript |
45 | $('.new_project, .edit_project').bind('ajax:before', function() { | 51 | $('.new_project, .edit_project').bind('ajax:before', function() { |
46 | $(this).find(".form_content").hide(); | 52 | $(this).find(".form_content").hide(); |
47 | $('.ajax_loader').show(); | 53 | $('.ajax_loader').show(); |
48 | }); | 54 | }); |
55 | + | ||
56 | +:javascript | ||
57 | + $(function(){ | ||
58 | + var tag_field = $('#tag_field').tagify(); | ||
59 | + | ||
60 | + tag_field.tagify('inputField').autocomplete({ | ||
61 | + source: '/tags.json' | ||
62 | + }); | ||
63 | + | ||
64 | + | ||
65 | + $('form').submit( function() { | ||
66 | + var tag_field = $('#tag_field') | ||
67 | + tag_field.val( tag_field.tagify('serialize') ); | ||
68 | + return true; | ||
69 | + }); | ||
70 | + }) |
app/views/projects/_list.html.haml
@@ -10,7 +10,12 @@ | @@ -10,7 +10,12 @@ | ||
10 | 10 | ||
11 | - @projects.each do |project| | 11 | - @projects.each do |project| |
12 | %tr{ :class => "project", :url => project_path(project) } | 12 | %tr{ :class => "project", :url => project_path(project) } |
13 | - %td= project.name | 13 | + %td |
14 | + = project.name | ||
15 | + .small-tags | ||
16 | + - project.tag_list.each do |tag| | ||
17 | + = link_to tag, "/tags/#{tag}" | ||
18 | + | ||
14 | %td= truncate project.url_to_repo | 19 | %td= truncate project.url_to_repo |
15 | %td= project.code | 20 | %td= project.code |
16 | %td= check_box_tag "read", 1, project.readers.include?(current_user), :disabled => :disabled | 21 | %td= check_box_tag "read", 1, project.readers.include?(current_user), :disabled => :disabled |
@@ -0,0 +1,8 @@ | @@ -0,0 +1,8 @@ | ||
1 | += form_tag destination, :method => :get, :class => "project-refs-form" do | ||
2 | + = select_tag "ref", grouped_options_refs, :onchange => "this.form.submit();", :class => "project-refs-select" | ||
3 | + | ||
4 | + | ||
5 | +:javascript | ||
6 | + $(function(){ | ||
7 | + $('.project-refs-select').chosen(); | ||
8 | + }) |
app/views/projects/_tile.html.haml
@@ -12,6 +12,11 @@ | @@ -12,6 +12,11 @@ | ||
12 | %span Last Activity: | 12 | %span Last Activity: |
13 | - last_note = project.notes.last | 13 | - last_note = project.notes.last |
14 | = last_note ? last_note.created_at.stamp("24 Aug, 2011") : "Never" | 14 | = last_note ? last_note.created_at.stamp("24 Aug, 2011") : "Never" |
15 | + | ||
16 | + %p.small-tags | ||
17 | + - project.tag_list.each do |tag| | ||
18 | + = link_to tag, "/tags/#{tag}" | ||
19 | + | ||
15 | .buttons | 20 | .buttons |
16 | %a.browse-code.button.yellow{:href => tree_project_path(project)} Browse code | 21 | %a.browse-code.button.yellow{:href => tree_project_path(project)} Browse code |
17 | %a.commits.button.green{:href => project_commits_path(project)} Commits | 22 | %a.commits.button.green{:href => project_commits_path(project)} Commits |
app/views/projects/_tree.html.haml
1 | -.left | ||
2 | - = form_tag tree_project_path(@project), :method => :get do | ||
3 | - = select_tag "branch", options_for_select(@repo.heads.map(&:name), @branch), :onchange => "this.form.submit();", :class => "", :prompt => "Branches" | ||
4 | -.left | ||
5 | - = form_tag tree_project_path(@project), :method => :get do | ||
6 | - = select_tag "tag", options_for_select(@project.tags, @tag), :onchange => "this.form.submit();", :class => "", :prompt => "Tags" | ||
7 | -.clear | ||
8 | - | ||
9 | -%br | ||
10 | 1 | ||
11 | -#%a.right.button{:href => "#"} Download | 2 | -#%a.right.button{:href => "#"} Download |
12 | -#-if can? current_user, :admin_project, @project | 3 | -#-if can? current_user, :admin_project, @project |
@@ -14,14 +5,9 @@ | @@ -14,14 +5,9 @@ | ||
14 | #tree-breadcrumbs | 5 | #tree-breadcrumbs |
15 | %h2.icon | 6 | %h2.icon |
16 | %span | 7 | %span |
17 | - = link_to tree_project_path(@project, :path => nil, :commit_id => @commit.try(:id)), :remote => true, :class => 'project-name' do | ||
18 | - %i.arrow> | ||
19 | - = @project.name | ||
20 | - | ||
21 | %d | 8 | %d |
22 | - %a{:href => "#"} | ||
23 | - = @ref | ||
24 | - | 9 | + = link_to tree_project_path(@project, :path => nil, :commit_id => @commit.try(:id)), :remote => true do |
10 | + = @project.name | ||
25 | - if params[:path] | 11 | - if params[:path] |
26 | - part_path = "" | 12 | - part_path = "" |
27 | - params[:path].split("\/").each do |part| | 13 | - params[:path].split("\/").each do |part| |
@@ -30,7 +16,8 @@ | @@ -30,7 +16,8 @@ | ||
30 | - part_path = part | 16 | - part_path = part |
31 | \/ | 17 | \/ |
32 | = link_to truncate(part, :length => 40), tree_file_project_path(@project, :path => part_path, :commit_id => @commit.try(:id), :branch => @branch, :tag => @tag), :remote => :true | 18 | = link_to truncate(part, :length => 40), tree_file_project_path(@project, :path => part_path, :commit_id => @commit.try(:id), :branch => @branch, :tag => @tag), :remote => :true |
33 | - | 19 | + |
20 | + .right= render :partial => "projects/refs", :locals => { :destination => tree_project_path(@project) } | ||
34 | .clear | 21 | .clear |
35 | 22 | ||
36 | #tree-content-holder | 23 | #tree-content-holder |
app/views/projects/_tree_item.html.haml
@@ -11,5 +11,8 @@ | @@ -11,5 +11,8 @@ | ||
11 | %td | 11 | %td |
12 | = time_ago_in_words(content_commit.committed_date) | 12 | = time_ago_in_words(content_commit.committed_date) |
13 | ago | 13 | ago |
14 | - %td | ||
15 | - = link_to truncate(content_commit.safe_message, :length => 40), project_commit_path(@project, content_commit) | 14 | + %td.commit |
15 | + = link_to truncate(content_commit.safe_message, :length => fixed_mode? ? 40 : 80), project_commit_path(@project, content_commit), :class => "tree-commit-link" | ||
16 | + - tm = @project.team_member_by_name_or_email(content_commit.author_email, content_commit.author_name) | ||
17 | + - if tm | ||
18 | + = link_to "[#{tm.user_name}]", project_team_member_path(@project, tm) |
app/views/projects/index.html.haml
1 | - content_for(:body_class, "projects-page") | 1 | - content_for(:body_class, "projects-page") |
2 | - content_for(:page_title) do | 2 | - content_for(:page_title) do |
3 | - .grid_4 | ||
4 | - - if current_user.can_create_project? | ||
5 | - %a.grey-button.right{:href => new_project_path} Create new project | ||
6 | - %h2.icon | ||
7 | - %span | ||
8 | - Projects | 3 | + .container_4 |
4 | + .grid_4 | ||
5 | + - if current_user.can_create_project? | ||
6 | + %a.grey-button.right{:href => new_project_path} Create new project | ||
7 | + %h2.icon | ||
8 | + %span | ||
9 | + Projects | ||
9 | 10 | ||
10 | -- unless @projects.empty? | ||
11 | - %div{:class => "tile", :style => view_mode_style("tile")} | ||
12 | - = render "tile" | ||
13 | - %div{:class => "list", :style => view_mode_style("list")} | ||
14 | - = render "list" | ||
15 | -- else | ||
16 | - %center.prepend-top | ||
17 | - %h2 | ||
18 | - %cite Nothing here | 11 | + %div.clear |
12 | + - unless @projects.empty? | ||
13 | + %div{:class => "tile", :style => view_mode_style("tile")} | ||
14 | + = render "tile" | ||
15 | + %div{:class => "list", :style => view_mode_style("list")} | ||
16 | + = render "list" | ||
17 | + - else | ||
18 | + %center.prepend-top | ||
19 | + %h2 | ||
20 | + %cite Nothing here |
app/views/projects/wall.html.haml
1 | %div.wall_page | 1 | %div.wall_page |
2 | - - if can? current_user, :write_note, @project | ||
3 | - = render "notes/form" | ||
4 | - .right | ||
5 | - = form_tag wall_project_path(@project), :method => :get do | ||
6 | - .span-2 | ||
7 | - = radio_button_tag :view, "recent", (params[:view] || "recent") == "recent", :onclick => "this.form.submit()", :id => "recent_view" | ||
8 | - = label_tag "recent_view","Recent" | ||
9 | - .span-2 | ||
10 | - = radio_button_tag :view, "day", params[:view] == "day", :onclick => "this.form.submit()", :id => "day_view" | ||
11 | - = label_tag "day_view","Today" | ||
12 | - .span-2 | ||
13 | - = radio_button_tag :view, "week", params[:view] == "week", :onclick => "this.form.submit()", :id => "week_view" | ||
14 | - = label_tag "week_view","Week" | ||
15 | - .span-2 | ||
16 | - = radio_button_tag :view, "all", params[:view] == "all", :onclick => "this.form.submit()", :id => "all_view" | ||
17 | - = label_tag "all_view","All" | ||
18 | - .clear | ||
19 | - %br | ||
20 | - %hr | ||
21 | -= render "notes/notes" | 2 | + = render "notes/notes" |
3 | + | ||
4 | +.loading{ :style => "display:none;"} | ||
5 | + %center= image_tag "ajax-loader.gif" | ||
22 | 6 | ||
23 | -:javascript | ||
24 | - $(function(){ | ||
25 | - $("#note_note").live("click", function(){ | ||
26 | - $(this).css("height", "100px"); | ||
27 | - $('.attach_holder').show(); | ||
28 | - }); | ||
29 | - }); |
app/views/projects/wall.js.haml
config/routes.rb
1 | Gitlab::Application.routes.draw do | 1 | Gitlab::Application.routes.draw do |
2 | + | ||
3 | + get 'tags'=> 'tags#index' | ||
4 | + get 'tags/:tag' => 'projects#index' | ||
5 | + | ||
6 | + | ||
2 | namespace :admin do | 7 | namespace :admin do |
3 | resources :users | 8 | resources :users |
4 | resources :projects | 9 | resources :projects |
@@ -20,6 +25,7 @@ Gitlab::Application.routes.draw do | @@ -20,6 +25,7 @@ Gitlab::Application.routes.draw do | ||
20 | 25 | ||
21 | resources :projects, :only => [:new, :create, :index] | 26 | resources :projects, :only => [:new, :create, :index] |
22 | resources :keys | 27 | resources :keys |
28 | + | ||
23 | devise_for :users | 29 | devise_for :users |
24 | 30 | ||
25 | resources :projects, :except => [:new, :create, :index], :path => "/" do | 31 | resources :projects, :except => [:new, :create, :index], :path => "/" do |
db/migrate/20111101222453_acts_as_taggable_on_migration.rb
0 → 100644
@@ -0,0 +1,28 @@ | @@ -0,0 +1,28 @@ | ||
1 | +class ActsAsTaggableOnMigration < ActiveRecord::Migration | ||
2 | + def self.up | ||
3 | + create_table :tags do |t| | ||
4 | + t.string :name | ||
5 | + end | ||
6 | + | ||
7 | + create_table :taggings do |t| | ||
8 | + t.references :tag | ||
9 | + | ||
10 | + # You should make sure that the column created is | ||
11 | + # long enough to store the required class names. | ||
12 | + t.references :taggable, :polymorphic => true | ||
13 | + t.references :tagger, :polymorphic => true | ||
14 | + | ||
15 | + t.string :context | ||
16 | + | ||
17 | + t.datetime :created_at | ||
18 | + end | ||
19 | + | ||
20 | + add_index :taggings, :tag_id | ||
21 | + add_index :taggings, [:taggable_id, :taggable_type, :context] | ||
22 | + end | ||
23 | + | ||
24 | + def self.down | ||
25 | + drop_table :taggings | ||
26 | + drop_table :tags | ||
27 | + end | ||
28 | +end |
db/schema.rb
@@ -11,7 +11,7 @@ | @@ -11,7 +11,7 @@ | ||
11 | # | 11 | # |
12 | # It's strongly recommended to check this file into your version control system. | 12 | # It's strongly recommended to check this file into your version control system. |
13 | 13 | ||
14 | -ActiveRecord::Schema.define(:version => 20111027152724) do | 14 | +ActiveRecord::Schema.define(:version => 20111101222453) do |
15 | 15 | ||
16 | create_table "issues", :force => true do |t| | 16 | create_table "issues", :force => true do |t| |
17 | t.string "title" | 17 | t.string "title" |
@@ -68,6 +68,23 @@ ActiveRecord::Schema.define(:version => 20111027152724) do | @@ -68,6 +68,23 @@ ActiveRecord::Schema.define(:version => 20111027152724) do | ||
68 | t.datetime "expires_at" | 68 | t.datetime "expires_at" |
69 | end | 69 | end |
70 | 70 | ||
71 | + create_table "taggings", :force => true do |t| | ||
72 | + t.integer "tag_id" | ||
73 | + t.integer "taggable_id" | ||
74 | + t.string "taggable_type" | ||
75 | + t.integer "tagger_id" | ||
76 | + t.string "tagger_type" | ||
77 | + t.string "context" | ||
78 | + t.datetime "created_at" | ||
79 | + end | ||
80 | + | ||
81 | + add_index "taggings", ["tag_id"], :name => "index_taggings_on_tag_id" | ||
82 | + add_index "taggings", ["taggable_id", "taggable_type", "context"], :name => "index_taggings_on_taggable_id_and_taggable_type_and_context" | ||
83 | + | ||
84 | + create_table "tags", :force => true do |t| | ||
85 | + t.string "name" | ||
86 | + end | ||
87 | + | ||
71 | create_table "users", :force => true do |t| | 88 | create_table "users", :force => true do |t| |
72 | t.string "email", :default => "", :null => false | 89 | t.string "email", :default => "", :null => false |
73 | t.string "encrypted_password", :limit => 128, :default => "", :null => false | 90 | t.string "encrypted_password", :limit => 128, :default => "", :null => false |
spec/requests/commits_notes_spec.rb
@@ -12,7 +12,6 @@ describe "Issues" do | @@ -12,7 +12,6 @@ describe "Issues" do | ||
12 | describe "add new note", :js => true do | 12 | describe "add new note", :js => true do |
13 | before do | 13 | before do |
14 | visit project_commit_path(project, commit) | 14 | visit project_commit_path(project, commit) |
15 | - click_link "Comments" # notes tab | ||
16 | fill_in "note_note", :with => "I commented this commit" | 15 | fill_in "note_note", :with => "I commented this commit" |
17 | click_button "Add note" | 16 | click_button "Add note" |
18 | end | 17 | end |
@@ -0,0 +1,31 @@ | @@ -0,0 +1,31 @@ | ||
1 | +require 'spec_helper' | ||
2 | + | ||
3 | +describe "Tags" do | ||
4 | + before { login_as :user } | ||
5 | + | ||
6 | + # describe "GET 'tags/index'" do | ||
7 | + # it "should be successful" do | ||
8 | + # get 'tags/index' | ||
9 | + # response.should be_success | ||
10 | + # end | ||
11 | + # end | ||
12 | + | ||
13 | + | ||
14 | + describe "GET '/tags.json'" do | ||
15 | + before do | ||
16 | + @project = Factory :project | ||
17 | + @project.add_access(@user, :read) | ||
18 | + @project.tag_list = 'demo1' | ||
19 | + @project.save | ||
20 | + visit '/tags.json' | ||
21 | + end | ||
22 | + | ||
23 | + | ||
24 | + it "should contains tags" do | ||
25 | + page.should have_content('demo1') | ||
26 | + end | ||
27 | +end | ||
28 | + | ||
29 | + | ||
30 | + | ||
31 | +end |
@@ -0,0 +1,143 @@ | @@ -0,0 +1,143 @@ | ||
1 | +/* Author: Alicia Liu */ | ||
2 | + | ||
3 | +(function ($) { | ||
4 | + | ||
5 | + $.widget("ui.tagify", { | ||
6 | + options: { | ||
7 | + delimiters: [13, 188], // what user can type to complete a tag in char codes: [enter], [comma] | ||
8 | + outputDelimiter: ',', // delimiter for tags in original input field | ||
9 | + cssClass: 'tagify-container', // CSS class to style the tagify div and tags, see stylesheet | ||
10 | + addTagPrompt: 'add tags' // placeholder text | ||
11 | + }, | ||
12 | + | ||
13 | + _create: function() { | ||
14 | + var self = this, | ||
15 | + el = self.element, | ||
16 | + opts = self.options; | ||
17 | + | ||
18 | + this.tags = []; | ||
19 | + | ||
20 | + // hide text field and replace with a div that contains it's own input field for entering tags | ||
21 | + this.tagInput = $("<input type='text'>") | ||
22 | + .attr( 'placeholder', opts.addTagPrompt ) | ||
23 | + .keypress( function(e) { | ||
24 | + var $this = $(this), | ||
25 | + pressed = e.which; | ||
26 | + | ||
27 | + for ( i in opts.delimiters ) { | ||
28 | + | ||
29 | + if (pressed == opts.delimiters[i]) { | ||
30 | + self.add( $this.val() ); | ||
31 | + e.preventDefault(); | ||
32 | + return false; | ||
33 | + } | ||
34 | + } | ||
35 | + }) | ||
36 | + // for some reason, in Safari, backspace is only recognized on keyup | ||
37 | + .keyup( function(e) { | ||
38 | + var $this = $(this), | ||
39 | + pressed = e.which; | ||
40 | + | ||
41 | + // if backspace is hit with no input, remove the last tag | ||
42 | + if (pressed == 8) { // backspace | ||
43 | + if ( $this.val() == "" ) { | ||
44 | + self.remove(); | ||
45 | + return false; | ||
46 | + } | ||
47 | + return; | ||
48 | + } | ||
49 | + }); | ||
50 | + | ||
51 | + this.tagDiv = $("<div></div>") | ||
52 | + .addClass( opts.cssClass ) | ||
53 | + .click( function() { | ||
54 | + $(this).children('input').focus(); | ||
55 | + }) | ||
56 | + .append( this.tagInput ) | ||
57 | + .insertAfter( el.hide() ); | ||
58 | + | ||
59 | + // if the field isn't empty, parse the field for tags, and prepopulate existing tags | ||
60 | + var initVal = $.trim( el.val() ); | ||
61 | + | ||
62 | + if ( initVal ) { | ||
63 | + var initTags = initVal.split( opts.outputDelimiter ); | ||
64 | + $.each( initTags, function(i, tag) { | ||
65 | + self.add( tag ); | ||
66 | + }); | ||
67 | + } | ||
68 | + }, | ||
69 | + | ||
70 | + _setOption: function( key, value ) { | ||
71 | + options.key = value; | ||
72 | + }, | ||
73 | + | ||
74 | + // add a tag, public function | ||
75 | + add: function(text) { | ||
76 | + var self = this; | ||
77 | + text = text || self.tagInput.val(); | ||
78 | + if (text) { | ||
79 | + var tagIndex = self.tags.length; | ||
80 | + | ||
81 | + var removeButton = $("<a href='#'>x</a>") | ||
82 | + .click( function() { | ||
83 | + self.remove( tagIndex ); | ||
84 | + return false; | ||
85 | + }); | ||
86 | + var newTag = $("<span></span>") | ||
87 | + .text( text ) | ||
88 | + .append( removeButton ); | ||
89 | + | ||
90 | + self.tagInput.before( newTag ); | ||
91 | + self.tags.push( text ); | ||
92 | + self.tagInput.val(''); | ||
93 | + } | ||
94 | + }, | ||
95 | + | ||
96 | + // remove a tag by index, public function | ||
97 | + // if index is blank, remove the last tag | ||
98 | + remove: function( tagIndex ) { | ||
99 | + var self = this; | ||
100 | + if ( tagIndex == null || tagIndex === (self.tags.length - 1) ) { | ||
101 | + this.tagDiv.children("span").last().remove(); | ||
102 | + self.tags.pop(); | ||
103 | + } | ||
104 | + if ( typeof(tagIndex) == 'number' ) { | ||
105 | + // otherwise just hide this tag, and we don't mess up the index | ||
106 | + this.tagDiv.children( "span:eq(" + tagIndex + ")" ).hide(); | ||
107 | + // we rely on the serialize function to remove null values | ||
108 | + delete( self.tags[tagIndex] ); | ||
109 | + } | ||
110 | + }, | ||
111 | + | ||
112 | + // serialize the tags with the given delimiter, and write it back into the tagified field | ||
113 | + serialize: function() { | ||
114 | + var self = this; | ||
115 | + var delim = self.options.outputDelimiter; | ||
116 | + var tagsStr = self.tags.join( delim ); | ||
117 | + | ||
118 | + // our tags might have deleted entries, remove them here | ||
119 | + var dupes = new RegExp(delim + delim + '+', 'g'); // regex: /,,+/g | ||
120 | + var ends = new RegExp('^' + delim + '|' + delim + '$', 'g'); // regex: /^,|,$/g | ||
121 | + var outputStr = tagsStr.replace( dupes, delim ).replace(ends, ''); | ||
122 | + | ||
123 | + self.element.val(outputStr); | ||
124 | + return outputStr; | ||
125 | + }, | ||
126 | + | ||
127 | + inputField: function() { | ||
128 | + return this.tagInput; | ||
129 | + }, | ||
130 | + | ||
131 | + containerDiv: function() { | ||
132 | + return this.tagDiv; | ||
133 | + }, | ||
134 | + | ||
135 | + // remove the div, and show original input | ||
136 | + destroy: function() { | ||
137 | + $.Widget.prototype.destroy.apply(this); | ||
138 | + this.tagDiv.remove(); | ||
139 | + this.element.show(); | ||
140 | + } | ||
141 | + }); | ||
142 | + | ||
143 | +})(jQuery); | ||
0 | \ No newline at end of file | 144 | \ No newline at end of file |
@@ -0,0 +1,34 @@ | @@ -0,0 +1,34 @@ | ||
1 | +/* Tagify styles | ||
2 | +Author: Alicia Liu test | ||
3 | +*/ | ||
4 | + | ||
5 | +.tagify-container { | ||
6 | +} | ||
7 | + | ||
8 | +.tagify-container > span { | ||
9 | + display: inline-block; | ||
10 | + padding: 8px 11px 8px 11px; | ||
11 | + margin: 1px 5px 0px 0px; | ||
12 | + border-radius: 4px; | ||
13 | + border: 1px solid #d0e1ff; | ||
14 | + background-color: #d0e1ff; | ||
15 | + color: #0f326d; | ||
16 | + font-weight: bold; | ||
17 | + font-size: 14px; | ||
18 | +} | ||
19 | + | ||
20 | +.tagify-container > span > a { | ||
21 | + padding-left: 5px !important; | ||
22 | + color: #83a5e1; | ||
23 | + text-decoration: none; | ||
24 | + font-weight: bold; | ||
25 | +} | ||
26 | + | ||
27 | +.tagify-container > input { | ||
28 | + border: 0 none; | ||
29 | + width: 100px !important; | ||
30 | +} | ||
31 | + | ||
32 | +.tagify-container > input:focus { | ||
33 | + outline: none; | ||
34 | +} | ||
0 | \ No newline at end of file | 35 | \ No newline at end of file |