diff --git a/.gitignore b/.gitignore index 74111a22..c53bac48 100644 --- a/.gitignore +++ b/.gitignore @@ -9,5 +9,10 @@ coverage/* *.swp public/uploads/ .rvmrc +.rbenv-version .directory nohup.out +Vagrantfile +.vagrant +config/gitlab.yml +config/database.yml diff --git a/.rbenv-version b/.rbenv-version deleted file mode 100644 index 0a95b9f5..00000000 --- a/.rbenv-version +++ /dev/null @@ -1 +0,0 @@ -1.9.2-p290 diff --git a/.travis.yml b/.travis.yml index 7a450b7d..0193d007 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,6 +4,8 @@ branches: - 'master' rvm: 1.9.2 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:migrate RAILS_ENV=test" - "bundle exec rake db:seed_fu RAILS_ENV=test" diff --git a/Gemfile b/Gemfile index b80dca11..5c0b660d 100644 --- a/Gemfile +++ b/Gemfile @@ -1,10 +1,10 @@ source "http://rubygems.org" -gem "rails", "3.1.1" +gem "rails", "3.2.1" gem "sqlite3" -gem "rake", "0.9.2.2" -gem "devise", "1.5.0" +gem "rake" +gem "devise" gem "stamp" gem "kaminari" gem "haml", "3.1.4" @@ -16,7 +16,7 @@ gem "carrierwave" gem "six" gem "therubyracer" gem "faker" -gem "seed-fu", "~> 2.1.0" +gem "seed-fu" gem "pygments.rb", "0.2.4" gem "thin" gem "git" @@ -24,20 +24,23 @@ gem "acts_as_list" gem "rdiscount" gem "acts-as-taggable-on", "~> 2.1.0" gem "drapper" -gem "resque" +gem "resque", "~> 1.20.0" gem "httparty" gem "charlock_holmes" gem "foreman" +gem "omniauth-ldap" +gem 'bootstrap-sass', "1.4.4" +gem "colored" group :assets do - gem "sass-rails", "~> 3.1.0" - gem "coffee-rails", "~> 3.1.0" - gem "uglifier" + gem "sass-rails", "3.2.3" + gem "coffee-rails", "3.2.1" + gem "uglifier", "1.0.3" end group :development do gem "letter_opener" - gem "rails-footnotes", "~> 3.7.5" + gem "rails-footnotes" gem "annotate", :git => "https://github.com/ctran/annotate_models.git" end @@ -46,9 +49,7 @@ group :development, :test do gem "capybara" gem "autotest" gem "autotest-rails" - unless ENV["CI"] - gem "ruby-debug19", :require => "ruby-debug" - end + gem "pry" gem "awesome_print" gem "database_cleaner" gem "launchy" @@ -58,5 +59,5 @@ end group :test do gem "turn", :require => false gem "simplecov", :require => false - gem "shoulda", "~> 3.0.0.beta2" + gem "shoulda", "3.0.0" end diff --git a/Gemfile.lock b/Gemfile.lock index ec171d2c..09457d5b 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,6 +1,6 @@ GIT remote: https://github.com/ctran/annotate_models.git - revision: fb73329243056a6d9a64878e5c543aba9b6417de + revision: a43c08f0eb4d69a48c6830630ebb60e35ccb2d2d specs: annotate (2.4.1.beta1) @@ -25,48 +25,48 @@ GEM remote: http://rubygems.org/ specs: ZenTest (4.5.0) - actionmailer (3.1.1) - actionpack (= 3.1.1) - mail (~> 2.3.0) - actionpack (3.1.1) - activemodel (= 3.1.1) - activesupport (= 3.1.1) + actionmailer (3.2.1) + actionpack (= 3.2.1) + mail (~> 2.4.0) + actionpack (3.2.1) + activemodel (= 3.2.1) + activesupport (= 3.2.1) builder (~> 3.0.0) erubis (~> 2.7.0) - i18n (~> 0.6) - rack (~> 1.3.2) + journey (~> 1.0.1) + rack (~> 1.4.0) rack-cache (~> 1.1) - rack-mount (~> 0.8.2) rack-test (~> 0.6.1) - sprockets (~> 2.0.2) - activemodel (3.1.1) - activesupport (= 3.1.1) + sprockets (~> 2.1.2) + activemodel (3.2.1) + activesupport (= 3.2.1) builder (~> 3.0.0) - i18n (~> 0.6) - activerecord (3.1.1) - activemodel (= 3.1.1) - activesupport (= 3.1.1) - arel (~> 2.2.1) + activerecord (3.2.1) + activemodel (= 3.2.1) + activesupport (= 3.2.1) + arel (~> 3.0.0) tzinfo (~> 0.3.29) - activeresource (3.1.1) - activemodel (= 3.1.1) - activesupport (= 3.1.1) - activesupport (3.1.1) + activeresource (3.2.1) + activemodel (= 3.2.1) + activesupport (= 3.2.1) + activesupport (3.2.1) + i18n (~> 0.6) multi_json (~> 1.0) acts-as-taggable-on (2.1.1) rails acts_as_list (0.1.4) addressable (2.2.6) - ansi (1.4.1) - archive-tar-minitar (0.5.2) - arel (2.2.1) + ansi (1.4.2) + arel (3.0.0) autotest (4.4.6) ZenTest (>= 4.4.1) autotest-rails (4.1.1) ZenTest (= 4.5) - awesome_print (0.4.0) + awesome_print (1.0.2) bcrypt-ruby (3.0.1) blankslate (2.1.2.4) + bootstrap-sass (1.4.4) + sass-rails (~> 3.1) builder (3.0.0) capybara (1.1.2) mime-types (>= 1.16) @@ -78,19 +78,20 @@ GEM carrierwave (0.5.8) activesupport (~> 3.0) charlock_holmes (0.6.8) - childprocess (0.2.2) + childprocess (0.3.1) ffi (~> 1.0.6) - coffee-rails (3.1.1) + coderay (1.0.5) + coffee-rails (3.2.1) coffee-script (>= 2.2.0) - railties (~> 3.1.0) + railties (~> 3.2.0.beta) coffee-script (2.2.0) coffee-script-source execjs - coffee-script-source (1.1.3) - columnize (0.3.4) + coffee-script-source (1.2.0) + colored (1.2) crack (0.3.1) - daemons (1.1.4) - database_cleaner (0.7.0) + daemons (1.1.8) + database_cleaner (0.7.1) devise (1.5.0) bcrypt-ruby (~> 3.0) orm_adapter (~> 0.0.3) @@ -99,13 +100,13 @@ GEM drapper (0.8.4) erubis (2.7.0) eventmachine (0.12.10) - execjs (1.2.9) + execjs (1.3.0) multi_json (~> 1.0) faker (1.0.1) i18n (~> 0.4) ffi (1.0.11) - foreman (0.27.0) - term-ansicolor (~> 1.0.5) + foreman (0.39.0) + term-ansicolor (~> 1.0.7) thor (>= 0.13.6) git (1.2.5) haml (3.1.4) @@ -115,139 +116,143 @@ GEM haml (~> 3.0) railties (~> 3.0) hashery (1.4.0) + hashie (1.2.0) hike (1.2.1) httparty (0.8.1) multi_json multi_xml i18n (0.6.0) - jquery-rails (1.0.17) - railties (~> 3.0) + journey (1.0.1) + jquery-rails (2.0.0) + railties (>= 3.2.0.beta, < 5.0) thor (~> 0.14) - json (1.6.1) - json_pure (1.6.1) - kaminari (0.12.4) - rails (>= 3.0.0) + json (1.6.5) + kaminari (0.13.0) + actionpack (>= 3.0.0) + activesupport (>= 3.0.0) + railties (>= 3.0.0) launchy (2.0.5) addressable (~> 2.2.6) letter_opener (0.0.2) launchy libv8 (3.3.10.4) - linecache19 (0.5.12) - ruby_core_source (>= 0.1.4) - mail (2.3.0) + mail (2.4.1) i18n (>= 0.4.0) mime-types (~> 1.16) treetop (~> 1.4.8) + method_source (0.7.0) mime-types (1.17.2) - multi_json (1.0.3) + multi_json (1.0.4) multi_xml (0.4.1) + net-ldap (0.2.2) 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) 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) rubypython (~> 0.5.3) - rack (1.3.5) + pyu-ruby-sasl (0.0.3.3) + rack (1.4.1) rack-cache (1.1) rack (>= 0.4) - rack-mount (0.8.3) - rack (>= 1.0.0) - rack-protection (1.1.4) + rack-protection (1.2.0) rack rack-ssl (1.3.2) rack rack-test (0.6.1) rack (>= 1.0) - rails (3.1.1) - actionmailer (= 3.1.1) - actionpack (= 3.1.1) - activerecord (= 3.1.1) - activeresource (= 3.1.1) - activesupport (= 3.1.1) + rails (3.2.1) + actionmailer (= 3.2.1) + actionpack (= 3.2.1) + activerecord (= 3.2.1) + activeresource (= 3.2.1) + activesupport (= 3.2.1) bundler (~> 1.0) - railties (= 3.1.1) + railties (= 3.2.1) rails-footnotes (3.7.5) rails (>= 3.0.0) - railties (3.1.1) - actionpack (= 3.1.1) - activesupport (= 3.1.1) + railties (3.2.1) + actionpack (= 3.2.1) + activesupport (= 3.2.1) rack-ssl (~> 1.3.2) rake (>= 0.8.7) rdoc (~> 3.4) thor (~> 0.14.6) rake (0.9.2.2) rdiscount (1.6.8) - rdoc (3.11) + rdoc (3.12) json (~> 1.4) redis (2.2.2) redis-namespace (1.0.3) redis (< 3.0.0) - resque (1.19.0) + resque (1.20.0) multi_json (~> 1.0) redis-namespace (~> 1.0.2) sinatra (>= 0.9.2) vegas (~> 0.1.2) - rspec (2.7.0) - rspec-core (~> 2.7.0) - rspec-expectations (~> 2.7.0) - rspec-mocks (~> 2.7.0) - rspec-core (2.7.1) - rspec-expectations (2.7.0) + rspec (2.8.0) + rspec-core (~> 2.8.0) + rspec-expectations (~> 2.8.0) + rspec-mocks (~> 2.8.0) + rspec-core (2.8.0) + rspec-expectations (2.8.0) diff-lcs (~> 1.1.2) - rspec-mocks (2.7.0) - rspec-rails (2.7.0) - actionpack (~> 3.0) - activesupport (~> 3.0) - railties (~> 3.0) - rspec (~> 2.7.0) - ruby-debug-base19 (0.11.25) - 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) + rspec-mocks (2.8.0) + rspec-rails (2.8.1) + actionpack (>= 3.0) + activesupport (>= 3.0) + railties (>= 3.0) + rspec (~> 2.8.0) + rubyntlm (0.1.1) rubypython (0.5.3) blankslate (>= 2.1.2.3) ffi (~> 1.0.7) - rubyzip (0.9.4) - sass (3.1.10) - sass-rails (3.1.4) - actionpack (~> 3.1.0) - railties (~> 3.1.0) - sass (>= 3.1.4) - sprockets (~> 2.0.0) - tilt (~> 1.3.2) - seed-fu (2.1.0) - activerecord (~> 3.1.0) - activesupport (~> 3.1.0) - selenium-webdriver (2.12.2) - childprocess (>= 0.2.1) + rubyzip (0.9.6.1) + sass (3.1.15) + sass-rails (3.2.3) + railties (~> 3.2.0.beta) + sass (>= 3.1.10) + tilt (~> 1.3) + seed-fu (2.2.0) + activerecord (~> 3.1) + activesupport (~> 3.1) + selenium-webdriver (2.19.0) + childprocess (>= 0.2.5) ffi (~> 1.0.9) - json_pure + multi_json (~> 1.0.4) rubyzip - shoulda (3.0.0.beta2) - shoulda-context (~> 1.0.0.beta1) - shoulda-matchers (~> 1.0.0.beta1) + shoulda (3.0.0) + shoulda-context (~> 1.0.0) + shoulda-matchers (~> 1.0.0) shoulda-context (1.0.0) shoulda-matchers (1.0.0) simplecov (0.5.4) multi_json (~> 1.0.3) simplecov-html (~> 0.5.3) simplecov-html (0.5.3) - sinatra (1.3.1) - rack (~> 1.3, >= 1.3.4) - rack-protection (~> 1.1, >= 1.1.2) + sinatra (1.3.2) + rack (~> 1.3, >= 1.3.6) + rack-protection (~> 1.2) tilt (~> 1.3, >= 1.3.3) six (0.2.0) - sprockets (2.0.3) + slop (2.4.4) + sprockets (2.1.2) hike (~> 1.2) rack (~> 1.0) tilt (~> 1.1, != 1.3.0) - sqlite3 (1.3.4) + sqlite3 (1.3.5) stamp (0.1.6) term-ansicolor (1.0.7) therubyracer (0.9.9) @@ -261,17 +266,17 @@ GEM treetop (1.4.10) polyglot polyglot (>= 0.3.1) - turn (0.8.3) + turn (0.9.2) ansi tzinfo (0.3.31) - uglifier (1.1.0) + uglifier (1.0.3) execjs (>= 0.3.0) multi_json (>= 1.0.2) - vegas (0.1.8) + vegas (0.1.11) rack (>= 1.0.0) warden (1.1.0) rack (>= 1.0) - webmock (1.7.8) + webmock (1.7.10) addressable (~> 2.2, > 2.2.5) crack (>= 0.1.7) xpath (0.1.4) @@ -287,12 +292,14 @@ DEPENDENCIES autotest autotest-rails awesome_print + bootstrap-sass (= 1.4.4) capybara carrierwave charlock_holmes - coffee-rails (~> 3.1.0) + coffee-rails (= 3.2.1) + colored database_cleaner - devise (= 1.5.0) + devise drapper faker foreman @@ -306,17 +313,18 @@ DEPENDENCIES kaminari launchy letter_opener + omniauth-ldap + pry pygments.rb (= 0.2.4) - rails (= 3.1.1) - rails-footnotes (~> 3.7.5) - rake (= 0.9.2.2) + rails (= 3.2.1) + rails-footnotes + rake rdiscount - resque + resque (~> 1.20.0) rspec-rails - ruby-debug19 - sass-rails (~> 3.1.0) - seed-fu (~> 2.1.0) - shoulda (~> 3.0.0.beta2) + sass-rails (= 3.2.3) + seed-fu + shoulda (= 3.0.0) simplecov six sqlite3 @@ -324,5 +332,5 @@ DEPENDENCIES therubyracer thin turn - uglifier + uglifier (= 1.0.3) webmock diff --git a/Procfile.production b/Procfile.production index 68e8556e..f1126486 100644 --- a/Procfile.production +++ b/Procfile.production @@ -1,2 +1,2 @@ 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=* diff --git a/VERSION b/VERSION index 7ec1d6db..ccbccc3d 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.1.0 +2.2.0 diff --git a/app/assets/images/Gear-UI.PNG b/app/assets/images/Gear-UI.PNG deleted file mode 100644 index 7720f0eb..00000000 Binary files a/app/assets/images/Gear-UI.PNG and /dev/null differ diff --git a/app/assets/images/Home-UI.PNG b/app/assets/images/Home-UI.PNG deleted file mode 100644 index f739af3c..00000000 Binary files a/app/assets/images/Home-UI.PNG and /dev/null differ diff --git a/app/assets/images/Info-UI.PNG b/app/assets/images/Info-UI.PNG index 92795486..7f48ed8d 100644 Binary files a/app/assets/images/Info-UI.PNG and b/app/assets/images/Info-UI.PNG differ diff --git a/app/assets/images/admin.PNG b/app/assets/images/admin.PNG new file mode 100644 index 00000000..73ff1dfb Binary files /dev/null and b/app/assets/images/admin.PNG differ diff --git a/app/assets/images/blueprint_add.png b/app/assets/images/blueprint_add.png index e63641d0..0f01128d 100644 Binary files a/app/assets/images/blueprint_add.png and b/app/assets/images/blueprint_add.png differ diff --git a/app/assets/images/blueprint_delete.png b/app/assets/images/blueprint_delete.png index f171846b..b4d360f3 100644 Binary files a/app/assets/images/blueprint_delete.png and b/app/assets/images/blueprint_delete.png differ diff --git a/app/assets/images/comment_add.png b/app/assets/images/comment_add.png new file mode 100644 index 00000000..010da964 Binary files /dev/null and b/app/assets/images/comment_add.png differ diff --git a/app/assets/images/help_commit.png b/app/assets/images/help_commit.png deleted file mode 100644 index e0a49b71..00000000 Binary files a/app/assets/images/help_commit.png and /dev/null differ diff --git a/app/assets/images/help_merge_request.png b/app/assets/images/help_merge_request.png deleted file mode 100644 index a6b5d3df..00000000 Binary files a/app/assets/images/help_merge_request.png and /dev/null differ diff --git a/app/assets/images/home_icon.PNG b/app/assets/images/home_icon.PNG new file mode 100644 index 00000000..b1d60d59 Binary files /dev/null and b/app/assets/images/home_icon.PNG differ diff --git a/app/assets/images/logo_tr.png b/app/assets/images/logo_tr.png new file mode 100644 index 00000000..7a934bbb Binary files /dev/null and b/app/assets/images/logo_tr.png differ diff --git a/app/assets/images/submodule.png b/app/assets/images/submodule.png new file mode 100644 index 00000000..62a88cc6 Binary files /dev/null and b/app/assets/images/submodule.png differ diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js index 5782f0af..b3142feb 100644 --- a/app/assets/javascripts/application.js +++ b/app/assets/javascripts/application.js @@ -10,6 +10,8 @@ //= require jquery.ui.selectmenu //= require jquery.tagify //= require jquery.cookie +//= require jquery.endless-scroll +//= require bootstrap-modal //= require modernizr //= require chosen //= require raphael @@ -21,9 +23,6 @@ $(document).ready(function(){ $(this).select(); }); - $('select#branch').selectmenu({style:'popup', width:200}); - $('select#tag').selectmenu({style:'popup', width:200}); - $(".account-box").mouseenter(showMenu); $(".account-box").mouseleave(resetMenu); @@ -43,6 +42,9 @@ $(document).ready(function(){ } }); + /** + * Focus search field by pressing 's' key + */ $(document).keypress(function(e) { if( $(e.target).is(":input") ) return; switch(e.which) { @@ -50,27 +52,12 @@ $(document).ready(function(){ e.preventDefault(); } }); - }); function focusSearch() { $("#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){ $.ajax({type: "GET", url: location.href, data: data, dataType: "script"}); } @@ -82,5 +69,3 @@ function showMenu() { function resetMenu() { $(this).removeClass("hover"); } - - diff --git a/app/assets/javascripts/commits.js b/app/assets/javascripts/commits.js index bb06df55..b31fe485 100644 --- a/app/assets/javascripts/commits.js +++ b/app/assets/javascripts/commits.js @@ -2,6 +2,7 @@ var CommitsList = { ref:null, limit:0, offset:0, + disable:false, init: function(ref, limit) { @@ -36,15 +37,21 @@ var CommitsList = { $("#commits_list").append(html); if(count > 0) { this.offset += count; - this.initLoadMore(); + } else { + this.disable = true; } }, initLoadMore: function() { - $(window).bind('scroll', function(){ - if($(window).scrollTop() == $(document).height() - $(window).height()){ - $(window).unbind('scroll'); + $(document).endlessScroll({ + bottomPixels: 400, + fireDelay: 1000, + fireOnce:true, + ceaseFire: function() { + return CommitsList.disable; + }, + callback: function(i) { CommitsList.getOld(); } }); diff --git a/app/assets/javascripts/issues.js b/app/assets/javascripts/issues.js index ef70a99d..ded66b1c 100644 --- a/app/assets/javascripts/issues.js +++ b/app/assets/javascripts/issues.js @@ -1,16 +1,18 @@ function switchToNewIssue(form){ - $("#issues-table-holder").hide("slide", { direction: "left" }, 150, function(){ - $(".project-content").append(form); + $(".issues_content").hide("fade", { direction: "left" }, 150, function(){ + $(".issues_content").after(form); $('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){ - $("#issues-table-holder").hide("slide", { direction: "left" }, 150, function(){ - $(".project-content").append(form); + $(".issues_content").hide("fade", { direction: "left" }, 150, function(){ + $(".issues_content").after(form); $('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(){ - $("#edit_issue_dialog, #new_issue_dialog").hide("slide", { direction: "right" }, 150, function(){ - $("#issues-table-holder").show("slide", { direction: "left" }, 150, function() { + $("#edit_issue_dialog, #new_issue_dialog").hide("fade", { direction: "right" }, 150, function(){ + $(".issues_content").show("fade", { direction: "left" }, 150, function() { $("#edit_issue_dialog").remove(); $("#new_issue_dialog").remove(); + $('.add_new').show(); }); }); } diff --git a/app/assets/javascripts/merge_requests.js b/app/assets/javascripts/merge_requests.js index 0d2f5355..1c262afc 100644 --- a/app/assets/javascripts/merge_requests.js +++ b/app/assets/javascripts/merge_requests.js @@ -4,46 +4,27 @@ var MergeRequest = { init: function() { - $(".merge-tabs a").live("click", function() { - $(".merge-tabs a").removeClass("active"); - $(this).addClass("active"); + $(".tabs a").live("click", function() { + $(".tabs a").parent().removeClass("active"); + $(this).parent().addClass("active"); }); - $(".merge-tabs a.merge-notes-tab").live("click", function() { - $(".merge-request-commits, .merge-request-diffs").hide(); + $(".tabs a.merge-notes-tab").live("click", function(e) { + $(".merge-request-diffs").hide(); $(".merge-request-notes").show(); + e.preventDefault(); }); - $(".merge-tabs a.merge-commits-tab").live("click", function() { - 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() { + $(".tabs a.merge-diffs-tab").live("click", function(e) { if(!MergeRequest.diffs_loaded) { MergeRequest.loadDiff(); } - $(".merge-request-notes, .merge-request-commits").hide(); + $(".merge-request-notes").hide(); $(".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: function() { $(".dashboard-loader").show(); @@ -52,7 +33,7 @@ var MergeRequest = { url: $(".merge-diffs-tab").attr("data-url"), complete: function(){ MergeRequest.diffs_loaded = true; - $(".merge-request-notes, .merge-request-commits").hide(); + $(".merge-request-notes").hide(); $(".dashboard-loader").hide()}, dataType: "script"}); } diff --git a/app/assets/javascripts/note.js b/app/assets/javascripts/note.js index c791623b..41759671 100644 --- a/app/assets/javascripts/note.js +++ b/app/assets/javascripts/note.js @@ -1,49 +1,66 @@ var NoteList = { +notes_path: null, +target_params: null, +target_id: 0, +target_type: null, first_id: 0, last_id: 0, -resource_name: null, +disable:false, init: - function(resource_name, first_id, last_id) { - this.resource_name = resource_name; - this.first_id = first_id; - this.last_id = last_id; + function(tid, tt, path) { + this.notes_path = path + ".js"; + this.target_id = tid; + 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.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() { - $('.loading').show(); - $.ajax({ - 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(); + // init timer + var intNew = setInterval("NoteList.getNew()", 10000); }, replace: - function(fid, lid, html) { - this.first_id = fid; - this.last_id = lid; - $("#notes-list").html(html); - this.initLoadMore(); + function(html) { + $("#new_notes_list").html(html); }, prepend: function(id, html) { if(id != this.last_id) { - this.last_id = id; - $("#notes-list").prepend(html); + $("#new_notes_list").prepend(html); } }, @@ -52,8 +69,8 @@ getNew: // refersh notes list $.ajax({ type: "GET", - url: location.href, - data: "last_id=" + this.last_id, + url: this.notes_path, + data: "last_id=" + this.last_id + this.target_params, dataType: "script"}); }, @@ -62,25 +79,85 @@ refresh: // refersh notes list $.ajax({ type: "GET", - url: location.href, - data: "first_id=" + this.first_id + "&last_id=" + this.last_id, + url: this.notes_path, + data: "first_id=" + this.first_id + "&last_id=" + this.last_id + this.target_params, dataType: "script"}); }, -initRefresh: - function() { - // init timer - var intNew = setInterval("NoteList.getNew()", 15000); - var intRefresh = setInterval("NoteList.refresh()", 90000); + +/** + * Init load of notes: + * 1. Get content with ajax call + * 2. Set content of notes list with loaded one + */ + + +getContent: + function() { + $.ajax({ + type: "GET", + 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: function() { - $(window).bind('scroll', function(){ - if($(window).scrollTop() == $(document).height() - $(window).height()){ - $(window).unbind('scroll'); + $(document).endlessScroll({ + bottomPixels: 400, + fireDelay: 1000, + fireOnce:true, + ceaseFire: function() { + return NoteList.disable; + }, + callback: function(i) { NoteList.getOld(); } - }); + }); } } diff --git a/app/assets/javascripts/projects.js b/app/assets/javascripts/pager.js similarity index 60% rename from app/assets/javascripts/projects.js rename to app/assets/javascripts/pager.js index 90de73a1..d42ae1e0 100644 --- a/app/assets/javascripts/projects.js +++ b/app/assets/javascripts/pager.js @@ -1,12 +1,14 @@ -var ProjectsList = { +var Pager = { limit:0, offset:0, + disable:false, init: function(limit) { this.limit=limit; this.offset=limit; this.initLoadMore(); + $('.loading').show(); }, getOld: @@ -22,21 +24,27 @@ var ProjectsList = { append: function(count, html) { - $(".tile").append(html); + $(".content_list").append(html); if(count > 0) { this.offset += count; - this.initLoadMore(); + } else { + this.disable = true; } }, initLoadMore: function() { - $(window).bind('scroll', function(){ - if($(window).scrollTop() == $(document).height() - $(window).height()){ - $(window).unbind('scroll'); + $(document).endlessScroll({ + bottomPixels: 400, + fireDelay: 1000, + fireOnce:true, + ceaseFire: function() { + return Pager.disable; + }, + callback: function(i) { $('.loading').show(); - ProjectsList.getOld(); + Pager.getOld(); } - }); + }); } } diff --git a/app/assets/javascripts/team.js b/app/assets/javascripts/team.js index e079a9e4..f4b04354 100644 --- a/app/assets/javascripts/team.js +++ b/app/assets/javascripts/team.js @@ -1,7 +1,7 @@ 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_member_new").remove(); + $("#new_team_member").remove(); $(".add_new").show(); }); }); diff --git a/app/assets/javascripts/tree.js b/app/assets/javascripts/tree.js index 2e9bcc82..1c62751a 100644 --- a/app/assets/javascripts/tree.js +++ b/app/assets/javascripts/tree.js @@ -5,21 +5,24 @@ var Tree = { init: function() { - (new Image).src = "ajax-loader-facebook.gif"; - - $('#tree-slider td.tree-item-file-name a, #tree-breadcrumbs a').live("click", function() { - history.pushState({ path: this.path }, '', this.href) + $('#tree-slider .tree-item-file-name a, .breadcrumb li > a').live("click", function() { $("#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") { - link = $(this).find("td.tree-item-file-name a"); + link = $(this).find(".tree-item-file-name a"); 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:complete": function() { $('.tree_progress').removeClass("loading"); } }); diff --git a/app/assets/stylesheets/application.css b/app/assets/stylesheets/application.css index 5a1fb42f..3d809b56 100644 --- a/app/assets/stylesheets/application.css +++ b/app/assets/stylesheets/application.css @@ -7,5 +7,5 @@ *= require jquery-ui/jquery.tagify *= require chosen *= require_self - *= require common + *= require main */ diff --git a/app/assets/stylesheets/commits.css.scss b/app/assets/stylesheets/commits.css.scss deleted file mode 100644 index b1fa9c18..00000000 --- a/app/assets/stylesheets/commits.css.scss +++ /dev/null @@ -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; - } - } - } -} diff --git a/app/assets/stylesheets/common.scss b/app/assets/stylesheets/common.scss index 4c6544a4..5670f1e0 100644 --- a/app/assets/stylesheets/common.scss +++ b/app/assets/stylesheets/common.scss @@ -1,55 +1,53 @@ -$text_color:#222; -$lite_text_color: #666; -$link_color:#111; -$active_link_color:#2FA0BB; -$active_bg_color:#79C3E0; -$active_bd_color: #2FA0BB; -$border_color:#CCC; -$lite_border_color:#EEE; -$app_width:980px; -$app_padding:20px; -$bg_color: #FFF; -$styled_border_color: #2FA0BB; +a { + color: $link_color; + &:hover { + text-decoration:none; + color: $style_color; + } -/** MIXINS **/ -@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; + &.btn { + color: $style_color; + } } -@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; +.vlink { + color: $link_color !important; } -@mixin round-borders-all($radius) { - border: 1px solid #eaeaea; - -moz-border-radius: $radius; - -webkit-border-radius: $radius; - border-radius: $radius; +.pills a:hover { + background-color:#ccc; +} + +.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 **/ .cgray { color:gray; } .cred { color:#D12F19; } .cgreen { color:#44aa22; } +.cblack { color:#111; } +.cwhite { color:#fff !important } /** COMMON STYLES **/ .left { float:left; } .right { - float:right; + float:right !important; } .width-50p{ width:50%; @@ -78,38 +76,559 @@ $styled_border_color: #2FA0BB; .no-borders { border:none; } +table.no-borders { + border:none; + tr, td { border:none } +} .no-padding { padding:0 !important; } +.underlined { + border-bottom: 1px solid $border_color; +} -/* General */ +/** LAYOUT **/ -body.collapsed { - background-color: $bg_color; +.container { + width:$min_app_width; + padding-top:0; + z-index:5; +} - #container{ - margin: auto; - margin-top:51px; - width: $app_width; - border-top: 0; - background-color: $bg_color; +.container .content { + margin:0 $app_padding; +} + +.container .sidebar { + 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 { - color: $link_color; +.wll { + 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"; -@import "projects.css.scss"; -@import "commits.css.scss"; -@import "notes.css.scss"; -@import "merge_requests.css.scss"; -@import "highlight.css.scss"; -@import "highlight.black.css.scss"; -@import "issues.css.scss"; -@import "commits.css.scss"; +.visible_link, +.author_link { + color: $link_color; +} +.entry { + position: relative; + padding: 7px 15px; + margin-bottom: 18px; + color: #404040; + filter:none; -@import "top_panel.scss"; -@import "dashboard.scss"; -@import "tree.scss"; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); + + -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; + } +} diff --git a/app/assets/stylesheets/dashboard.scss b/app/assets/stylesheets/dashboard.scss deleted file mode 100644 index 5e38fcc6..00000000 --- a/app/assets/stylesheets/dashboard.scss +++ /dev/null @@ -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 */ - diff --git a/app/assets/stylesheets/highlight.black.css.scss b/app/assets/stylesheets/highlight.black.scss similarity index 99% rename from app/assets/stylesheets/highlight.black.css.scss rename to app/assets/stylesheets/highlight.black.scss index e094e48f..e63e08c8 100644 --- a/app/assets/stylesheets/highlight.black.css.scss +++ b/app/assets/stylesheets/highlight.black.scss @@ -1,5 +1,6 @@ .black .highlighttable { background: #333; + td.linenos { border:none; } pre { color: #eee } .highlight { background: #333; border-left:1px solid #555; } diff --git a/app/assets/stylesheets/highlight.css.scss b/app/assets/stylesheets/highlight.scss similarity index 92% rename from app/assets/stylesheets/highlight.css.scss rename to app/assets/stylesheets/highlight.scss index d65865ec..0dbfc0ed 100644 --- a/app/assets/stylesheets/highlight.css.scss +++ b/app/assets/stylesheets/highlight.scss @@ -10,13 +10,15 @@ table.highlighttable margin:0px; padding:0px; font-size:12px; - table-layout:fixed + table-layout:fixed; + background: #F7F7F7; } td.code, td.linenos{ padding:0; margin:0; + border-top:0; vertical-align:top; } @@ -24,8 +26,16 @@ td.linenos{ background:none; padding:10px 0px 0px 10px; margin-left:0px; + border-left: 1px solid #DEE2E3; + background: white; } + +.linenodiv pre, .highlight pre{ + margin:0; + padding:0; + background:none; + border:none; } .linenodiv pre { @@ -48,7 +58,7 @@ td.code .highlight { table.highlighttable pre{ padding:0; margin:0; - font-family: 'Courier New', 'andale mono','lucida console',monospace; + font-family: 'Menlo', 'Courier New', 'andale mono','lucida console',monospace; color: #333; text-align:left; } @@ -62,7 +72,7 @@ table.highlighttable pre{ padding:0; line-height:2.0; margin:0; - font-family: 'Courier New', 'andale mono','lucida console',monospace; + font-family: 'Menlo', 'Courier New', 'andale mono','lucida console',monospace; color: #333; text-align:left;} } diff --git a/app/assets/stylesheets/issues.css.scss b/app/assets/stylesheets/issues.css.scss deleted file mode 100644 index d2341edc..00000000 --- a/app/assets/stylesheets/issues.css.scss +++ /dev/null @@ -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; - } - } - -} diff --git a/app/assets/stylesheets/login.scss b/app/assets/stylesheets/login.scss new file mode 100644 index 00000000..3bba7062 --- /dev/null +++ b/app/assets/stylesheets/login.scss @@ -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} + diff --git a/app/assets/stylesheets/main.scss b/app/assets/stylesheets/main.scss new file mode 100644 index 00000000..58818809 --- /dev/null +++ b/app/assets/stylesheets/main.scss @@ -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"; diff --git a/app/assets/stylesheets/merge_requests.css.scss b/app/assets/stylesheets/merge_requests.css.scss deleted file mode 100644 index 2b60605b..00000000 --- a/app/assets/stylesheets/merge_requests.css.scss +++ /dev/null @@ -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; - } -} diff --git a/app/assets/stylesheets/notes.css.scss b/app/assets/stylesheets/notes.css.scss deleted file mode 100644 index 4aba53cf..00000000 --- a/app/assets/stylesheets/notes.css.scss +++ /dev/null @@ -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; -} diff --git a/app/assets/stylesheets/notes.scss b/app/assets/stylesheets/notes.scss new file mode 100644 index 00000000..1f05d13b --- /dev/null +++ b/app/assets/stylesheets/notes.scss @@ -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); +} diff --git a/app/assets/stylesheets/projects.css.scss b/app/assets/stylesheets/projects.css.scss deleted file mode 100644 index c9bba0c1..00000000 --- a/app/assets/stylesheets/projects.css.scss +++ /dev/null @@ -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; -} diff --git a/app/assets/stylesheets/projects.css.scss~ b/app/assets/stylesheets/projects.css.scss~ new file mode 100644 index 00000000..4bdf5dee --- /dev/null +++ b/app/assets/stylesheets/projects.css.scss~ @@ -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; +} diff --git a/app/assets/stylesheets/ref_select.scss b/app/assets/stylesheets/ref_select.scss new file mode 100644 index 00000000..ff0ffa9f --- /dev/null +++ b/app/assets/stylesheets/ref_select.scss @@ -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; + } + } +} + diff --git a/app/assets/stylesheets/style.scss b/app/assets/stylesheets/style.scss deleted file mode 100644 index 4bb5fef9..00000000 --- a/app/assets/stylesheets/style.scss +++ /dev/null @@ -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; - } - } -} diff --git a/app/assets/stylesheets/tags.css.css b/app/assets/stylesheets/tags.css.css deleted file mode 100644 index 829d2c78..00000000 --- a/app/assets/stylesheets/tags.css.css +++ /dev/null @@ -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; -} diff --git a/app/assets/stylesheets/top_panel.scss b/app/assets/stylesheets/top_panel.scss deleted file mode 100644 index 57c1e077..00000000 --- a/app/assets/stylesheets/top_panel.scss +++ /dev/null @@ -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; -} diff --git a/app/assets/stylesheets/tree.scss b/app/assets/stylesheets/tree.scss index 57070871..59299254 100644 --- a/app/assets/stylesheets/tree.scss +++ b/app/assets/stylesheets/tree.scss @@ -1,121 +1,178 @@ -#tree-breadcrumbs { - div { - margin:0; - margin-bottom:20px; +#tree-holder { + #tree-content-holder { float:left; - font-size:14px; + width:100%; } -} - -.tree_progress { - float:left; - width:16px; - height:16px; - margin:2px 6px; - &.loading { - background-position: 0px 0px; - background: url("ajax-loader-facebook.gif") no-repeat; - } -} - - -/** FILE CONTENT VIEW **/ -.view_file_content{ - .old_line, .new_line { - background:#ECECEC; - color:#777; - width:15px; + #tree-readme-holder { float:left; - padding: 0px 10px; - border-right: 1px solid #ccc; + width:100%; + .readme { + @include round-borders-all(4px); + padding:4px 15px; + background: #F7F7F7; + } } - .old_line{ + + .tree_progress { display:none; + margin:20px; + &.loading { + display:block; + } } -} -.view_file .view_file_header, -.diff_file .diff_file_header { - 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); + + /** FILE CONTENT VIEW **/ + .view_file_content{ + .old_line, .new_line { + background:#ECECEC; + color:#777; + width:15px; + float:left; + padding: 0px 10px; + border-right: 1px solid #ccc; + } + .old_line{ + display:none; + } + } + + .view_file .view_file_header, + .diff_file .diff_file_header { + background:#f5f5f5; margin: 0; font-weight: normal; font-weight: bold; text-align: left; color: #666; - border-bottom: 1px solid #DEE2E3; + border-bottom: 1px solid #ccc; padding: 7px 10px; .mode_text, .file_icon { - margin-right:15px; - padding-right:15px; - border-right:1px solid $lite_border_color; - float:left; color:#aaa; } - - .file_icon { - padding-left:15px; - } -} - -.view_file { - border:1px solid #CCC; - margin-bottom:1em; - - .view_file_content { - background:#fff; - color:#514721; - font-size: 11px; } - .view_file_content_image { - background:#eee; - text-align:center; - img { - padding:100px; - max-width:300px; + + .view_file { + border:1px solid #CCC; + margin-bottom:1em; + + .view_file_content { + background:#fff; + color:#514721; + font-size: 11px; + } + .view_file_content_image { + background:#eee; + text-align:center; + img { + padding:100px; + max-width:300px; + } } } -} -td.code { - width: 100%; - .highlight { - margin-left: 55px; - overflow:auto; - overflow-y:hidden; - border-left: 1px solid #DEE2E3; - background: white; - } -} -.highlight pre { - white-space: pre; - word-wrap:normal; -} - -table.highlighttable { - border: none; - background: #F7F7F7; -} -body.project-page table.highlighttable td { border: none } -table.highlighttable tr:hover { background:none;} - -table.highlighttable pre{ - line-height:16px !important; - font-size:12px !important; -} - -table.highlighttable .linenodiv pre { - text-align: right; - padding-right: 4px; - color:#888; -} - -.tree-item { - &:hover { - background: #FFFFCF; + td.code { + width: 100%; + .highlight { + margin-left: 55px; + overflow:auto; + overflow-y:hidden; + } + } + .highlight pre { + white-space: pre; + word-wrap:normal; + } + + table.highlighttable { + border: none; + } + body.project-page table.highlighttable td { border: none } + table.highlighttable tr:hover { background:none;} + + table.highlighttable pre{ + line-height:16px !important; + font-size:12px !important; + } + + table.highlighttable .linenodiv pre { + text-align: right; + padding-right: 4px; + color:#888; + } + + .tree-item { + &:hover { + 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; } } diff --git a/app/assets/stylesheets/ui_basic.scss b/app/assets/stylesheets/ui_basic.scss new file mode 100644 index 00000000..b01e4d16 --- /dev/null +++ b/app/assets/stylesheets/ui_basic.scss @@ -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 + * + */ +} diff --git a/app/assets/stylesheets/ui_mars.scss b/app/assets/stylesheets/ui_mars.scss new file mode 100644 index 00000000..b2230f5b --- /dev/null +++ b/app/assets/stylesheets/ui_mars.scss @@ -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 + * + */ +} diff --git a/app/controllers/admin/projects_controller.rb b/app/controllers/admin/projects_controller.rb index 813e135b..868bec7c 100644 --- a/app/controllers/admin/projects_controller.rb +++ b/app/controllers/admin/projects_controller.rb @@ -52,6 +52,12 @@ class Admin::ProjectsController < ApplicationController def update @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]) redirect_to [:admin, @admin_project], notice: 'Project was successfully updated.' else diff --git a/app/controllers/admin/team_members_controller.rb b/app/controllers/admin/team_members_controller.rb index d04d32a6..57803b01 100644 --- a/app/controllers/admin/team_members_controller.rb +++ b/app/controllers/admin/team_members_controller.rb @@ -3,39 +3,15 @@ class Admin::TeamMembersController < ApplicationController before_filter :authenticate_user! 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 @admin_team_member = UsersProject.find(params[:id]) 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 @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]) - 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 render action: "edit" end @@ -45,6 +21,6 @@ class Admin::TeamMembersController < ApplicationController @admin_team_member = UsersProject.find(params[:id]) @admin_team_member.destroy - redirect_to admin_team_members_url + redirect_to :back end end diff --git a/app/controllers/admin/users_controller.rb b/app/controllers/admin/users_controller.rb index 85a95de5..21643145 100644 --- a/app/controllers/admin/users_controller.rb +++ b/app/controllers/admin/users_controller.rb @@ -9,8 +9,28 @@ class Admin::UsersController < ApplicationController def show @admin_user = User.find(params[:id]) + + @projects = if @admin_user.projects.empty? + Project + else + Project.without_user(@admin_user) + end.all 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 @admin_user = User.new(:projects_limit => 10) end diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 00ab93a1..ff00208c 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -5,7 +5,11 @@ class ApplicationController < ActionController::Base helper_method :abilities, :can? 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 layout :layout_by_resource @@ -33,7 +37,8 @@ class ApplicationController < ActionController::Base end def project - @project ||= Project.find_by_code(params[:project_id]) + @project ||= current_user.projects.find_by_code(params[:project_id]) + @project || render_404 end def add_project_abilities @@ -45,11 +50,23 @@ class ApplicationController < ActionController::Base end 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 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 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? 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 response.headers["Cache-Control"] = "no-cache, no-store, max-age=0, must-revalidate" response.headers["Pragma"] = "no-cache" response.headers["Expires"] = "Fri, 01 Jan 1990 00:00:00 GMT" end + + def render_full_content + @full_content = true + end end diff --git a/app/controllers/commits_controller.rb b/app/controllers/commits_controller.rb index a938461f..0d36957c 100644 --- a/app/controllers/commits_controller.rb +++ b/app/controllers/commits_controller.rb @@ -7,12 +7,14 @@ class CommitsController < ApplicationController # Authorize before_filter :add_project_abilities before_filter :authorize_read_project! + before_filter :authorize_code_access! before_filter :require_non_empty_project before_filter :load_refs, :only => :index # load @branch, @tag & @ref + before_filter :render_full_content def index @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) respond_to do |format| @@ -24,14 +26,31 @@ class CommitsController < ApplicationController def show @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) - + @comments_allowed = true @line_notes = project.commit_line_notes(@commit) + end - respond_to do |format| - format.html - format.js { respond_with_notes } + def compare + first = project.commit(params[:to]) + 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 diff --git a/app/controllers/dashboard_controller.rb b/app/controllers/dashboard_controller.rb index 6a8fd1c3..fe9604ec 100644 --- a/app/controllers/dashboard_controller.rb +++ b/app/controllers/dashboard_controller.rb @@ -3,7 +3,16 @@ class DashboardController < ApplicationController def index @projects = current_user.projects.all + @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 # Get authored or assigned open merge requests diff --git a/app/controllers/errors_controller.rb b/app/controllers/errors_controller.rb index 3ef7aa46..9f60c645 100644 --- a/app/controllers/errors_controller.rb +++ b/app/controllers/errors_controller.rb @@ -1,5 +1,7 @@ class ErrorsController < ApplicationController + layout "error" + def githost - render :file => File.join(Rails.root, "public", "githost_error"), :layout => false + render "errors/gitolite" end end diff --git a/app/controllers/issues_controller.rb b/app/controllers/issues_controller.rb index 7c10d2a8..4e3be259 100644 --- a/app/controllers/issues_controller.rb +++ b/app/controllers/issues_controller.rb @@ -1,6 +1,7 @@ class IssuesController < ApplicationController before_filter :authenticate_user! before_filter :project + before_filter :module_enabled before_filter :issue, :only => [:edit, :update, :destroy, :show] layout "project" @@ -48,7 +49,6 @@ class IssuesController < ApplicationController end def show - @notes = @issue.notes.inc_author.order("created_at DESC").limit(20) @note = @project.notes.new(:noteable => @issue) @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| format.html - format.js { respond_with_notes } + format.js end end @@ -69,7 +69,10 @@ class IssuesController < ApplicationController @issue.author = current_user @issue.save - respond_with(@issue) + respond_to do |format| + format.html { redirect_to project_issue_path(@project, @issue) } + format.js + end end def update @@ -125,11 +128,14 @@ class IssuesController < ApplicationController end def authorize_modify_issue! - can?(current_user, :modify_issue, @issue) || - @issue.assignee == current_user + return render_404 unless can?(current_user, :modify_issue, @issue) end 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 diff --git a/app/controllers/keys_controller.rb b/app/controllers/keys_controller.rb index 33c6958d..ce49e3e7 100644 --- a/app/controllers/keys_controller.rb +++ b/app/controllers/keys_controller.rb @@ -1,6 +1,6 @@ class KeysController < ApplicationController layout "profile" - respond_to :js + respond_to :js, :html def index @keys = current_user.keys.all diff --git a/app/controllers/merge_requests_controller.rb b/app/controllers/merge_requests_controller.rb index 3456a0a7..cfb9e6dc 100644 --- a/app/controllers/merge_requests_controller.rb +++ b/app/controllers/merge_requests_controller.rb @@ -1,6 +1,7 @@ class MergeRequestsController < ApplicationController before_filter :authenticate_user! before_filter :project + before_filter :module_enabled before_filter :merge_request, :only => [:edit, :update, :destroy, :show, :commits, :diffs] layout "project" @@ -23,7 +24,9 @@ class MergeRequestsController < ApplicationController @merge_requests = @project.merge_requests @merge_requests = case params[:f].to_i + when 1 then @merge_requests when 2 then @merge_requests.closed + when 2 then @merge_requests.opened.assigned(current_user) else @merge_requests.opened end @@ -33,26 +36,31 @@ class MergeRequestsController < ApplicationController def show unless @project.repo.heads.map(&:name).include?(@merge_request.target_branch) && @project.repo.heads.map(&:name).include?(@merge_request.source_branch) - head(404)and return + git_not_found! and return end - @notes = @merge_request.notes.inc_author.order("created_at DESC").limit(20) @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| format.html - format.js { respond_with_notes } + format.js 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 @diffs = @merge_request.diffs @commit = @merge_request.last_commit - @line_notes = [] + + @comments_allowed = true + @line_notes = @merge_request.notes.where("line_code is not null") end def new @@ -105,11 +113,14 @@ class MergeRequestsController < ApplicationController end def authorize_modify_merge_request! - can?(current_user, :modify_merge_request, @merge_request) || - @merge_request.assignee == current_user + return render_404 unless can?(current_user, :modify_merge_request, @merge_request) end 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 diff --git a/app/controllers/notes_controller.rb b/app/controllers/notes_controller.rb index 19c85717..a2638d95 100644 --- a/app/controllers/notes_controller.rb +++ b/app/controllers/notes_controller.rb @@ -9,6 +9,11 @@ class NotesController < ApplicationController respond_to :js + def index + notes + respond_with(@notes) + end + def create @note = @project.notes.new(params[:note]) @note.author = current_user @@ -24,9 +29,7 @@ class NotesController < ApplicationController def destroy @note = @project.notes.find(params[:id]) - return access_denied! unless can?(current_user, :admin_note, @note) - @note.destroy respond_to do |format| @@ -34,4 +37,28 @@ class NotesController < ApplicationController 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 diff --git a/app/controllers/omniauth_callbacks_controller.rb b/app/controllers/omniauth_callbacks_controller.rb new file mode 100644 index 00000000..629b6819 --- /dev/null +++ b/app/controllers/omniauth_callbacks_controller.rb @@ -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 diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb index 6bd72a86..26eabe5f 100644 --- a/app/controllers/projects_controller.rb +++ b/app/controllers/projects_controller.rb @@ -28,7 +28,7 @@ class ProjectsController < ApplicationController Project.transaction do @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 # project repository should be updated after first user add @@ -57,7 +57,7 @@ class ProjectsController < ApplicationController def update respond_to do |format| 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 else format.html { render action: "edit" } @@ -68,33 +68,29 @@ class ProjectsController < ApplicationController def show return render "projects/empty" unless @project.repo_exists? && @project.has_commits? - limit = (params[:limit] || 20).to_i - @activities = @project.activities(limit)#updates_wo_repo(limit) + limit = (params[:limit] || 10).to_i + @activities = @project.activities(limit) end def files @notes = @project.notes.where("attachment != 'NULL'").order("created_at DESC").limit(100) end - def info - end - # # Wall # def wall + return render_404 unless @project.wall_enabled @note = Note.new - @notes = @project.common_notes.order("created_at DESC") - @notes = @notes.fresh.limit(20) respond_to do |format| format.html - format.js { respond_with_notes } end end def graph + render_full_content @days_json, @commits_json = GraphCommit.to_graph(project) end @@ -114,6 +110,7 @@ class ProjectsController < ApplicationController def project @project ||= Project.find_by_code(params[:id]) + @project || render_404 end def determine_layout diff --git a/app/controllers/protected_branches_controller.rb b/app/controllers/protected_branches_controller.rb new file mode 100644 index 00000000..0b86f525 --- /dev/null +++ b/app/controllers/protected_branches_controller.rb @@ -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 diff --git a/app/controllers/refs_controller.rb b/app/controllers/refs_controller.rb index d2be5ad5..b8ab1bce 100644 --- a/app/controllers/refs_controller.rb +++ b/app/controllers/refs_controller.rb @@ -4,20 +4,32 @@ class RefsController < ApplicationController # Authorize before_filter :add_project_abilities before_filter :authorize_read_project! + before_filter :authorize_code_access! before_filter :require_non_empty_project before_filter :ref before_filter :define_tree_vars, :only => [:tree, :blob] + before_filter :render_full_content + layout "project" def switch - new_path = if params[:destination] == "tree" - tree_project_ref_path(@project, params[:ref]) - else - project_commits_path(@project, :ref => params[:ref]) - end + respond_to do |format| + format.html do + new_path = if params[:destination] == "tree" + tree_project_ref_path(@project, params[:ref]) + else + project_commits_path(@project, :ref => params[:ref]) + end - redirect_to new_path + redirect_to new_path + end + format.js do + @ref = params[:ref] + define_tree_vars + render "tree" + end + end end # @@ -37,7 +49,12 @@ class RefsController < ApplicationController def 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 head(404) end @@ -48,6 +65,8 @@ class RefsController < ApplicationController protected def define_tree_vars + params[:path] = nil if params[:path].blank? + @repo = project.repo @commit = project.commit(@ref) @tree = Tree.new(@commit.tree, project, @ref, params[:path]) diff --git a/app/controllers/repositories_controller.rb b/app/controllers/repositories_controller.rb index 1e715931..036eb371 100644 --- a/app/controllers/repositories_controller.rb +++ b/app/controllers/repositories_controller.rb @@ -4,7 +4,9 @@ class RepositoriesController < ApplicationController # Authorize before_filter :add_project_abilities before_filter :authorize_read_project! + before_filter :authorize_code_access! before_filter :require_non_empty_project + before_filter :render_full_content layout "project" @@ -19,4 +21,28 @@ class RepositoriesController < ApplicationController def tags @tags = @project.repo.tags.sort_by(&:name).reverse 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 diff --git a/app/controllers/snippets_controller.rb b/app/controllers/snippets_controller.rb index 45b3f529..bfcfda0f 100644 --- a/app/controllers/snippets_controller.rb +++ b/app/controllers/snippets_controller.rb @@ -1,6 +1,7 @@ class SnippetsController < ApplicationController before_filter :authenticate_user! before_filter :project + before_filter :snippet, :only => [:show, :edit, :destroy, :update] layout "project" # Authorize @@ -41,11 +42,9 @@ class SnippetsController < ApplicationController end def edit - @snippet = @project.snippets.find(params[:id]) end def update - @snippet = @project.snippets.find(params[:id]) @snippet.update_attributes(params[:snippet]) if @snippet.valid? @@ -56,14 +55,11 @@ class SnippetsController < ApplicationController end def show - @snippet = @project.snippets.find(params[:id]) - @notes = @snippet.notes @note = @project.notes.new(:noteable => @snippet) + render_full_content end def destroy - @snippet = @project.snippets.find(params[:id]) - return access_denied! unless can?(current_user, :admin_snippet, @snippet) @snippet.destroy @@ -72,12 +68,15 @@ class SnippetsController < ApplicationController end protected + def snippet + @snippet ||= @project.snippets.find(params[:id]) + end def authorize_modify_snippet! - can?(current_user, :modify_snippet, @snippet) + return render_404 unless can?(current_user, :modify_snippet, @snippet) end def authorize_admin_snippet! - can?(current_user, :admin_snippet, @snippet) + return render_404 unless can?(current_user, :admin_snippet, @snippet) end end diff --git a/app/controllers/tags_controller.rb b/app/controllers/tags_controller.rb deleted file mode 100644 index 938beb64..00000000 --- a/app/controllers/tags_controller.rb +++ /dev/null @@ -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 diff --git a/app/controllers/team_members_controller.rb b/app/controllers/team_members_controller.rb index c05602f9..ab51c19e 100644 --- a/app/controllers/team_members_controller.rb +++ b/app/controllers/team_members_controller.rb @@ -40,7 +40,7 @@ class TeamMembersController < ApplicationController @team_member.destroy respond_to do |format| - format.html { redirect_to root_path } + format.html { redirect_to team_project_path(@project) } format.js { render :nothing => true } end end diff --git a/app/controllers/wikis_controller.rb b/app/controllers/wikis_controller.rb new file mode 100644 index 00000000..9bcd20c3 --- /dev/null +++ b/app/controllers/wikis_controller.rb @@ -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 diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 9f0f1e68..12fe333a 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -3,7 +3,8 @@ module ApplicationHelper def gravatar_icon(user_email, size = 40) 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 def fixed_mode? @@ -52,6 +53,13 @@ module ApplicationHelper [ "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) end @@ -71,11 +79,11 @@ module ApplicationHelper if @project && !@project.new_record? project_nav = [ - { :label => "#{@project.code} / Issues", :url => project_issues_path(@project) }, - { :label => "#{@project.code} / Wall", :url => wall_project_path(@project) }, - { :label => "#{@project.code} / Tree", :url => tree_project_ref_path(@project, @project.root_ref) }, - { :label => "#{@project.code} / Commits", :url => project_commits_path(@project) }, - { :label => "#{@project.code} / Team", :url => team_project_path(@project) } + { :label => "#{@project.name} / Issues", :url => project_issues_path(@project) }, + { :label => "#{@project.name} / Wall", :url => wall_project_path(@project) }, + { :label => "#{@project.name} / Tree", :url => tree_project_ref_path(@project, @project.root_ref) }, + { :label => "#{@project.name} / Commits", :url => project_commits_path(@project) }, + { :label => "#{@project.name} / Team", :url => team_project_path(@project) } ] end @@ -83,14 +91,26 @@ module ApplicationHelper end def project_layout - @project && !@project.new_record? + layout == "project" + end + + def admin_layout + layout == "admin" end def profile_layout - controller.controller_name == "dashboard" || current_page?(projects_path) || controller.controller_name == "profile" || controller.controller_name == "keys" + layout == "profile" end def help_layout controller.controller_name == "help" end + + def ldap_enable? + Devise.omniauth_providers.include?(:ldap) + end + + def layout + controller.send :_layout + end end diff --git a/app/helpers/commits_helper.rb b/app/helpers/commits_helper.rb index 4607e9da..d097c271 100644 --- a/app/helpers/commits_helper.rb +++ b/app/helpers/commits_helper.rb @@ -7,16 +7,6 @@ module CommitsHelper end - def diff_line_class(line) - if line[0] == "+" - "new" - elsif line[0] == "-" - "old" - else - nil - end - end - def more_commits_link offset = params[:offset] || 0 limit = params[:limit] || 100 @@ -42,11 +32,58 @@ module CommitsHelper preserve out end - def build_line_code(line, index, line_new, line_old) - if diff_line_class(line) == "new" - "NEW_#{index}_#{line_new}" + def diff_line_class(line) + if line[0] == "+" + "new" + elsif line[0] == "-" + "old" 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 diff --git a/app/helpers/dashboard_helper.rb b/app/helpers/dashboard_helper.rb index 5cf10278..55ed901c 100644 --- a/app/helpers/dashboard_helper.rb +++ b/app/helpers/dashboard_helper.rb @@ -3,6 +3,7 @@ module DashboardHelper case object.class.name.to_s 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 "MergeRequest" then project_merge_request_path(project, object.id) when "Note" then note = object @@ -26,6 +27,7 @@ module DashboardHelper when "Note" then markdown(object.note) when "Issue" then object.title when "Commit" then object.safe_message + when "MergeRequest" then object.title else return "Project Wall" end diff --git a/app/helpers/issues_helper.rb b/app/helpers/issues_helper.rb index d09fad5f..d902be0e 100644 --- a/app/helpers/issues_helper.rb +++ b/app/helpers/issues_helper.rb @@ -9,4 +9,26 @@ module IssuesHelper params[:f] ||= cookies['issue_filter'] project_issues_path project, params 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 diff --git a/app/helpers/merge_requests_helper.rb b/app/helpers/merge_requests_helper.rb index fac9870f..afdf65bd 100644 --- a/app/helpers/merge_requests_helper.rb +++ b/app/helpers/merge_requests_helper.rb @@ -1,2 +1,23 @@ 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 diff --git a/app/helpers/projects_helper.rb b/app/helpers/projects_helper.rb index 817ab475..16e3d9d0 100644 --- a/app/helpers/projects_helper.rb +++ b/app/helpers/projects_helper.rb @@ -17,11 +17,13 @@ module ProjectsHelper end 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) end if controller.controller_name == "snippets" || + controller.controller_name == "hooks" || + controller.controller_name == "deploy_keys" || controller.controller_name == "team_members" "current" end @@ -33,9 +35,26 @@ module ProjectsHelper end def repository_tab_class - if controller.controller_name == "repositories" || - controller.controller_name == "hooks" - "current" + #if controller.controller_name == "repositories" || + #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" + 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 diff --git a/app/helpers/wikis_helper.rb b/app/helpers/wikis_helper.rb new file mode 100644 index 00000000..0c24f57a --- /dev/null +++ b/app/helpers/wikis_helper.rb @@ -0,0 +1,5 @@ +module WikisHelper + def markdown_to_html(text) + RDiscount.new(text).to_html.html_safe + end +end diff --git a/app/mailers/notify.rb b/app/mailers/notify.rb index 6f408125..50ccb991 100644 --- a/app/mailers/notify.rb +++ b/app/mailers/notify.rb @@ -27,8 +27,7 @@ class Notify < ActionMailer::Base @user = user @note = note @project = note.project - @commit = @project.repo.commits(note.noteable_id).first - return unless ( note.notify or ( note.notify_author and @commit.author.email == @user.email ) ) + @commit = @note.target mail(:to => @user.email, :subject => "gitlab | note for commit | #{@note.project.name} ") end diff --git a/app/models/ability.rb b/app/models/ability.rb index a02f44a4..e97b662b 100644 --- a/app/models/ability.rb +++ b/app/models/ability.rb @@ -5,6 +5,7 @@ class Ability when "Issue" then issue_abilities(object, subject) when "Note" then note_abilities(object, subject) when "Snippet" then snippet_abilities(object, subject) + when "MergeRequest" then merge_request_abilities(object, subject) else [] end end @@ -14,31 +15,40 @@ class Ability rules << [ :read_project, + :read_wiki, :read_issue, :read_snippet, :read_team_member, :read_merge_request, - :read_note - ] if project.allow_read_for?(user) - - rules << [ + :read_note, :write_project, :write_issue, - :write_snippet, - :write_merge_request, :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 << [ :modify_issue, :modify_snippet, + :modify_merge_request, :admin_project, :admin_issue, :admin_snippet, :admin_team_member, :admin_merge_request, - :admin_note - ] if project.allow_admin_for?(user) + :admin_note, + :admin_wiki + ] if project.master_access_for?(user) || project.owner == user + rules.flatten end @@ -53,6 +63,12 @@ class Ability :"modify_#{name}", :"admin_#{name}" ] + elsif subject.respond_to?(:assignee) && subject.assignee == user + [ + :"read_#{name}", + :"write_#{name}", + :"modify_#{name}", + ] else subject.respond_to?(:project) ? project_abilities(user, subject.project) : [] diff --git a/app/models/activity_observer.rb b/app/models/activity_observer.rb new file mode 100644 index 00000000..46564161 --- /dev/null +++ b/app/models/activity_observer.rb @@ -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 diff --git a/app/models/commit.rb b/app/models/commit.rb index 695dfa52..a59e8803 100644 --- a/app/models/commit.rb +++ b/app/models/commit.rb @@ -1,14 +1,18 @@ class Commit + include ActiveModel::Conversion + extend ActiveModel::Naming attr_accessor :commit attr_accessor :head attr_accessor :refs delegate :message, + :authored_date, :committed_date, :parents, :sha, :date, + :committer, :author, :message, :diffs, @@ -16,6 +20,10 @@ class Commit :id, :to => :commit + def persisted? + false + end + def initialize(raw_commit, head = nil) @commit = raw_commit @head = head @@ -34,10 +42,22 @@ class Commit end def author_name - author.name + author.name.force_encoding("UTF-8") + end + + def committer_name + committer.name + end + + def committer_email + committer.email end def prev_commit parents.first end + + def prev_commit_id + prev_commit.id + end end diff --git a/app/models/event.rb b/app/models/event.rb new file mode 100644 index 00000000..e1732f00 --- /dev/null +++ b/app/models/event.rb @@ -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 +# + diff --git a/app/models/key.rb b/app/models/key.rb index fb59d759..4114e526 100644 --- a/app/models/key.rb +++ b/app/models/key.rb @@ -14,6 +14,7 @@ class Key < ActiveRecord::Base before_save :set_identifier after_save :update_repository after_destroy :repository_delete_key + delegate :name, :email, :to => :user, :prefix => true def set_identifier if is_deploy_key diff --git a/app/models/mailer_observer.rb b/app/models/mailer_observer.rb index 2bf383e5..f84cbdea 100644 --- a/app/models/mailer_observer.rb +++ b/app/models/mailer_observer.rb @@ -27,20 +27,25 @@ class MailerObserver < ActiveRecord::Observer end def new_note(note) - return unless note.notify or note.notify_author - note.project.users.reject { |u| u.id == current_user.id } .each do |u| - case note.noteable_type - when "Commit" then - Notify.note_commit_email(u, note).deliver - when "Issue" then - Notify.note_issue_email(u, note).deliver - when "MergeRequest" then - Notify.note_merge_request_email(u, note).deliver - when "Snippet" - true - else - Notify.note_wall_email(u, note).deliver + # Notify whole team except author of note + if note.notify + note.project.users.reject { |u| u.id == current_user.id } .each do |u| + case note.noteable_type + when "Commit" then + Notify.note_commit_email(u, note).deliver + when "Issue" then + Notify.note_issue_email(u, note).deliver + when "MergeRequest" then + Notify.note_merge_request_email(u, note).deliver + when "Snippet" + true + else + Notify.note_wall_email(u, note).deliver + end end + # Notify only author of resource + elsif note.notify_author + Notify.note_commit_email(note.commit_author, note).deliver end end diff --git a/app/models/note.rb b/app/models/note.rb index f499b62d..581f7833 100644 --- a/app/models/note.rb +++ b/app/models/note.rb @@ -58,21 +58,34 @@ class Note < ActiveRecord::Base nil end - def line_file_id - @line_file_id ||= line_code.split("_")[1].to_i if line_code + # Check if we can notify commit author + # 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 - def line_type_id - @line_type_id ||= line_code.split("_").first if line_code + def commit? + noteable_type == "Commit" end - def line_number - @line_number ||= line_code.split("_").last.to_i if line_code - end - - def for_line?(file_id, old_line, new_line) - line_file_id == file_id && - ((line_type_id == "NEW" && line_number == new_line) || (line_type_id == "OLD" && line_number == old_line )) + def commit_author + @commit_author ||= + project.users.find_by_email(target.author_email) || + project.users.find_by_name(target.author_name) + rescue + nil end end # == Schema Information diff --git a/app/models/project.rb b/app/models/project.rb index e1c66c95..c9b6f73b 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -1,13 +1,9 @@ require "grit" class Project < ActiveRecord::Base - PROJECT_N = 0 - PROJECT_R = 1 - PROJECT_RW = 2 - PROJECT_RWA = 3 - belongs_to :owner, :class_name => "User" + has_many :events, :dependent => :destroy has_many :merge_requests, :dependent => :destroy has_many :issues, :dependent => :destroy, :order => "position" has_many :users_projects, :dependent => :destroy @@ -16,6 +12,8 @@ class Project < ActiveRecord::Base has_many :snippets, :dependent => :destroy has_many :deploy_keys, :dependent => :destroy, :foreign_key => "project_id", :class_name => "Key" has_many :web_hooks, :dependent => :destroy + has_many :protected_branches, :dependent => :destroy + has_many :wikis, :dependent => :destroy acts_as_taggable @@ -53,18 +51,14 @@ class Project < ActiveRecord::Base attr_protected :private_flag, :owner_id 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 joins(:issues, :notes, :merge_requests).order("issues.created_at, notes.created_at, merge_requests.created_at DESC") end def self.access_options - { - "Denied" => PROJECT_N, - "Read" => PROJECT_R, - "Report" => PROJECT_RW, - "Admin" => PROJECT_RWA - } + UsersProject.access_roles end def repository @@ -96,21 +90,35 @@ class Project < ActiveRecord::Base [GIT_HOST['host'], code].join("/") 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('/') # Return if this is not a push to a branch (e.g. new commits) 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) } 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 = { before: oldrev, after: newrev, ref: ref, + user_id: key.user.id, + user_name: key.user_name, repository: { name: name, url: web_url, @@ -137,6 +145,15 @@ class Project < ActiveRecord::Base data 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) user = users.where("email like ? or name like ?", email, name).first 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 def add_access(user, *access) access = if access.include?(:admin) - { :project_access => PROJECT_RWA } + { :project_access => UsersProject::MASTER } elsif access.include?(:write) - { :project_access => PROJECT_RW } + { :project_access => UsersProject::DEVELOPER } else - { :project_access => PROJECT_R } + { :project_access => UsersProject::REPORTER } end opts = { :user => user } opts.merge!(access) @@ -199,38 +216,52 @@ class Project < ActiveRecord::Base def repository_readers 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) end def repository_writers 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) end 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 def writers - @writers ||= users_projects.includes(:user).where(:project_access => [PROJECT_RW, PROJECT_RWA]).map(&:user) + @writers ||= users_projects.includes(:user).map(&:user) end 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 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 - def allow_write_for?(user) - !users_projects.where(:user_id => user.id, :project_access => [PROJECT_RW, PROJECT_RWA]).empty? + def guest_access_for?(user) + !users_projects.where(:user_id => user.id).empty? end - def allow_admin_for?(user) - !users_projects.where(:user_id => user.id, :project_access => [PROJECT_RWA]).empty? || owner_id == user.id + def report_access_for?(user) + !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 def root_ref @@ -335,15 +366,19 @@ end # # Table name: projects # -# id :integer not null, primary key -# name :string(255) -# path :string(255) -# description :text -# created_at :datetime -# updated_at :datetime -# private_flag :boolean default(TRUE), not null -# code :string(255) -# owner_id :integer -# default_branch :string(255) default("master"), not null +# id :integer not null, primary key +# name :string(255) +# path :string(255) +# description :text +# created_at :datetime +# updated_at :datetime +# private_flag :boolean default(TRUE), not null +# code :string(255) +# owner_id :integer +# 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 # diff --git a/app/models/protected_branch.rb b/app/models/protected_branch.rb new file mode 100644 index 00000000..9c2d391d --- /dev/null +++ b/app/models/protected_branch.rb @@ -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 +# + diff --git a/app/models/repository.rb b/app/models/repository.rb index f4fdfe54..1e78e588 100644 --- a/app/models/repository.rb +++ b/app/models/repository.rb @@ -1,10 +1,6 @@ require File.join(Rails.root, "lib", "gitlabhq", "git_host") class Repository - REPO_N = 0 - REPO_R = 1 - REPO_RW = 2 - attr_accessor :project def self.default_ref @@ -12,11 +8,7 @@ class Repository end def self.access_options - { - "Denied" => REPO_N, - "Pull" => REPO_R, - "Pull & Push" => REPO_RW - } + {} end def initialize(project) @@ -56,7 +48,7 @@ class Repository end def path_to_repo - GIT_HOST["base_path"] + path + ".git" + File.join(GIT_HOST["base_path"], "#{path}.git") end def update_repository diff --git a/app/models/user.rb b/app/models/user.rb index a13a6f77..942f3337 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -2,7 +2,7 @@ class User < ActiveRecord::Base # Include default devise modules. Others available are: # :token_authenticatable, :encryptable, :confirmable, :lockable, :timeoutable and :omniauthable devise :database_authenticatable, :token_authenticatable, - :recoverable, :rememberable, :trackable, :validatable + :recoverable, :rememberable, :trackable, :validatable, :omniauthable # Setup accessible (or protected) attributes for your model attr_accessible :email, :password, :password_confirmation, :remember_me, @@ -62,6 +62,30 @@ class User < ActiveRecord::Base def last_activity_project projects.first 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 # == Schema Information # diff --git a/app/models/users_project.rb b/app/models/users_project.rb index b98aa1fd..726a85ae 100644 --- a/app/models/users_project.rb +++ b/app/models/users_project.rb @@ -1,4 +1,9 @@ class UsersProject < ActiveRecord::Base + GUEST = 10 + REPORTER = 20 + DEVELOPER = 30 + MASTER = 40 + belongs_to :user belongs_to :project @@ -17,7 +22,6 @@ class UsersProject < ActiveRecord::Base UsersProject.transaction do user_ids.each do |user_id| users_project = UsersProject.new( - :repo_access => repo_access, :project_access => project_access, :user_id => user_id ) @@ -27,11 +31,45 @@ class UsersProject < ActiveRecord::Base 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 Gitlabhq::GitHost.system.new.configure do |c| c.update_project(project.path, project) end end + + def project_access_human + Project.access_options.key(self.project_access) + end + + def repo_access_human + "" + end end # == Schema Information # @@ -42,7 +80,6 @@ end # project_id :integer not null # created_at :datetime # updated_at :datetime -# repo_access :integer default(0), not null # project_access :integer default(0), not null # diff --git a/app/models/wiki.rb b/app/models/wiki.rb new file mode 100644 index 00000000..ad3e4a38 --- /dev/null +++ b/app/models/wiki.rb @@ -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 +# + diff --git a/app/views/admin/projects/_form.html.haml b/app/views/admin/projects/_form.html.haml index ea42ed22..4f6bc692 100644 --- a/app/views/admin/projects/_form.html.haml +++ b/app/views/admin/projects/_form.html.haml @@ -1,39 +1,66 @@ = form_for [:admin, @admin_project] do |f| -if @admin_project.errors.any? - #error_explanation - %h2= "#{pluralize(@admin_project.errors.count, "error")} prohibited this admin_project from being saved:" + .alert-message.block-message.error %ul - @admin_project.errors.full_messages.each do |msg| %li= msg - .form-row + .clearfix = f.label :name - %br - = f.text_field :name - .form-row - = f.label :code - %br - = f.text_field :code - .form-row - = f.label :path - %br - = f.text_field :path + .input= f.text_field :name + .clearfix + = f.label :path do + Path + .input + .input-prepend + %span.add-on= "git@#{GIT_HOST["host"]}:" + = f.text_field :path, :placeholder => "example_project", :disabled => !@admin_project.new_record? + .clearfix + = f.label :code do + Code + .input + .input-prepend + %span.add-on= "http://#{GIT_HOST["host"]}/" + = f.text_field :code, :placeholder => "example" - .form-row - = f.label :tag_list - %br - = f.text_area :tag_list, :placeholder => "project tags", :style => "height:50px", :id => :tag_field + - unless @admin_project.new_record? + .clearfix + = f.label :owner_id + .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 - %br - = f.text_area :description + .input= f.text_area :description, :class => "xxlarge" .clear %br .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 $(function(){ taggifyForm(); + $('#project_owner_id').chosen(); + $('#project_default_branch').chosen(); }) diff --git a/app/views/admin/projects/edit.html.haml b/app/views/admin/projects/edit.html.haml index a6062be4..b8d6f689 100644 --- a/app/views/admin/projects/edit.html.haml +++ b/app/views/admin/projects/edit.html.haml @@ -1,7 +1,3 @@ -%h2= @admin_project.name +%h3= @admin_project.name +%hr = render 'form' - -%br -= link_to 'Back', admin_projects_path, :class => "" -| -= link_to 'Show', [:admin, @admin_project], :class => "" diff --git a/app/views/admin/projects/index.html.haml b/app/views/admin/projects/index.html.haml index f57b98d0..7cda5220 100644 --- a/app/views/admin/projects/index.html.haml +++ b/app/views/admin/projects/index.html.haml @@ -1,7 +1,10 @@ -%table +%h3 + Projects + = link_to 'New Project', new_admin_project_path, :class => "btn small right" +%hr +%table.zebra-striped %thead %th Name - %th Code %th Path %th Team Members %th Last Commit @@ -11,12 +14,9 @@ - @admin_projects.each do |project| %tr %td= link_to project.name, [:admin, project] - %td= project.code %td= project.path %td= project.users_projects.count %td= last_commit(project) - %td= link_to 'Edit', edit_admin_project_path(project), :id => "edit_#{dom_id(project)}" - %td= link_to 'Destroy', [:admin, project], :confirm => 'Are you sure?', :method => :delete - + %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, :class => "btn small danger" = paginate @admin_projects -= link_to 'New Project', new_admin_project_path, :class => "grey-button" diff --git a/app/views/admin/projects/show.html.haml b/app/views/admin/projects/show.html.haml index cc83add6..5142dac5 100644 --- a/app/views/admin/projects/show.html.haml +++ b/app/views/admin/projects/show.html.haml @@ -1,10 +1,10 @@ -- unless notice.nil? - %p#notice= notice +%h3 + = @admin_project.name + = link_to 'Edit', edit_admin_project_path(@admin_project), :class => "btn right small" +%hr -%h2= @admin_project.name - -%table.round-borders +%table.zebra-striped %tr %td %b @@ -29,14 +29,32 @@ Description: %td = @admin_project.description - %tr - %td{:colspan => 2} - = link_to 'Edit', edit_admin_project_path(@admin_project), :class => "grey-button" .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 %table @@ -49,29 +67,9 @@ %tr %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 :repo_access, options_for_select(Repository.access_options), :class => "repo-access-select" - %tr - %td{ :colspan => 3 } - = 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 + .actions + = submit_tag 'Add', :class => "btn primary" :css form select { diff --git a/app/views/admin/team_members/_form.html.haml b/app/views/admin/team_members/_form.html.haml index f8e7f104..0bf9020f 100644 --- a/app/views/admin/team_members/_form.html.haml +++ b/app/views/admin/team_members/_form.html.haml @@ -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? - #error_explanation - %h2= "#{pluralize(@admin_team_member.errors.count, "error")} prohibited this admin_project from being saved:" + .alert-message.block-message.error %ul - @admin_team_member.errors.full_messages.each do |msg| %li= msg - - if @admin_team_member.new_record? - .span-6 - = f.label :user_id - .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] } + .clearfix + %label Project Access: + .input + = f.select :project_access, options_for_select(Project.access_options, @admin_team_member.project_access), {}, :class => "project-access-select" - .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" - - .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 .actions - = f.submit 'Save', :class => "grey-button" + = f.submit 'Save', :class => "btn primary" + = link_to 'Cancel', :back, :class => "btn" :css form select { diff --git a/app/views/admin/team_members/edit.html.haml b/app/views/admin/team_members/edit.html.haml index 2f4832b8..431387be 100644 --- a/app/views/admin/team_members/edit.html.haml +++ b/app/views/admin/team_members/edit.html.haml @@ -1,6 +1,19 @@ -= render 'form' +%h3 + Edit access + %small + = @admin_team_member.project.name + – + = @admin_team_member.user_name -%br -= link_to 'Show', admin_team_member_path(@admin_team_member) -\| -= link_to 'Back', admin_team_members_path +%hr +%table.zebra-striped + %tr + %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' diff --git a/app/views/admin/team_members/index.html.haml b/app/views/admin/team_members/index.html.haml deleted file mode 100644 index 8033e690..00000000 --- a/app/views/admin/team_members/index.html.haml +++ /dev/null @@ -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" diff --git a/app/views/admin/team_members/new.html.haml b/app/views/admin/team_members/new.html.haml deleted file mode 100644 index c08ddc48..00000000 --- a/app/views/admin/team_members/new.html.haml +++ /dev/null @@ -1,6 +0,0 @@ -%h1 New team member - -= render 'form' - -%br -= link_to 'Back', admin_team_members_path diff --git a/app/views/admin/team_members/show.html.haml b/app/views/admin/team_members/show.html.haml deleted file mode 100644 index 8579b6af..00000000 --- a/app/views/admin/team_members/show.html.haml +++ /dev/null @@ -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 diff --git a/app/views/admin/users/_form.html.haml b/app/views/admin/users/_form.html.haml index e6953322..bb54c184 100644 --- a/app/views/admin/users/_form.html.haml +++ b/app/views/admin/users/_form.html.haml @@ -2,48 +2,43 @@ = form_for [:admin, @admin_user] do |f| -if @admin_user.errors.any? #error_explanation - %h2= "#{pluralize(@admin_user.errors.count, "error")} prohibited this admin_user from being saved:" %ul - @admin_user.errors.full_messages.each do |msg| %li= msg - .form-row + .clearfix = f.label :name - %br - = f.text_field :name - .form-row + .input= f.text_field :name + .clearfix = f.label :email - %br - = f.text_field :email - .form-row + .input= f.text_field :email + .clearfix = f.label :password - %br - = f.password_field :password - .form-row + .input= f.password_field :password + .clearfix = f.label :password_confirmation - %br - = f.password_field :password_confirmation - .form-row - = f.check_box :admin - = f.label :admin + .input= f.password_field :password_confirmation - .form-row - = f.text_field :projects_limit, :class => "small_input" + .clearfix = f.label :projects_limit + .input= f.text_field :projects_limit, :class => "small_input" - .form-row + .clearfix = f.label :skype - %br - = f.text_field :skype - .form-row + .input= f.text_field :skype + .clearfix = f.label :linkedin - %br - = f.text_field :linkedin - .form-row + .input= f.text_field :linkedin + .clearfix = f.label :twitter - %br - = f.text_field :twitter - .clear - %br + .input= f.text_field :twitter + .clearfix + = f.label :admin do + = f.check_box :admin + %span Administrator .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" diff --git a/app/views/admin/users/edit.html.haml b/app/views/admin/users/edit.html.haml index 2ccd2f72..0e94be9e 100644 --- a/app/views/admin/users/edit.html.haml +++ b/app/views/admin/users/edit.html.haml @@ -1,6 +1,3 @@ +%h3= @admin_user.name +%hr = render 'form' - -%br -= link_to 'Back', admin_users_path, :class => "" -| -= link_to 'Show', [:admin, @admin_user], :class => "" diff --git a/app/views/admin/users/index.html.haml b/app/views/admin/users/index.html.haml index db58a6b4..a0b4df1f 100644 --- a/app/views/admin/users/index.html.haml +++ b/app/views/admin/users/index.html.haml @@ -1,4 +1,8 @@ -%table +%h3 + Users + = link_to 'New User', new_admin_user_path, :class => "btn small right" +%hr +%table.zebra-striped %thead %th Admin %th Name @@ -13,9 +17,7 @@ %td= link_to user.name, [:admin, user] %td= user.email %td= user.users_projects.count - %td= link_to 'Edit', edit_admin_user_path(user), :id => "edit_#{dom_id(user)}" - %td= link_to 'Destroy', [:admin, user], :confirm => 'Are you sure?', :method => :delete + %td= link_to 'Edit', edit_admin_user_path(user), :id => "edit_#{dom_id(user)}", :class => "btn small" + %td= link_to 'Destroy', [:admin, user], :confirm => 'Are you sure?', :method => :delete, :class => "btn small danger" = paginate @admin_users -%br -= link_to 'New User', new_admin_user_path, :class => "grey-button" diff --git a/app/views/admin/users/new.html.haml b/app/views/admin/users/new.html.haml index 87ea570b..87d6b0f2 100644 --- a/app/views/admin/users/new.html.haml +++ b/app/views/admin/users/new.html.haml @@ -1,6 +1,3 @@ -%h1 New user - +%h2 New user +%hr = render 'form' - -%br -= link_to 'Back', admin_users_path, :class => "" diff --git a/app/views/admin/users/show.html.haml b/app/views/admin/users/show.html.haml index da8f4370..21529ab6 100644 --- a/app/views/admin/users/show.html.haml +++ b/app/views/admin/users/show.html.haml @@ -1,6 +1,10 @@ -%h2= @admin_user.name +%h3 + = @admin_user.name + = link_to 'Edit', edit_admin_user_path(@admin_user), :class => "btn small right" -%table.round-borders +%hr + +%table.zebra-striped %tr %td %b @@ -39,31 +43,55 @@ Twitter: %td = @admin_user.twitter + +%h3 Projects +%hr + +%table.zebra-striped %tr - %td{:colspan => 2} - = link_to 'Edit', edit_admin_user_path(@admin_user), :class => "grey-button" + %thead + %th Name + %th Project Access + %th Repository Access + %th + %th -.span-14 - %h2 Projects - - %table.round-borders + - @admin_user.users_projects.each do |tm| + - project = tm.project %tr - %thead - %th Name - %th Added - %th Project Access - %th Repository Access - %th - %th + %td= link_to project.name, admin_project_path(project) + %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 small danger" - - @admin_user.users_projects.each do |tm| - - project = tm.project += form_tag team_update_admin_user_path(@admin_user), :class => "bulk_import", :method => :put do + %table + %thead %tr - %td= link_to project.name, admin_project_path(project) - %td= time_ago_in_words(tm.updated_at) + " ago" - %td= select_tag :project_access, options_for_select(Project.access_options, tm.project_access), :class => "project-access-select", :disabled => :disabled - %td= select_tag :repo_access, options_for_select(Repository.access_options, tm.repo_access), :class => "repo-access-select", :disabled => :disabled - %td= link_to 'Edit', edit_admin_team_member_path(tm) - %td= link_to 'Cancel', admin_team_member_path(tm), :confirm => 'Are you sure?', :method => :delete + %th Projects + %th Project Access: + %th Repo Access: + + %tr + %td= select_tag :project_ids, options_from_collection_for_select(@projects , :id, :name), :multiple => true + %td= select_tag :project_access, options_for_select(Project.access_options), :class => "project-access-select" + + .actions + = submit_tag 'Add', :class => "btn primary" + + +:css + form select { + width:150px; + } + + #project_ids { + width:300px; + } + + +:javascript + $('select#project_ids').chosen(); + $('select#repo_access').chosen(); + $('select#project_access').chosen(); - = link_to 'Add To Another Project', new_admin_team_member_path(:team_member => {:user_id => @admin_user.id}), :class => "grey-button" diff --git a/app/views/commits/_commit.html.haml b/app/views/commits/_commit.html.haml new file mode 100644 index 00000000..a579cca9 --- /dev/null +++ b/app/views/commits/_commit.html.haml @@ -0,0 +1,17 @@ +%li.wll.commit + .right.span2 + %p + %strong= link_to "Browse Code »", tree_project_ref_path(@project, commit.id), :class => "right" + = link_to project_commit_path(@project, :id => commit.id) do + %p + %code.left= commit.id.to_s[0..10] + %strong.cgray= commit.author_name + – + = image_tag gravatar_icon(commit.author_email), :class => "avatar", :width => 16 + %span.row_title= truncate(commit.safe_message, :length => 50) rescue "--broken encoding" + + %span.right.cgray + = time_ago_in_words(commit.committed_date) + ago + + diff --git a/app/views/commits/_commits.html.haml b/app/views/commits/_commits.html.haml index 108d1b4c..c2c9ca62 100644 --- a/app/views/commits/_commits.html.haml +++ b/app/views/commits/_commits.html.haml @@ -1,24 +1,4 @@ - @commits.group_by { |c| c.committed_date.to_date }.each do |day, commits| - %div{ :class => "commits-date ui-box ui-box-small ui-box-big" } - .day-commits-table - %h3= day.stamp("28 Aug, 2010") - .data - - commits.each do |commit| - %a{ :class => "commit", :href => project_commit_path(@project, :id => commit.id) } - %span.commit-info - %data.commit-button - = truncate(commit.id.to_s, :length => 16) - %i - %data.commit-browse{ :onclick => "location.href='#{tree_project_ref_path(@project, commit.id)}';return false;"} - Browse Code - - if commit.author_email - = image_tag gravatar_icon(commit.author_email), :class => "left", :width => 40, :style => "padding-right:5px;" - - else - = image_tag "no_avatar.png", :class => "left", :width => 40, :style => "padding-right:5px;" - %span.commit-title - %strong - = truncate(commit.safe_message, :length => 70) - %span.commit-author - %strong= commit.author_name - = time_ago_in_words(commit.committed_date) - ago + %div.ui-box + %h5= day.stamp("28 Aug, 2010") + %ul.unstyled= render commits diff --git a/app/views/commits/_diff_head.html.haml b/app/views/commits/_diff_head.html.haml index 6e32fca0..20ec3cf1 100644 --- a/app/views/commits/_diff_head.html.haml +++ b/app/views/commits/_diff_head.html.haml @@ -1,5 +1,5 @@ %ul.bordered-list - - @commit.diffs.each do |diff| + - diffs.each do |diff| %li - if diff.deleted_file %span.removed_file diff --git a/app/views/commits/_diff.html.haml b/app/views/commits/_diffs.html.haml similarity index 68% rename from app/views/commits/_diff.html.haml rename to app/views/commits/_diffs.html.haml index 190c95dd..29eae1c4 100644 --- a/app/views/commits/_diff.html.haml +++ b/app/views/commits/_diffs.html.haml @@ -1,24 +1,26 @@ .file_stats - = render "commits/diff_head" - -- @commit.diffs.each_with_index do |diff, i| + = render "commits/diff_head", :diffs => diffs + +- diffs.each_with_index do |diff, i| - next if diff.diff.empty? - file = (@commit.tree / diff.b_path) + - file = (@commit.prev_commit.tree / diff.a_path) unless file - next unless file .diff_file .diff_file_header - if diff.deleted_file - %strong{:id => "#{diff.b_path}"}= diff.a_path + %strong{:id => "#{diff.a_path}"}= diff.a_path - else = link_to tree_file_project_ref_path(@project, @commit.id, diff.b_path) do %strong{:id => "#{diff.b_path}"}= diff.b_path %br/ .diff_file_content - if file.text? - = render :partial => "commits/text_file", :locals => { :diff => diff, :index => i } + = render "commits/text_file", :diff => diff, :index => i - elsif file.image? .diff_file_content_image %img{:src => "data:#{file.mime_type};base64,#{Base64.encode64(file.data)}"} - else %p %center No preview for this file type + diff --git a/app/views/commits/_head.html.haml b/app/views/commits/_head.html.haml new file mode 100644 index 00000000..6951c3a2 --- /dev/null +++ b/app/views/commits/_head.html.haml @@ -0,0 +1,35 @@ +%ul.tabs + %li + = form_tag switch_project_refs_path(@project), :method => :get, :class => "project-refs-form" do + = select_tag "ref", grouped_options_refs, :onchange => "$(this.form).trigger('submit');", :class => "project-refs-select" + = hidden_field_tag :destination, "commits" + + %li{:class => "#{'active' if current_page?(project_commits_path(@project)) }"} + = link_to project_commits_path(@project) do + Commits + %li{:class => "#{'active' if current_page?(compare_project_commits_path(@project)) }"} + = link_to compare_project_commits_path(@project) do + Compare + %li{:class => "#{branches_tab_class}"} + = link_to project_repository_path(@project) do + Branches + %span.number= @project.repo.branches.count + + %li{:class => "#{'active' if current_page?(tags_project_repository_path(@project)) }"} + = link_to tags_project_repository_path(@project) do + Tags + %span.number= @project.repo.tags.count + + + - if current_page?(project_commits_path(@project)) && current_user.private_token + %li.right + %span + = link_to project_commits_path(@project, :atom, { :private_token => current_user.private_token, :ref => @ref }), :class => "btn" do + feed + = image_tag "Rss-UI.PNG", :width => 14, :title => "feed" + + +:javascript + $(function(){ + $('.project-refs-select').chosen(); + }); diff --git a/app/views/commits/_index.html.haml b/app/views/commits/_index.html.haml deleted file mode 100644 index f1e4c7eb..00000000 --- a/app/views/commits/_index.html.haml +++ /dev/null @@ -1,9 +0,0 @@ -= form_tag project_commits_path(@project), :method => :get do - %h3 - = @project.name - [ #{select_tag "branch", options_for_select(@repo.heads.map(&:name), @branch), :onchange => "this.form.submit();", :class => "small"} ] -= link_to 'Back', project_path(@project), :class => "button" -%h1 Listing commits -%div{:id => dom_id(@project)} - = render "commits" -%br/ diff --git a/app/views/commits/_text_file.html.haml b/app/views/commits/_text_file.html.haml index 513efdf0..441bdf2c 100644 --- a/app/views/commits/_text_file.html.haml +++ b/app/views/commits/_text_file.html.haml @@ -1,38 +1,22 @@ %table - - line_old = 0 - - line_new = 0 - - diff_str = diff.diff - - lines_arr = diff_str.lines.to_a - - lines_arr.each do |line| - - next if line.match(/^--- \/dev\/null/) - - next if line.match(/^--- a/) - - next if line.match(/^\+\+\+ b/) - - if line.match(/^@@ -/) - - unless line_old.zero? && line_new.zero? - %tr.line_holder - %td.old_line= "..." - %td.new_line= "..." - %td.line_content - - - 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 - - - full_line = html_escape(line.gsub(/\n/, '')) + - each_diff_line(diff.diff.lines.to_a, index) do |line, type, line_code, line_new, line_old| %tr.line_holder - %td.old_line - = link_to raw(diff_line_class(line) == "new" ? " " : line_old), "#OLD#{index}-#{line_old}", :id => "OLD#{index}-#{line_old}" - %td.new_line - = link_to raw(diff_line_class(line) == "old" ? " " : line_new) , "#NEW#{index}-#{line_new}", :id => "NEW#{index}-#{line_new}" - %td.line_content{:class => "#{diff_line_class(full_line)} #{build_line_code(line, index, line_new, line_old)}", "line_code" => build_line_code(line, index, line_new, line_old)}= raw "#{full_line} " - - comments = @line_notes.select { |n| n.for_line?(index, line_old, line_new) }.sort_by(&:created_at).reverse - - unless comments.empty? - - comments.each do |note| - = render "notes/per_line_show", :note => note - - if line[0] == "+" - - line_new += 1 - - elsif line[0] == "-" - - line_old += 1 - - else - - line_new += 1 - - line_old += 1 + - if type == "match" + %td.old_line= "..." + %td.new_line= "..." + %td.line_content.matched= line + - else + %td.old_line + = link_to raw(type == "new" ? " " : line_old), "##{line_code}", :id => line_code + - if @comments_allowed + = link_to "", "#", :class => "line_note_link", "line_code" => line_code, :title => "Add note for this line" + %td.new_line= link_to raw(type == "old" ? " " : line_new) , "##{line_code}", :id => line_code + %td.line_content{:class => "noteable_line #{type} #{line_code}", "line_code" => line_code}= raw "#{line} " + + - if @comments_allowed + - comments = @line_notes.select { |n| n.line_code == line_code }.sort_by(&:created_at).reverse + - unless comments.empty? + - comments.each_with_index do |note, i| + = render "notes/reply_button", :line_code => line_code if i.zero? + = render "notes/per_line_show", :note => note + - @line_notes.reject!{ |n| n == note } diff --git a/app/views/commits/compare.html.haml b/app/views/commits/compare.html.haml new file mode 100644 index 00000000..877bd407 --- /dev/null +++ b/app/views/commits/compare.html.haml @@ -0,0 +1,49 @@ += render "head" + +%h3 + Compare View +%hr + +%div + %p + Fill input field with commit id like + %code '4eedf23' + or branch/tag name like + %code master + & press compare button for commits list, code diff. + + %br + + = form_tag compare_project_commits_path(@project), :method => :get do + .clearfix + = text_field_tag :from, params[:from], :placeholder => "master", :class => "xlarge" + = "..." + = text_field_tag :to, params[:to], :placeholder => "aa8b4ef", :class => "xlarge" + .actions + = submit_tag "Compare", :class => "btn primary" + + +- unless @commits.empty? + %h4 Commits + %ul.unstyled= render @commits + +- unless @diffs.empty? + %h4 Diff + = render "commits/diffs", :diffs => @diffs + + +:javascript + $(function() { + var availableTags = #{@project.heads.map(&:name).to_json}; + + $( "#from" ).autocomplete({ + source: availableTags, + minLength: 1 + }); + + $( "#to" ).autocomplete({ + source: availableTags, + minLength: 1 + }); + }); + diff --git a/app/views/commits/index.html.haml b/app/views/commits/index.html.haml index 5a760b3a..6cc6ba5f 100644 --- a/app/views/commits/index.html.haml +++ b/app/views/commits/index.html.haml @@ -1,16 +1,14 @@ -- content_for(:body_class, "project-page commits-page") -- if current_user.private_token - = content_for :rss_icon do - .rss-icon - = link_to project_commits_path(@project, :atom, { :private_token => current_user.private_token, :ref => @ref }) do - = image_tag "Rss-UI.PNG", :width => 22, :title => "feed" += render "head" - if params[:path] - %h2 - = link_to project_commits_path(@project) do - = @project.code - \/ - %a{:href => "#"}= params[:path].split("/").join(" / ") + %ul.breadcrumb + %li + = link_to project_commits_path(@project) do + = @project.code + %span.divider + \/ + %li + %a{:href => "#"}= params[:path].split("/").join(" / ") %div{:id => dom_id(@project)} #commits_list= render "commits" @@ -21,5 +19,6 @@ - if @commits.count == @limit :javascript $(function(){ - CommitsList.init("#{@ref}", 20); + CommitsList.init("#{@ref}", #{@limit}); }); + diff --git a/app/views/commits/show.html.haml b/app/views/commits/show.html.haml index 3e847e78..9c1df54e 100644 --- a/app/views/commits/show.html.haml +++ b/app/views/commits/show.html.haml @@ -1,20 +1,16 @@ -- content_for(:body_class, "project-page commits-page") .commit - %span.commit-info - = link_to tree_project_ref_path(@project, @commit.id) do - %data.commit-button - Browse Code - %i - - if @commit.author_email - = image_tag gravatar_icon(@commit.author_email), :class => "left", :width => 40, :style => "padding-right:5px;" - - else - = image_tag "no_avatar.png", :class => "left", :width => 40, :style => "padding-right:5px;" - %span.commit-title - %strong - = truncate(@commit.id.to_s, :length => 60) - %span.commit-author - %strong= @commit.author_name - = @commit.created_at.stamp("Aug 21, 2011 9:23pm") + = link_to tree_project_ref_path(@project, @commit.id), :class => "btn right small" do + Browse Code » + = image_tag gravatar_icon(@commit.author_email), :class => "avatar" + %code= @commit.id.to_s + %h5 + = @commit.author_name + %small= @commit.created_at.stamp("Aug 21, 2011 9:23pm") + - if @commit.author_name != @commit.committer_name or @commit.author_email != @commit.committer_email or @commit.authored_date != @commit.committed_date + – + %cite committed by + = @commit.committer_name + %small= @commit.committed_date.stamp("Aug 21, 2011 9:23pm") %hr %pre.commit_message @@ -22,17 +18,20 @@ .clear %br -= render "commits/diff" -= render "notes/notes" +%p.cgray + Showing #{pluralize(@commit.diffs.count, "changed file")} += render "commits/diffs", :diffs => @commit.diffs += render "notes/notes", :tid => @commit.id, :tt => "commit" = render "notes/per_line_form" :javascript $(document).ready(function(){ - $(".line_content").live("dblclick", function(e) { + $(".line_note_link, .line_note_reply_link").live("click", function(e) { var form = $(".per_line_form"); - $(this).parent().after(form); + $(this).parent().parent().after(form); form.find("#note_line_code").val($(this).attr("line_code")); form.show(); + return false; }); }); diff --git a/app/views/dashboard/_events_feed.html.haml b/app/views/dashboard/_events_feed.html.haml new file mode 100644 index 00000000..e3413195 --- /dev/null +++ b/app/views/dashboard/_events_feed.html.haml @@ -0,0 +1,19 @@ +- @events.each do |event| + .wll.event_feed + - if event.push? + - if event.new_branch? + User pushed new branch + - else + = image_tag gravatar_icon(event.pusher_email), :class => "avatar" + #{event.pusher_name} pushed to + = link_to project_commits_path(event.project, :ref => event.branch_name) do + %strong= event.branch_name + %span.cgray + = time_ago_in_words(event.created_at) + ago. + - if event.commits.count > 1 + = link_to compare_project_commits_path(event.project, :from => event.commits.first.prev_commit_id, :to => event.commits.last.id) do + Compare #{event.commits.first.commit.id[0..8]}...#{event.commits.last.id[0..8]} + - @project = event.project + %ul.unstyled + = render event.commits diff --git a/app/views/dashboard/_issues_feed.html.haml b/app/views/dashboard/_issues_feed.html.haml index 45892664..5c0e05ef 100644 --- a/app/views/dashboard/_issues_feed.html.haml +++ b/app/views/dashboard/_issues_feed.html.haml @@ -1,26 +1,10 @@ -#feeds_content_holder - - unless @issues.empty? - .project-box.project-updates.ui-box.ui-box-small.ui-box-big - .data - - @issues.each do |update| - %a.project-update{:href => dashboard_feed_path(update.project, update)} - %strong.issue-number= "##{update.id}" - %span.update-title - = truncate update.title, :length => 35 - .right= truncate update.project.name - %span.update-author - %strong= update.author_name - authored - = time_ago_in_words(update.created_at) - ago - .right - - if update.critical - %span.tag.high critical - - if update.today? - %span.tag.today today - - - else - %h2 - No assigned - %span.tag.open open - issues +- @issues.each do |issue| + .wll + = link_to [issue.project, issue] do + %p + %strong + %span.label= issue.project.name + – + Issue # + = issue.id + = truncate issue.title, :length => 50 diff --git a/app/views/dashboard/_menu.html.haml b/app/views/dashboard/_menu.html.haml deleted file mode 100644 index 73d4149d..00000000 --- a/app/views/dashboard/_menu.html.haml +++ /dev/null @@ -1,21 +0,0 @@ --#%h4.dash-tabs - = link_to "Activities", dashboard_path, :remote => true, :class => "dash-button #{"active" if current_page?(dashboard_path) || current_page?(root_path) }", :id => "activities_slide" - = link_to "Issues", dashboard_issues_path, :remote => true, :class => "dash-button #{"active" if current_page?(dashboard_issues_path)}", :id => "issues_slide" - = link_to "Merge Requests", dashboard_merge_requests_path, :remote => true, :class => "dash-button #{"active" if current_page?(dashboard_merge_requests_path)}", :id => "merge_requests_slide" - = image_tag "ajax-loader-facebook.gif", :class => "dashboard-loader" - -:javascript - $(function(){ - $(".dash-button").live("click", function() { - $(".dash-button").removeClass("active"); - $(this).addClass("active"); - }); - - $(".dash-button").live("ajax:before", function() { - $(".dashboard-loader").show(); - }); - - $(".dash-button").live("ajax:complete", function() { - $(".dashboard-loader").hide(); - }); - }); diff --git a/app/views/dashboard/_merge_requests_feed.html.haml b/app/views/dashboard/_merge_requests_feed.html.haml index 1f8553e4..db1ebd32 100644 --- a/app/views/dashboard/_merge_requests_feed.html.haml +++ b/app/views/dashboard/_merge_requests_feed.html.haml @@ -1,24 +1,10 @@ -#feeds_content_holder - - unless @merge_requests.empty? - .project-box.project-updates.ui-box.ui-box-small.ui-box-big - .data - - @merge_requests.each do |update| - %a.project-update{:href => project_merge_request_path(update.project, update)} - = image_tag gravatar_icon(update.author_email), :class => "left", :width => 40 - %span.update-title - = truncate update.title, :length => 35 - .right= truncate update.project.name - %span.update-author - %strong= update.author_name - authored - = time_ago_in_words(update.created_at) - ago - .right - %span.tag.commit= update.source_branch - → - %span.tag.commit= update.target_branch - - else - %h2 - No authored or assigned - %span.tag.open open - merge requests +- @merge_requests.each do |merge_request| + .wll + = link_to [merge_request.project, merge_request] do + %p + %strong + %span.label= merge_request.project.name + – + Merge Request # + = merge_request.id + = truncate merge_request.title, :length => 50 diff --git a/app/views/dashboard/_projects_feed.html.haml b/app/views/dashboard/_projects_feed.html.haml index 0d347246..1d53cf74 100644 --- a/app/views/dashboard/_projects_feed.html.haml +++ b/app/views/dashboard/_projects_feed.html.haml @@ -1,20 +1,8 @@ -#feeds_content_holder - - @active_projects.first(3).each do |project| - .project-box.project-updates.ui-box.ui-box-small.ui-box-big - = link_to project do - %h3= project.name - .data - - project.updates(3).each do |update| - %a.project-update{:href => dashboard_feed_path(project, update)} - = image_tag gravatar_icon(update.author_email), :class => "left", :width => 40 - %span.update-title - = dashboard_feed_title(update) - %span.update-author - %strong= update.author_name - authored - = time_ago_in_words(update.created_at) - ago - .right - - klass = update.class.to_s.split("::").last.downcase - %span.tag{ :class => klass }= klass - +- @active_projects.first(5).each do |project| + .wll + = link_to project do + %h4 + = project.name + %small + last activity at + = project.last_activity_date_cached.stamp("Aug 25, 2011") diff --git a/app/views/dashboard/_sidebar.html.haml b/app/views/dashboard/_sidebar.html.haml deleted file mode 100644 index dec71186..00000000 --- a/app/views/dashboard/_sidebar.html.haml +++ /dev/null @@ -1,15 +0,0 @@ -%aside - %h4 - - if current_user.can_create_project? - %a.button-small.button-green{:href => new_project_path} New Project - Your Projects - %ol.project-list - - @projects.each do |project| - %li - %a{:href => project_path(project)} - -#%span.arrow → - %span.project-name= project.name - %span.time - %strong Last activity: - = project.last_activity_date_cached ? time_ago_in_words(project.last_activity_date_cached) + " ago" : "Never" - diff --git a/app/views/dashboard/index.html.haml b/app/views/dashboard/index.html.haml index 7f6beffb..27490e40 100644 --- a/app/views/dashboard/index.html.haml +++ b/app/views/dashboard/index.html.haml @@ -1,6 +1,65 @@ -- content_for(:body_class, "dashboard-page") +- if current_user.require_ssh_key? + .alert-message.warning + %p + You wont be able to pull/push project code unless you + = link_to new_key_path, :class => "vlink" do + add new key + to your profile -#dashboard-content.dashboard-content.content - = render "dashboard/sidebar" - = render "dashboard/menu" - #news-feed.news-feed= render "dashboard/projects_feed" +%div.dashboard_category + %h3 + Projects + %small + ( most recent ) + + %strong.right + = link_to projects_path do + Projects list → + %hr + .row + .dashboard_block + .row + .span9= render "dashboard/projects_feed" + .span3.right + - if current_user.can_create_project? + .alert-message.block-message.warning + You can create up to + = current_user.projects_limit + projects. Click on link below to add a new one + .link_holder + = link_to new_project_path, :class => "" do + New Project » + + +- unless @merge_requests.blank? + %div.dashboard_category + %h3 + Merge Requests + %small ( authored or assigned to you ) + %strong.right + = link_to dashboard_merge_requests_path do + Vist merge requests page → + %hr + .row + .dashboard_block= render "dashboard/merge_requests_feed" + +- unless @issues.blank? + %div.dashboard_category + %h3 + Issues + %small ( assigned to you ) + %strong.right + = link_to dashboard_merge_requests_path do + Vist issues page → + %hr + .row + .dashboard_block= render "dashboard/issues_feed" + +- unless @events.blank? + %div.dashboard_category + %h3 + Activities + + %hr + .row + .dashboard_block= render "dashboard/events_feed" diff --git a/app/views/dashboard/issues.html.haml b/app/views/dashboard/issues.html.haml index 4b7af96a..b9c467a5 100644 --- a/app/views/dashboard/issues.html.haml +++ b/app/views/dashboard/issues.html.haml @@ -1,6 +1,6 @@ -- content_for(:body_class, "dashboard-page") +%h3 + Issues + %small ( assigned to you ) -#dashboard-content.dashboard-content.content - = render "dashboard/sidebar" - = render "dashboard/menu" - #news-feed.news-feed= render "dashboard/issues_feed" +%br +.ui-box= render "dashboard/issues_feed" diff --git a/app/views/dashboard/merge_requests.html.haml b/app/views/dashboard/merge_requests.html.haml index 3497062c..ec1c233c 100644 --- a/app/views/dashboard/merge_requests.html.haml +++ b/app/views/dashboard/merge_requests.html.haml @@ -1,6 +1,6 @@ -- content_for(:body_class, "dashboard-page") +%h3 + Merge Requests + %small ( authored or assigned to you ) -#dashboard-content.dashboard-content.content - = render "dashboard/sidebar" - = render "dashboard/menu" - #news-feed.news-feed= render "dashboard/merge_requests_feed" +%br +.ui-box= render "dashboard/merge_requests_feed" diff --git a/app/views/deploy_keys/_form.html.haml b/app/views/deploy_keys/_form.html.haml index f0a300bb..2aa57cdc 100644 --- a/app/views/deploy_keys/_form.html.haml +++ b/app/views/deploy_keys/_form.html.haml @@ -1,18 +1,18 @@ %div = form_for [@project, @key], :url => project_deploy_keys_path do |f| -if @key.errors.any? - %ul.errors_holder - - @key.errors.full_messages.each do |msg| - %li= msg - - %table.no-borders - %tr - %td= f.label :title - %td= f.text_field :title, :style => "width:300px" - %tr - %td= f.label :key - %td= f.text_area :key, :style => "width:300px; height:130px" - %br - .merge-tabs - = f.submit 'Save', :class => "positive-button" + .alert-message.block-message.error + %ul + - @key.errors.full_messages.each do |msg| + %li= msg + + .clearfix + = f.label :title + .input= f.text_field :title + .clearfix + = f.label :key + .input= f.text_area :key, :class => "xlarge" + .actions + = f.submit 'Save', :class => "primary btn" + = link_to "Cancel", project_deploy_keys_path(@project), :class => "btn" diff --git a/app/views/deploy_keys/_show.html.haml b/app/views/deploy_keys/_show.html.haml index b1622f35..ff17b3cd 100644 --- a/app/views/deploy_keys/_show.html.haml +++ b/app/views/deploy_keys/_show.html.haml @@ -1,7 +1,12 @@ -%a.update-item{:href => project_deploy_key_path(key.project, key)} - %span.update-title - = key.title - %span.update-author - Added - = time_ago_in_words(key.created_at) - ago +%tr + %td + %a{:href => project_deploy_key_path(key.project, key)} + %strong= key.title + %td + %span.update-author + Added + = time_ago_in_words(key.created_at) + ago + %td + = link_to 'Remove', project_deploy_key_path(key.project, key), :confirm => 'Are you sure?', :method => :delete, :class => "danger btn delete-key small right" + diff --git a/app/views/deploy_keys/index.html.haml b/app/views/deploy_keys/index.html.haml index 02c8c135..b03e7539 100644 --- a/app/views/deploy_keys/index.html.haml +++ b/app/views/deploy_keys/index.html.haml @@ -1,17 +1,10 @@ = render "repositories/head" +- if can? current_user, :admin_project, @project + .alert-message.block-message + Deploy keys allow read-only access to repository. + = link_to new_project_deploy_key_path(@project), :class => "btn small", :title => "New Deploy Key" do + Add Deploy Key -%div#keys-table{ :class => "update-data ui-box ui-box-small ui-box-big" } - .data - - @keys.each do |key| - = render(:partial => 'show', :locals => {:key => key}) - -- if @keys.blank? - .notice_holder - %li Deploy Keys do not exist yet. - - if can? current_user, :admin_project, @project - %li You can add a new one by clicking on "Add New" button - -:javascript - $('.delete-key').live('ajax:success', function() { - $(this).closest('.update-item').fadeOut(); }); - +%table.zebra-striped.borders + - @keys.each do |key| + = render(:partial => 'show', :locals => {:key => key}) diff --git a/app/views/deploy_keys/new.html.haml b/app/views/deploy_keys/new.html.haml index 1e6b7e77..a2f1010b 100644 --- a/app/views/deploy_keys/new.html.haml +++ b/app/views/deploy_keys/new.html.haml @@ -1,5 +1,6 @@ = render "repositories/head" -%h2 New Deploy key +%h3 New Deploy key +%hr = render 'form' diff --git a/app/views/deploy_keys/show.html.haml b/app/views/deploy_keys/show.html.haml index 2c5c6149..16c441be 100644 --- a/app/views/deploy_keys/show.html.haml +++ b/app/views/deploy_keys/show.html.haml @@ -1,10 +1,7 @@ -.ui-box.width-100p - %h3= @key.title - .data - %pre= @key.key - .clear - .buttons - = link_to 'Remove', project_deploy_key_path(@key.project, @key), :confirm => 'Are you sure?', :method => :delete, :class => "red-button delete-key right" - .clear - - += render "repositories/head" +%h3= @key.title +%hr +%pre= @key.key +.actions + = link_to 'Remove', project_deploy_key_path(@key.project, @key), :confirm => 'Are you sure?', :method => :delete, :class => "danger btn delete-key" + .clear diff --git a/app/views/devise/passwords/edit.html.erb b/app/views/devise/passwords/edit.html.erb deleted file mode 100644 index ff76588c..00000000 --- a/app/views/devise/passwords/edit.html.erb +++ /dev/null @@ -1,16 +0,0 @@ -
<%= link_to "via LDAP", user_omniauth_authorize_path(:ldap)%>
+ <% end -%> <% end %> diff --git a/app/views/devise/shared/_links.erb b/app/views/devise/shared/_links.erb index 33b1120f..c624c2d5 100644 --- a/app/views/devise/shared/_links.erb +++ b/app/views/devise/shared/_links.erb @@ -1,5 +1,5 @@ <%- if controller_name != 'sessions' %> - <%= link_to "Sign in", new_session_path(resource_name) %>