Merge remote-tracking branch 'upstream/master'

This commit is contained in:
Ariejan de Vroom 2012-03-01 15:09:23 +01:00
commit bfe0906f2f
312 changed files with 6572 additions and 4819 deletions

5
.gitignore vendored
View file

@ -9,5 +9,10 @@ coverage/*
*.swp *.swp
public/uploads/ public/uploads/
.rvmrc .rvmrc
.rbenv-version
.directory .directory
nohup.out nohup.out
Vagrantfile
.vagrant
config/gitlab.yml
config/database.yml

View file

@ -1 +0,0 @@
1.9.2-p290

View file

@ -4,6 +4,8 @@ branches:
- 'master' - 'master'
rvm: 1.9.2 rvm: 1.9.2
before_script: before_script:
- "cp config/database.yml.example config/database.yml"
- "cp config/gitlab.yml.example config/gitlab.yml"
- "bundle exec rake db:create RAILS_ENV=test" - "bundle exec rake db:create RAILS_ENV=test"
- "bundle exec rake db:migrate RAILS_ENV=test" - "bundle exec rake db:migrate RAILS_ENV=test"
- "bundle exec rake db:seed_fu RAILS_ENV=test" - "bundle exec rake db:seed_fu RAILS_ENV=test"

27
Gemfile
View file

@ -1,10 +1,10 @@
source "http://rubygems.org" source "http://rubygems.org"
gem "rails", "3.1.1" gem "rails", "3.2.1"
gem "sqlite3" gem "sqlite3"
gem "rake", "0.9.2.2" gem "rake"
gem "devise", "1.5.0" gem "devise"
gem "stamp" gem "stamp"
gem "kaminari" gem "kaminari"
gem "haml", "3.1.4" gem "haml", "3.1.4"
@ -16,7 +16,7 @@ gem "carrierwave"
gem "six" gem "six"
gem "therubyracer" gem "therubyracer"
gem "faker" gem "faker"
gem "seed-fu", "~> 2.1.0" gem "seed-fu"
gem "pygments.rb", "0.2.4" gem "pygments.rb", "0.2.4"
gem "thin" gem "thin"
gem "git" gem "git"
@ -24,20 +24,23 @@ gem "acts_as_list"
gem "rdiscount" gem "rdiscount"
gem "acts-as-taggable-on", "~> 2.1.0" gem "acts-as-taggable-on", "~> 2.1.0"
gem "drapper" gem "drapper"
gem "resque" gem "resque", "~> 1.20.0"
gem "httparty" gem "httparty"
gem "charlock_holmes" gem "charlock_holmes"
gem "foreman" gem "foreman"
gem "omniauth-ldap"
gem 'bootstrap-sass', "1.4.4"
gem "colored"
group :assets do group :assets do
gem "sass-rails", "~> 3.1.0" gem "sass-rails", "3.2.3"
gem "coffee-rails", "~> 3.1.0" gem "coffee-rails", "3.2.1"
gem "uglifier" gem "uglifier", "1.0.3"
end end
group :development do group :development do
gem "letter_opener" gem "letter_opener"
gem "rails-footnotes", "~> 3.7.5" gem "rails-footnotes"
gem "annotate", :git => "https://github.com/ctran/annotate_models.git" gem "annotate", :git => "https://github.com/ctran/annotate_models.git"
end end
@ -46,9 +49,7 @@ group :development, :test do
gem "capybara" gem "capybara"
gem "autotest" gem "autotest"
gem "autotest-rails" gem "autotest-rails"
unless ENV["CI"] gem "pry"
gem "ruby-debug19", :require => "ruby-debug"
end
gem "awesome_print" gem "awesome_print"
gem "database_cleaner" gem "database_cleaner"
gem "launchy" gem "launchy"
@ -58,5 +59,5 @@ end
group :test do group :test do
gem "turn", :require => false gem "turn", :require => false
gem "simplecov", :require => false gem "simplecov", :require => false
gem "shoulda", "~> 3.0.0.beta2" gem "shoulda", "3.0.0"
end end

View file

@ -1,6 +1,6 @@
GIT GIT
remote: https://github.com/ctran/annotate_models.git remote: https://github.com/ctran/annotate_models.git
revision: fb73329243056a6d9a64878e5c543aba9b6417de revision: a43c08f0eb4d69a48c6830630ebb60e35ccb2d2d
specs: specs:
annotate (2.4.1.beta1) annotate (2.4.1.beta1)
@ -25,48 +25,48 @@ GEM
remote: http://rubygems.org/ remote: http://rubygems.org/
specs: specs:
ZenTest (4.5.0) ZenTest (4.5.0)
actionmailer (3.1.1) actionmailer (3.2.1)
actionpack (= 3.1.1) actionpack (= 3.2.1)
mail (~> 2.3.0) mail (~> 2.4.0)
actionpack (3.1.1) actionpack (3.2.1)
activemodel (= 3.1.1) activemodel (= 3.2.1)
activesupport (= 3.1.1) activesupport (= 3.2.1)
builder (~> 3.0.0) builder (~> 3.0.0)
erubis (~> 2.7.0) erubis (~> 2.7.0)
i18n (~> 0.6) journey (~> 1.0.1)
rack (~> 1.3.2) rack (~> 1.4.0)
rack-cache (~> 1.1) rack-cache (~> 1.1)
rack-mount (~> 0.8.2)
rack-test (~> 0.6.1) rack-test (~> 0.6.1)
sprockets (~> 2.0.2) sprockets (~> 2.1.2)
activemodel (3.1.1) activemodel (3.2.1)
activesupport (= 3.1.1) activesupport (= 3.2.1)
builder (~> 3.0.0) builder (~> 3.0.0)
i18n (~> 0.6) activerecord (3.2.1)
activerecord (3.1.1) activemodel (= 3.2.1)
activemodel (= 3.1.1) activesupport (= 3.2.1)
activesupport (= 3.1.1) arel (~> 3.0.0)
arel (~> 2.2.1)
tzinfo (~> 0.3.29) tzinfo (~> 0.3.29)
activeresource (3.1.1) activeresource (3.2.1)
activemodel (= 3.1.1) activemodel (= 3.2.1)
activesupport (= 3.1.1) activesupport (= 3.2.1)
activesupport (3.1.1) activesupport (3.2.1)
i18n (~> 0.6)
multi_json (~> 1.0) multi_json (~> 1.0)
acts-as-taggable-on (2.1.1) acts-as-taggable-on (2.1.1)
rails rails
acts_as_list (0.1.4) acts_as_list (0.1.4)
addressable (2.2.6) addressable (2.2.6)
ansi (1.4.1) ansi (1.4.2)
archive-tar-minitar (0.5.2) arel (3.0.0)
arel (2.2.1)
autotest (4.4.6) autotest (4.4.6)
ZenTest (>= 4.4.1) ZenTest (>= 4.4.1)
autotest-rails (4.1.1) autotest-rails (4.1.1)
ZenTest (= 4.5) ZenTest (= 4.5)
awesome_print (0.4.0) awesome_print (1.0.2)
bcrypt-ruby (3.0.1) bcrypt-ruby (3.0.1)
blankslate (2.1.2.4) blankslate (2.1.2.4)
bootstrap-sass (1.4.4)
sass-rails (~> 3.1)
builder (3.0.0) builder (3.0.0)
capybara (1.1.2) capybara (1.1.2)
mime-types (>= 1.16) mime-types (>= 1.16)
@ -78,19 +78,20 @@ GEM
carrierwave (0.5.8) carrierwave (0.5.8)
activesupport (~> 3.0) activesupport (~> 3.0)
charlock_holmes (0.6.8) charlock_holmes (0.6.8)
childprocess (0.2.2) childprocess (0.3.1)
ffi (~> 1.0.6) ffi (~> 1.0.6)
coffee-rails (3.1.1) coderay (1.0.5)
coffee-rails (3.2.1)
coffee-script (>= 2.2.0) coffee-script (>= 2.2.0)
railties (~> 3.1.0) railties (~> 3.2.0.beta)
coffee-script (2.2.0) coffee-script (2.2.0)
coffee-script-source coffee-script-source
execjs execjs
coffee-script-source (1.1.3) coffee-script-source (1.2.0)
columnize (0.3.4) colored (1.2)
crack (0.3.1) crack (0.3.1)
daemons (1.1.4) daemons (1.1.8)
database_cleaner (0.7.0) database_cleaner (0.7.1)
devise (1.5.0) devise (1.5.0)
bcrypt-ruby (~> 3.0) bcrypt-ruby (~> 3.0)
orm_adapter (~> 0.0.3) orm_adapter (~> 0.0.3)
@ -99,13 +100,13 @@ GEM
drapper (0.8.4) drapper (0.8.4)
erubis (2.7.0) erubis (2.7.0)
eventmachine (0.12.10) eventmachine (0.12.10)
execjs (1.2.9) execjs (1.3.0)
multi_json (~> 1.0) multi_json (~> 1.0)
faker (1.0.1) faker (1.0.1)
i18n (~> 0.4) i18n (~> 0.4)
ffi (1.0.11) ffi (1.0.11)
foreman (0.27.0) foreman (0.39.0)
term-ansicolor (~> 1.0.5) term-ansicolor (~> 1.0.7)
thor (>= 0.13.6) thor (>= 0.13.6)
git (1.2.5) git (1.2.5)
haml (3.1.4) haml (3.1.4)
@ -115,139 +116,143 @@ GEM
haml (~> 3.0) haml (~> 3.0)
railties (~> 3.0) railties (~> 3.0)
hashery (1.4.0) hashery (1.4.0)
hashie (1.2.0)
hike (1.2.1) hike (1.2.1)
httparty (0.8.1) httparty (0.8.1)
multi_json multi_json
multi_xml multi_xml
i18n (0.6.0) i18n (0.6.0)
jquery-rails (1.0.17) journey (1.0.1)
railties (~> 3.0) jquery-rails (2.0.0)
railties (>= 3.2.0.beta, < 5.0)
thor (~> 0.14) thor (~> 0.14)
json (1.6.1) json (1.6.5)
json_pure (1.6.1) kaminari (0.13.0)
kaminari (0.12.4) actionpack (>= 3.0.0)
rails (>= 3.0.0) activesupport (>= 3.0.0)
railties (>= 3.0.0)
launchy (2.0.5) launchy (2.0.5)
addressable (~> 2.2.6) addressable (~> 2.2.6)
letter_opener (0.0.2) letter_opener (0.0.2)
launchy launchy
libv8 (3.3.10.4) libv8 (3.3.10.4)
linecache19 (0.5.12) mail (2.4.1)
ruby_core_source (>= 0.1.4)
mail (2.3.0)
i18n (>= 0.4.0) i18n (>= 0.4.0)
mime-types (~> 1.16) mime-types (~> 1.16)
treetop (~> 1.4.8) treetop (~> 1.4.8)
method_source (0.7.0)
mime-types (1.17.2) mime-types (1.17.2)
multi_json (1.0.3) multi_json (1.0.4)
multi_xml (0.4.1) multi_xml (0.4.1)
net-ldap (0.2.2)
nokogiri (1.5.0) nokogiri (1.5.0)
orm_adapter (0.0.5) omniauth (1.0.2)
hashie (~> 1.2)
rack
omniauth-ldap (1.0.2)
net-ldap (~> 0.2.2)
omniauth (~> 1.0)
pyu-ruby-sasl (~> 0.0.3.1)
rubyntlm (~> 0.1.1)
orm_adapter (0.0.6)
polyglot (0.3.3) polyglot (0.3.3)
posix-spawn (0.3.6) posix-spawn (0.3.6)
pry (0.9.8.2)
coderay (~> 1.0.5)
method_source (~> 0.7)
slop (>= 2.4.4, < 3)
pygments.rb (0.2.4) pygments.rb (0.2.4)
rubypython (~> 0.5.3) rubypython (~> 0.5.3)
rack (1.3.5) pyu-ruby-sasl (0.0.3.3)
rack (1.4.1)
rack-cache (1.1) rack-cache (1.1)
rack (>= 0.4) rack (>= 0.4)
rack-mount (0.8.3) rack-protection (1.2.0)
rack (>= 1.0.0)
rack-protection (1.1.4)
rack rack
rack-ssl (1.3.2) rack-ssl (1.3.2)
rack rack
rack-test (0.6.1) rack-test (0.6.1)
rack (>= 1.0) rack (>= 1.0)
rails (3.1.1) rails (3.2.1)
actionmailer (= 3.1.1) actionmailer (= 3.2.1)
actionpack (= 3.1.1) actionpack (= 3.2.1)
activerecord (= 3.1.1) activerecord (= 3.2.1)
activeresource (= 3.1.1) activeresource (= 3.2.1)
activesupport (= 3.1.1) activesupport (= 3.2.1)
bundler (~> 1.0) bundler (~> 1.0)
railties (= 3.1.1) railties (= 3.2.1)
rails-footnotes (3.7.5) rails-footnotes (3.7.5)
rails (>= 3.0.0) rails (>= 3.0.0)
railties (3.1.1) railties (3.2.1)
actionpack (= 3.1.1) actionpack (= 3.2.1)
activesupport (= 3.1.1) activesupport (= 3.2.1)
rack-ssl (~> 1.3.2) rack-ssl (~> 1.3.2)
rake (>= 0.8.7) rake (>= 0.8.7)
rdoc (~> 3.4) rdoc (~> 3.4)
thor (~> 0.14.6) thor (~> 0.14.6)
rake (0.9.2.2) rake (0.9.2.2)
rdiscount (1.6.8) rdiscount (1.6.8)
rdoc (3.11) rdoc (3.12)
json (~> 1.4) json (~> 1.4)
redis (2.2.2) redis (2.2.2)
redis-namespace (1.0.3) redis-namespace (1.0.3)
redis (< 3.0.0) redis (< 3.0.0)
resque (1.19.0) resque (1.20.0)
multi_json (~> 1.0) multi_json (~> 1.0)
redis-namespace (~> 1.0.2) redis-namespace (~> 1.0.2)
sinatra (>= 0.9.2) sinatra (>= 0.9.2)
vegas (~> 0.1.2) vegas (~> 0.1.2)
rspec (2.7.0) rspec (2.8.0)
rspec-core (~> 2.7.0) rspec-core (~> 2.8.0)
rspec-expectations (~> 2.7.0) rspec-expectations (~> 2.8.0)
rspec-mocks (~> 2.7.0) rspec-mocks (~> 2.8.0)
rspec-core (2.7.1) rspec-core (2.8.0)
rspec-expectations (2.7.0) rspec-expectations (2.8.0)
diff-lcs (~> 1.1.2) diff-lcs (~> 1.1.2)
rspec-mocks (2.7.0) rspec-mocks (2.8.0)
rspec-rails (2.7.0) rspec-rails (2.8.1)
actionpack (~> 3.0) actionpack (>= 3.0)
activesupport (~> 3.0) activesupport (>= 3.0)
railties (~> 3.0) railties (>= 3.0)
rspec (~> 2.7.0) rspec (~> 2.8.0)
ruby-debug-base19 (0.11.25) rubyntlm (0.1.1)
columnize (>= 0.3.1)
linecache19 (>= 0.5.11)
ruby_core_source (>= 0.1.4)
ruby-debug19 (0.11.6)
columnize (>= 0.3.1)
linecache19 (>= 0.5.11)
ruby-debug-base19 (>= 0.11.19)
ruby_core_source (0.1.5)
archive-tar-minitar (>= 0.5.2)
rubypython (0.5.3) rubypython (0.5.3)
blankslate (>= 2.1.2.3) blankslate (>= 2.1.2.3)
ffi (~> 1.0.7) ffi (~> 1.0.7)
rubyzip (0.9.4) rubyzip (0.9.6.1)
sass (3.1.10) sass (3.1.15)
sass-rails (3.1.4) sass-rails (3.2.3)
actionpack (~> 3.1.0) railties (~> 3.2.0.beta)
railties (~> 3.1.0) sass (>= 3.1.10)
sass (>= 3.1.4) tilt (~> 1.3)
sprockets (~> 2.0.0) seed-fu (2.2.0)
tilt (~> 1.3.2) activerecord (~> 3.1)
seed-fu (2.1.0) activesupport (~> 3.1)
activerecord (~> 3.1.0) selenium-webdriver (2.19.0)
activesupport (~> 3.1.0) childprocess (>= 0.2.5)
selenium-webdriver (2.12.2)
childprocess (>= 0.2.1)
ffi (~> 1.0.9) ffi (~> 1.0.9)
json_pure multi_json (~> 1.0.4)
rubyzip rubyzip
shoulda (3.0.0.beta2) shoulda (3.0.0)
shoulda-context (~> 1.0.0.beta1) shoulda-context (~> 1.0.0)
shoulda-matchers (~> 1.0.0.beta1) shoulda-matchers (~> 1.0.0)
shoulda-context (1.0.0) shoulda-context (1.0.0)
shoulda-matchers (1.0.0) shoulda-matchers (1.0.0)
simplecov (0.5.4) simplecov (0.5.4)
multi_json (~> 1.0.3) multi_json (~> 1.0.3)
simplecov-html (~> 0.5.3) simplecov-html (~> 0.5.3)
simplecov-html (0.5.3) simplecov-html (0.5.3)
sinatra (1.3.1) sinatra (1.3.2)
rack (~> 1.3, >= 1.3.4) rack (~> 1.3, >= 1.3.6)
rack-protection (~> 1.1, >= 1.1.2) rack-protection (~> 1.2)
tilt (~> 1.3, >= 1.3.3) tilt (~> 1.3, >= 1.3.3)
six (0.2.0) six (0.2.0)
sprockets (2.0.3) slop (2.4.4)
sprockets (2.1.2)
hike (~> 1.2) hike (~> 1.2)
rack (~> 1.0) rack (~> 1.0)
tilt (~> 1.1, != 1.3.0) tilt (~> 1.1, != 1.3.0)
sqlite3 (1.3.4) sqlite3 (1.3.5)
stamp (0.1.6) stamp (0.1.6)
term-ansicolor (1.0.7) term-ansicolor (1.0.7)
therubyracer (0.9.9) therubyracer (0.9.9)
@ -261,17 +266,17 @@ GEM
treetop (1.4.10) treetop (1.4.10)
polyglot polyglot
polyglot (>= 0.3.1) polyglot (>= 0.3.1)
turn (0.8.3) turn (0.9.2)
ansi ansi
tzinfo (0.3.31) tzinfo (0.3.31)
uglifier (1.1.0) uglifier (1.0.3)
execjs (>= 0.3.0) execjs (>= 0.3.0)
multi_json (>= 1.0.2) multi_json (>= 1.0.2)
vegas (0.1.8) vegas (0.1.11)
rack (>= 1.0.0) rack (>= 1.0.0)
warden (1.1.0) warden (1.1.0)
rack (>= 1.0) rack (>= 1.0)
webmock (1.7.8) webmock (1.7.10)
addressable (~> 2.2, > 2.2.5) addressable (~> 2.2, > 2.2.5)
crack (>= 0.1.7) crack (>= 0.1.7)
xpath (0.1.4) xpath (0.1.4)
@ -287,12 +292,14 @@ DEPENDENCIES
autotest autotest
autotest-rails autotest-rails
awesome_print awesome_print
bootstrap-sass (= 1.4.4)
capybara capybara
carrierwave carrierwave
charlock_holmes charlock_holmes
coffee-rails (~> 3.1.0) coffee-rails (= 3.2.1)
colored
database_cleaner database_cleaner
devise (= 1.5.0) devise
drapper drapper
faker faker
foreman foreman
@ -306,17 +313,18 @@ DEPENDENCIES
kaminari kaminari
launchy launchy
letter_opener letter_opener
omniauth-ldap
pry
pygments.rb (= 0.2.4) pygments.rb (= 0.2.4)
rails (= 3.1.1) rails (= 3.2.1)
rails-footnotes (~> 3.7.5) rails-footnotes
rake (= 0.9.2.2) rake
rdiscount rdiscount
resque resque (~> 1.20.0)
rspec-rails rspec-rails
ruby-debug19 sass-rails (= 3.2.3)
sass-rails (~> 3.1.0) seed-fu
seed-fu (~> 2.1.0) shoulda (= 3.0.0)
shoulda (~> 3.0.0.beta2)
simplecov simplecov
six six
sqlite3 sqlite3
@ -324,5 +332,5 @@ DEPENDENCIES
therubyracer therubyracer
thin thin
turn turn
uglifier uglifier (= 1.0.3)
webmock webmock

View file

@ -1,2 +1,2 @@
web: bundle exec rails s -p $PORT -e production web: bundle exec rails s -p $PORT -e production
worker: bundle exec rake environment resque:work RAILS_ENV=production QUEUE=* VVERBOSE=1 worker: bundle exec rake environment resque:work RAILS_ENV=production QUEUE=*

View file

@ -1 +1 @@
2.1.0 2.2.0

Binary file not shown.

Before

Width:  |  Height:  |  Size: 940 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 782 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 800 B

After

Width:  |  Height:  |  Size: 801 B

BIN
app/assets/images/admin.PNG Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 556 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 518 B

After

Width:  |  Height:  |  Size: 177 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 469 B

After

Width:  |  Height:  |  Size: 295 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 96 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 596 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 641 B

View file

@ -10,6 +10,8 @@
//= require jquery.ui.selectmenu //= require jquery.ui.selectmenu
//= require jquery.tagify //= require jquery.tagify
//= require jquery.cookie //= require jquery.cookie
//= require jquery.endless-scroll
//= require bootstrap-modal
//= require modernizr //= require modernizr
//= require chosen //= require chosen
//= require raphael //= require raphael
@ -21,9 +23,6 @@ $(document).ready(function(){
$(this).select(); $(this).select();
}); });
$('select#branch').selectmenu({style:'popup', width:200});
$('select#tag').selectmenu({style:'popup', width:200});
$(".account-box").mouseenter(showMenu); $(".account-box").mouseenter(showMenu);
$(".account-box").mouseleave(resetMenu); $(".account-box").mouseleave(resetMenu);
@ -43,6 +42,9 @@ $(document).ready(function(){
} }
}); });
/**
* Focus search field by pressing 's' key
*/
$(document).keypress(function(e) { $(document).keypress(function(e) {
if( $(e.target).is(":input") ) return; if( $(e.target).is(":input") ) return;
switch(e.which) { switch(e.which) {
@ -50,27 +52,12 @@ $(document).ready(function(){
e.preventDefault(); e.preventDefault();
} }
}); });
}); });
function focusSearch() { function focusSearch() {
$("#search").focus(); $("#search").focus();
} }
function taggifyForm(){
var tag_field = $('#tag_field').tagify();
tag_field.tagify('inputField').autocomplete({
source: '/tags.json'
});
$('form').submit( function() {
var tag_field = $('#tag_field')
tag_field.val( tag_field.tagify('serialize') );
return true;
});
}
function updatePage(data){ function updatePage(data){
$.ajax({type: "GET", url: location.href, data: data, dataType: "script"}); $.ajax({type: "GET", url: location.href, data: data, dataType: "script"});
} }
@ -82,5 +69,3 @@ function showMenu() {
function resetMenu() { function resetMenu() {
$(this).removeClass("hover"); $(this).removeClass("hover");
} }

View file

@ -2,6 +2,7 @@ var CommitsList = {
ref:null, ref:null,
limit:0, limit:0,
offset:0, offset:0,
disable:false,
init: init:
function(ref, limit) { function(ref, limit) {
@ -36,15 +37,21 @@ var CommitsList = {
$("#commits_list").append(html); $("#commits_list").append(html);
if(count > 0) { if(count > 0) {
this.offset += count; this.offset += count;
this.initLoadMore(); } else {
this.disable = true;
} }
}, },
initLoadMore: initLoadMore:
function() { function() {
$(window).bind('scroll', function(){ $(document).endlessScroll({
if($(window).scrollTop() == $(document).height() - $(window).height()){ bottomPixels: 400,
$(window).unbind('scroll'); fireDelay: 1000,
fireOnce:true,
ceaseFire: function() {
return CommitsList.disable;
},
callback: function(i) {
CommitsList.getOld(); CommitsList.getOld();
} }
}); });

View file

@ -1,16 +1,18 @@
function switchToNewIssue(form){ function switchToNewIssue(form){
$("#issues-table-holder").hide("slide", { direction: "left" }, 150, function(){ $(".issues_content").hide("fade", { direction: "left" }, 150, function(){
$(".project-content").append(form); $(".issues_content").after(form);
$('select#issue_assignee_id').chosen(); $('select#issue_assignee_id').chosen();
$("#new_issue_dialog").show("slide", { direction: "right" }, 150); $("#new_issue_dialog").show("fade", { direction: "right" }, 150);
$('.top-tabs .add_new').hide();
}); });
} }
function switchToEditIssue(form){ function switchToEditIssue(form){
$("#issues-table-holder").hide("slide", { direction: "left" }, 150, function(){ $(".issues_content").hide("fade", { direction: "left" }, 150, function(){
$(".project-content").append(form); $(".issues_content").after(form);
$('select#issue_assignee_id').chosen(); $('select#issue_assignee_id').chosen();
$("#edit_issue_dialog").show("slide", { direction: "right" }, 150); $("#edit_issue_dialog").show("fade", { direction: "right" }, 150);
$('.add_new').hide();
}); });
} }
@ -23,10 +25,11 @@ function switchFromEditIssue(){
} }
function backToIssues(){ function backToIssues(){
$("#edit_issue_dialog, #new_issue_dialog").hide("slide", { direction: "right" }, 150, function(){ $("#edit_issue_dialog, #new_issue_dialog").hide("fade", { direction: "right" }, 150, function(){
$("#issues-table-holder").show("slide", { direction: "left" }, 150, function() { $(".issues_content").show("fade", { direction: "left" }, 150, function() {
$("#edit_issue_dialog").remove(); $("#edit_issue_dialog").remove();
$("#new_issue_dialog").remove(); $("#new_issue_dialog").remove();
$('.add_new').show();
}); });
}); });
} }

View file

@ -4,46 +4,27 @@ var MergeRequest = {
init: init:
function() { function() {
$(".merge-tabs a").live("click", function() { $(".tabs a").live("click", function() {
$(".merge-tabs a").removeClass("active"); $(".tabs a").parent().removeClass("active");
$(this).addClass("active"); $(this).parent().addClass("active");
}); });
$(".merge-tabs a.merge-notes-tab").live("click", function() { $(".tabs a.merge-notes-tab").live("click", function(e) {
$(".merge-request-commits, .merge-request-diffs").hide(); $(".merge-request-diffs").hide();
$(".merge-request-notes").show(); $(".merge-request-notes").show();
e.preventDefault();
}); });
$(".merge-tabs a.merge-commits-tab").live("click", function() { $(".tabs a.merge-diffs-tab").live("click", function(e) {
if(!MergeRequest.commits_loaded) {
MergeRequest.loadCommits();
}
$(".merge-request-notes, .merge-request-diffs").hide();
$(".merge-request-commits").show();
});
$(".merge-tabs a.merge-diffs-tab").live("click", function() {
if(!MergeRequest.diffs_loaded) { if(!MergeRequest.diffs_loaded) {
MergeRequest.loadDiff(); MergeRequest.loadDiff();
} }
$(".merge-request-notes, .merge-request-commits").hide(); $(".merge-request-notes").hide();
$(".merge-request-diffs").show(); $(".merge-request-diffs").show();
e.preventDefault();
}); });
}, },
loadCommits:
function() {
$(".dashboard-loader").show();
$.ajax({
type: "GET",
url: $(".merge-commits-tab").attr("data-url"),
complete: function(){
MergeRequest.commits_loaded = true;
$(".merge-request-notes, .merge-request-diffs").hide();
$(".dashboard-loader").hide()},
dataType: "script"});
},
loadDiff: loadDiff:
function() { function() {
$(".dashboard-loader").show(); $(".dashboard-loader").show();
@ -52,7 +33,7 @@ var MergeRequest = {
url: $(".merge-diffs-tab").attr("data-url"), url: $(".merge-diffs-tab").attr("data-url"),
complete: function(){ complete: function(){
MergeRequest.diffs_loaded = true; MergeRequest.diffs_loaded = true;
$(".merge-request-notes, .merge-request-commits").hide(); $(".merge-request-notes").hide();
$(".dashboard-loader").hide()}, $(".dashboard-loader").hide()},
dataType: "script"}); dataType: "script"});
} }

View file

@ -1,49 +1,66 @@
var NoteList = { var NoteList = {
notes_path: null,
target_params: null,
target_id: 0,
target_type: null,
first_id: 0, first_id: 0,
last_id: 0, last_id: 0,
resource_name: null, disable:false,
init: init:
function(resource_name, first_id, last_id) { function(tid, tt, path) {
this.resource_name = resource_name; this.notes_path = path + ".js";
this.first_id = first_id; this.target_id = tid;
this.last_id = last_id; this.target_type = tt;
this.target_params = "&target_type=" + this.target_type + "&target_id=" + this.target_id;
// get notes
this.getContent();
// get new notes every n seconds
this.initRefresh(); this.initRefresh();
this.initLoadMore();
$('.delete-note').live('ajax:success', function() {
$(this).closest('li').fadeOut(); });
$("#new_note").live("ajax:before", function(){
$("#submit_note").attr("disabled", "disabled");
})
$("#new_note").live("ajax:complete", function(){
$("#submit_note").removeAttr("disabled");
})
$("#note_note").live("click", function(){
$(this).css("height", "100px");
$('.attach_holder').show();
});
}, },
getOld:
/**
* Load new notes to fresh list called 'new_notes_list':
* - Replace 'new_notes_list' with new list every n seconds
* - Append new notes to this list after submit
*/
initRefresh:
function() { function() {
$('.loading').show(); // init timer
$.ajax({ var intNew = setInterval("NoteList.getNew()", 10000);
type: "GET",
url: location.href,
data: "first_id=" + this.first_id,
complete: function(){ $('.loading').hide()},
dataType: "script"});
},
append:
function(id, html) {
this.first_id = id;
$("#notes-list").append(html);
this.initLoadMore();
}, },
replace: replace:
function(fid, lid, html) { function(html) {
this.first_id = fid; $("#new_notes_list").html(html);
this.last_id = lid;
$("#notes-list").html(html);
this.initLoadMore();
}, },
prepend: prepend:
function(id, html) { function(id, html) {
if(id != this.last_id) { if(id != this.last_id) {
this.last_id = id; $("#new_notes_list").prepend(html);
$("#notes-list").prepend(html);
} }
}, },
@ -52,8 +69,8 @@ getNew:
// refersh notes list // refersh notes list
$.ajax({ $.ajax({
type: "GET", type: "GET",
url: location.href, url: this.notes_path,
data: "last_id=" + this.last_id, data: "last_id=" + this.last_id + this.target_params,
dataType: "script"}); dataType: "script"});
}, },
@ -62,23 +79,83 @@ refresh:
// refersh notes list // refersh notes list
$.ajax({ $.ajax({
type: "GET", type: "GET",
url: location.href, url: this.notes_path,
data: "first_id=" + this.first_id + "&last_id=" + this.last_id, data: "first_id=" + this.first_id + "&last_id=" + this.last_id + this.target_params,
dataType: "script"}); dataType: "script"});
}, },
initRefresh:
/**
* Init load of notes:
* 1. Get content with ajax call
* 2. Set content of notes list with loaded one
*/
getContent:
function() { function() {
// init timer $.ajax({
var intNew = setInterval("NoteList.getNew()", 15000); type: "GET",
var intRefresh = setInterval("NoteList.refresh()", 90000); url: this.notes_path,
data: "?" + this.target_params,
complete: function(){ $('.status').removeClass("loading")},
beforeSend: function() { $('.status').addClass("loading") },
dataType: "script"});
}, },
setContent:
function(fid, lid, html) {
this.last_id = lid;
this.first_id = fid;
$("#notes-list").html(html);
// Init infinite scrolling
this.initLoadMore();
},
/**
* Paging for old notes when scroll to bottom:
* 1. Init scroll events with 'initLoadMore'
* 2. Load onlder notes with 'getOld' method
* 3. append old notes to bottom of list with 'append'
*
*/
getOld:
function() {
$('.loading').show();
$.ajax({
type: "GET",
url: this.notes_path,
data: "first_id=" + this.first_id + this.target_params,
complete: function(){ $('.status').removeClass("loading")},
beforeSend: function() { $('.status').addClass("loading") },
dataType: "script"});
},
append:
function(id, html) {
if(this.first_id == id) {
this.disable = true;
} else {
this.first_id = id;
$("#notes-list").append(html);
}
},
initLoadMore: initLoadMore:
function() { function() {
$(window).bind('scroll', function(){ $(document).endlessScroll({
if($(window).scrollTop() == $(document).height() - $(window).height()){ bottomPixels: 400,
$(window).unbind('scroll'); fireDelay: 1000,
fireOnce:true,
ceaseFire: function() {
return NoteList.disable;
},
callback: function(i) {
NoteList.getOld(); NoteList.getOld();
} }
}); });

View file

@ -1,12 +1,14 @@
var ProjectsList = { var Pager = {
limit:0, limit:0,
offset:0, offset:0,
disable:false,
init: init:
function(limit) { function(limit) {
this.limit=limit; this.limit=limit;
this.offset=limit; this.offset=limit;
this.initLoadMore(); this.initLoadMore();
$('.loading').show();
}, },
getOld: getOld:
@ -22,20 +24,26 @@ var ProjectsList = {
append: append:
function(count, html) { function(count, html) {
$(".tile").append(html); $(".content_list").append(html);
if(count > 0) { if(count > 0) {
this.offset += count; this.offset += count;
this.initLoadMore(); } else {
this.disable = true;
} }
}, },
initLoadMore: initLoadMore:
function() { function() {
$(window).bind('scroll', function(){ $(document).endlessScroll({
if($(window).scrollTop() == $(document).height() - $(window).height()){ bottomPixels: 400,
$(window).unbind('scroll'); fireDelay: 1000,
fireOnce:true,
ceaseFire: function() {
return Pager.disable;
},
callback: function(i) {
$('.loading').show(); $('.loading').show();
ProjectsList.getOld(); Pager.getOld();
} }
}); });
} }

View file

@ -1,7 +1,7 @@
function backToMembers(){ function backToMembers(){
$("#team_member_new").hide("slide", { direction: "right" }, 150, function(){ $("#new_team_member").hide("slide", { direction: "right" }, 150, function(){
$("#team-table").show("slide", { direction: "left" }, 150, function() { $("#team-table").show("slide", { direction: "left" }, 150, function() {
$("#team_member_new").remove(); $("#new_team_member").remove();
$(".add_new").show(); $(".add_new").show();
}); });
}); });

View file

@ -5,21 +5,24 @@
var Tree = { var Tree = {
init: init:
function() { function() {
(new Image).src = "ajax-loader-facebook.gif"; $('#tree-slider .tree-item-file-name a, .breadcrumb li > a').live("click", function() {
$('#tree-slider td.tree-item-file-name a, #tree-breadcrumbs a').live("click", function() {
history.pushState({ path: this.path }, '', this.href)
$("#tree-content-holder").hide("slide", { direction: "left" }, 150) $("#tree-content-holder").hide("slide", { direction: "left" }, 150)
}) })
$("#tree-slider tr.tree-item").live('click', function(e){ $('.project-refs-form').live({
"ajax:beforeSend": function() {
$("#tree-content-holder").hide("slide", { direction: "left" }, 150);
}
})
$("#tree-slider .tree-item").live('click', function(e){
if(e.target.nodeName != "A") { if(e.target.nodeName != "A") {
link = $(this).find("td.tree-item-file-name a"); link = $(this).find(".tree-item-file-name a");
link.trigger("click"); link.trigger("click");
} }
}); });
$('#tree-slider td.tree-item-file-name a, #tree-breadcrumbs a').live({ $('#tree-slider .tree-item-file-name a, .breadcrumb a, .project-refs-form').live({
"ajax:beforeSend": function() { $('.tree_progress').addClass("loading"); }, "ajax:beforeSend": function() { $('.tree_progress').addClass("loading"); },
"ajax:complete": function() { $('.tree_progress').removeClass("loading"); } "ajax:complete": function() { $('.tree_progress').removeClass("loading"); }
}); });

View file

@ -7,5 +7,5 @@
*= require jquery-ui/jquery.tagify *= require jquery-ui/jquery.tagify
*= require chosen *= require chosen
*= require_self *= require_self
*= require common *= require main
*/ */

View file

@ -1,191 +0,0 @@
/* Commit Page */
body.project-page.commits-page .commit-info{float: right;}
body.project-page.commits-page .commit-info data{
padding: 4px 10px;
font-size: 11px;
}
body.project-page.commits-page .commit-info data.commit-button{
background-image: -webkit-gradient(linear, 0 0, 0 26, color-stop(0.192, #fff), to(#f4f4f4));
background-image: -webkit-linear-gradient(#fff 19.2%, #f4f4f4);
background-image: -moz-linear-gradient(#fff 19.2%, #f4f4f4);
background-image: -o-linear-gradient(#fff 19.2%, #f4f4f4);
box-shadow: 0 -1px 0 white inset;
display: block;
border: 1px solid #eee;
border-radius: 5px;
margin-bottom: 2px;
position: relative;
padding-right: 20px;
}
body.project-page.commits-page .commit-button i{
background: url('images.png') no-repeat -138px -27px;
width: 6px;
height: 9px;
float: right;
position: absolute;
top: 6px;
right: 5px;
}
body.project-page.commits-page .commits-date {display: block; width: 100%; margin-bottom: 20px}
body.project-page.commits-page .commits-date .data {padding: 0}
body.project-page.commits-page a.commit{padding: 10px; border-bottom: 1px solid #eee; overflow: hidden; display: block;}
body.project-page.commits-page .commits-date a.commit {padding: 10px; border-bottom: none; overflow: hidden; display: block;}
body.project-page.commits-page .commits-date a.commit:last-child{border-bottom: 0}
body.project-page.commits-page .commits-date a.commit img{float: left; margin-right: 10px;}
body.project-page.commits-page .commits-date a.commit span.commit-title{display: block;}
body.project-page.commits-page .commits-date a.commit span.commit-title{margin-bottom: 10px}
body.project-page.commits-page .commits-date a.commit span.commit-author{color: #999; font-weight: normal; font-style: italic;}
body.project-page.commits-page .commits-date a.commit span.commit-author strong{font-weight: bold; font-style: normal;}
/* eo Commit Page */
/** Commit diff view **/
.diff_file {
border:1px solid #CCC;
margin-bottom:1em;
.diff_file_header {
padding:5px 5px;
border-bottom:1px solid #CCC;
background: #eee;
}
.diff_file_content {
overflow:auto;
overflow-y:hidden;
background:#fff;
color:#333;
font-size: 12px;
font-family: 'Courier New', 'andale mono','lucida console',monospace;
}
.diff_file_content_image {
background:#eee;
text-align:center;
img {
padding:100px;
max-width:300px;
}
}
}
.diff_file_content{
table {
border:none;
margin:0px;
padding:0px;
}
.old_line, .new_line {
margin:0px;
padding:0px;
border:none;
background:#F7F7F7;
color:#aaa;
padding: 0px 5px;
border-right: 1px solid #ccc;
text-align:right;
min-width:35px;
max-width:35px;
width:35px;
a {
float:left;
width:35px;
font-weight:normal;
color:#aaa;
&:hover {
text-decoration:underline;
}
}
}
.line_content {
white-space:pre;
height:14px;
margin:0px;
padding:0px;
border:none;
&.new {
background: #DFD;
}
&.old {
background: #FDD;
}
}
}
pre.commit_message {
white-space: pre-wrap;
font-family: "Helvetica", sans-serif;
color: #555;
font-weight:bold;
font-size:15px;
}
/** COMMIT BLOCK **/
.commit-title{display: block;}
.commit-title{margin-bottom: 10px}
.commit-author{color: #999; font-weight: normal; font-style: italic;}
.commit-author strong{font-weight: bold; font-style: normal;}
/** bordered list **/
ul.bordered-list {
margin:5px 0px;
padding:0px;
li {
padding: 5px 0;
border-bottom: 1px solid #EEE;
overflow: hidden;
display: block;
margin:0px;
}
}
ul.bordered-list li:last-child { border:none }
.line_holder {
&:hover {
td {
background: #FFFFCF !important;
}
}
}
.per_line_form {
font-family: "Helvetica", sans-serif;
background: #2FA0BB;
td {
padding:0;
}
form {
margin:5px;
width: 756px;
border: 1px solid #CCC;
padding: 20px;
background: white;
}
}
tr.line_notes_row {
font-family: "Helvetica", sans-serif;
&:hover {
background:none;
}
td {
margin:0px;
padding:0px;
border-bottom:1px solid #DEE2E3;
ul {
display:block;
list-style:none;
margin:0px;
padding:0px;
li {
border-top:1px solid #DEE2E3;
padding:10px;
}
}
}
}

View file

@ -1,55 +1,53 @@
$text_color:#222; a {
$lite_text_color: #666; color: $link_color;
$link_color:#111; &:hover {
$active_link_color:#2FA0BB; text-decoration:none;
$active_bg_color:#79C3E0; color: $style_color;
$active_bd_color: #2FA0BB; }
$border_color:#CCC;
$lite_border_color:#EEE;
$app_width:980px;
$app_padding:20px;
$bg_color: #FFF;
$styled_border_color: #2FA0BB;
/** MIXINS **/ &.btn {
@mixin round-borders-bottom($radius) { color: $style_color;
border-top: 1px solid #eaeaea; }
-moz-border-radius-bottomright: $radius;
-moz-border-radius-bottomleft: $radius;
border-bottom-right-radius: $radius;
border-bottom-left-radius: $radius;
-webkit-border-bottom-left-radius: $radius;
-webkit-border-bottom-right-radius: $radius;
} }
@mixin round-borders-top($radius) { .vlink {
border-top: 1px solid #eaeaea; color: $link_color !important;
-moz-border-radius-topright: $radius;
-moz-border-radius-topleft: $radius;
border-top-right-radius: $radius;
border-top-left-radius: $radius;
-webkit-border-top-left-radius: $radius;
-webkit-border-top-right-radius: $radius;
} }
@mixin round-borders-all($radius) { .pills a:hover {
border: 1px solid #eaeaea; background-color:#ccc;
-moz-border-radius: $radius; }
-webkit-border-radius: $radius;
border-radius: $radius; .pills .active a {
background-color: #aaa;
}
.label {
background-color: #474D57;
}
.tabs > li > a, .pills > li > a {
color:$style_color;
}
.diff_file_header a,
.file_stats a {
color:$style_color;
} }
/** COLORS **/ /** COLORS **/
.cgray { color:gray; } .cgray { color:gray; }
.cred { color:#D12F19; } .cred { color:#D12F19; }
.cgreen { color:#44aa22; } .cgreen { color:#44aa22; }
.cblack { color:#111; }
.cwhite { color:#fff !important }
/** COMMON STYLES **/ /** COMMON STYLES **/
.left { .left {
float:left; float:left;
} }
.right { .right {
float:right; float:right !important;
} }
.width-50p{ .width-50p{
width:50%; width:50%;
@ -78,38 +76,559 @@ $styled_border_color: #2FA0BB;
.no-borders { .no-borders {
border:none; border:none;
} }
table.no-borders {
border:none;
tr, td { border:none }
}
.no-padding { .no-padding {
padding:0 !important; padding:0 !important;
} }
.underlined {
border-bottom: 1px solid $border_color;
}
/* General */ /** LAYOUT **/
body.collapsed { .container {
background-color: $bg_color; width:$min_app_width;
padding-top:0;
z-index:5;
}
#container{ .container .content {
margin: auto; margin:0 $app_padding;
margin-top:51px; }
width: $app_width;
border-top: 0; .container .sidebar {
background-color: $bg_color; width: 200px;
height:100%;
min-height:450px;
float:right;
}
img.avatar {
float:left;
margin-right:15px;
width:40px;
-webkit-border-radius: 4px;
-moz-border-radius: 4px;
border-radius: 4px;
}
img.lil_av {
padding-left: 5px;
position: relative;
top: 3px;
}
.media-grid {
h3, h2 , h4 {
&.media_h {
padding-left:10px;
float:left;
}
} }
} }
a { .wll {
color: $link_color; background-color: #FFF;
padding: 10px 5px;
min-height: 20px;
border-bottom: 1px solid #eee;
border-bottom: 1px solid rgba(0, 0, 0, 0.05);
cursor:pointer;
&:hover {
background:$hover;
}
&:last-child { border:none }
p { padding-top:5px; margin:0; color:$style_color;}
.author { color: #999; }
p {
color:#222;
margin-bottom: 0;
img {
position:relative;
top:3px;
}
}
} }
@import "style.scss"; .visible_link,
@import "projects.css.scss"; .author_link {
@import "commits.css.scss"; color: $link_color;
@import "notes.css.scss"; }
@import "merge_requests.css.scss"; .entry {
@import "highlight.css.scss"; position: relative;
@import "highlight.black.css.scss"; padding: 7px 15px;
@import "issues.css.scss"; margin-bottom: 18px;
@import "commits.css.scss"; color: #404040;
filter:none;
@import "top_panel.scss"; text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
@import "dashboard.scss"; text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5);
@import "tree.scss";
-webkit-border-radius: 4px;
-moz-border-radius: 4px;
border-radius: 4px;
-webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25);
-moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25);
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25);
background:#F1F1F1;
border: 1px solid #ccc;
p {
color:$style_color;
margin-bottom: 0;
img {
position:relative;
top:3px;
}
}
}
.widget {
@include shade;
padding:20px;
margin-bottom:20px;
border: 1px solid #DDD;
border-radius: 5px;
background:#fafafa;
.link_holder {
background:#eee;
position:relative;
left:-20px;
top:20px;
padding:10px 20px;
width:100%;
border-top:1px solid #ccc;
a {
font-size:14px;
color:#666;
}
}
}
.ui-box {
margin-bottom: 40px;
@include round-borders-all(4px);
@include shade;
border-color:#ddd;
ul {
margin:0;
}
h5, .title {
padding: 0 10px;
background:#f5f5f5;
border-bottom: 1px solid #eee;
@include round-borders-top(4px);
border-top:none;
form {
padding-top:16px;
}
}
.row_title {
font-weight:bold;
color:#444;
&:hover {
text-decoration:underline;
}
}
li, .wll {
padding:10px;
&:first-child {
@include round-borders-top(4px);
border-top:none;
}
&:last-child {
@include round-borders-bottom(4px);
border:none;
}
}
}
.help li { color:#111 }
.back_link {
text-decoration:underline;
font-size:14px;
font-weight:bold;
padding:10px 0;
padding-bottom:0;
}
.info_link {
margin-right:5px;
float:left;
img {
width:20px;
}
}
.borders {
border: 1px solid #ccc;
@include shade;
}
.download_repo_link {
background: url("images.png") no-repeat 0 -48px;
padding-left:20px;
}
.number {
border-radius: 4px;
text-shadow: none;
background: rgba(0,0,0,.12);
text-align: center;
padding: 2px 4px;
line-height:20px;
margin-left:2px;
}
table a code {
position: relative;
top: -2px;
margin-right: 3px;
}
.span12 hr{
margin-top: 5px;
}
.btn.padded {
margin-right:3px;
}
.loading {
margin:20px auto;
background: url(ajax-loader-facebook.gif) no-repeat center center;
width:40px;
height:40px;
}
/** FLASH message **/
#flash_container {
height:45px;
position:fixed;
z-index:10001;
top:0px;
width:100%;
margin-bottom:15px;
overflow:hidden;
background:white;
cursor:pointer;
border-bottom:1px solid #777;
h4 {
color:#444;
font-size:22px;
padding-top:5px;
margin:2px;
}
}
.git_url_wrapper {
margin-right:50px
}
.file_stats {
span {
img {
width:14px;
float:left;
margin-right:6px;
padding:2px 0;
}
}
}
.handle:hover {
cursor:move;
}
span.update-author {
display:block;
}
span.update-author {
color:#999;
font-weight:normal;
font-style:italic;
}
span.update-author strong {
font-weight:bold;
font-style: normal;
}
/** UPDATE ITEM **/
span.update-author {
display:block;
}
/** END UPDATE ITEM **/
.ajax-tab-loading {
padding:40px;
display:none;
}
.dashboard-loader {
float:left;
margin:10px;
display:none;
}
.user-mention {
color:#2FA0BB;
font-weight:bold;
}
a.project-update.titled {
position:relative;
padding-left:35% !important;
.title-block {
padding:10px;
width:35%;
position:absolute;
left:0;
top:0;
}
}
/**
* Project graph
*/
#holder {
cursor: move;
height: 70%;
overflow: hidden;
}
input.git_clone_url {
width:475px;
}
.team_member_row {
img {
width:60px;
}
}
.merge-request-form-holder {
select {
width:300px;
}
}
/** Issues **/
#issue_assignee_id {
width:300px;
}
#new_issue_dialog textarea{
height: 100px;
}
.project_list_url {
width:250px;
background:#fff !important;
}
.project_tile {
@include shade;
@include round-borders-all(4px);
margin-bottom:20px;
width:298px;
float:left;
margin-left:20px;
border: 1px solid #DDD;
padding-bottom:20px;
.title {
background:#f5f5f5;
padding: 5px 10px 2px 20px;
border-bottom: 1px solid #DDD;
margin-bottom: 15px;
h3 {
&:hover {
text-decoration: underline;
}
}
}
.data {
margin: 0 20px;
}
.buttons {
margin: 0 20px;
}
}
/**
*
* COMMIT SHOw
*
*/
.diff_file {
border:1px solid #CCC;
margin-bottom:1em;
.diff_file_header {
padding:5px 5px;
border-bottom:1px solid #CCC;
background: #eee;
}
.diff_file_content {
overflow:auto;
overflow-y:hidden;
background:#fff;
color:#333;
font-size: 12px;
font-family: 'Menlo', 'Courier New', 'andale mono','lucida console',monospace;
}
.diff_file_content_image {
background:#eee;
text-align:center;
img {
padding:100px;
max-width:300px;
}
}
}
.diff_file_content{
table {
border:none;
margin:0px;
padding:0px;
tr {
td {
font-size:12px;
}
}
}
.old_line, .new_line {
margin:0px;
padding:0px;
border:none;
background:#F7F7F7;
color:#aaa;
padding: 0px 5px;
border-right: 1px solid #ccc;
text-align:right;
min-width:35px;
max-width:35px;
width:35px;
moz-user-select: none;
-khtml-user-select: none;
user-select: none;
a {
float:left;
width:35px;
font-weight:normal;
color:#aaa;
&:hover {
text-decoration:underline;
}
}
}
.line_content {
white-space:pre;
height:14px;
margin:0px;
padding:0px;
border:none;
&.new {
background: #CFD;
}
&.old {
background: #FDD;
}
&.matched {
color:#ccc;
background:#fafafa;
}
}
}
/** COMMIT BLOCK **/
.commit-title{display: block;}
.commit-title{margin-bottom: 10px}
.commit-author, .commit-committer{display: block;color: #999; font-weight: normal; font-style: italic;}
.commit-author strong, .commit-committer strong{font-weight: bold; font-style: normal;}
/** bordered list **/
ul.bordered-list {
margin:5px 0px;
padding:0px;
li {
padding: 5px 0;
border-bottom: 1px solid #EEE;
overflow: hidden;
display: block;
margin:0px;
}
}
ul.bordered-list li:last-child { border:none }
.line_holder {
&:hover {
td {
background: #FFFFCF !important;
}
}
}
li.commit {
.avatar {
width:24px;
top:-3px;
margin-right:10px;
margin-left:10px;
}
code {
padding:4px;
}
}
p.time {
color: #999;
font-size: 90%;
margin: 30px 3px 3px 2px;
}
.dashboard_category {
margin-bottom:30px;
.dashboard_block {
width:700px;
margin:auto;
.wll {
border:none;
&:hover {
background:none;
}
h4 {
color:#666;
}
}
}
}
.event_feed {
ul {
margin-left:50px;
}
}

View file

@ -1,30 +0,0 @@
body.dashboard-page h2.icon span{ background-position: 9px -69px; }
body.dashboard-page header{margin-bottom: 0}
body.dashboard-page .news-feed{margin-left: 285px; min-height: 600px; margin-top: 20px; margin-right:2px; padding:20px;}
body.dashboard-page .dashboard-content{ position: relative; float: left; width: 100%; height: 100%; }
body.dashboard-page .news-feed h2{float: left;}
body.dashboard-page aside{
min-height: 820px; position: relative; top: 0; bottom: 0; right: 0; width: 260px; float: left; border-right: 1px solid $border_color; padding:20px; padding-right:0;
h4{margin: 0; border-bottom: 1px solid #ccc; padding: 20px 20px 20px 0px; font-size: 11px; font-weight: bold; text-transform: uppercase;}
h4 a.button-small{float: right; text-transform: none; border-radius: 4px; margin-right: 2%; margin-top: -4px; display: block;}
.project-list {list-style: none; margin: 0; padding: 0;}
.project-list li a {background: white; color: #{$blue_link}; display: block; border-bottom: 1px solid $lite_border_color; padding: 14px 6% 14px 0px;}
.project-list li a span.project-name{font-size: 14px; display: block; margin-bottom: 8px}
.project-list li a span.time{color: #666; font-weight: normal; font-size: 11px}
.project-list li a span.arrow{float: right; background: #E3E5EA; padding: 10px; border-radius: 5px; margin-top: 2px; text-shadow: none; color: #999}
}
body.dashboard-page .news-feed .project-updates {
margin-bottom: 20px; display: block; width: 100%;
.data{ padding: 0}
a.project-update {padding: 10px; overflow: hidden; display: block;}
a.project-update:last-child{border-bottom: 0}
a.project-update img{float: left; margin-right: 10px;}
a.project-update span.update-title, .dashboard-page .news-feed .project-updates li a span.update-author{display: block;}
a.project-update span.update-title{margin-bottom: 10px}
a.project-update span.update-author{color: #999; font-weight: normal; font-style: italic;}
a.project-update span.update-author strong{font-weight: bold; font-style: normal;}
}
/* eo Dashboard Page */

View file

@ -1,5 +1,6 @@
.black .highlighttable { .black .highlighttable {
background: #333; background: #333;
td.linenos { border:none; }
pre { color: #eee } pre { color: #eee }
.highlight { background: #333; border-left:1px solid #555; } .highlight { background: #333; border-left:1px solid #555; }

View file

@ -10,13 +10,15 @@ table.highlighttable
margin:0px; margin:0px;
padding:0px; padding:0px;
font-size:12px; font-size:12px;
table-layout:fixed table-layout:fixed;
background: #F7F7F7;
} }
td.code, td.code,
td.linenos{ td.linenos{
padding:0; padding:0;
margin:0; margin:0;
border-top:0;
vertical-align:top; vertical-align:top;
} }
@ -24,8 +26,16 @@ td.linenos{
background:none; background:none;
padding:10px 0px 0px 10px; padding:10px 0px 0px 10px;
margin-left:0px; margin-left:0px;
border-left: 1px solid #DEE2E3;
background: white;
} }
.linenodiv pre,
.highlight pre{ .highlight pre{
margin:0;
padding:0;
background:none;
border:none;
} }
.linenodiv pre { .linenodiv pre {
@ -48,7 +58,7 @@ td.code .highlight {
table.highlighttable pre{ table.highlighttable pre{
padding:0; padding:0;
margin:0; margin:0;
font-family: 'Courier New', 'andale mono','lucida console',monospace; font-family: 'Menlo', 'Courier New', 'andale mono','lucida console',monospace;
color: #333; color: #333;
text-align:left; text-align:left;
} }
@ -62,7 +72,7 @@ table.highlighttable pre{
padding:0; padding:0;
line-height:2.0; line-height:2.0;
margin:0; margin:0;
font-family: 'Courier New', 'andale mono','lucida console',monospace; font-family: 'Menlo', 'Courier New', 'andale mono','lucida console',monospace;
color: #333; color: #333;
text-align:left;} text-align:left;}
} }

View file

@ -1,84 +0,0 @@
.issue-number {
float: left;
border-radius: 5px;
text-shadow: none;
background: rgba(0, 0, 0, 0.12);
text-align: center;
padding: 14px 8px;
width: 40px;
margin-right: 10px;
color: #444;
}
.issues_filter {
margin:10px 0;
.left {
margin-right:15px;
}
}
.top_panel_issues{
#issue_search_form {
margin:5px 0;
input {
border:1px solid #D3D3D3;
padding: 3px;
height: 28px;
width: 250px;
-webkit-appearance:none;
box-sizing: border-box;
-moz-box-sizing: border-box;
&:focus {
border-color:#c2e1ef;
}
}
}
}
/** ISSUES LIST **/
.issue .action-links {
display:none;
a {
margin-left:10px;
}
}
.issue:hover .action-links { display:block; }
.issue-show-holder {
width:100%;
.data p { font-size:16px }
}
#issue_assignee_id {
width:300px;
}
.issue-form-holder .ui-box .data {
margin: 0;
padding: 0;
}
body.project-page .merge-request-form-holder table.no-borders tr,
body.project-page .merge-request-form-holder table.no-borders td,
body.project-page .issue-form-holder table.no-borders tr,
body.project-page .issue-form-holder table.no-borders td,
body.project-page .new_snippet table tr,
body.project-page .new_snippet table td,
body.project-page .edit_snippet table tr,
body.project-page .edit_snippet table td
{
&:hover {
background:none;
}
}
#issues-table {
tr {
border-top: 1px solid $lite_border_color;
&:first-child {
border:none;
}
}
}

View file

@ -0,0 +1,44 @@
/* Login Page */
body.login-page{
padding-top: 10%;
background:#f1f1f1;
}
.login-box{
width: 304px;
position: relative;
border-radius: 5px;
margin: auto;
padding: 20px;
background: white;
}
.login-box .login-logo{
margin: 10px 0 30px 0;
display: block;
}
.login-box input.text{background-color: #f1f1f1; font-size: 16px; border-radius: 0; padding: 14px 10px; width: 280px}
.login-box input.text.top{
-webkit-border-top-left-radius: 5px;
-webkit-border-top-right-radius: 5px;
-moz-border-radius-topleft: 5px;
-moz-border-radius-topright: 5px;
border-top-left-radius: 5px;
border-top-right-radius: 5px;
}
.login-box input.text.bottom{
-webkit-border-bottom-right-radius: 5px;
-webkit-border-bottom-left-radius: 5px;
-moz-border-radius-bottomright: 5px;
-moz-border-radius-bottomleft: 5px;
border-bottom-right-radius: 5px;
border-bottom-left-radius: 5px;
border-top: 0;
margin-bottom: 20px;
}
.login-box a.forgot{float: right; padding-top: 6px}

View file

@ -0,0 +1,118 @@
@import "bootstrap";
/** GITLAB colors **/
$text_color:#222;
$lite_text_color: #666;
$link_color:#2A79A3;
$active_link_color:#2FA0BB;
$active_bg_color:#79C3E0;
$active_bd_color: #2FA0BB;
$border_color:#CCC;
$lite_border_color:#EEE;
$min_app_width:980px;
$max_app_width:980px;
$app_padding:20px;
$bg_color: #FFF;
$styled_border_color: #2FA0BB;
$color: "#4BB8D2";
$blue_link: "#2fa0bb";
/** Style colors **/
$style_color: #474D57;
$hover: #FDF5D9;
/** MIXINS **/
@mixin shade {
-moz-box-shadow: 0 0 3px #ddd;
-webkit-box-shadow: 0 0 3px #ddd;
box-shadow: 0 0 3px #ddd;
}
@mixin round-borders-bottom($radius) {
border-top: 1px solid #eaeaea;
-moz-border-radius-bottomright: $radius;
-moz-border-radius-bottomleft: $radius;
border-bottom-right-radius: $radius;
border-bottom-left-radius: $radius;
-webkit-border-bottom-left-radius: $radius;
-webkit-border-bottom-right-radius: $radius;
}
@mixin round-borders-top($radius) {
border-top: 1px solid #eaeaea;
-moz-border-radius-topright: $radius;
-moz-border-radius-topleft: $radius;
border-top-right-radius: $radius;
border-top-left-radius: $radius;
-webkit-border-top-left-radius: $radius;
-webkit-border-top-right-radius: $radius;
}
@mixin round-borders-all($radius) {
border: 1px solid #eaeaea;
-moz-border-radius: $radius;
-webkit-border-radius: $radius;
border-radius: $radius;
}
/**
* This file represent some UI that can be changed
* during web app restyle or theme select.
*
* Next items should be placed there
* - link colors
* - header styles
* - main menu styles
*
*/
@import "ui_basic.scss";
/**
* UI mars theme
*/
@import "ui_mars.scss";
/**
* Most of application styles placed here.
* This file represent common UI that should not be changed between themes
* or project restyling like form width or user avatar class or commit title
*
* TODO: clean it
*/
@import "common.scss";
/**
* This scss file redefine chozen selectbox styles for
* project Branch/Tag select element
*/
@import "ref_select.scss";
/**
* Code (files list) styles. Browsing project files there
*/
@import "tree.scss";
/**
* This file represent notes(comments) styles
*/
@import "notes.scss";
/**
* Devise styles
*/
@import "login.scss";
/**
* CODE HIGHTLIGHT BASE
*
*/
@import "highlight.scss";
/**
* CODE HIGHTLIGHT DARK schema
*
*/
@import "highlight.black.scss";

View file

@ -1,10 +0,0 @@
// Place all the styles related to the MergeRequests controller here.
// They will automatically be included in application.css.
// You can use Sass (SCSS) here: http://sass-lang.com/
.merge-request-form-holder {
select {
width:300px;
}
}

View file

@ -1,52 +0,0 @@
/** Notes **/
#notes-list {
display:block;
list-style:none;
margin:0px;
padding:0px;
}
.issue_notes {
.note_content {
float:left;
width:400px;
}
}
/* Note textare */
#note_note {
height:100px;
width:97%;
font-size:14px;
}
#new_note {
#note_note {
height:25px;
}
.attach_holder {
display:none;
}
}
#notes-list .note .delete-note { display:none; }
#notes-list .note:hover .delete-note { display:block; }
body.project-page #notes-list .note {padding: 10px 0; border-bottom: 1px solid #eee; overflow: hidden; display: block;}
body.project-page #notes-list .note img{float: left; margin-right: 10px;}
body.project-page #notes-list .note span.note-title{display: block;}
body.project-page #notes-list .note span.note-title{margin-bottom: 10px}
body.project-page #notes-list .note span.note-author{color: #999; font-weight: normal; font-style: italic;}
body.project-page #notes-list .note span.note-author strong{font-weight: bold; font-style: normal;}
.note .note-title { margin-left:55px; }
p.notify_controls input{
margin: 5px;
}
p.notify_controls span{
font-weight: 700;
}

View file

@ -0,0 +1,121 @@
/**
* Notes
*
*/
#notes-list,
#new_notes_list {
display:block;
list-style:none;
margin:0px;
padding:0px;
}
#new_notes_list li:last-child{
border-bottom:1px solid #aaa;
}
.issue_notes {
.note_content {
float:left;
width:400px;
}
}
/* Note textare */
#note_note {
height:100px;
width:97%;
font-size:14px;
}
#new_note {
#note_note {
height:25px;
}
.attach_holder {
display:none;
}
}
.note .delete-note {
display:none;
float:right;
}
.note:hover .delete-note { display:block; }
.note {padding: 10px 0; border-bottom: 1px solid #eee; overflow: hidden; display: block;}
.note img{float: left; margin-right: 10px;}
.note span.note-title{display: block;}
.note span.note-title{margin-bottom: 10px}
.note span.note-author{color: #999; font-weight: normal; font-style: italic;}
.note span.note-author strong{font-weight: bold; font-style: normal;}
.note p { color:$style_color; }
.note .note-author { color: $style_color;}
.note .note-title { margin-left:55px; }
p.notify_controls input{
margin: 5px;
}
p.notify_controls span{
font-weight: 700;
}
tr.line_notes_row {
border-bottom:1px solid #DDD;
&.reply {
background:#eee;
td {
padding:7px 10px;
}
a.line_note_reply_link {
@include round-borders-all(4px);
border-color:#aaa;
background: #bbb;
padding: 3px 20px;
color: white;
}
}
ul {
margin:0;
li {
padding:0;
border:none;
}
}
}
.line_notes_row, .per_line_form { font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; }
.per_line_form {
background:#f5f5f5;
form { margin: 0; }
td {
border-bottom:1px solid #ddd;
}
}
td .line_note_link {
position:absolute;
margin-left:-70px;
margin-top:-10px;
z-index:10;
background: url("comment_add.png") no-repeat left 0;
width:32px;
height:32px;
opacity: 0.0;
filter: alpha(opacity=0);
&:hover {
opacity: 1.0;
filter: alpha(opacity=100);
}
}
.diff_file_content tr.line_holder:hover > td { background: $hover !important; }
.diff_file_content tr.line_holder:hover > td .line_note_link {
opacity: 1.0;
filter: alpha(opacity=100);
}

View file

@ -1,572 +0,0 @@
body.project-page h2.icon .project-name, body.project-page h2.icon d{border: 1px solid #eee; padding: 5px 30px 5px 10px; border-radius: 5px; position: relative;}
body.project-page h2.icon .project-name i.arrow{float: right;
position: absolute;
right: 10px;
top: 13px;
display: block;
background: url('images.png') no-repeat -97px -29px;
width: 4px;
height: 5px;
}
body.project-page h2.icon span{ background-position: -78px -68px; }
body.project-page .project-container{ position: relative; float: left; width: 100%; height: 100%; padding-bottom: 10px;}
body.project-page .page-title{margin-bottom: 0}
body.project-page .project-sidebar {
width: 110px;
left: 0;
top: 0;
height: 100%;
bottom: 0;
position: absolute;
float: left;
display: inline-block;
background: #FFF;
padding: $app_padding;
padding-right:0px;
margin: 0;
border-right: 1px solid $border_color;
}
body.projects-page input.text.git-url { font-size: 12px; border-radius: 5px; color: #666; box-shadow: 0 1px 2px rgba(0,0,0,.2) inset; padding: 8px 0 8px 30px; margin-bottom: 20px; background: white url('images.png') no-repeat 8px -40px; width: 136px}
body.projects-page input.text.git-url {margin:10px 0 0 }
.git_url_wrapper { margin-right:50px }
.projects_selector:hover > .project-box{ -moz-box-shadow:0px 0px 10px rgba(0, 0, 0, .1); -webkit-box-shadow:0px 0px 10px rgba(0, 0, 0, .1); box-shadow:0px 0px 10px rgba(0, 0, 0, .1); }
/* New project Page */
.new-project-page .container table{background: white}
body.project-page .project-sidebar aside{width: 109px}
body.project-page .project-sidebar aside a{
display: block;
position: relative;
padding: 15px 10px;
margin: 10px 0 0 0;
}
body.project-page .project-sidebar aside a span.number{float: right; border-radius: 5px; text-shadow: none; background: rgba(0,0,0,.12); text-align: center; padding: 5px 8px; position: absolute; top: 10px; right: 10px}
body.project-page .project-sidebar aside a.current {
color: white;
background: $active_bg_color;
border: 1px solid $active_bd_color;
border-radius:5px;
-webkit-border-top-right-radius: 0;
-webkit-border-bottom-right-radius: 0;
-moz-border-radius-topright: 0px;
-moz-border-radius-bottomright: 0px;
border-top-right-radius: 0;
border-bottom-right-radius: 0;
margin-right: -1px;
}
body.project-page .project-content{ padding: $app_padding; display: block; margin-left: 130px; min-height: 600px}
body.project-page .project-content h2{ margin-top: 6px}
body.project-page .project-content .button.right{margin-left: 20px}
body.project-page table .commit a{color: #{$blue_link}}
body.project-page table th, body.project-page table td{ border-bottom: 1px solid #DEE2E3;}
body.project-page .fixed{position: fixed; }
/** File stat **/
.file_stats {
span {
img {
width:14px;
float:left;
margin-right: 6px;
padding:2px 0;
}
}
}
.round-borders {
@include round-borders-all(4px);
padding: 4px 0px;
}
table.round-borders {
float:left;
text-align: left;
}
/** PROJECTS **/
input.ssh_project_url {
padding:5px;
margin:0px;
float:right;
width:400px;
text-align:center;
}
#projects-list .project {
height:50px;
}
#tree-slider .tree-item,
#projects-list .project,
#snippets-table .snippet,
#issues-table .issue{
cursor:pointer;
}
.clear {
clear: both;
}
/** Buttons **/
.lbutton,
.lite_button {
display:block;
float:left;
margin: 0px 5px 0px 0px;
padding:5px 10px;
font-family:"Helvetica Neue", Arial, Helvetica, sans-serif;
border:1px solid #D3D3D3;
background:white;
font-size:12px !important;
line-height:130%;
text-decoration:none;
font-weight:bold;
color:#565656;
cursor:pointer;
&:hover {
border:1px solid #C2E1EF;
color: #0099FF;
}
&.hm {
margin: 0px 0px;
}
&.vm {
margin: 5px 0px;
}
}
#user_projects_limit{
width: 60px;
}
.handle:hover{
cursor: move;
}
.project-refs-form {
span {
background: none !important;
position:static !important;
width:auto !important;
height: auto !important;
}
}
.project-refs-select {
width:200px;
}
.filter .left { margin-right:15px; }
body.project-page table .commit {
a.tree-commit-link {
color:#444;
&:hover {
text-decoration:underline;
}
}
}
/** NEW PROJECT **/
.new-project-hodler {
.icon span { background-position: -31px -70px; }
td { border-bottom: 1px solid #DEE2E3; }
}
/** Feed entry **/
.commit,
.snippet,
.message {
.title {
color:#666;
a { color:#666 !important; }
p { margin-top:0px; }
}
.author { color: #999 }
}
/** JQuery UI **/
.ui-autocomplete { @include round-borders-all(5px); }
.ui-menu-item { cursor: pointer }
.ui-selectmenu{
@include round-borders-all(4px);
margin-right:10px;
font-size:1.5em;
height:auto;
font-weight:bold;
.ui-selectmenu-status {
padding:3px 10px;
}
}
/** Snippets **/
.new_snippet textarea,
.edit_snippet textarea {
height:300px;
padding: 8px;
width: 95%;
}
.snippet .action-links {
display:none;
a {
margin-left:10px;
}
}
.snippet:hover .action-links { display:block; }
/** ISSUES TAGS **/
.tag {
@include round-borders-all(4px);
padding:2px 4px;
border:none;
text-shadow:none;
&.inline {
display:inline;
}
&.high, &.closed {
background: #D12F19;
color:white;
}
&.today, &.open {
background: #44aa22;
color:white;
}
&.yours {
background: #4466cc;
color:white;
}
&.normal {
background: #2c5ca6;
color:white;
}
&.notes {
background: #2c5c66;
color:white;
}
&.note {
background-image: -webkit-gradient(linear, 0 0, 0 26, color-stop(0.076, #fefefe), to(#F6F7F8));
background-image: -webkit-linear-gradient(#fefefe 7.6%, #F6F7F8);
background-image: -moz-linear-gradient(#fefefe 7.6%, #F6F7F8);
background-image: -o-linear-gradient(#fefefe 7.6%, #F6F7F8);
color: #777;
border: 1px solid #DEDFE1;
}
&.issue {
background: #D12F19;
color:white;
}
&.commit {
background-image: -webkit-gradient(linear, 0 0, 0 26, color-stop(0.076, #fefefe), to(#F6F7F8));
background-image: -webkit-linear-gradient(#fefefe 7.6%, #F6F7F8);
background-image: -moz-linear-gradient(#fefefe 7.6%, #F6F7F8);
background-image: -o-linear-gradient(#fefefe 7.6%, #F6F7F8);
color: #777;
border: 1px solid #DEDFE1;
}
}
#holder {
background:#FAFAFA;
border: 1px solid #EEE;
cursor: move;
height: 70%;
overflow: hidden;
}
/* Project Dashboard Page */
html, body { height: 100%; }
body.dashboard.project-page .news-feed h2{float: left;}
body.dashboard.project-page .news-feed .project-updates {margin-bottom: 20px; display: block; width: 100%;}
body.dashboard.project-page .news-feed .project-updates .data{ padding: 0}
body.dashboard.project-page .news-feed .project-updates a.project-update {padding: 10px; border-bottom: 1px solid #eee; overflow: hidden; display: block;}
body.dashboard.project-page .news-feed .project-updates a.project-update:last-child{border-bottom: 0}
body.dashboard.project-page .news-feed .project-updates a.project-update img{float: left; margin-right: 10px;}
body.dashboard.project-page .news-feed .project-updates a.project-update span.update-title, .dashboard-page .news-feed .project-updates li a span.update-author{display: block;}
body.dashboard.project-page .news-feed .project-updates a.project-update span.update-title{margin-bottom: 10px}
body.dashboard.project-page .news-feed .project-updates a.project-update span.update-author{color: #999; font-weight: normal; font-style: italic;}
body.dashboard.project-page .news-feed .project-updates a.project-update span.update-author strong{font-weight: bold; font-style: normal;}
/* eo Dashboard Page */
/** Merge requests */
body.project-page .merge-request-commits {margin-bottom: 20px; display: block; width: 100%;}
body.project-page .merge-request-commits .data{ padding: 0}
body.project-page .merge-request-commits a.commit {padding: 10px; border-bottom: 1px solid #eee; overflow: hidden; display: block;}
body.project-page .merge-request-commits a.commit:last-child{border-bottom: 0}
body.project-page .merge-request-commits a.commit img{float: left; margin-right: 10px;}
body.project-page .merge-request-commits a.commit span.update-title, .dashboard-page .news-feed .project-updates li a span.update-author{display: block;}
body.project-page .merge-request-commits a.commit span.update-title{margin-bottom: 10px}
body.project-page .merge-request-commits a.commit span.update-author{color: #999; font-weight: normal; font-style: italic;}
body.project-page .merge-request-commits a.commit span.update-author strong{font-weight: bold; font-style: normal;}
/** Update entry **/
.update-data { padding: 0 }
.update-data { width:100%; }
.update-data.ui-box .data { padding:0; }
a.update-item {padding: 10px; border-bottom: 1px solid #eee; overflow: hidden; display: block;}
a.update-item:last-child{border-bottom: 0}
a.update-item img{float: left; margin-right: 10px;}
a.update-item span.update-title, .dashboard-page .news-feed .project-updates li a span.update-author{display: block;}
a.update-item span.update-title{margin-bottom: 10px}
a.update-item span.update-author{color: #999; font-weight: normal; font-style: italic;}
a.update-item span.update-author strong{font-weight: bold; font-style: normal;}
body.project-page .team_member_new .span-6, .team_member_edit .span-6{ padding:10px 0; }
body.projects-page input.text.git-url.project_list_url { width:165px; }
body.project-page table.no-borders th {
background:none;
border-bottom:1px solid #CCC;
color:#333;
}
body.project-page table.no-borders tr,
body.project-page table.no-borders td{
border:none;
}
.ajax-tab-loading {
padding:40px;
display:none;
}
#tree-content-holder { float:left; width:100%; }
#tree-readme-holder {
float:left;
width:100%;
.readme {
@include round-borders-all(4px);
padding: 4px 15px;
background:#F7F7F7;
}
}
/* Commit Page */
.entity-info {float: right;}
.entity-button{
background-image: -webkit-gradient(linear, 0 0, 0 26, color-stop(0.192, #fff), to(#f4f4f4));
background-image: -webkit-linear-gradient(#fff 19.2%, #f4f4f4);
background-image: -moz-linear-gradient(#fff 19.2%, #f4f4f4);
background-image: -o-linear-gradient(#fff 19.2%, #f4f4f4);
box-shadow: 0 -1px 0 white inset;
display: block;
border: 1px solid #eee;
border-radius: 5px;
margin-bottom: 2px;
position: relative;
padding: 4px 10px;
font-size: 11px;
padding-right: 20px;
}
.entity-button i{
background: url('images.png') no-repeat -138px -27px;
width: 6px;
height: 9px;
float: right;
position: absolute;
top: 6px;
right: 5px;
}
.box-arrow{float: right; background: #E3E5EA; padding: 10px; border-radius: 5px; margin-top: 2px; text-shadow: none; color: #999; margin: 1.5em 0;}
h4.dash-tabs {
margin: 0;
border-bottom: 1px solid #ccc;
padding: 10px 10px;
font-size: 11px;
padding-left:20px;
font-weight: bold; text-transform: uppercase;
background: #F7F7F7;
margin-bottom:20px;
height:13px;
}
.dash-button {
border-right: 1px solid #ddd;
background:none;
padding: 10px 15px;
float:left;
position:relative;
top:-10px;
left:0px;
height:13px;
&:first-child {
border-left: 1px solid #ddd;
}
&.active {
background: #eaeaea;
}
}
.dashboard-loader {
float:right;
margin-right:30px;
display:none;
}
.merge-tabs {
margin: 0;
border: 1px solid #ccc;
padding: 5px;
font-size: 12px;
background: #F7F7F7;
margin-bottom:20px;
height:26px;
-moz-border-radius: 4px;
-webkit-border-radius: 4px;
border-radius: 4px;
.tab {
font-weight: bold;
border-right: 1px solid #ddd;
background:none;
padding: 10px;
min-width:60px;
float:left;
position:relative;
top:-5px;
left:-5px;
height:16px;
padding-left:34px;
span {
width: 20px;
height: 20px;
display: inline-block;
position: absolute;
left: 8px;
top: 8px;
}
&.active {
background: #eaeaea;
}
}
}
.merge-tabs.repository .tab span{ background: url("images.png") no-repeat -38px -77px; }
.activities-tab span { background: url("images.png") no-repeat -161px -1px; }
.stat-tab span,
.team-tab span,
.snippets-tab span { background: url("images.png") no-repeat -38px -77px; }
.files-tab span { background: url("images.png") no-repeat -112px -23px; }
.merge-notes-tab span { background: url("images.png") no-repeat -161px -1px; }
.merge-commits-tab span { background: url("images.png") no-repeat -86px 1px; }
.merge-diffs-tab span { background: url("images.png") no-repeat -118px 1px; }
.merge-tabs .dashboard-loader { padding:8px; }
.user-mention {
color: #2FA0BB;
font-weight: bold;
}
.author {
color: #999;
}
.red-button{
border-radius: 5px;
font-size: 12px;
font-weight: bold;
padding: 5px 17px;
border: 1px solid #999;
color: #666;
display: inline-block;
box-shadow: 0 1px 2px rgba(0,0,0,.3);
background: #D12F19;
color: white;
}
.positive-button{
border-radius: 5px;
font-size: 12px;
font-weight: bold;
padding: 5px 17px;
border: 1px solid #999;
color: #666;
display: inline-block;
box-shadow: 0 1px 2px rgba(0,0,0,.3);
background: #4A2;
color: white;
}
.dark_scheme_box {
padding:20px 0;
label {
float:left;
box-shadow: 0 0px 5px rgba(0,0,0,.3);
img {
}
}
}
a.project-update.titled {
position: relative;
padding-left: 235px !important;
.title-block {
padding: 10px;
width: 205px;
position: absolute;
left: 0;
top: 0;
}
}
.add_new {
float: right;
background: #A6B807;
color: white;
padding: 4px 10px;
@include round-borders-all(4px);
font-size:11px;
margin: 10px 0;
}
.new-project-hodler {
padding:20px;
}

View file

@ -0,0 +1,385 @@
.git_url_wrapper { margin-right:50px }
.sidebar aside a{
display: block;
position: relative;
padding: 15px 10px;
margin: 10px 0 0 0;
font-size:13px;
font-weight:bold;
color:#333;
&.current {
color: white;
background: $active_bg_color;
border: 1px solid $active_bd_color;
border-radius:5px;
-webkit-border-top-right-radius: 0;
-webkit-border-bottom-right-radius: 0;
-moz-border-radius-topright: 0px;
-moz-border-radius-bottomright: 0px;
border-top-right-radius: 0;
border-bottom-right-radius: 0;
margin-right: -1px;
}
}
body table .commit a{color: #{$blue_link}}
body table th, body table td{ border-bottom: 1px solid #DEE2E3;}
body .fixed{position: fixed; }
/** File stat **/
.file_stats {
span {
img {
width:14px;
float:left;
margin-right: 6px;
padding:2px 0;
}
}
}
.round-borders {
@include round-borders-all(4px);
padding: 4px 0px;
}
table.round-borders {
float:left;
text-align: left;
}
/** PROJECTS **/
input.ssh_project_url {
padding:5px;
margin:0px;
float:right;
width:400px;
text-align:center;
}
#projects-list .project {
height:50px;
}
#tree-slider .tree-item,
#projects-list .project,
#snippets-table .snippet,
#issues-table .issue{
cursor:pointer;
}
.clear {
clear: both;
}
#user_projects_limit{
width: 60px;
}
.handle:hover{
cursor: move;
}
.project-refs-form {
span {
background: none !important;
position:static !important;
width:auto !important;
height: auto !important;
}
}
.project-refs-select {
width:200px;
}
.filter .left { margin-right:15px; }
body table .commit {
a.tree-commit-link {
color:#444;
&:hover {
text-decoration:underline;
}
}
}
/** NEW PROJECT **/
.new-project-hodler {
.icon span { background-position: -31px -70px; }
td { border-bottom: 1px solid #DEE2E3; }
}
/** Feed entry **/
.commit,
.snippet,
.message {
.title {
color:#666;
a { color:#666 !important; }
p { margin-top:0px; }
}
.author { color: #999 }
}
/** JQuery UI **/
.ui-autocomplete { @include round-borders-all(5px); }
.ui-menu-item { cursor: pointer }
.ui-selectmenu{
@include round-borders-all(4px);
margin-right:10px;
font-size:1.5em;
height:auto;
font-weight:bold;
.ui-selectmenu-status {
padding:3px 10px;
}
}
#holder {
background:#FAFAFA;
border: 1px solid #EEE;
cursor: move;
height: 70%;
overflow: hidden;
}
/* Project Dashboard Page */
html, body { height: 100%; }
.news-feed h2{float: left;}
.news-feed .project-updates {margin-bottom: 20px; display: block; width: 100%;}
.news-feed .project-updates .data{ padding: 0}
.news-feed .project-updates a.project-update {padding: 10px; border-bottom: 1px solid #eee; overflow: hidden; display: block;}
.news-feed .project-updates a.project-update:last-child{border-bottom: 0}
.news-feed .project-updates a.project-update img{float: left; margin-right: 10px;}
.news-feed .project-updates a.project-update span.update-title, .dashboard-page .news-feed .project-updates li a span.update-author{display: block;}
.news-feed .project-updates a.project-update span.update-title{margin-bottom: 10px}
.news-feed .project-updates a.project-update span.update-author{color: #999; font-weight: normal; font-style: italic;}
.news-feed .project-updates a.project-update span.update-author strong{font-weight: bold; font-style: normal;}
/* eo Dashboard Page */
/** Update entry **/
.update-data { padding: 0 }
.update-data { width:100%; }
.update-data.ui-box .data { padding:0; }
a.update-item {padding: 10px; border-bottom: 1px solid #eee; overflow: hidden; display: block;}
a.update-item:last-child{border-bottom: 0}
a.update-item img{float: left; margin-right: 10px;}
a.update-item span.update-title, .dashboard-page .news-feed .project-updates li a span.update-author{display: block;}
a.update-item span.update-title{margin-bottom: 10px}
a.update-item span.update-author{color: #999; font-weight: normal; font-style: italic;}
a.update-item span.update-author strong{font-weight: bold; font-style: normal;}
body .team_member_new .span-6, .team_member_edit .span-6{ padding:10px 0; }
body.projects-page input.text.git-url.project_list_url { width:165px; }
body table.no-borders th {
background:none;
border-bottom:1px solid #CCC;
color:#333;
}
body table.no-borders tr,
body table.no-borders td{
border:none;
}
.ajax-tab-loading {
padding:40px;
display:none;
}
#tree-content-holder { float:left; width:100%; }
#tree-readme-holder {
float:left;
width:100%;
.readme {
@include round-borders-all(4px);
padding: 4px 15px;
background:#F7F7F7;
}
}
/* Commit Page */
.entity-info {float: right;}
.entity-button{
background-image: -webkit-gradient(linear, 0 0, 0 26, color-stop(0.192, #fff), to(#f4f4f4));
background-image: -webkit-linear-gradient(#fff 19.2%, #f4f4f4);
background-image: -moz-linear-gradient(#fff 19.2%, #f4f4f4);
background-image: -o-linear-gradient(#fff 19.2%, #f4f4f4);
box-shadow: 0 -1px 0 white inset;
display: block;
border: 1px solid #eee;
border-radius: 5px;
margin-bottom: 2px;
position: relative;
padding: 4px 10px;
font-size: 11px;
padding-right: 20px;
}
.entity-button i{
background: url('images.png') no-repeat -138px -27px;
width: 6px;
height: 9px;
float: right;
position: absolute;
top: 6px;
right: 5px;
}
.box-arrow{float: right; background: #E3E5EA; padding: 10px; border-radius: 5px; margin-top: 2px; text-shadow: none; color: #999; margin: 1.5em 0;}
h4.dash-tabs {
margin: 0;
border-bottom: 1px solid #ccc;
padding: 10px 10px;
font-size: 11px;
padding-left:20px;
font-weight: bold; text-transform: uppercase;
background: #F7F7F7;
margin-bottom:20px;
height:13px;
}
.dash-button {
border-right: 1px solid #ddd;
background:none;
padding: 10px 15px;
float:left;
position:relative;
top:-10px;
left:0px;
height:13px;
&:first-child {
border-left: 1px solid #ddd;
}
&.active {
background: #eaeaea;
}
}
.dashboard-loader {
float:right;
margin-right:30px;
display:none;
}
.merge-tabs {
margin: 0;
border: 1px solid #ccc;
padding: 5px;
font-size: 12px;
background: #F7F7F7;
margin-bottom:20px;
height:26px;
-moz-border-radius: 4px;
-webkit-border-radius: 4px;
border-radius: 4px;
.tab {
font-weight: bold;
border-right: 1px solid #ddd;
background:none;
padding: 10px;
min-width:60px;
float:left;
position:relative;
top:-5px;
left:-5px;
height:16px;
padding-left:34px;
span {
width: 20px;
height: 20px;
display: inline-block;
position: absolute;
left: 8px;
top: 8px;
}
&.active {
background: #eaeaea;
}
}
}
.merge-tabs.repository .tab span{ background: url("images.png") no-repeat -38px -77px; }
.activities-tab span { background: url("images.png") no-repeat -161px -1px; }
.stat-tab span,
.team-tab span,
.snippets-tab span { background: url("images.png") no-repeat -38px -77px; }
.files-tab span { background: url("images.png") no-repeat -112px -23px; }
.merge-notes-tab span { background: url("images.png") no-repeat -161px -1px; }
.merge-commits-tab span { background: url("images.png") no-repeat -86px 1px; }
.merge-diffs-tab span { background: url("images.png") no-repeat -118px 1px; }
.merge-tabs .dashboard-loader { padding:8px; }
.user-mention {
color: #2FA0BB;
font-weight: bold;
}
.author {
color: #999;
}
.dark_scheme_box {
padding:20px 0;
label {
float:left;
box-shadow: 0 0px 5px rgba(0,0,0,.3);
img {
}
}
}
a.project-update.titled {
position: relative;
padding-left: 235px !important;
.title-block {
padding: 10px;
width: 205px;
position: absolute;
left: 0;
top: 0;
}
}
.add_new {
float: right;
background: #A6B807;
color: white;
padding: 4px 10px;
@include round-borders-all(4px);
font-size:11px;
margin: 10px 0;
}

View file

@ -0,0 +1,50 @@
/** Branch/tag selector **/
.project-refs-form {
margin:0;
span {
background:none !important;
position:static !important;
width:auto !important;
height:auto !important;
}
}
.project-refs-select {
width:120px;
}
.project-refs-form .chzn-container {
position: relative;
top: 0;
left: 0;
margin-right: 10px;
.chzn-drop {
margin:7px 0;
border: 1px solid #CCC;
min-width: 300px;
.chzn-results {
max-height:300px;
}
.chzn-search input {
min-width:200px;
}
}
.chzn-single {
background:#ddd;
//border:none;
//box-shadow:none;
div {
background:transparent;
border-left:none;
}
span {
font-weight: normal;
}
}
}

View file

@ -1,802 +0,0 @@
/* HTML5 Boilerplate
* ==|== normalize ==========================================================
*/
article, aside, details, figcaption, figure, footer, header, hgroup, nav, section { display: block; }
audio, canvas, video { display: inline-block; *display: inline; *zoom: 1; }
audio:not([controls]) { display: none; }
[hidden] { display: none; }
html { font-size: 100%; overflow-y: scroll; -webkit-text-size-adjust: 100%; -ms-text-size-adjust: 100%; }
body { margin: 0; font-size: 13px; line-height: 1.231; }
body, button, input, select, textarea {
font-family: "helvetica", "arial", "freesans", "clean", sans-serif;
color: #222; }
::-moz-selection { background: #79c3e0; color: #fff; text-shadow: none; }
::selection { background: #79c3e0; color: #fff; text-shadow: none; }
a { color: #00e; }
a:hover { color: #06e; }
a:focus { outline: thin dotted; }
a:hover, a:active { outline: 0; }
abbr[title] { border-bottom: 1px dotted; }
b, strong { font-weight: bold; }
blockquote { margin: 1em 40px; }
dfn { font-style: italic; }
hr { display: block; height: 1px; border: 0; border-top: 1px solid #ccc; margin: 1em 0; padding: 0; }
ins { background: #ff9; color: #000; text-decoration: none; }
mark { background: #ff0; color: #000; font-style: italic; font-weight: bold; }
pre, code, kbd, samp { font-family: monospace, monospace; _font-family: 'courier new', monospace; font-size: 1em; }
pre { white-space: pre; white-space: pre-wrap; word-wrap: break-word; }
q { quotes: none; }
q:before, q:after { content: ""; content: none; }
small { font-size: 85%; }
sub, sup { font-size: 75%; line-height: 0; position: relative; vertical-align: baseline; }
sup { top: -0.5em; }
sub { bottom: -0.25em; }
ul, ol { margin: 1em 0; padding: 0 0 0 40px; }
dd { margin: 0 0 0 40px; }
nav ul, nav ol { list-style: none; list-style-image: none; margin: 0; padding: 0; }
img { border: 0; -ms-interpolation-mode: bicubic; vertical-align: middle; }
svg:not(:root) { overflow: hidden; }
figure { margin: 0; }
form { margin: 0; }
fieldset { border: 0; margin: 0; padding: 0; }
label { cursor: pointer; }
legend { border: 0; *margin-left: -7px; padding: 0; }
button, input, select, textarea { font-size: 100%; margin: 0; vertical-align: baseline; *vertical-align: middle; }
button, input { line-height: normal; *overflow: visible; }
table button, table input { *overflow: auto; }
button, input[type="button"], input[type="reset"], input[type="submit"] { cursor: pointer; -webkit-appearance: button; }
input[type="checkbox"], input[type="radio"] { box-sizing: border-box; }
input[type="search"] { -webkit-appearance: textfield; -moz-box-sizing: content-box; -webkit-box-sizing: content-box; box-sizing: content-box; }
input[type="search"]::-webkit-search-decoration { -webkit-appearance: none; }
button::-moz-focus-inner, input::-moz-focus-inner { border: 0; padding: 0; }
textarea { overflow: auto; vertical-align: top; resize: vertical; }
input:valid, textarea:valid { }
input:invalid, textarea:invalid { background-color: #f0dddd; }
table { border-collapse: collapse; border-spacing: 0; }
td { vertical-align: top; }
/* ==|== primary styles =====================================================
Author: Ricardo Rauch
========================================================================== */
/* 960gs */
.container_4{width:98%;margin-left:1%;margin-right:1%}.grid_1,.grid_2,.grid_3,.grid_4{display:inline;float:left;position:relative;margin-left:1%;margin-right:1%}.alpha{margin-left:0}.omega{margin-right:0}.container_4 .grid_1{width:23.0%}.container_4 .grid_2{width:48.0%}.container_4 .grid_3{width:73.0%}.container_4 .grid_4{width:98.0%}.container_4 .prefix_1{padding-left:25.0%}.container_4 .prefix_2{padding-left:50.0%}.container_4 .prefix_3{padding-left:75.0%}.container_4 .suffix_1{padding-right:25.0%}.container_4 .suffix_2{padding-right:50.0%}.container_4 .suffix_3{padding-right:75.0%}.container_4 .push_1{left:25.0%}.container_4 .push_2{left:50.0%}.container_4 .push_3{left:75.0%}.container_4 .pull_1{left:-25.0%}.container_4 .pull_2{left:-50.0%}.container_4 .pull_3{left:-75.0%}.clear{clear:both;display:block;overflow:hidden;visibility:hidden;width:0;height:0}.clearfix:after{clear:both;content:' ';display:block;font-size:0;line-height:0;visibility:hidden;width:0;height:0}.clearfix{display:inline-block}* html .clearfix{height:1%}.clearfix{display:block}
/* eo 960gs*/
/* Vars */
$color: "#4BB8D2";
$blue_link: "#2fa0bb";
/* eo Vars */
html{ -webkit-font-smoothing:antialiased; }
body {
font-size: 12px;
background-color: #FFFFFF;
}
a{text-decoration: none; font-weight: bold; color: #444}
a:hover{color: #555}
/* Typography */
h1,h2,h3,h4,h5{font-weight: normal; color: #666}
h2{margin: 1.5em 0}
/* eo Typography */
/* Forms */
input[type="text"]:focus, input[type="password"]:focus { outline: none; }
input.text{border: 1px solid #ccc; border-radius: 4px; display: block; padding: 10px}
.form-row{
padding: 0px 0px 10px 0px;
}
.form-row label{
font-weight:bold;
display: inline-block;
padding: 0px 0px 5px 0px;
}
/* eo Forms */
/* Tables */
table {width:100%; border: 1px solid #DEE2E3; margin-bottom: 20px}
table thead{
-webkit-border-top-left-radius: 5px;
-webkit-border-top-right-radius: 5px;
-moz-border-radius-topleft: 5px;
-moz-border-radius-topright: 5px;
border-top-left-radius: 5px;
border-top-right-radius: 5px;
}
table thead th{
background-image: -webkit-gradient(linear, 0 0, 0 26, color-stop(0.076, #fefefe), to(#F6F7F8));
background-image: -webkit-linear-gradient(#fefefe 7.6%, #F6F7F8);
background-image: -moz-linear-gradient(#fefefe 7.6%, #F6F7F8);
background-image: -o-linear-gradient(#fefefe 7.6%, #F6F7F8);
margin: 0;
font-weight: normal;
font-weight: bold;
text-align: left;
color: #97A0A5;
}
td, th{ padding: .9em 1em; vertical-align: middle; }
table thead .image{width:100px}
.listed_items tr.odd:hover{background-color:#FFFFCF}
/* eo Tables */
/* Buttons */
.grey-button{
border-radius: 5px;
font-size: 12px;
font-weight: bold;
padding: 5px 17px;
border: 1px solid #999;
color: #666;
display: inline-block;
box-shadow: 0 1px 2px rgba(0,0,0,.3);
background-image: -webkit-gradient(linear, 0 0, 0 26, color-stop(0.076, #f7f7f7), to(#d5d5d5));
background-image: -webkit-linear-gradient(#f7f7f7 7.6%, #d5d5d5);
background-image: -moz-linear-gradient(#f7f7f7 7.6%, #d5d5d5);
background-image: -o-linear-gradient(#f7f7f7 7.6%, #d5d5d5);
}
a.button, input.button {
font-weight: bold;
padding: 10px 20px;
text-align: center;
display: inline-block;
border-radius: 5px;
color: #578E91;
font-size: 12px;
text-transform: uppercase;
border: 1px solid #8CE2E6;
background-image: -webkit-gradient(linear, 0 0, 0 34, color-stop(0.794, #dbf5f6), to(#c5eef0));
background-image: -webkit-linear-gradient(#dbf5f6 79.4%, #c5eef0);
background-image: -moz-linear-gradient(#dbf5f6 79.4%, #c5eef0);
background-image: -o-linear-gradient(#dbf5f6 79.4%, #c5eef0);
}
input.button{margin-bottom: 1.5em}
.button:hover {color: rgba(0,0,0,.8)}
.button.green {margin-right: 0; }
.button.yellow{
color: #908054;
border-color: #DDCDA1;
background-image: -webkit-gradient(linear, 0 0, 0 34, color-stop(0.794, #FFEFC3), to(#F3E3B7));
background-image: -webkit-linear-gradient(#FFEFC3 79.4%, #F3E3B7);
background-image: -moz-linear-gradient(#FFEFC3 79.4%, #F3E3B7);
background-image: -o-linear-gradient(#FFEFC3 79.4%, #F3E3B7);
}
.button.blue{
color: #417E97;
border-color: #b2cdec;
background-image: -webkit-gradient(linear, 0 0, 0 34, color-stop(0.794, #dbe8f6), to(#c7daf1));
background-image: -webkit-linear-gradient(#dbe8f6 79.4%, #c7daf1);
background-image: -moz-linear-gradient(#dbe8f6 79.4%, #c7daf1);
background-image: -o-linear-gradient(#dbe8f6 79.4%, #c7daf1);
}
.button-small{ text-shadow: none; padding: 4px 10px; }
.button-green{background: #A6B807; color: white}
/* eo Buttons */
/* UI Box */
//.ui-box{border: 1px solid #DEDFE1; float: left; border-radius: 5px}
.ui-box{float: left;}
.ui-box h3{
background-image: -webkit-gradient(linear, 0 0, 0 26, color-stop(0.076, #fefefe), to(#F6F7F8));
background-image: -webkit-linear-gradient(#fefefe 7.6%, #F6F7F8);
background-image: -moz-linear-gradient(#fefefe 7.6%, #F6F7F8);
background-image: -o-linear-gradient(#fefefe 7.6%, #F6F7F8);
background:none;
margin: 0;
padding: 1em;
font-size: 12px;
font-weight: normal;
font-weight: bold;
font-size: 16px;
border-bottom: 1px solid #DEDFE1;
-webkit-border-top-left-radius: 5px;
-webkit-border-top-right-radius: 5px;
-moz-border-radius-topleft: 5px;
-moz-border-radius-topright: 5px;
border-top-left-radius: 5px;
border-top-right-radius: 5px;
}
.ui-box.ui-box-small h3{
padding: 8px 10px;
font-size: 12px;
}
.ui-box .data{padding: .5em 1em}
.ui-box .buttons{
padding: 1em;
border-top:1px solid $lite_border_color;
}
.ui-box .buttons .button{padding: 8px 9px; font-size: 11px}
.ui-box.hover:hover{box-shadow: 0 0 10px rgba(0,0,0,.1); border: 1px solid #ccc;
-webkit-transition: all 200ms cubic-bezier(0.470, 0.000, 0.745, 0.715);
-moz-transition: all 200ms cubic-bezier(0.470, 0.000, 0.745, 0.715);
-o-transition: all 200ms cubic-bezier(0.470, 0.000, 0.745, 0.715);
transition: all 200ms cubic-bezier(0.470, 0.000, 0.745, 0.715);
}
/* eo UI Box */
/* Login Page */
body.login-page{background-color: #f1f1f1; padding-top: 10%}
.login-box{
width: 304px;
position: relative;
border-radius: 5px;
margin: auto;
padding: 20px;
background: white;
box-shadow: rgba(0, 0, 0, 0.07) 0 1px 0,white 0 2px 0,rgba(0, 0, 0, 0.07) 0 3px 0,white 0 4px 0, rgba(0, 0, 0, 0.07) 0 5px 0;
}
.login-box .login-logo{
margin: 10px 0 30px 0;
display: block;
}
.login-box input.text{background-color: #f1f1f1; font-size: 16px; border-radius: 0; padding: 14px 10px; width: 280px}
.login-box input.text.top{
-webkit-border-top-left-radius: 5px;
-webkit-border-top-right-radius: 5px;
-moz-border-radius-topleft: 5px;
-moz-border-radius-topright: 5px;
border-top-left-radius: 5px;
border-top-right-radius: 5px;
}
.login-box input.text.bottom{
-webkit-border-bottom-right-radius: 5px;
-webkit-border-bottom-left-radius: 5px;
-moz-border-radius-bottomright: 5px;
-moz-border-radius-bottomleft: 5px;
border-bottom-right-radius: 5px;
border-bottom-left-radius: 5px;
border-top: 0;
margin-bottom: 20px;
}
.login-box a.forgot{float: right; padding-top: 6px}
/* Icons */
.directory, .file{
display: inline-block;
margin-right: 10px;
width: 14px;
}
.directory{
background: url('images.png') no-repeat -73px -26px;
height: 11px;
margin-bottom: -1px;
}
.file{
background: url('images.png') no-repeat -114px -24px;
height: 16px;
margin-bottom: -3px;
}
/* eo Icons*/
/* Errors */
#error_explanation{background: #ffe5eb; padding: 20px; margin-bottom: 20px; border-radius: 5px}
#error_explanation h2{margin: 0; margin-bottom: 20px; color: red}
#error_explanation ul li{margin-bottom: 10px}
#error_explanation ul li:last-child{margin-bottom: 0}
.field_with_errors {
input[type="text"],
input[type="password"],
textarea
{
border: 1px solid #D30 !important;
}
}
/* eo Errors */
/* Notices */
#notice{background: #dfffe1; padding: 20px; margin-bottom: 20px; border-radius: 5px; color: green; font-size: 1.3em;}
/* eo Notices */
/* InfoBlock */
#infoblock{
background: #eeeeee;
padding: 20px;
margin-bottom: 20px;
border-radius: 5px;
}
/* eo InfoBlock */
/* Header */
header{
background: #474D57 url('bg-header.png') repeat-x bottom;
z-index: 10000;
height: 44px;
padding: 10px 2% 6px 2%;
}
header a:hover{color: #f1f1f1}
header h1{
width: 65px;
}
header h1.logo{margin: 0; padding: 0}
header h1.logo a{
background: url('images.png') no-repeat -3px -7px;
width: 65px;
height: 26px;
margin: 5px 0;
padding: 0;
display: block;
float: left;
text-indent: -1000em;
}
header nav{border-radius: 4px; box-shadow: 0 1px 2px black; width: 294px; margin: auto;
background-image: -webkit-gradient(linear, 0 0, 0 30, color-stop(0.066, #595d63), to(#31363e));
background-image: -webkit-linear-gradient(#595d63 6.6%, #31363e);
background-image: -moz-linear-gradient(#595d63 6.6%, #31363e);
background-image: -o-linear-gradient(#595d63 6.6%, #31363e);
margin-top: 2px;
height:30px
}
header nav.shorter_nav{
width: 207px;
}
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}
header nav a span{width: 20px; height: 20px; display: inline-block; background: red; position: absolute; left: 8px; top: 6px;}
header nav a:last-child {border: 0; box-shadow: none}
header nav a:hover, header nav a.current{
background-image: -webkit-gradient(linear, 0 0, 0 30, color-stop(0.066, #595d63), to(#2c2f35));
background-image: -webkit-linear-gradient(#595d63 6.6%, #2c2f35);
background-image: -moz-linear-gradient(#595d63 6.6%, #202227);
background-image: -o-linear-gradient(#595d63 6.6%, #202227);
}
header nav a:active{
box-shadow: 0 1px 4px rgba(0,0,0,.8) inset;
}
header nav a.dashboard {
-webkit-border-top-left-radius: 4px;
-webkit-border-bottom-left-radius: 4px;
-moz-border-radius-topleft: 4px;
-moz-border-radius-bottomleft: 4px;
border-top-left-radius: 4px;
border-bottom-left-radius: 4px;
}
header nav a.last_elem{
-webkit-border-top-right-radius: 4px;
-webkit-border-bottom-right-radius: 4px;
-moz-border-radius-topright: 4px;
-moz-border-radius-bottomright: 4px;
border-top-right-radius: 4px;
border-bottom-right-radius: 4px;
}
header .search{ display: inline-block; float: right; margin-right: 90px}
header nav a span{width: 20px; height: 20px; display: inline-block; background: red; position: absolute; left: 8px; top: 6px;}
header nav a.dashboard span{background: url('images.png') no-repeat -161px 0;}
header nav a.admin span{background: url('images.png') no-repeat -184px 0;}
header nav a.project span{background: url('images.png') no-repeat -209px -1px; top: 7px}
header nav a.issues span{background: url('images.png') no-repeat -209px -1px; top: 7px}
header .login-top{float: right; width: 180px;
background-image: -webkit-gradient(linear, 0 0, 0 62, color-stop(0.032, #464c56), to(#363c45));
background-image: -webkit-linear-gradient(#464c56 3.2%, #363c45);
background-image: -moz-linear-gradient(#464c56 3.2%, #363c45);
background-image: -o-linear-gradient(#464c56 3.2%, #363c45);
padding: 0 10px;
height: 44px;
}
header .login-top a{display: block;}
header .login-top a.pic{float: left; margin-right: 10px;
img{ height: 36px; width: 36px; border: 1px solid black}
}
header .login-top a.username{margin-bottom: 5px}
header .login-top a.logout{color: #ccc}
header{margin-bottom: 0; clear: both; position:relative;}
.page-title{background-color: #f1f1f1;display: block; float: left; clear: both; width: 98%; padding: 1% 1%; border-bottom: 1px solid #ccc; box-shadow: 0 -1px 0 white inset; margin-bottom: 1.5em}
.page-title h1{font-size: 20px; width: 400px; margin: 0; padding-top: 8px }
.page-title a.grey-button{float: right;}
.right{float: right;}
/* Account box */
header .account-box{
position: absolute;
right: 0;
top: 8px;
z-index: 10000;
width: 128px;
font-size: 11px;
float: right;
display: block;
cursor: pointer;}
header .account-box img{
border-radius: 4px;
right: 20px;
position: absolute;
width: 33px; height: 33px;
display: block; top:0;}
header .account-box img:after{
content: " ";
display: block;
position: absolute;
top: 0;
right: 0;
left: 0;
bottom: 0;
float: right;
border-radius: 5px;
border: 1px solid rgba(255, 255, 255, .1);
border-bottom: 0;
background: -webkit-gradient(linear, 0% 0%, 0% 100%, from(rgba(255, 255, 255, .15)), to(rgba(0, 0, 0, .25))), -webkit-gradient(linear, left top, right bottom, color-stop(0, rgba(255, 255, 255, 0)), color-stop(0.5, rgba(255, 255, 255, .1)), color-stop(0.501, rgba(255, 255, 255, 0)), color-stop(1, rgba(255, 255, 255, 0)));
background: -moz-linear-gradient(top, rgba(255, 255, 255, .15), rgba(0, 0, 0, .25)), -moz-linear-gradient(left top, rgba(255, 255, 255, 0), rgba(255, 255, 255, .1) 50%, rgba(255, 255, 255, 0) 50%, rgba(255, 255, 255, 0));
background: linear-gradient(top, rgba(255, 255, 255, .15), rgba(0, 0, 0, .25)), linear-gradient(left top, rgba(255, 255, 255, 0), rgba(255, 255, 255, .1) 50%, rgba(255, 255, 255, 0) 50%, rgba(255, 255, 255, 0));
-webkit-background-origin: border-box;
-moz-background-origin: border;
background-origin: border-box;
}
.account-box.hover{height: 138px;}
.account-box:hover > .account-links{display: block;}
header .account-links{
background: #79C3E0; display: none; border-radius: 5px; width: 100px; margin-top: 0; float: right; box-shadow: 0 1px 1px rgba(0,0,0,.2); position:relative;}
header .account-links:before {
content: ".";
width:0;
height:0;
position:absolute;
border:5px solid transparent;
border-color:rgba(255,255,255,0);
border-bottom-color:#fafafa;
text-indent:-9999px;
top:-10px;
line-height:0;
right:10px;
z-index:10;
}
/* Inspired by http://maxvoltar.com/temp/nowplaying/ */
header .account-links{background: white; display: none; z-index: 100000; border-radius: 5px; width: 100px; position: absolute; right: 20px; top: 46px; margin-top: 0; float: right; box-shadow: 0 1px 1px rgba(0,0,0,.2); }
header .account-links a{color: #666; padding: 6px 10px; display: block; text-shadow: none; border-bottom: 1px solid #eee}
header .account-links a:hover{
background: #3aacec;
background: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#39acec), to(#279ada), color-stop(.05, #4cbefe));
background: -moz-linear-gradient(top, #39acec, #4cbefe 5%, #279ada);
background: linear-gradient(top, #39acec, #4cbefe 5%, #279ada);
color: #fff;
text-shadow: #1488c8 0 -1px 0;
}
.account-box.hover .arrow-up{top: 41px; right: 6px; position: absolute}
header .account-links a:first-child{
-webkit-border-top-left-radius: 5px;
-webkit-border-top-right-radius: 5px;
-moz-border-radius-topleft: 5px;
-moz-border-radius-topright: 5px;
border-top-left-radius: 5px;
border-top-right-radius: 5px;
}
header .account-links a:last-child{
-webkit-border-bottom-right-radius: 5px;
-webkit-border-bottom-left-radius: 5px;
-moz-border-radius-bottomright: 5px;
-moz-border-radius-bottomleft: 5px;
border-bottom-right-radius: 5px;
border-bottom-left-radius: 5px;
border-bottom: 0;
}
.big-message{
background-image: -webkit-gradient(linear, 0 48, 0 0, color-stop(0.041, #eccb40), to(#ffee4d));
background-image: -webkit-linear-gradient(90deg, #eccb40 4.1%, #ffee4d);
background-image: -moz-linear-gradient(90deg, #eccb40 4.1%, #ffee4d);
background-image: -o-linear-gradient(90deg, #eccb40 4.1%, #ffee4d);
text-align: center;
font-weight: bold;
padding: 10px 20px;
text-shadow: 0 1px 0 rgba(255,255,255,.3);
color: #333;
color: rgba(0,0,0,.7);
font-size: 14px;
box-shadow: 0 1px 2px rgba(0,0,0,.7);
z-index: 100000;
margin-bottom: 2px;
}
.big-message a{color: #000; text-decoration: underline;}
.big-message.error{
background-color: #722523;
background-image: -webkit-gradient(linear, 0 49, 0 0, color-stop(0.04, #722523), to(#ad4846));
background-image: -webkit-linear-gradient(90deg, #9b403f 4%, #c16765);
background-image: -moz-linear-gradient(90deg, #722523 4%, #ad4846);
background-image: -o-linear-gradient(90deg, #722523 4%, #ad4846);
color: #2E0D0C;
}
.big-message.success{
background-color: #7a9339;
background-image: -webkit-gradient(linear, 0 48, 0 0, color-stop(0.062, #7a9339), to(#93ae46));
background-image: -webkit-linear-gradient(90deg, #7a9339 6.2%, #93ae46);
background-image: -moz-linear-gradient(90deg, #7a9339 6.2%, #93ae46);
background-image: -o-linear-gradient(90deg, #7a9339 6.2%, #93ae46)
}
.big-message.success{
background-color: #7a9339;
background-image: -webkit-gradient(linear, 0 48, 0 0, color-stop(0.062, #7a9339), to(#93ae46));
background-image: -webkit-linear-gradient(90deg, #7a9339 6.2%, #93ae46);
background-image: -moz-linear-gradient(90deg, #7a9339 6.2%, #93ae46);
background-image: -o-linear-gradient(90deg, #7a9339 6.2%, #93ae46)
}
.big-message.notice{
background-image: -webkit-gradient(linear, 0 49, 0 0, color-stop(0.061, #447790), color-stop(0.897, #5da2bf));
background-image: -webkit-linear-gradient(90deg, #447790 6.1%, #5da2bf 89.7%);
background-image: -moz-linear-gradient(90deg, #447790 6.1%, #5da2bf 89.7%);
background-image: -o-linear-gradient(90deg, #447790 6.1%, #5da2bf 89.7%)
}
/* eo Account Box */
input.search-input{
float: left;
text-shadow: none;
width: 116px;
background-image: url('icon-search.png') ;
background-repeat: no-repeat;
background-position: 10px;
border-radius: 4px;
border: 1px solid #AAA;
background-color: #FFF;
padding: 5px;
padding-left: 26px;
margin-top: 2px;
margin-right: 10px;
}
/*input.search-input:focus{ background-color: white; width: 216px;}*/
input.search-input::-webkit-input-placeholder {color: #666}
/* eo Header */
h2.icon{position: relative; padding-left: 40px; float: left; }
/*h2 a{font-weight: normal;}*/
h2.icon span{background: #E3E5EA url('images.png'); height: 32px; width: 32px; left: 0; top: -5px; border-radius: 4px; display: inline-block; position: absolute}
/* Dashboard Page */
html, body { height: 100%; }
.grey-button.right{margin-top: 20px}
/* Project Page */
/* eo New Project Page */
/* eo Project Page */
/* Projects Page */
body.projects-page h2.icon span{background-position: -31px -70px;}
body.projects-page .project-box.ui-box .data .repository {margin-bottom: 20px}
body.projects-page .project-box.ui-box .data .title span{ font-weight: bold;}
body.projects-page .project-box{width: 100%; margin-bottom: 3em}
body.projects-page .browse-code{margin-right: 10px}
/* eo Projects Page */
/* ==|== non-semantic helper classes ======================================== */
.ir { display: block; border: 0; text-indent: -999em; overflow: hidden; background-color: transparent; background-repeat: no-repeat; text-align: left; direction: ltr; }
.ir br { display: none; }
.hidden { display: none !important; visibility: hidden; }
.visuallyhidden { border: 0; clip: rect(0 0 0 0); height: 1px; margin: -1px; overflow: hidden; padding: 0; position: absolute; width: 1px; }
.visuallyhidden.focusable:active, .visuallyhidden.focusable:focus { clip: auto; height: auto; margin: 0; overflow: visible; position: static; width: auto; }
.invisible { visibility: hidden; }
.clearfix:before, .clearfix:after { content: ""; display: table; }
.clearfix:after { clear: both; }
.clearfix { zoom: 1; }
/* ==|== media queries ====================================================== */
@media only screen and (min-width: 480px) {
}
@media only screen and (min-width: 768px) {
}
/* ==|== print styles ======================================================= */
@media print {
* { background: transparent !important; color: black !important; text-shadow: none !important; filter:none !important; -ms-filter: none !important; }
a, a:visited { text-decoration: underline; }
a[href]:after { content: " (" attr(href) ")"; }
abbr[title]:after { content: " (" attr(title) ")"; }
.ir a:after, a[href^="javascript:"]:after, a[href^="#"]:after { content: ""; }
pre, blockquote { border: 1px solid #999; page-break-inside: avoid; }
thead { display: table-header-group; }
tr, img { page-break-inside: avoid; }
img { max-width: 100% !important; }
@page { margin: 0.5cm; }
p, h2, h3 { orphans: 3; widows: 3; }
h2, h3 { page-break-after: avoid; }
}
body, button, input, select, textarea {
font-family: "helvetica", "arial", "freesans", "clean", sans-serif;
}
/** FORM INPUTS **/
.new_merge_request,
.edit_merge_request,
.user_new,
.new_key,
.new_issue,
.new_note,
.edit_user,
.edit_issue,
.new_project,
.new_snippet,
.edit_snippet,
.edit_project {
input[type='text'],
input[type='email'],
input[type='password'],
textarea {
width:400px;
padding:8px;
font-size:14px;
@include round-borders-all(4px);
}
}
.text_field {
width:400px;
padding:8px;
font-size:14px;
@include round-borders-all(4px);
}
.input_button {
padding:8px;
font-size:14px;
cursor:pointer;
background-color: #F5F5F5;
border-color: #EEEEEE #DEDEDE #DEDEDE #EEEEEE;
border-right: 1px solid #DEDEDE;
border-style: solid;
border-width: 1px;
}
/** FLASH **/
#flash_container {
height:45px;
position:fixed;
z-index:10001;
top:0px;
width:100%;
margin-bottom:15px;
overflow:hidden;
background:white;
cursor:pointer;
border-bottom:1px solid #777;
h4 {
color:#444;
font-size:22px;
padding-top:5px;
margin:2px;
}
}
.errors_holder {
background:#D30;
color:#fff;
@include round-borders-all(4px);
border:1px solid #a30;
padding:5px;
list-style:none;
font-weight: bold;
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
li {
padding:10px;
}
}
.notice_holder {
background:#DDF4FB;
color:#444;
border:1px solid #C6EDF9;
@include round-borders-all(4px);
padding:5px;
list-style:none;
font-weight: bold;
text-shadow: 0 -1px 0 rgba(255, 255, 255, 0.25);
li {
padding:10px;
}
}
.alert_holder {
background:#FDF5D9;
color:#444;
border:1px solid #FCEEC1;
@include round-borders-all(4px);
padding:5px;
list-style:none;
font-weight: bold;
text-shadow: 0 -1px 0 rgba(255, 255, 255, 0.25);
li {
padding:10px;
}
}
.help_content {
margin:20px;
margin-top:71px;
h2 {
margin:0;
padding:0;
}
.menu {
float:left;
width:20%;
.active {
color: $active_bd_color;
}
}
.content {
float:right;
width:78%;
}
.bash {
@include round-borders-all(4px);
background:#eee;
padding:5px;
//overflow-x:scroll;
pre{
padding:0;
line-height:2.0;
margin:0;
font-family: 'Courier New', 'andale mono','lucida console',monospace;
color: #333;
text-align:left;
}
}
}

View file

@ -1,42 +0,0 @@
.tags-list {
padding : 0px 10px 10px 10px;
}
.tags-list a {
display: inline-block;
padding: 8px 11px 8px 11px;
margin: 1px 5px 0px 0px;
border-radius: 4px;
border: 1px solid #72bbdf;
background-color: #72bbdf;
color: #0f326d;
font-weight: bold;
font-size: 14px;
}
.small-tags a{
font-size: 9px;
display: inline-block;
padding: 2px 3px 1px 3px;
margin: 0px 3px 0px 0px;
border-radius: 2px;
background-color: #72bbdf;
color: #FFF;
text-shadow: none;
font-weight: bold;
}
.medium-tags a{
font-size: 12px;
display: inline-block;
padding: 3px 4px 2px 4px;
margin: 0px 7px 8px 0px;
border-radius: 3px;
background-color: #72bbdf;
color: #FFF;
text-shadow: none;
font-weight: bold;
}

View file

@ -1,146 +0,0 @@
.main_links {
width:130px;
float:left;
a {
float:left;
}
}
.dashboard_links {
padding:7px;
float:left;
a {
margin: 0 14px;
float: left;
font-size: 14px;
&.active {
color:$active_link_color;
}
&:hover {
color:$active_link_color;
}
}
}
.top-tabs {
margin: 0;
padding: 5px;
font-size: 14px;
padding-bottom:10px;
margin-bottom:20px;
height:26px;
border-bottom:1px solid #ccc;
.tab {
font-weight: bold;
background:none;
padding: 10px;
float:left;
padding-left:0px;
padding-right:40px;
&.active {
color: $active_link_color;
}
}
}
body header {
position:absolute;
width:100%;
padding:0;
margin:0;
top:0;
left:0;
background: #999; /* for non-css3 browsers */
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFFFFF', endColorstr='#EAEAEA'); /* for IE */
background: -webkit-gradient(linear, left top, left bottom, from(#FFFFFF), to(#EAEAEA)); /* for webkit browsers */
background: -moz-linear-gradient(top, #FFFFFF, #EAEAEA); /* for firefox 3.6+ */
background: -o-linear-gradient(top, #FFFFFF, #EAEAEA); /* for firefox 3.6+ */
border-bottom: 1px solid #ccc;
height:50px;
.wrapper {
margin:auto;
width:$app_width;
position:relative;
.top_panel_content {
padding:10px $app_padding;
}
}
.project_name {
float:left;
width:235px;
margin-right:30px;
font-size:16px;
font-weight:bold;
padding:8px;
color:#333;
}
.git_url_wrapper {
padding:0px;
margin:0px;
float:left;
.git-url {
padding:0px;
margin:0px;
font-size: 12px;
margin-right:10px;
border-radius: 4px;
-moz-border-radius: 4px;
color: #666;
border: 1px solid #AAA;
padding: 0 10px 0 30px;
background: transparent url('images.png') no-repeat 8px -42px;
width: 160px;
height:26px;
}
}
}
.top_panel_holder .chzn-container {
position:relative;
.chzn-drop {
margin:7px 0;
border: 1px solid #CCC;
min-width: 300px;
.chzn-results {
max-height:300px;
}
}
.chzn-single {
background:transparent;
-moz-border-radius: 4px;
border-radius: 4px;
div {
background:transparent;
border-left:none;
}
span {
font-weight: normal;
}
}
}
.rss-icon {
margin:0 15px;
padding:3px;
border:1px solid #AAA;
border-radius:3px;
float:left;
}

View file

@ -1,26 +1,29 @@
#tree-breadcrumbs { #tree-holder {
div { #tree-content-holder {
margin:0;
margin-bottom:20px;
float:left; float:left;
font-size:14px; width:100%;
} }
} #tree-readme-holder {
.tree_progress {
float:left; float:left;
width:16px; width:100%;
height:16px; .readme {
margin:2px 6px; @include round-borders-all(4px);
padding:4px 15px;
background: #F7F7F7;
}
}
.tree_progress {
display:none;
margin:20px;
&.loading { &.loading {
background-position: 0px 0px; display:block;
background: url("ajax-loader-facebook.gif") no-repeat; }
} }
}
/** FILE CONTENT VIEW **/ /** FILE CONTENT VIEW **/
.view_file_content{ .view_file_content{
.old_line, .new_line { .old_line, .new_line {
background:#ECECEC; background:#ECECEC;
color:#777; color:#777;
@ -32,37 +35,26 @@
.old_line{ .old_line{
display:none; display:none;
} }
} }
.view_file .view_file_header, .view_file .view_file_header,
.diff_file .diff_file_header { .diff_file .diff_file_header {
background-image: -webkit-gradient(linear, 0 0, 0 26, color-stop(0.076, #fefefe), to(#F6F7F8)); background:#f5f5f5;
background-image: -webkit-linear-gradient(#fefefe 7.6%, #F6F7F8);
background-image: -moz-linear-gradient(#fefefe 7.6%, #F6F7F8);
background-image: -o-linear-gradient(#fefefe 7.6%, #F6F7F8);
margin: 0; margin: 0;
font-weight: normal; font-weight: normal;
font-weight: bold; font-weight: bold;
text-align: left; text-align: left;
color: #666; color: #666;
border-bottom: 1px solid #DEE2E3; border-bottom: 1px solid #ccc;
padding: 7px 10px; padding: 7px 10px;
.mode_text, .mode_text,
.file_icon { .file_icon {
margin-right:15px;
padding-right:15px;
border-right:1px solid $lite_border_color;
float:left;
color:#aaa; color:#aaa;
} }
.file_icon {
padding-left:15px;
} }
}
.view_file { .view_file {
border:1px solid #CCC; border:1px solid #CCC;
margin-bottom:1em; margin-bottom:1em;
@ -79,43 +71,108 @@
max-width:300px; max-width:300px;
} }
} }
} }
td.code { td.code {
width: 100%; width: 100%;
.highlight { .highlight {
margin-left: 55px; margin-left: 55px;
overflow:auto; overflow:auto;
overflow-y:hidden; overflow-y:hidden;
border-left: 1px solid #DEE2E3;
background: white;
} }
} }
.highlight pre { .highlight pre {
white-space: pre; white-space: pre;
word-wrap:normal; word-wrap:normal;
} }
table.highlighttable { table.highlighttable {
border: none; border: none;
background: #F7F7F7; }
} body.project-page table.highlighttable td { border: none }
body.project-page table.highlighttable td { border: none } table.highlighttable tr:hover { background:none;}
table.highlighttable tr:hover { background:none;}
table.highlighttable pre{ table.highlighttable pre{
line-height:16px !important; line-height:16px !important;
font-size:12px !important; font-size:12px !important;
} }
table.highlighttable .linenodiv pre { table.highlighttable .linenodiv pre {
text-align: right; text-align: right;
padding-right: 4px; padding-right: 4px;
color:#888; color:#888;
} }
.tree-item { .tree-item {
&:hover { &:hover {
background: #FFFFCF; background: $hover;
cursor:pointer;
}
.tree-item-file-name {
font-weight:bold;
a {
color:$style_color;
}
img {
position: relative;
top: 2px;
}
}
}
ul.breadcrumb {
background:white;
border:none;
a {
color:#666;
font-weight:bold;
font-size:14px;
}
}
#tree-slider {
@include shade;
td {
padding:7px;
border-color:#f1f1f1;
}
th {
background:#f5f5f5;
}
}
.tree-commit-link {
color:#333;
}
#tree-content-holder .view_file{
@include shade;
}
#tree-readme-holder .readme {
@include shade;
margin-bottom:20px;
}
a.tree-commit-link {
color: #666;
&:hover {
text-decoration: underline;
}
}
.arrow {
background: url("images.png") no-repeat -85px -77px;
width: 19px;
height: 16px;
float: left;
position: relative;
left: -10px;
} }
} }

View file

@ -0,0 +1,309 @@
/**
* This file represent some UI that can be changed
* during web app restyle or theme select.
*
* Next items should be placed there
* - link colors
* - header styles
* - main menu styles
*
*/
.ui_basic {
/*
* Common styles
*
*/
a {
color: $link_color;
&:hover {
text-decoration:none;
color: $style_color;
}
}
/*
* Application Header
*
*/
header {
width:100%;
padding:0;
margin:0;
top:1px;
left:0;
background: #F1F1F1; /* for non-css3 browsers */
border-bottom: 1px solid #ccc;
box-shadow: 0 -1px 0 white inset;
-moz-box-shadow: 0 -1px 0 white inset;
-webkit-box-shadow: 0 -1px 0 white inset;
z-index:10;
height:60px;
.app_logo {
width:230px;
float:left;
a {
float:left;
h1 {
float:left;
margin-left:5px;
font-size:20px;
line-height:34px;
font-weight:bold;
color:#aaa;
text-shadow: 0 1px 1px #FFF;
}
&.home {
img {
float: left;
position: relative;
top: -9px;
width:46px;
}
}
&.admin_link {
width:16px;
height:16px;
padding: 5px;
border: 1px solid #ccc;
border-radius: 4px;
margin: 0px;
background: #eee;
margin-left:20px;
&:hover {
background:#f7f7f7;
}
img {
width:16px;
}
}
}
}
.wrapper {
margin:auto;
min-width:$min_app_width;
max-width:$max_app_width;
position:relative;
padding:15px 0;
.top_panel_content {
margin:0 $app_padding;
}
}
.project_name {
float:left;
width:400px;
margin:0;
margin-right:30px;
font-size:20px;
line-height:34px;
font-weight:bold;
color:$style_color;
text-shadow: 0 1px 1px #FFF;
}
.git_url_wrapper {
padding:0px;
margin:0px;
float:left;
.git-url {
padding:0px;
margin:0px;
font-size: 12px;
margin-right:10px;
border-radius: 4px;
-moz-border-radius: 4px;
color: #666;
border: 1px solid #AAA;
padding: 0 10px 0 30px;
background: transparent url('images.png') no-repeat 8px -42px;
width: 260px;
height:26px;
}
}
/* Account box */
.account-box {
position: absolute;
right: 0;
top: 13px;
z-index: 10000;
width: 128px;
font-size: 11px;
float: right;
display: block;
cursor: pointer;
img {
border-radius: 4px;
right: 20px;
position: absolute;
width: 33px;
height: 33px;
display: block;
top: 0;
&:after {
content: " ";
display: block;
position: absolute;
top: 0;
right: 0;
left: 0;
bottom: 0;
float: right;
border-radius: 5px;
border: 1px solid rgba(255, 255, 255, 0.1);
border-bottom: 0;
background: -webkit-gradient(linear, 0% 0%, 0% 100%, from(rgba(255, 255, 255, 0.15)), to(rgba(0, 0, 0, 0.25))), -webkit-gradient(linear, left top, right bottom, color-stop(0, rgba(255, 255, 255, 0)), color-stop(0.5, rgba(255, 255, 255, 0.1)), color-stop(0.501, rgba(255, 255, 255, 0)), color-stop(1, rgba(255, 255, 255, 0)));
background: -moz-linear-gradient(top, rgba(255, 255, 255, 0.15), rgba(0, 0, 0, 0.25)), -moz-linear-gradient(left top, rgba(255, 255, 255, 0), rgba(255, 255, 255, 0.1) 50%, rgba(255, 255, 255, 0) 50%, rgba(255, 255, 255, 0));
background: linear-gradient(top, rgba(255, 255, 255, 0.15), rgba(0, 0, 0, 0.25)), linear-gradient(left top, rgba(255, 255, 255, 0), rgba(255, 255, 255, 0.1) 50%, rgba(255, 255, 255, 0) 50%, rgba(255, 255, 255, 0));
-webkit-background-origin: border-box;
-moz-background-origin: border;
background-origin: border-box; } } }
.account-box {
&.hover {
height: 138px; }
&:hover > .account-links {
display: block; } }
.account-links {
background: #79C3E0;
display: none;
border-radius: 5px;
width: 100px;
margin-top: 0;
float: right;
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2);
position: relative;
&:before {
content: ".";
width: 0;
height: 0;
position: absolute;
border: 5px solid transparent;
border-color: rgba(255, 255, 255, 0);
border-bottom-color: #333;
text-indent: -9999px;
top: -10px;
line-height: 0;
right: 10px;
z-index: 10; }
background: #333;
display: none;
z-index: 100000;
border-radius: 5px;
width: 100px;
position: absolute;
right: 20px;
top: 46px;
margin-top: 0;
float: right;
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2);
a {
color: #EEE;
padding: 6px 10px;
display: block;
text-shadow: none;
border-bottom: 1px solid #555;
&:hover {
background: #444; } } }
.account-box.hover .arrow-up {
top: 41px;
right: 6px;
position: absolute; }
.account-links a {
&:first-child {
-webkit-border-top-left-radius: 5px;
-webkit-border-top-right-radius: 5px;
-moz-border-radius-topleft: 5px;
-moz-border-radius-topright: 5px;
border-top-left-radius: 5px;
border-top-right-radius: 5px; }
&:last-child {
-webkit-border-bottom-right-radius: 5px;
-webkit-border-bottom-left-radius: 5px;
-moz-border-radius-bottomright: 5px;
-moz-border-radius-bottomleft: 5px;
border-bottom-right-radius: 5px;
border-bottom-left-radius: 5px;
border-bottom: 0; } }
}
/*
* End of Application Header
*
*/
/*
* Main Menu of Application
*
*/
nav.main_menu {
overflow:hidden;
border-radius: 4px;
margin: auto;
margin:30px $app_padding;
background:#eee;
border:1px solid #ccc;
height:38px;
background-image: -webkit-gradient(linear, 0 0, 0 30, color-stop(0.066, #eee), to(#dfdfdf));
background-image: -webkit-linear-gradient(#eee 6.6%, #dfdfdf);
background-image: -moz-linear-gradient(#eee 6.6%, #dfdfdf);
background-image: -o-linear-gradient(#eee 6.6%, #dfdfdf);
@include shade;
.count {
color:#aaa;
margin-left:3px;
}
.label {
background:$hover;
text-shadow:none;
color:$style_color;
}
a {
font-weight:bold;
&:first-child{
-webkit-border-top-left-radius: 4px;
-webkit-border-bottom-left-radius: 4px;
-moz-border-radius-topleft: 4px;
-moz-border-radius-bottomleft: 4px;
border-top-left-radius: 4px;
border-bottom-left-radius: 4px;
}
padding: 10px 25px;
display: inline-block;
color: $style_color;
border-right: 1px solid #d5d5d5;
position: relative;
box-shadow: 1px 0 0 rgba(255, 255, 255, 0.1);
margin: 0;
float:left;
text-shadow:0 1px 1px white;
&.home {
background: url(home_icon.PNG) no-repeat center center;
text-indent:-9999px;
min-width:40px;
img {
position:relative;
top:4px;
}
}
&.current {
background-color:#DDD;
}
}
}
/*
* End of Main Menu
*
*/
}

View file

@ -0,0 +1,337 @@
/**
* This file represent some UI that can be changed
* during web app restyle or theme select.
*
* Next items should be placed there
* - link colors
* - header styles
* - main menu styles
*
*/
.ui_mars {
/*
* Common styles
*
*/
a {
color: $link_color;
&:hover {
text-decoration:none;
color: $style_color;
}
}
/*
* Application Header
*
*/
header {
width:100%;
padding:0;
margin:0;
top:1px;
left:0;
background: #474D57 url('bg-header.png') repeat-x bottom;
z-index:10;
height:60px;
.search-input {
background-image:url("icon-search.png");
float: right;
text-shadow: none;
width: 116px;
background-image: url("icon-search.png");
background-repeat: no-repeat;
background-position: 10px;
border-radius: 100px;
border: 1px solid rgba(0, 0, 0, 0.7);
box-shadow: 0 1px 0 rgba(255, 255, 255, 0.2), 0 2px 2px rgba(0, 0, 0, 0.4) inset;
background-color: #D2D5DA;
background-color: rgba(255, 255, 255, 0.5);
padding: 5px;
padding-left: 26px;
margin-right: 50px;
&:focus {
background-color: white;
width: 166px;
}
}
.search-input::-webkit-input-placeholder {
color: #666;
}
.app_logo {
width:230px;
float:left;
position:relative;
top:-4px;
a {
float:left;
h1 {
background: url('images.png') no-repeat -3px -7px;
width: 65px;
height: 26px;
margin: 5px 0;
padding: 0;
display: block;
float: left;
text-indent: -1000em;
}
&.home {
img {
display:none
}
}
&.admin_link {
width:16px;
height:16px;
padding: 5px;
border: 1px solid #888;
border-radius: 4px;
margin: 0px;
background:#474D57 ;
margin-left:20px;
margin-top:4px;
&:hover {
background:#f7f7f7;
}
img {
width:16px;
}
}
}
}
.wrapper {
margin:auto;
min-width:$min_app_width;
max-width:$max_app_width;
position:relative;
padding:15px 0;
.top_panel_content {
margin:0 $app_padding;
}
}
.project_name {
float:left;
width:400px;
margin:0;
margin-right:30px;
font-size:20px;
line-height:34px;
font-weight:bold;
color:#fff;
text-shadow: 0 1px 1px #111;
}
.git_url_wrapper {
padding:0px;
margin:0px;
float:left;
.git-url {
padding:0px;
margin:0px;
font-size: 12px;
margin-right:10px;
border-radius: 4px;
-moz-border-radius: 4px;
color: #666;
border: 1px solid #AAA;
padding: 0 10px 0 30px;
background: transparent url('images.png') no-repeat 8px -42px;
width: 260px;
height:26px;
}
}
/* Account box */
.account-box {
position: absolute;
right: 0;
top: 13px;
z-index: 10000;
width: 128px;
font-size: 11px;
float: right;
display: block;
cursor: pointer;
img {
border-radius: 4px;
right: 20px;
position: absolute;
width: 33px;
height: 33px;
display: block;
top: 0;
&:after {
content: " ";
display: block;
position: absolute;
top: 0;
right: 0;
left: 0;
bottom: 0;
float: right;
border-radius: 5px;
border: 1px solid rgba(255, 255, 255, 0.1);
border-bottom: 0;
background: -webkit-gradient(linear, 0% 0%, 0% 100%, from(rgba(255, 255, 255, 0.15)), to(rgba(0, 0, 0, 0.25))), -webkit-gradient(linear, left top, right bottom, color-stop(0, rgba(255, 255, 255, 0)), color-stop(0.5, rgba(255, 255, 255, 0.1)), color-stop(0.501, rgba(255, 255, 255, 0)), color-stop(1, rgba(255, 255, 255, 0)));
background: -moz-linear-gradient(top, rgba(255, 255, 255, 0.15), rgba(0, 0, 0, 0.25)), -moz-linear-gradient(left top, rgba(255, 255, 255, 0), rgba(255, 255, 255, 0.1) 50%, rgba(255, 255, 255, 0) 50%, rgba(255, 255, 255, 0));
background: linear-gradient(top, rgba(255, 255, 255, 0.15), rgba(0, 0, 0, 0.25)), linear-gradient(left top, rgba(255, 255, 255, 0), rgba(255, 255, 255, 0.1) 50%, rgba(255, 255, 255, 0) 50%, rgba(255, 255, 255, 0));
-webkit-background-origin: border-box;
-moz-background-origin: border;
background-origin: border-box; } } }
.account-box {
&.hover {
height: 138px; }
&:hover > .account-links {
display: block; } }
.account-links {
background: #79C3E0;
display: none;
border-radius: 5px;
width: 100px;
margin-top: 0;
float: right;
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2);
position: relative;
&:before {
content: ".";
width: 0;
height: 0;
position: absolute;
border: 5px solid transparent;
border-color: rgba(255, 255, 255, 0);
border-bottom-color: #333;
text-indent: -9999px;
top: -10px;
line-height: 0;
right: 10px;
z-index: 10; }
background: #333;
display: none;
z-index: 100000;
border-radius: 5px;
width: 100px;
position: absolute;
right: 20px;
top: 46px;
margin-top: 0;
float: right;
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2);
a {
color: #EEE;
padding: 6px 10px;
display: block;
text-shadow: none;
border-bottom: 1px solid #555;
&:hover {
background: #444; } } }
.account-box.hover .arrow-up {
top: 41px;
right: 6px;
position: absolute; }
.account-links a {
&:first-child {
-webkit-border-top-left-radius: 5px;
-webkit-border-top-right-radius: 5px;
-moz-border-radius-topleft: 5px;
-moz-border-radius-topright: 5px;
border-top-left-radius: 5px;
border-top-right-radius: 5px; }
&:last-child {
-webkit-border-bottom-right-radius: 5px;
-webkit-border-bottom-left-radius: 5px;
-moz-border-radius-bottomright: 5px;
-moz-border-radius-bottomleft: 5px;
border-bottom-right-radius: 5px;
border-bottom-left-radius: 5px;
border-bottom: 0; } }
}
/*
* End of Application Header
*
*/
/*
* Main Menu of Application
*
*/
nav.main_menu {
overflow:hidden;
border-radius: 4px;
margin: auto;
margin:30px $app_padding;
background:#eee;
border:1px solid #ccc;
height:38px;
background-image: -webkit-gradient(linear, 0 0, 0 30, color-stop(0.066, #eee), to(#dfdfdf));
background-image: -webkit-linear-gradient(#eee 6.6%, #dfdfdf);
background-image: -moz-linear-gradient(#eee 6.6%, #dfdfdf);
background-image: -o-linear-gradient(#eee 6.6%, #dfdfdf);
@include shade;
.count {
color:#aaa;
margin-left:3px;
}
.label {
background:$hover;
text-shadow:none;
color:$style_color;
}
a {
font-weight:bold;
&:first-child{
-webkit-border-top-left-radius: 4px;
-webkit-border-bottom-left-radius: 4px;
-moz-border-radius-topleft: 4px;
-moz-border-radius-bottomleft: 4px;
border-top-left-radius: 4px;
border-bottom-left-radius: 4px;
}
padding: 10px 25px;
display: inline-block;
color: $style_color;
border-right: 1px solid #d5d5d5;
position: relative;
box-shadow: 1px 0 0 rgba(255, 255, 255, 0.1);
margin: 0;
float:left;
text-shadow:0 1px 1px white;
&.home {
background: url(home_icon.PNG) no-repeat center center;
text-indent:-9999px;
min-width:40px;
img {
position:relative;
top:4px;
}
}
&.current {
background-color:#DDD;
}
}
}
/*
* End of Main Menu
*
*/
}

View file

@ -52,6 +52,12 @@ class Admin::ProjectsController < ApplicationController
def update def update
@admin_project = Project.find_by_code(params[:id]) @admin_project = Project.find_by_code(params[:id])
owner_id = params[:project].delete(:owner_id)
if owner_id
@admin_project.owner = User.find(owner_id)
end
if @admin_project.update_attributes(params[:project]) if @admin_project.update_attributes(params[:project])
redirect_to [:admin, @admin_project], notice: 'Project was successfully updated.' redirect_to [:admin, @admin_project], notice: 'Project was successfully updated.'
else else

View file

@ -3,39 +3,15 @@ class Admin::TeamMembersController < ApplicationController
before_filter :authenticate_user! before_filter :authenticate_user!
before_filter :authenticate_admin! before_filter :authenticate_admin!
def index
@admin_team_members = UsersProject.page(params[:page]).per(100).order("project_id DESC")
end
def show
@admin_team_member = UsersProject.find(params[:id])
end
def new
@admin_team_member = UsersProject.new(params[:team_member])
end
def edit def edit
@admin_team_member = UsersProject.find(params[:id]) @admin_team_member = UsersProject.find(params[:id])
end end
def create
@admin_team_member = UsersProject.new(params[:team_member])
@admin_team_member.project_id = params[:team_member][:project_id]
if @admin_team_member.save
redirect_to admin_team_member_path(@admin_team_member), notice: 'UsersProject was successfully created.'
else
render action: "new"
end
end
def update def update
@admin_team_member = UsersProject.find(params[:id]) @admin_team_member = UsersProject.find(params[:id])
@admin_team_member.project_id = params[:team_member][:project_id]
if @admin_team_member.update_attributes(params[:team_member]) if @admin_team_member.update_attributes(params[:team_member])
redirect_to admin_team_member_path(@admin_team_member), notice: 'UsersProject was successfully updated.' redirect_to [:admin, @admin_team_member.project], notice: 'Project Access was successfully updated.'
else else
render action: "edit" render action: "edit"
end end
@ -45,6 +21,6 @@ class Admin::TeamMembersController < ApplicationController
@admin_team_member = UsersProject.find(params[:id]) @admin_team_member = UsersProject.find(params[:id])
@admin_team_member.destroy @admin_team_member.destroy
redirect_to admin_team_members_url redirect_to :back
end end
end end

View file

@ -9,8 +9,28 @@ class Admin::UsersController < ApplicationController
def show def show
@admin_user = User.find(params[:id]) @admin_user = User.find(params[:id])
@projects = if @admin_user.projects.empty?
Project
else
Project.without_user(@admin_user)
end.all
end end
def team_update
@admin_user = User.find(params[:id])
UsersProject.user_bulk_import(
@admin_user,
params[:project_ids],
params[:project_access],
params[:repo_access]
)
redirect_to [:admin, @admin_user], notice: 'Teams were successfully updated.'
end
def new def new
@admin_user = User.new(:projects_limit => 10) @admin_user = User.new(:projects_limit => 10)
end end

View file

@ -5,7 +5,11 @@ class ApplicationController < ActionController::Base
helper_method :abilities, :can? helper_method :abilities, :can?
rescue_from Gitlabhq::Gitolite::AccessDenied do |exception| rescue_from Gitlabhq::Gitolite::AccessDenied do |exception|
render :file => File.join(Rails.root, "public", "githost_error"), :layout => false render "errors/gitolite", :layout => "error"
end
rescue_from ActiveRecord::RecordNotFound do |exception|
render "errors/not_found", :layout => "error", :status => 404
end end
layout :layout_by_resource layout :layout_by_resource
@ -33,7 +37,8 @@ class ApplicationController < ActionController::Base
end end
def project def project
@project ||= Project.find_by_code(params[:project_id]) @project ||= current_user.projects.find_by_code(params[:project_id])
@project || render_404
end end
def add_project_abilities def add_project_abilities
@ -45,11 +50,23 @@ class ApplicationController < ActionController::Base
end end
def authorize_project!(action) def authorize_project!(action)
return render_404 unless can?(current_user, action, project) return access_denied! unless can?(current_user, action, project)
end
def authorize_code_access!
return access_denied! unless can?(current_user, :download_code, project)
end end
def access_denied! def access_denied!
render_404 render "errors/access_denied", :layout => "error", :status => 404
end
def not_found!
render "errors/not_found", :layout => "error", :status => 404
end
def git_not_found!
render "errors/git_not_found", :layout => "error", :status => 404
end end
def method_missing(method_sym, *arguments, &block) def method_missing(method_sym, *arguments, &block)
@ -78,21 +95,13 @@ class ApplicationController < ActionController::Base
redirect_to @project unless @project.repo_exists? && @project.has_commits? redirect_to @project unless @project.repo_exists? && @project.has_commits?
end end
def respond_with_notes
if params[:last_id] && params[:first_id]
@notes = @notes.where("id >= ?", params[:first_id])
elsif params[:last_id]
@notes = @notes.where("id > ?", params[:last_id])
elsif params[:first_id]
@notes = @notes.where("id < ?", params[:first_id])
else
nil
end
end
def no_cache_headers def no_cache_headers
response.headers["Cache-Control"] = "no-cache, no-store, max-age=0, must-revalidate" response.headers["Cache-Control"] = "no-cache, no-store, max-age=0, must-revalidate"
response.headers["Pragma"] = "no-cache" response.headers["Pragma"] = "no-cache"
response.headers["Expires"] = "Fri, 01 Jan 1990 00:00:00 GMT" response.headers["Expires"] = "Fri, 01 Jan 1990 00:00:00 GMT"
end end
def render_full_content
@full_content = true
end
end end

View file

@ -7,12 +7,14 @@ class CommitsController < ApplicationController
# Authorize # Authorize
before_filter :add_project_abilities before_filter :add_project_abilities
before_filter :authorize_read_project! before_filter :authorize_read_project!
before_filter :authorize_code_access!
before_filter :require_non_empty_project before_filter :require_non_empty_project
before_filter :load_refs, :only => :index # load @branch, @tag & @ref before_filter :load_refs, :only => :index # load @branch, @tag & @ref
before_filter :render_full_content
def index def index
@repo = project.repo @repo = project.repo
@limit, @offset = (params[:limit] || 20), (params[:offset] || 0) @limit, @offset = (params[:limit] || 40), (params[:offset] || 0)
@commits = @project.commits(@ref, params[:path], @limit, @offset) @commits = @project.commits(@ref, params[:path], @limit, @offset)
respond_to do |format| respond_to do |format|
@ -24,14 +26,31 @@ class CommitsController < ApplicationController
def show def show
@commit = project.commit(params[:id]) @commit = project.commit(params[:id])
@notes = project.commit_notes(@commit).fresh.limit(20)
git_not_found! and return unless @commit
@note = @project.build_commit_note(@commit) @note = @project.build_commit_note(@commit)
@comments_allowed = true
@line_notes = project.commit_line_notes(@commit) @line_notes = project.commit_line_notes(@commit)
end
respond_to do |format| def compare
format.html first = project.commit(params[:to])
format.js { respond_with_notes } last = project.commit(params[:from])
@diffs = []
@commits = []
@line_notes = []
if first && last
commits = [first, last].sort_by(&:created_at)
younger = commits.first
older = commits.last
@commits = project.repo.commits_between(younger.id, older.id).map {|c| Commit.new(c)}
@diffs = project.repo.diff(younger.id, older.id) rescue []
@commit = Commit.new(older)
end end
end end
end end

View file

@ -3,7 +3,16 @@ class DashboardController < ApplicationController
def index def index
@projects = current_user.projects.all @projects = current_user.projects.all
@active_projects = @projects.select(&:repo_exists?).select(&:last_activity_date_cached).sort_by(&:last_activity_date_cached).reverse @active_projects = @projects.select(&:repo_exists?).select(&:last_activity_date_cached).sort_by(&:last_activity_date_cached).reverse
@merge_requests = MergeRequest.where("author_id = :id or assignee_id = :id", :id => current_user.id).opened.order("created_at DESC").limit(10)
@user = current_user
@issues = current_user.assigned_issues.opened.order("created_at DESC").limit(10)
@issues = @issues.includes(:author, :project)
@events = Event.where(:project_id => @projects.map(&:id)).recent.limit(20)
end end
# Get authored or assigned open merge requests # Get authored or assigned open merge requests

View file

@ -1,5 +1,7 @@
class ErrorsController < ApplicationController class ErrorsController < ApplicationController
layout "error"
def githost def githost
render :file => File.join(Rails.root, "public", "githost_error"), :layout => false render "errors/gitolite"
end end
end end

View file

@ -1,6 +1,7 @@
class IssuesController < ApplicationController class IssuesController < ApplicationController
before_filter :authenticate_user! before_filter :authenticate_user!
before_filter :project before_filter :project
before_filter :module_enabled
before_filter :issue, :only => [:edit, :update, :destroy, :show] before_filter :issue, :only => [:edit, :update, :destroy, :show]
layout "project" layout "project"
@ -48,7 +49,6 @@ class IssuesController < ApplicationController
end end
def show def show
@notes = @issue.notes.inc_author.order("created_at DESC").limit(20)
@note = @project.notes.new(:noteable => @issue) @note = @project.notes.new(:noteable => @issue)
@commits = if @issue.branch_name && @project.repo.heads.map(&:name).include?(@issue.branch_name) @commits = if @issue.branch_name && @project.repo.heads.map(&:name).include?(@issue.branch_name)
@ -60,7 +60,7 @@ class IssuesController < ApplicationController
respond_to do |format| respond_to do |format|
format.html format.html
format.js { respond_with_notes } format.js
end end
end end
@ -69,7 +69,10 @@ class IssuesController < ApplicationController
@issue.author = current_user @issue.author = current_user
@issue.save @issue.save
respond_with(@issue) respond_to do |format|
format.html { redirect_to project_issue_path(@project, @issue) }
format.js
end
end end
def update def update
@ -125,11 +128,14 @@ class IssuesController < ApplicationController
end end
def authorize_modify_issue! def authorize_modify_issue!
can?(current_user, :modify_issue, @issue) || return render_404 unless can?(current_user, :modify_issue, @issue)
@issue.assignee == current_user
end end
def authorize_admin_issue! def authorize_admin_issue!
can?(current_user, :admin_issue, @issue) return render_404 unless can?(current_user, :admin_issue, @issue)
end
def module_enabled
return render_404 unless @project.issues_enabled
end end
end end

View file

@ -1,6 +1,6 @@
class KeysController < ApplicationController class KeysController < ApplicationController
layout "profile" layout "profile"
respond_to :js respond_to :js, :html
def index def index
@keys = current_user.keys.all @keys = current_user.keys.all

View file

@ -1,6 +1,7 @@
class MergeRequestsController < ApplicationController class MergeRequestsController < ApplicationController
before_filter :authenticate_user! before_filter :authenticate_user!
before_filter :project before_filter :project
before_filter :module_enabled
before_filter :merge_request, :only => [:edit, :update, :destroy, :show, :commits, :diffs] before_filter :merge_request, :only => [:edit, :update, :destroy, :show, :commits, :diffs]
layout "project" layout "project"
@ -23,7 +24,9 @@ class MergeRequestsController < ApplicationController
@merge_requests = @project.merge_requests @merge_requests = @project.merge_requests
@merge_requests = case params[:f].to_i @merge_requests = case params[:f].to_i
when 1 then @merge_requests
when 2 then @merge_requests.closed when 2 then @merge_requests.closed
when 2 then @merge_requests.opened.assigned(current_user)
else @merge_requests.opened else @merge_requests.opened
end end
@ -33,26 +36,31 @@ class MergeRequestsController < ApplicationController
def show def show
unless @project.repo.heads.map(&:name).include?(@merge_request.target_branch) && unless @project.repo.heads.map(&:name).include?(@merge_request.target_branch) &&
@project.repo.heads.map(&:name).include?(@merge_request.source_branch) @project.repo.heads.map(&:name).include?(@merge_request.source_branch)
head(404)and return git_not_found! and return
end end
@notes = @merge_request.notes.inc_author.order("created_at DESC").limit(20)
@note = @project.notes.new(:noteable => @merge_request) @note = @project.notes.new(:noteable => @merge_request)
@commits = @project.repo.
commits_between(@merge_request.target_branch, @merge_request.source_branch).
map {|c| Commit.new(c)}.
sort_by(&:created_at).
reverse
render_full_content
respond_to do |format| respond_to do |format|
format.html format.html
format.js { respond_with_notes } format.js
end end
end end
def commits
@commits = @project.repo.commits_between(@merge_request.target_branch, @merge_request.source_branch).map {|c| Commit.new(c)}
end
def diffs def diffs
@diffs = @merge_request.diffs @diffs = @merge_request.diffs
@commit = @merge_request.last_commit @commit = @merge_request.last_commit
@line_notes = []
@comments_allowed = true
@line_notes = @merge_request.notes.where("line_code is not null")
end end
def new def new
@ -105,11 +113,14 @@ class MergeRequestsController < ApplicationController
end end
def authorize_modify_merge_request! def authorize_modify_merge_request!
can?(current_user, :modify_merge_request, @merge_request) || return render_404 unless can?(current_user, :modify_merge_request, @merge_request)
@merge_request.assignee == current_user
end end
def authorize_admin_merge_request! def authorize_admin_merge_request!
can?(current_user, :admin_merge_request, @merge_request) return render_404 unless can?(current_user, :admin_merge_request, @merge_request)
end
def module_enabled
return render_404 unless @project.merge_requests_enabled
end end
end end

View file

@ -9,6 +9,11 @@ class NotesController < ApplicationController
respond_to :js respond_to :js
def index
notes
respond_with(@notes)
end
def create def create
@note = @project.notes.new(params[:note]) @note = @project.notes.new(params[:note])
@note.author = current_user @note.author = current_user
@ -24,9 +29,7 @@ class NotesController < ApplicationController
def destroy def destroy
@note = @project.notes.find(params[:id]) @note = @project.notes.find(params[:id])
return access_denied! unless can?(current_user, :admin_note, @note) return access_denied! unless can?(current_user, :admin_note, @note)
@note.destroy @note.destroy
respond_to do |format| respond_to do |format|
@ -34,4 +37,28 @@ class NotesController < ApplicationController
end end
end end
protected
def notes
@notes = case params[:target_type]
when "commit"
then project.commit_notes(project.commit((params[:target_id]))).fresh.limit(20)
when "snippet"
then project.snippets.find(params[:target_id]).notes
when "wall"
then project.common_notes.order("created_at DESC").fresh.limit(50)
when "issue"
then project.issues.find(params[:target_id]).notes.inc_author.order("created_at DESC").limit(20)
when "merge_request"
then project.merge_requests.find(params[:target_id]).notes.inc_author.order("created_at DESC").limit(20)
end
@notes = if params[:last_id]
@notes.where("id > ?", params[:last_id])
elsif params[:first_id]
@notes.where("id < ?", params[:first_id])
else
@notes
end
end
end end

View file

@ -0,0 +1,13 @@
class OmniauthCallbacksController < Devise::OmniauthCallbacksController
def ldap
# We only find ourselves here if the authentication to LDAP was successful.
info = request.env["omniauth.auth"]["info"]
@user = User.find_for_ldap_auth(info)
if @user.persisted?
@user.remember_me = true
end
sign_in_and_redirect @user
end
end

View file

@ -28,7 +28,7 @@ class ProjectsController < ApplicationController
Project.transaction do Project.transaction do
@project.save! @project.save!
@project.users_projects.create!(:repo_access => Repository::REPO_RW , :project_access => Project::PROJECT_RWA, :user => current_user) @project.users_projects.create!(:project_access => UsersProject::MASTER, :user => current_user)
# when project saved no team member exist so # when project saved no team member exist so
# project repository should be updated after first user add # project repository should be updated after first user add
@ -57,7 +57,7 @@ class ProjectsController < ApplicationController
def update def update
respond_to do |format| respond_to do |format|
if project.update_attributes(params[:project]) if project.update_attributes(params[:project])
format.html { redirect_to info_project_path(project), :notice => 'Project was successfully updated.' } format.html { redirect_to edit_project_path(project), :notice => 'Project was successfully updated.' }
format.js format.js
else else
format.html { render action: "edit" } format.html { render action: "edit" }
@ -68,33 +68,29 @@ class ProjectsController < ApplicationController
def show def show
return render "projects/empty" unless @project.repo_exists? && @project.has_commits? return render "projects/empty" unless @project.repo_exists? && @project.has_commits?
limit = (params[:limit] || 20).to_i limit = (params[:limit] || 10).to_i
@activities = @project.activities(limit)#updates_wo_repo(limit) @activities = @project.activities(limit)
end end
def files def files
@notes = @project.notes.where("attachment != 'NULL'").order("created_at DESC").limit(100) @notes = @project.notes.where("attachment != 'NULL'").order("created_at DESC").limit(100)
end end
def info
end
# #
# Wall # Wall
# #
def wall def wall
return render_404 unless @project.wall_enabled
@note = Note.new @note = Note.new
@notes = @project.common_notes.order("created_at DESC")
@notes = @notes.fresh.limit(20)
respond_to do |format| respond_to do |format|
format.html format.html
format.js { respond_with_notes }
end end
end end
def graph def graph
render_full_content
@days_json, @commits_json = GraphCommit.to_graph(project) @days_json, @commits_json = GraphCommit.to_graph(project)
end end
@ -114,6 +110,7 @@ class ProjectsController < ApplicationController
def project def project
@project ||= Project.find_by_code(params[:id]) @project ||= Project.find_by_code(params[:id])
@project || render_404
end end
def determine_layout def determine_layout

View file

@ -0,0 +1,32 @@
class ProtectedBranchesController < ApplicationController
before_filter :project
# Authorize
before_filter :add_project_abilities
before_filter :authorize_read_project!
before_filter :require_non_empty_project
before_filter :authorize_admin_project!, :only => [:destroy, :create]
before_filter :render_full_content
layout "project"
def index
@branches = @project.protected_branches.all
@protected_branch = @project.protected_branches.new
end
def create
@project.protected_branches.create(params[:protected_branch])
redirect_to project_protected_branches_path(@project)
end
def destroy
@project.protected_branches.find(params[:id]).destroy
respond_to do |format|
format.html { redirect_to project_protected_branches_path }
format.js { render :nothing => true }
end
end
end

View file

@ -4,13 +4,18 @@ class RefsController < ApplicationController
# Authorize # Authorize
before_filter :add_project_abilities before_filter :add_project_abilities
before_filter :authorize_read_project! before_filter :authorize_read_project!
before_filter :authorize_code_access!
before_filter :require_non_empty_project before_filter :require_non_empty_project
before_filter :ref before_filter :ref
before_filter :define_tree_vars, :only => [:tree, :blob] before_filter :define_tree_vars, :only => [:tree, :blob]
before_filter :render_full_content
layout "project" layout "project"
def switch def switch
respond_to do |format|
format.html do
new_path = if params[:destination] == "tree" new_path = if params[:destination] == "tree"
tree_project_ref_path(@project, params[:ref]) tree_project_ref_path(@project, params[:ref])
else else
@ -19,6 +24,13 @@ class RefsController < ApplicationController
redirect_to new_path redirect_to new_path
end end
format.js do
@ref = params[:ref]
define_tree_vars
render "tree"
end
end
end
# #
# Repository preview # Repository preview
@ -37,7 +49,12 @@ class RefsController < ApplicationController
def blob def blob
if @tree.is_blob? if @tree.is_blob?
send_data(@tree.data, :type => @tree.mime_type, :disposition => 'inline', :filename => @tree.name) send_data(
@tree.data,
:type => @tree.text? ? "text/plain" : @tree.mime_type,
:disposition => 'inline',
:filename => @tree.name
)
else else
head(404) head(404)
end end
@ -48,6 +65,8 @@ class RefsController < ApplicationController
protected protected
def define_tree_vars def define_tree_vars
params[:path] = nil if params[:path].blank?
@repo = project.repo @repo = project.repo
@commit = project.commit(@ref) @commit = project.commit(@ref)
@tree = Tree.new(@commit.tree, project, @ref, params[:path]) @tree = Tree.new(@commit.tree, project, @ref, params[:path])

View file

@ -4,7 +4,9 @@ class RepositoriesController < ApplicationController
# Authorize # Authorize
before_filter :add_project_abilities before_filter :add_project_abilities
before_filter :authorize_read_project! before_filter :authorize_read_project!
before_filter :authorize_code_access!
before_filter :require_non_empty_project before_filter :require_non_empty_project
before_filter :render_full_content
layout "project" layout "project"
@ -19,4 +21,28 @@ class RepositoriesController < ApplicationController
def tags def tags
@tags = @project.repo.tags.sort_by(&:name).reverse @tags = @project.repo.tags.sort_by(&:name).reverse
end end
def archive
unless can?(current_user, :download_code, @project)
render_404 and return
end
ref = params[:ref] || @project.root_ref
commit = @project.commit(ref)
render_404 and return unless commit
# Build file path
file_name = @project.code + "-" + commit.id.to_s + ".tar.gz"
storage_path = File.join(Rails.root, "tmp", "repositories", @project.code)
file_path = File.join(storage_path, file_name)
# Create file if not exists
unless File.exists?(file_path)
FileUtils.mkdir_p storage_path
file = @project.repo.archive_to_file(ref, nil, file_path)
end
# Send file to user
send_file file_path
end
end end

View file

@ -1,6 +1,7 @@
class SnippetsController < ApplicationController class SnippetsController < ApplicationController
before_filter :authenticate_user! before_filter :authenticate_user!
before_filter :project before_filter :project
before_filter :snippet, :only => [:show, :edit, :destroy, :update]
layout "project" layout "project"
# Authorize # Authorize
@ -41,11 +42,9 @@ class SnippetsController < ApplicationController
end end
def edit def edit
@snippet = @project.snippets.find(params[:id])
end end
def update def update
@snippet = @project.snippets.find(params[:id])
@snippet.update_attributes(params[:snippet]) @snippet.update_attributes(params[:snippet])
if @snippet.valid? if @snippet.valid?
@ -56,14 +55,11 @@ class SnippetsController < ApplicationController
end end
def show def show
@snippet = @project.snippets.find(params[:id])
@notes = @snippet.notes
@note = @project.notes.new(:noteable => @snippet) @note = @project.notes.new(:noteable => @snippet)
render_full_content
end end
def destroy def destroy
@snippet = @project.snippets.find(params[:id])
return access_denied! unless can?(current_user, :admin_snippet, @snippet) return access_denied! unless can?(current_user, :admin_snippet, @snippet)
@snippet.destroy @snippet.destroy
@ -72,12 +68,15 @@ class SnippetsController < ApplicationController
end end
protected protected
def snippet
@snippet ||= @project.snippets.find(params[:id])
end
def authorize_modify_snippet! def authorize_modify_snippet!
can?(current_user, :modify_snippet, @snippet) return render_404 unless can?(current_user, :modify_snippet, @snippet)
end end
def authorize_admin_snippet! def authorize_admin_snippet!
can?(current_user, :admin_snippet, @snippet) return render_404 unless can?(current_user, :admin_snippet, @snippet)
end end
end end

View file

@ -1,11 +0,0 @@
class TagsController < ApplicationController
def index
@tags = Project.tag_counts.order('count DESC')
@tags = @tags.where('name like ?', "%#{params[:term]}%") unless params[:term].blank?
respond_to do |format|
format.html
format.json { render json: @tags.limit(8).map {|t| t.name}}
end
end
end

View file

@ -40,7 +40,7 @@ class TeamMembersController < ApplicationController
@team_member.destroy @team_member.destroy
respond_to do |format| respond_to do |format|
format.html { redirect_to root_path } format.html { redirect_to team_project_path(@project) }
format.js { render :nothing => true } format.js { render :nothing => true }
end end
end end

View file

@ -0,0 +1,59 @@
class WikisController < ApplicationController
before_filter :project
before_filter :add_project_abilities
before_filter :authorize_read_wiki!
before_filter :authorize_write_wiki!, :only => [:edit, :create, :history]
before_filter :authorize_admin_wiki!, :only => :destroy
layout "project"
def show
if params[:old_page_id]
@wiki = @project.wikis.find(params[:old_page_id])
else
@wiki = @project.wikis.where(:slug => params[:id]).order("created_at").last
end
unless @wiki
return render_404 unless can?(current_user, :write_wiki, @project)
end
respond_to do |format|
if @wiki
format.html
else
@wiki = @project.wikis.new(:slug => params[:id])
format.html { render "edit" }
end
end
end
def edit
@wiki = @project.wikis.where(:slug => params[:id]).order("created_at").last
@wiki = Wiki.regenerate_from @wiki
end
def create
@wiki = @project.wikis.new(params[:wiki])
@wiki.user = current_user
respond_to do |format|
if @wiki.save
format.html { redirect_to [@project, @wiki], notice: 'Wiki was successfully updated.' }
else
format.html { render action: "edit" }
end
end
end
def history
@wikis = @project.wikis.where(:slug => params[:id]).order("created_at")
end
def destroy
@wikis = @project.wikis.where(:slug => params[:id]).delete_all
respond_to do |format|
format.html { redirect_to project_wiki_path(@project, :index), notice: "Page was successfully deleted" }
end
end
end

View file

@ -3,7 +3,8 @@ module ApplicationHelper
def gravatar_icon(user_email, size = 40) def gravatar_icon(user_email, size = 40)
gravatar_host = request.ssl? ? "https://secure.gravatar.com" : "http://www.gravatar.com" gravatar_host = request.ssl? ? "https://secure.gravatar.com" : "http://www.gravatar.com"
"#{gravatar_host}/avatar/#{Digest::MD5.hexdigest(user_email)}?s=#{size}&d=identicon" user_email.strip!
"#{gravatar_host}/avatar/#{Digest::MD5.hexdigest(user_email.downcase)}?s=#{size}&d=identicon"
end end
def fixed_mode? def fixed_mode?
@ -52,6 +53,13 @@ module ApplicationHelper
[ "Tag", @project.tags ] [ "Tag", @project.tags ]
] ]
# If reference is commit id -
# we should add it to branch/tag selectbox
if(@ref && !options.flatten.include?(@ref) &&
@ref =~ /^[0-9a-zA-Z]{6,52}$/)
options << ["Commit", [@ref]]
end
grouped_options_for_select(options, @ref || @project.default_branch) grouped_options_for_select(options, @ref || @project.default_branch)
end end
@ -71,11 +79,11 @@ module ApplicationHelper
if @project && !@project.new_record? if @project && !@project.new_record?
project_nav = [ project_nav = [
{ :label => "#{@project.code} / Issues", :url => project_issues_path(@project) }, { :label => "#{@project.name} / Issues", :url => project_issues_path(@project) },
{ :label => "#{@project.code} / Wall", :url => wall_project_path(@project) }, { :label => "#{@project.name} / Wall", :url => wall_project_path(@project) },
{ :label => "#{@project.code} / Tree", :url => tree_project_ref_path(@project, @project.root_ref) }, { :label => "#{@project.name} / Tree", :url => tree_project_ref_path(@project, @project.root_ref) },
{ :label => "#{@project.code} / Commits", :url => project_commits_path(@project) }, { :label => "#{@project.name} / Commits", :url => project_commits_path(@project) },
{ :label => "#{@project.code} / Team", :url => team_project_path(@project) } { :label => "#{@project.name} / Team", :url => team_project_path(@project) }
] ]
end end
@ -83,14 +91,26 @@ module ApplicationHelper
end end
def project_layout def project_layout
@project && !@project.new_record? layout == "project"
end
def admin_layout
layout == "admin"
end end
def profile_layout def profile_layout
controller.controller_name == "dashboard" || current_page?(projects_path) || controller.controller_name == "profile" || controller.controller_name == "keys" layout == "profile"
end end
def help_layout def help_layout
controller.controller_name == "help" controller.controller_name == "help"
end end
def ldap_enable?
Devise.omniauth_providers.include?(:ldap)
end
def layout
controller.send :_layout
end
end end

View file

@ -7,16 +7,6 @@ module CommitsHelper
end end
def diff_line_class(line)
if line[0] == "+"
"new"
elsif line[0] == "-"
"old"
else
nil
end
end
def more_commits_link def more_commits_link
offset = params[:offset] || 0 offset = params[:offset] || 0
limit = params[:limit] || 100 limit = params[:limit] || 100
@ -42,11 +32,58 @@ module CommitsHelper
preserve out preserve out
end end
def build_line_code(line, index, line_new, line_old) def diff_line_class(line)
if diff_line_class(line) == "new" if line[0] == "+"
"NEW_#{index}_#{line_new}" "new"
elsif line[0] == "-"
"old"
else else
"OLD_#{index}_#{line_old}" nil
end
end
def build_line_code(line, index, line_new, line_old)
"#{index}_#{line_old}_#{line_new}"
end
def each_diff_line(diff_arr, index)
line_old = 1
line_new = 1
type = nil
lines_arr = diff_arr
lines_arr.each do |line|
next if line.match(/^\-\-\- \/dev\/null/)
next if line.match(/^\+\+\+ \/dev\/null/)
next if line.match(/^\-\-\- a/)
next if line.match(/^\+\+\+ b/)
full_line = html_escape(line.gsub(/\n/, '')).force_encoding("UTF-8")
if line.match(/^@@ -/)
type = "match"
line_old = line.match(/\-[0-9]*/)[0].to_i.abs rescue 0
line_new = line.match(/\+[0-9]*/)[0].to_i.abs rescue 0
next if line_old == 1 && line_new == 1
yield(line, type, nil, nil, nil)
next
else
type = diff_line_class(line)
line_code = build_line_code(line, index, line_new, line_old)
yield(full_line, type, line_code, line_new, line_old)
end
if line[0] == "+"
line_new += 1
elsif line[0] == "-"
line_old += 1
else
line_new += 1
line_old += 1
end
end end
end end
end end

View file

@ -3,6 +3,7 @@ module DashboardHelper
case object.class.name.to_s case object.class.name.to_s
when "Issue" then project_issue_path(project, project.issues.find(object.id)) when "Issue" then project_issue_path(project, project.issues.find(object.id))
when "Commit" then project_commit_path(project, project.repo.commits(object.id).first) when "Commit" then project_commit_path(project, project.repo.commits(object.id).first)
when "MergeRequest" then project_merge_request_path(project, object.id)
when "Note" when "Note"
then then
note = object note = object
@ -26,6 +27,7 @@ module DashboardHelper
when "Note" then markdown(object.note) when "Note" then markdown(object.note)
when "Issue" then object.title when "Issue" then object.title
when "Commit" then object.safe_message when "Commit" then object.safe_message
when "MergeRequest" then object.title
else return "Project Wall" else return "Project Wall"
end end

View file

@ -9,4 +9,26 @@ module IssuesHelper
params[:f] ||= cookies['issue_filter'] params[:f] ||= cookies['issue_filter']
project_issues_path project, params project_issues_path project, params
end end
def link_to_issue_assignee(issue)
project = issue.project
tm = project.team_member_by_id(issue.assignee_id)
if tm
link_to issue.assignee_name, project_team_member_path(project, tm), :class => "author_link"
else
issue.assignee_name
end
end
def link_to_issue_author(issue)
project = issue.project
tm = project.team_member_by_id(issue.author_id)
if tm
link_to issue.author_name, project_team_member_path(project, tm), :class => "author_link"
else
issue.author_name
end
end
end end

View file

@ -1,2 +1,23 @@
module MergeRequestsHelper module MergeRequestsHelper
def link_to_merge_request_assignee(merge_request)
project = merge_request.project
tm = project.team_member_by_id(merge_request.assignee_id)
if tm
link_to merge_request.assignee_name, project_team_member_path(project, tm), :class => "author_link"
else
merge_request.assignee_name
end
end
def link_to_merge_request_author(merge_request)
project = merge_request.project
tm = project.team_member_by_id(merge_request.author_id)
if tm
link_to merge_request.author_name, project_team_member_path(project, tm), :class => "author_link"
else
merge_request.author_name
end
end
end end

View file

@ -17,11 +17,13 @@ module ProjectsHelper
end end
def project_tab_class def project_tab_class
[:show, :files, :team, :edit, :update, :info].each do |action| [:show, :files, :team, :edit, :update].each do |action|
return "current" if current_page?(:controller => "projects", :action => action, :id => @project) return "current" if current_page?(:controller => "projects", :action => action, :id => @project)
end end
if controller.controller_name == "snippets" || if controller.controller_name == "snippets" ||
controller.controller_name == "hooks" ||
controller.controller_name == "deploy_keys" ||
controller.controller_name == "team_members" controller.controller_name == "team_members"
"current" "current"
end end
@ -33,9 +35,26 @@ module ProjectsHelper
end end
def repository_tab_class def repository_tab_class
if controller.controller_name == "repositories" || #if controller.controller_name == "repositories" ||
controller.controller_name == "hooks" #controller.controller_name == "hooks" ||
#controller.controller_name == "deploy_keys"
#"current"
#end
end
def commit_tab_class
if controller.controller_name == "commits" ||
controller.controller_name == "repositories" ||
controller.controller_name == "protected_branches"
"current" "current"
end end
end end
def branches_tab_class
if current_page?(branches_project_repository_path(@project)) ||
controller.controller_name == "protected_branches" ||
current_page?(project_repository_path(@project))
'active'
end
end
end end

View file

@ -0,0 +1,5 @@
module WikisHelper
def markdown_to_html(text)
RDiscount.new(text).to_html.html_safe
end
end

View file

@ -27,8 +27,7 @@ class Notify < ActionMailer::Base
@user = user @user = user
@note = note @note = note
@project = note.project @project = note.project
@commit = @project.repo.commits(note.noteable_id).first @commit = @note.target
return unless ( note.notify or ( note.notify_author and @commit.author.email == @user.email ) )
mail(:to => @user.email, :subject => "gitlab | note for commit | #{@note.project.name} ") mail(:to => @user.email, :subject => "gitlab | note for commit | #{@note.project.name} ")
end end

View file

@ -5,6 +5,7 @@ class Ability
when "Issue" then issue_abilities(object, subject) when "Issue" then issue_abilities(object, subject)
when "Note" then note_abilities(object, subject) when "Note" then note_abilities(object, subject)
when "Snippet" then snippet_abilities(object, subject) when "Snippet" then snippet_abilities(object, subject)
when "MergeRequest" then merge_request_abilities(object, subject)
else [] else []
end end
end end
@ -14,31 +15,40 @@ class Ability
rules << [ rules << [
:read_project, :read_project,
:read_wiki,
:read_issue, :read_issue,
:read_snippet, :read_snippet,
:read_team_member, :read_team_member,
:read_merge_request, :read_merge_request,
:read_note :read_note,
] if project.allow_read_for?(user)
rules << [
:write_project, :write_project,
:write_issue, :write_issue,
:write_snippet,
:write_merge_request,
:write_note :write_note
] if project.allow_write_for?(user) ] if project.guest_access_for?(user)
rules << [
:download_code,
:write_merge_request,
:write_snippet
] if project.report_access_for?(user)
rules << [
:write_wiki
] if project.dev_access_for?(user)
rules << [ rules << [
:modify_issue, :modify_issue,
:modify_snippet, :modify_snippet,
:modify_merge_request,
:admin_project, :admin_project,
:admin_issue, :admin_issue,
:admin_snippet, :admin_snippet,
:admin_team_member, :admin_team_member,
:admin_merge_request, :admin_merge_request,
:admin_note :admin_note,
] if project.allow_admin_for?(user) :admin_wiki
] if project.master_access_for?(user) || project.owner == user
rules.flatten rules.flatten
end end
@ -53,6 +63,12 @@ class Ability
:"modify_#{name}", :"modify_#{name}",
:"admin_#{name}" :"admin_#{name}"
] ]
elsif subject.respond_to?(:assignee) && subject.assignee == user
[
:"read_#{name}",
:"write_#{name}",
:"modify_#{name}",
]
else else
subject.respond_to?(:project) ? subject.respond_to?(:project) ?
project_abilities(user, subject.project) : [] project_abilities(user, subject.project) : []

View file

@ -0,0 +1,12 @@
class ActivityObserver < ActiveRecord::Observer
observe :issue, :merge_request, :note
def after_create(record)
Event.create(
:project => record.project,
:target_id => record.id,
:target_type => record.class.name,
:action => Event.determine_action(record)
)
end
end

View file

@ -1,14 +1,18 @@
class Commit class Commit
include ActiveModel::Conversion
extend ActiveModel::Naming
attr_accessor :commit attr_accessor :commit
attr_accessor :head attr_accessor :head
attr_accessor :refs attr_accessor :refs
delegate :message, delegate :message,
:authored_date,
:committed_date, :committed_date,
:parents, :parents,
:sha, :sha,
:date, :date,
:committer,
:author, :author,
:message, :message,
:diffs, :diffs,
@ -16,6 +20,10 @@ class Commit
:id, :id,
:to => :commit :to => :commit
def persisted?
false
end
def initialize(raw_commit, head = nil) def initialize(raw_commit, head = nil)
@commit = raw_commit @commit = raw_commit
@head = head @head = head
@ -34,10 +42,22 @@ class Commit
end end
def author_name def author_name
author.name author.name.force_encoding("UTF-8")
end
def committer_name
committer.name
end
def committer_email
committer.email
end end
def prev_commit def prev_commit
parents.first parents.first
end end
def prev_commit_id
prev_commit.id
end
end end

70
app/models/event.rb Normal file
View file

@ -0,0 +1,70 @@
class Event < ActiveRecord::Base
Created = 1
Updated = 2
Closed = 3
Reopened = 4
Pushed = 5
Commented = 6
belongs_to :project
belongs_to :target, :polymorphic => true
serialize :data
scope :recent, order("created_at DESC")
def self.determine_action(record)
if [Issue, MergeRequest].include? record.class
Event::Created
elsif record.kind_of? Note
Event::Commented
end
end
def push?
action == self.class::Pushed
end
def new_branch?
data[:before] =~ /^00000/
end
def commit_from
data[:before]
end
def commit_to
data[:after]
end
def branch_name
@branch_name ||= data[:ref].gsub("refs/heads/", "")
end
def pusher
User.find_by_id(data[:user_id])
end
def commits
@commits ||= data[:commits].map do |commit|
project.commit(commit[:id])
end
end
delegate :id, :name, :email, :to => :pusher, :prefix => true, :allow_nil => true
end
# == Schema Information
#
# Table name: events
#
# id :integer not null, primary key
# target_type :string(255)
# target_id :integer
# title :string(255)
# data :text
# project_id :integer
# created_at :datetime not null
# updated_at :datetime not null
# action :integer
#

View file

@ -14,6 +14,7 @@ class Key < ActiveRecord::Base
before_save :set_identifier before_save :set_identifier
after_save :update_repository after_save :update_repository
after_destroy :repository_delete_key after_destroy :repository_delete_key
delegate :name, :email, :to => :user, :prefix => true
def set_identifier def set_identifier
if is_deploy_key if is_deploy_key

View file

@ -27,7 +27,8 @@ class MailerObserver < ActiveRecord::Observer
end end
def new_note(note) def new_note(note)
return unless note.notify or note.notify_author # Notify whole team except author of note
if note.notify
note.project.users.reject { |u| u.id == current_user.id } .each do |u| note.project.users.reject { |u| u.id == current_user.id } .each do |u|
case note.noteable_type case note.noteable_type
when "Commit" then when "Commit" then
@ -42,6 +43,10 @@ class MailerObserver < ActiveRecord::Observer
Notify.note_wall_email(u, note).deliver Notify.note_wall_email(u, note).deliver
end end
end end
# Notify only author of resource
elsif note.notify_author
Notify.note_commit_email(note.commit_author, note).deliver
end
end end
def new_merge_request(merge_request) def new_merge_request(merge_request)

View file

@ -58,21 +58,34 @@ class Note < ActiveRecord::Base
nil nil
end end
def line_file_id # Check if we can notify commit author
@line_file_id ||= line_code.split("_")[1].to_i if line_code # with email about our comment
#
# If commit author email exist in project
# and commit author is not passed user we can
# send email to him
#
# params:
# user - current user
#
# return:
# Boolean
#
def notify_only_author?(user)
commit? && commit_author &&
commit_author.email != user.email
end end
def line_type_id def commit?
@line_type_id ||= line_code.split("_").first if line_code noteable_type == "Commit"
end end
def line_number def commit_author
@line_number ||= line_code.split("_").last.to_i if line_code @commit_author ||=
end project.users.find_by_email(target.author_email) ||
project.users.find_by_name(target.author_name)
def for_line?(file_id, old_line, new_line) rescue
line_file_id == file_id && nil
((line_type_id == "NEW" && line_number == new_line) || (line_type_id == "OLD" && line_number == old_line ))
end end
end end
# == Schema Information # == Schema Information

View file

@ -1,13 +1,9 @@
require "grit" require "grit"
class Project < ActiveRecord::Base class Project < ActiveRecord::Base
PROJECT_N = 0
PROJECT_R = 1
PROJECT_RW = 2
PROJECT_RWA = 3
belongs_to :owner, :class_name => "User" belongs_to :owner, :class_name => "User"
has_many :events, :dependent => :destroy
has_many :merge_requests, :dependent => :destroy has_many :merge_requests, :dependent => :destroy
has_many :issues, :dependent => :destroy, :order => "position" has_many :issues, :dependent => :destroy, :order => "position"
has_many :users_projects, :dependent => :destroy has_many :users_projects, :dependent => :destroy
@ -16,6 +12,8 @@ class Project < ActiveRecord::Base
has_many :snippets, :dependent => :destroy has_many :snippets, :dependent => :destroy
has_many :deploy_keys, :dependent => :destroy, :foreign_key => "project_id", :class_name => "Key" has_many :deploy_keys, :dependent => :destroy, :foreign_key => "project_id", :class_name => "Key"
has_many :web_hooks, :dependent => :destroy has_many :web_hooks, :dependent => :destroy
has_many :protected_branches, :dependent => :destroy
has_many :wikis, :dependent => :destroy
acts_as_taggable acts_as_taggable
@ -53,18 +51,14 @@ class Project < ActiveRecord::Base
attr_protected :private_flag, :owner_id attr_protected :private_flag, :owner_id
scope :public_only, where(:private_flag => false) scope :public_only, where(:private_flag => false)
scope :without_user, lambda { |user| where("id not in (:ids)", :ids => user.projects.map(&:id) ) }
def self.active def self.active
joins(:issues, :notes, :merge_requests).order("issues.created_at, notes.created_at, merge_requests.created_at DESC") joins(:issues, :notes, :merge_requests).order("issues.created_at, notes.created_at, merge_requests.created_at DESC")
end end
def self.access_options def self.access_options
{ UsersProject.access_roles
"Denied" => PROJECT_N,
"Read" => PROJECT_R,
"Report" => PROJECT_RW,
"Admin" => PROJECT_RWA
}
end end
def repository def repository
@ -96,21 +90,35 @@ class Project < ActiveRecord::Base
[GIT_HOST['host'], code].join("/") [GIT_HOST['host'], code].join("/")
end end
def execute_web_hooks(oldrev, newrev, ref) def observe_push(oldrev, newrev, ref, author_key_id)
data = web_hook_data(oldrev, newrev, ref, author_key_id)
Event.create(
:project => self,
:action => Event::Pushed,
:data => data
)
end
def execute_web_hooks(oldrev, newrev, ref, author_key_id)
ref_parts = ref.split('/') ref_parts = ref.split('/')
# Return if this is not a push to a branch (e.g. new commits) # Return if this is not a push to a branch (e.g. new commits)
return if ref_parts[1] !~ /heads/ || oldrev == "00000000000000000000000000000000" return if ref_parts[1] !~ /heads/ || oldrev == "00000000000000000000000000000000"
data = web_hook_data(oldrev, newrev, ref) data = web_hook_data(oldrev, newrev, ref, author_key_id)
web_hooks.each { |web_hook| web_hook.execute(data) } web_hooks.each { |web_hook| web_hook.execute(data) }
end end
def web_hook_data(oldrev, newrev, ref) def web_hook_data(oldrev, newrev, ref, author_key_id)
key = Key.find_by_identifier(author_key_id)
data = { data = {
before: oldrev, before: oldrev,
after: newrev, after: newrev,
ref: ref, ref: ref,
user_id: key.user.id,
user_name: key.user_name,
repository: { repository: {
name: name, name: name,
url: web_url, url: web_url,
@ -137,6 +145,15 @@ class Project < ActiveRecord::Base
data data
end end
def open_branches
if protected_branches.empty?
self.repo.heads
else
pnames = protected_branches.map(&:name)
self.repo.heads.reject { |h| pnames.include?(h.name) }
end.sort_by(&:name)
end
def team_member_by_name_or_email(email = nil, name = nil) def team_member_by_name_or_email(email = nil, name = nil)
user = users.where("email like ? or name like ?", email, name).first user = users.where("email like ? or name like ?", email, name).first
users_projects.find_by_user_id(user.id) if user users_projects.find_by_user_id(user.id) if user
@ -182,11 +199,11 @@ class Project < ActiveRecord::Base
# Should be rewrited for new access rights # Should be rewrited for new access rights
def add_access(user, *access) def add_access(user, *access)
access = if access.include?(:admin) access = if access.include?(:admin)
{ :project_access => PROJECT_RWA } { :project_access => UsersProject::MASTER }
elsif access.include?(:write) elsif access.include?(:write)
{ :project_access => PROJECT_RW } { :project_access => UsersProject::DEVELOPER }
else else
{ :project_access => PROJECT_R } { :project_access => UsersProject::REPORTER }
end end
opts = { :user => user } opts = { :user => user }
opts.merge!(access) opts.merge!(access)
@ -199,38 +216,52 @@ class Project < ActiveRecord::Base
def repository_readers def repository_readers
keys = Key.joins({:user => :users_projects}). keys = Key.joins({:user => :users_projects}).
where("users_projects.project_id = ? AND users_projects.repo_access = ?", id, Repository::REPO_R) where("users_projects.project_id = ? AND users_projects.project_access = ?", id, UsersProject::REPORTER)
keys.map(&:identifier) + deploy_keys.map(&:identifier) keys.map(&:identifier) + deploy_keys.map(&:identifier)
end end
def repository_writers def repository_writers
keys = Key.joins({:user => :users_projects}). keys = Key.joins({:user => :users_projects}).
where("users_projects.project_id = ? AND users_projects.repo_access = ?", id, Repository::REPO_RW) where("users_projects.project_id = ? AND users_projects.project_access = ?", id, UsersProject::DEVELOPER)
keys.map(&:identifier)
end
def repository_masters
keys = Key.joins({:user => :users_projects}).
where("users_projects.project_id = ? AND users_projects.project_access = ?", id, UsersProject::MASTER)
keys.map(&:identifier) keys.map(&:identifier)
end end
def readers def readers
@readers ||= users_projects.includes(:user).where(:project_access => [PROJECT_R, PROJECT_RW, PROJECT_RWA]).map(&:user) @readers ||= users_projects.includes(:user).map(&:user)
end end
def writers def writers
@writers ||= users_projects.includes(:user).where(:project_access => [PROJECT_RW, PROJECT_RWA]).map(&:user) @writers ||= users_projects.includes(:user).map(&:user)
end end
def admins def admins
@admins ||= users_projects.includes(:user).where(:project_access => PROJECT_RWA).map(&:user) @admins ||= users_projects.includes(:user).where(:project_access => UsersProject::MASTER).map(&:user)
end end
def allow_read_for?(user) def allow_read_for?(user)
!users_projects.where(:user_id => user.id, :project_access => [PROJECT_R, PROJECT_RW, PROJECT_RWA]).empty? !users_projects.where(:user_id => user.id).empty?
end end
def allow_write_for?(user) def guest_access_for?(user)
!users_projects.where(:user_id => user.id, :project_access => [PROJECT_RW, PROJECT_RWA]).empty? !users_projects.where(:user_id => user.id).empty?
end end
def allow_admin_for?(user) def report_access_for?(user)
!users_projects.where(:user_id => user.id, :project_access => [PROJECT_RWA]).empty? || owner_id == user.id !users_projects.where(:user_id => user.id, :project_access => [UsersProject::REPORTER, UsersProject::DEVELOPER, UsersProject::MASTER]).empty?
end
def dev_access_for?(user)
!users_projects.where(:user_id => user.id, :project_access => [UsersProject::DEVELOPER, UsersProject::MASTER]).empty?
end
def master_access_for?(user)
!users_projects.where(:user_id => user.id, :project_access => [UsersProject::MASTER]).empty? || owner_id == user.id
end end
def root_ref def root_ref
@ -345,5 +376,9 @@ end
# code :string(255) # code :string(255)
# owner_id :integer # owner_id :integer
# default_branch :string(255) default("master"), not null # default_branch :string(255) default("master"), not null
# issues_enabled :boolean default(TRUE), not null
# wall_enabled :boolean default(TRUE), not null
# merge_requests_enabled :boolean default(TRUE), not null
# wiki_enabled :boolean default(TRUE), not null
# #

View file

@ -0,0 +1,29 @@
class ProtectedBranch < ActiveRecord::Base
belongs_to :project
validates_presence_of :project_id
validates_presence_of :name
after_save :update_repository
after_destroy :update_repository
def update_repository
Gitlabhq::GitHost.system.new.configure do |c|
c.update_project(project.path, project)
end
end
def commit
project.commit(self.name)
end
end
# == Schema Information
#
# Table name: protected_branches
#
# id :integer not null, primary key
# project_id :integer not null
# name :string(255) not null
# created_at :datetime not null
# updated_at :datetime not null
#

View file

@ -1,10 +1,6 @@
require File.join(Rails.root, "lib", "gitlabhq", "git_host") require File.join(Rails.root, "lib", "gitlabhq", "git_host")
class Repository class Repository
REPO_N = 0
REPO_R = 1
REPO_RW = 2
attr_accessor :project attr_accessor :project
def self.default_ref def self.default_ref
@ -12,11 +8,7 @@ class Repository
end end
def self.access_options def self.access_options
{ {}
"Denied" => REPO_N,
"Pull" => REPO_R,
"Pull & Push" => REPO_RW
}
end end
def initialize(project) def initialize(project)
@ -56,7 +48,7 @@ class Repository
end end
def path_to_repo def path_to_repo
GIT_HOST["base_path"] + path + ".git" File.join(GIT_HOST["base_path"], "#{path}.git")
end end
def update_repository def update_repository

View file

@ -2,7 +2,7 @@ class User < ActiveRecord::Base
# Include default devise modules. Others available are: # Include default devise modules. Others available are:
# :token_authenticatable, :encryptable, :confirmable, :lockable, :timeoutable and :omniauthable # :token_authenticatable, :encryptable, :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :token_authenticatable, devise :database_authenticatable, :token_authenticatable,
:recoverable, :rememberable, :trackable, :validatable :recoverable, :rememberable, :trackable, :validatable, :omniauthable
# Setup accessible (or protected) attributes for your model # Setup accessible (or protected) attributes for your model
attr_accessible :email, :password, :password_confirmation, :remember_me, attr_accessible :email, :password, :password_confirmation, :remember_me,
@ -62,6 +62,30 @@ class User < ActiveRecord::Base
def last_activity_project def last_activity_project
projects.first projects.first
end end
def self.generate_random_password
(0...8).map{ ('a'..'z').to_a[rand(26)] }.join
end
def first_name
name.split(" ").first unless name.blank?
end
def self.find_for_ldap_auth(omniauth_info)
name = omniauth_info.name
email = omniauth_info.email
if @user = User.find_by_email(email)
@user
else
password = generate_random_password
@user = User.create(:name => name,
:email => email,
:password => password,
:password_confirmation => password
)
end
end
end end
# == Schema Information # == Schema Information
# #

View file

@ -1,4 +1,9 @@
class UsersProject < ActiveRecord::Base class UsersProject < ActiveRecord::Base
GUEST = 10
REPORTER = 20
DEVELOPER = 30
MASTER = 40
belongs_to :user belongs_to :user
belongs_to :project belongs_to :project
@ -17,7 +22,6 @@ class UsersProject < ActiveRecord::Base
UsersProject.transaction do UsersProject.transaction do
user_ids.each do |user_id| user_ids.each do |user_id|
users_project = UsersProject.new( users_project = UsersProject.new(
:repo_access => repo_access,
:project_access => project_access, :project_access => project_access,
:user_id => user_id :user_id => user_id
) )
@ -27,11 +31,45 @@ class UsersProject < ActiveRecord::Base
end end
end end
def self.user_bulk_import(user, project_ids, project_access, repo_access)
UsersProject.transaction do
project_ids.each do |project_id|
users_project = UsersProject.new(
:project_access => project_access,
)
users_project.project_id = project_id
users_project.user_id = user.id
users_project.save
end
end
end
def self.access_roles
{
"Guest" => GUEST,
"Reporter" => REPORTER,
"Developer" => DEVELOPER,
"Master" => MASTER
}
end
def role_access
project_access
end
def update_repository def update_repository
Gitlabhq::GitHost.system.new.configure do |c| Gitlabhq::GitHost.system.new.configure do |c|
c.update_project(project.path, project) c.update_project(project.path, project)
end end
end end
def project_access_human
Project.access_options.key(self.project_access)
end
def repo_access_human
""
end
end end
# == Schema Information # == Schema Information
# #
@ -42,7 +80,6 @@ end
# project_id :integer not null # project_id :integer not null
# created_at :datetime # created_at :datetime
# updated_at :datetime # updated_at :datetime
# repo_access :integer default(0), not null
# project_access :integer default(0), not null # project_access :integer default(0), not null
# #

47
app/models/wiki.rb Normal file
View file

@ -0,0 +1,47 @@
class Wiki < ActiveRecord::Base
belongs_to :project
belongs_to :user
validates :content, :title, :user_id, :presence => true
validates :title, :length => 1..250
before_update :set_slug
def to_param
slug
end
protected
def set_slug
self.slug = self.title.parameterize
end
class << self
def regenerate_from wiki
regenerated_field = [:slug, :content, :title]
new_wiki = Wiki.new
regenerated_field.each do |field|
new_wiki.send("#{field}=", wiki.send(field))
end
new_wiki
end
end
end
# == Schema Information
#
# Table name: wikis
#
# id :integer not null, primary key
# title :string(255)
# content :text
# project_id :integer
# created_at :datetime not null
# updated_at :datetime not null
# slug :string(255)
# user_id :integer
#

View file

@ -1,39 +1,66 @@
= form_for [:admin, @admin_project] do |f| = form_for [:admin, @admin_project] do |f|
-if @admin_project.errors.any? -if @admin_project.errors.any?
#error_explanation .alert-message.block-message.error
%h2= "#{pluralize(@admin_project.errors.count, "error")} prohibited this admin_project from being saved:"
%ul %ul
- @admin_project.errors.full_messages.each do |msg| - @admin_project.errors.full_messages.each do |msg|
%li= msg %li= msg
.form-row .clearfix
= f.label :name = f.label :name
%br .input= f.text_field :name
= f.text_field :name .clearfix
.form-row = f.label :path do
= f.label :code Path
%br .input
= f.text_field :code .input-prepend
.form-row %span.add-on= "git@#{GIT_HOST["host"]}:"
= f.label :path = f.text_field :path, :placeholder => "example_project", :disabled => !@admin_project.new_record?
%br .clearfix
= f.text_field :path = f.label :code do
Code
.input
.input-prepend
%span.add-on= "http://#{GIT_HOST["host"]}/"
= f.text_field :code, :placeholder => "example"
.form-row - unless @admin_project.new_record?
= f.label :tag_list .clearfix
%br = f.label :owner_id
= f.text_area :tag_list, :placeholder => "project tags", :style => "height:50px", :id => :tag_field .input= f.select :owner_id, User.all.map { |user| [user.name, user.id] }
.form-row - unless @admin_project.heads.empty?
.clearfix
= f.label :default_branch, "Default Branch"
.input= f.select(:default_branch, @admin_project.heads.map(&:name), {}, :style => "width:210px;")
.well
%h5 Features
.clearfix
= f.label :issues_enabled, "Issues"
.input= f.check_box :issues_enabled
.clearfix
= f.label :merge_requests_enabled, "Merge Requests"
.input= f.check_box :merge_requests_enabled
.clearfix
= f.label :wall_enabled, "Wall"
.input= f.check_box :wall_enabled
.clearfix
= f.label :description = f.label :description
%br .input= f.text_area :description, :class => "xxlarge"
= f.text_area :description
.clear .clear
%br %br
.actions .actions
= f.submit 'Save', :class => "grey-button" = f.submit 'Save', :class => "btn primary"
= link_to 'Cancel', [:admin, @admin_project], :class => "btn"
= link_to 'Destroy', [:admin, @admin_project], :confirm => 'Are you sure?', :method => :delete, :class => "btn danger right"
:javascript :javascript
$(function(){ $(function(){
taggifyForm(); taggifyForm();
$('#project_owner_id').chosen();
$('#project_default_branch').chosen();
}) })

View file

@ -1,7 +1,3 @@
%h2= @admin_project.name %h3= @admin_project.name
%hr
= render 'form' = render 'form'
%br
= link_to 'Back', admin_projects_path, :class => ""
|
= link_to 'Show', [:admin, @admin_project], :class => ""

View file

@ -1,7 +1,10 @@
%table %h3
Projects
= link_to 'New Project', new_admin_project_path, :class => "btn small right"
%hr
%table.zebra-striped
%thead %thead
%th Name %th Name
%th Code
%th Path %th Path
%th Team Members %th Team Members
%th Last Commit %th Last Commit
@ -11,12 +14,9 @@
- @admin_projects.each do |project| - @admin_projects.each do |project|
%tr %tr
%td= link_to project.name, [:admin, project] %td= link_to project.name, [:admin, project]
%td= project.code
%td= project.path %td= project.path
%td= project.users_projects.count %td= project.users_projects.count
%td= last_commit(project) %td= last_commit(project)
%td= link_to 'Edit', edit_admin_project_path(project), :id => "edit_#{dom_id(project)}" %td= link_to 'Edit', edit_admin_project_path(project), :id => "edit_#{dom_id(project)}", :class => "btn small"
%td= link_to 'Destroy', [:admin, project], :confirm => 'Are you sure?', :method => :delete %td= link_to 'Destroy', [:admin, project], :confirm => 'Are you sure?', :method => :delete, :class => "btn small danger"
= paginate @admin_projects = paginate @admin_projects
= link_to 'New Project', new_admin_project_path, :class => "grey-button"

View file

@ -1,10 +1,10 @@
- unless notice.nil? %h3
%p#notice= notice = @admin_project.name
= link_to 'Edit', edit_admin_project_path(@admin_project), :class => "btn right small"
%hr
%h2= @admin_project.name %table.zebra-striped
%table.round-borders
%tr %tr
%td %td
%b %b
@ -29,14 +29,32 @@
Description: Description:
%td %td
= @admin_project.description = @admin_project.description
%tr
%td{:colspan => 2}
= link_to 'Edit', edit_admin_project_path(@admin_project), :class => "grey-button"
.span-14 .span-14
%h2 Team %h3
Team
%small
( #{@admin_project.users_projects.count} )
%hr
%table.zebra-striped
%thead
%tr
%th Name
%th Project Access
%th Repository Access
%th
- @admin_project.users_projects.each do |tm|
%tr
%td
= link_to tm.user_name, admin_users_path(tm.user)
%td= select_tag :tm_project_access, options_for_select(Project.access_options, tm.project_access), :class => "medium project-access-select", :disabled => :disabled
%td= link_to 'Edit Access', edit_admin_team_member_path(tm), :class => "btn small"
%td= link_to 'Remove from team', admin_team_member_path(tm), :confirm => 'Are you sure?', :method => :delete, :class => "btn danger small"
= form_tag team_update_admin_project_path(@admin_project), :class => "bulk_import", :method => :put do = form_tag team_update_admin_project_path(@admin_project), :class => "bulk_import", :method => :put do
%table %table
@ -49,29 +67,9 @@
%tr %tr
%td= select_tag :user_ids, options_from_collection_for_select(@users , :id, :name), :multiple => true %td= select_tag :user_ids, options_from_collection_for_select(@users , :id, :name), :multiple => true
%td= select_tag :project_access, options_for_select(Project.access_options), :class => "project-access-select" %td= select_tag :project_access, options_for_select(Project.access_options), :class => "project-access-select"
%td= select_tag :repo_access, options_for_select(Repository.access_options), :class => "repo-access-select"
%tr .actions
%td{ :colspan => 3 } = submit_tag 'Add', :class => "btn primary"
= submit_tag 'Add', :class => "positive-button"
%table.round-borders
%thead
%tr
%th Name
%th Added
%th Project Access
%th Repository Access
%th
- @admin_project.users_projects.each do |tm|
%tr
%td
= link_to tm.user_name, admin_team_member_path(tm)
%td= time_ago_in_words(tm.updated_at) + " ago"
%td= select_tag :tm_project_access, options_for_select(Project.access_options, tm.project_access), :class => "project-access-select", :disabled => :disabled
%td= select_tag :tm_repo_access, options_for_select(Repository.access_options, tm.repo_access), :class => "repo-access-select", :disabled => :disabled
%td= link_to 'Destroy', admin_team_member_path(tm), :confirm => 'Are you sure?', :method => :delete
:css :css
form select { form select {

View file

@ -1,33 +1,19 @@
= form_for @admin_team_member, :as => :team_member, :url => @admin_team_member.new_record? ? admin_team_members_path(@admin_team_member) : admin_team_member_path(@admin_team_member) do |f| = form_for @admin_team_member, :as => :team_member, :url => admin_team_member_path(@admin_team_member) do |f|
-if @admin_team_member.errors.any? -if @admin_team_member.errors.any?
#error_explanation .alert-message.block-message.error
%h2= "#{pluralize(@admin_team_member.errors.count, "error")} prohibited this admin_project from being saved:"
%ul %ul
- @admin_team_member.errors.full_messages.each do |msg| - @admin_team_member.errors.full_messages.each do |msg|
%li= msg %li= msg
- if @admin_team_member.new_record? .clearfix
.span-6 %label Project Access:
= f.label :user_id .input
.span-6
= f.select :user_id, User.all.map { |user| [user.name, user.id] }
.span-6
= f.label :project_id
.span-6
= f.select :project_id, Project.all.map { |user| [user.name, user.id] }
.span-6
%b Project Access:
.span-6
= f.select :project_access, options_for_select(Project.access_options, @admin_team_member.project_access), {}, :class => "project-access-select" = f.select :project_access, options_for_select(Project.access_options, @admin_team_member.project_access), {}, :class => "project-access-select"
.span-6
%b Repository Access:
.span-6
= f.select :repo_access, options_for_select(Repository.access_options, @admin_team_member.repo_access), {}, :class => "repo-access-select"
%br %br
.actions .actions
= f.submit 'Save', :class => "grey-button" = f.submit 'Save', :class => "btn primary"
= link_to 'Cancel', :back, :class => "btn"
:css :css
form select { form select {

View file

@ -1,6 +1,19 @@
= render 'form' %h3
Edit access
%small
= @admin_team_member.project.name
&ndash;
= @admin_team_member.user_name
%br %hr
= link_to 'Show', admin_team_member_path(@admin_team_member) %table.zebra-striped
\| %tr
= link_to 'Back', admin_team_members_path %td User:
%td= @admin_team_member.user_name
%tr
%td Project:
%td= @admin_team_member.project.name
%tr
%td Since:
%td= @admin_team_member.updated_at.stamp("Nov 11, 2010")
= render 'form'

View file

@ -1,28 +0,0 @@
- @admin_team_members.group_by(&:project).sort.each do |project, members|
%h3= link_to project.name, [:admin, project]
%table
%thead
%th Name
%th Project Access
%th Repo Access
%th Added
%th
%th
- members.each do |tm|
- user = tm.user
%tr
%td.span-6
= link_to tm.user_name, admin_team_member_path(tm)
%br
%br
= tm.user_email
%td.span-3= select_tag :project_access, options_for_select(Project.access_options, tm.project_access), :class => "project-access-select", :disabled => :disabled
%td.span-3= select_tag :repo_access, options_for_select(Repository.access_options, tm.repo_access), :class => "repo-access-select", :disabled => :disabled
%td.span-3= time_ago_in_words(tm.updated_at) + " ago"
%td= link_to 'Edit', edit_admin_team_member_path(tm), :id => "edit_#{dom_id(tm)}"
%td= link_to 'Destroy', admin_team_member_path(tm), :confirm => 'Are you sure?', :method => :delete
%br
= paginate @admin_team_members
= link_to 'New Team Member', new_admin_team_member_path, :class => "grey-button"

View file

@ -1,6 +0,0 @@
%h1 New team member
= render 'form'
%br
= link_to 'Back', admin_team_members_path

View file

@ -1,26 +0,0 @@
#infoblock
%p
%b Name:
= @admin_team_member.user_name
%p
%b Project:
= @admin_team_member.project.name
%p
%b Since:
= @admin_team_member.updated_at.stamp("Nov 11, 2010")
#infoblock
.span-6
%b Project Access:
= select_tag :project_access, options_for_select(Project.access_options, @admin_team_member.project_access), :class => "project-access-select", :disabled => true
%br
.span-6
%b Repository Access:
= select_tag :repo_access, options_for_select(Repository.access_options, @admin_team_member.repo_access), :class => "repo-access-select", :disabled => true
%br
= link_to 'Edit', edit_admin_team_member_path(@admin_project)
\|
= link_to 'Back', admin_team_members_path

View file

@ -2,48 +2,43 @@
= form_for [:admin, @admin_user] do |f| = form_for [:admin, @admin_user] do |f|
-if @admin_user.errors.any? -if @admin_user.errors.any?
#error_explanation #error_explanation
%h2= "#{pluralize(@admin_user.errors.count, "error")} prohibited this admin_user from being saved:"
%ul %ul
- @admin_user.errors.full_messages.each do |msg| - @admin_user.errors.full_messages.each do |msg|
%li= msg %li= msg
.form-row .clearfix
= f.label :name = f.label :name
%br .input= f.text_field :name
= f.text_field :name .clearfix
.form-row
= f.label :email = f.label :email
%br .input= f.text_field :email
= f.text_field :email .clearfix
.form-row
= f.label :password = f.label :password
%br .input= f.password_field :password
= f.password_field :password .clearfix
.form-row
= f.label :password_confirmation = f.label :password_confirmation
%br .input= f.password_field :password_confirmation
= f.password_field :password_confirmation
.form-row
= f.check_box :admin
= f.label :admin
.form-row .clearfix
= f.text_field :projects_limit, :class => "small_input"
= f.label :projects_limit = f.label :projects_limit
.input= f.text_field :projects_limit, :class => "small_input"
.form-row .clearfix
= f.label :skype = f.label :skype
%br .input= f.text_field :skype
= f.text_field :skype .clearfix
.form-row
= f.label :linkedin = f.label :linkedin
%br .input= f.text_field :linkedin
= f.text_field :linkedin .clearfix
.form-row
= f.label :twitter = f.label :twitter
%br .input= f.text_field :twitter
= f.text_field :twitter .clearfix
.clear = f.label :admin do
%br = f.check_box :admin
%span Administrator
.actions .actions
= f.submit 'Save', :class => "grey-button" = f.submit 'Save', :class => "btn primary"
- if @admin_user.new_record?
= link_to 'Cancel', admin_users_path, :class => "btn"
- else
= link_to 'Cancel', admin_user_path(@admin_user), :class => "btn"

View file

@ -1,6 +1,3 @@
%h3= @admin_user.name
%hr
= render 'form' = render 'form'
%br
= link_to 'Back', admin_users_path, :class => ""
|
= link_to 'Show', [:admin, @admin_user], :class => ""

Some files were not shown because too many files have changed in this diff Show more