Merge branch 'master' into stable

Conflicts:
	doc/install/installation.md
3-1-stable
Dmitriy Zaporozhets 2012-11-22 12:52:08 +02:00
commit 319f0c3057
508 changed files with 105205 additions and 3020 deletions

View File

@ -3,8 +3,11 @@ env:
- DB=mysql - DB=mysql
before_install: before_install:
- sudo apt-get install libicu-dev -y - sudo apt-get install libicu-dev -y
- sudo apt-get install libqt4-dev libqtwebkit-dev -y - wget -P /tmp http://phantomjs.googlecode.com/files/phantomjs-1.7.0-linux-i686.tar.bz2
- gem install charlock_holmes -v="0.6.8" - tar -xf /tmp/phantomjs-1.7.0-linux-i686.tar.bz2 -C /tmp/
- sudo rm -rf /usr/local/phantomjs
- sudo mv /tmp/phantomjs-1.7.0-linux-i686 /usr/local/phantomjs
- gem install charlock_holmes -v="0.6.9"
branches: branches:
only: only:
- 'master' - 'master'

View File

@ -1,3 +1,21 @@
v 3.1.0
- Updated gems
- Services: Gitlab CI integration
- Events filter on dashboard
- Own namespace for redis/resque
- Optimized commit diff views
- add alphabetical order for projects admin page
- Improved web editor
- Commit stats page
- Documentation split and cleanup
- Link to commit authors everywhere
- Restyled milestones list
- added Milestone to Merge Request
- Restyled Top panel
- Refactored Satellite Code
- Added file line links
- moved from capybara-webkit to poltergeist + phantomjs
v 3.0.3 v 3.0.3
- Fixed bug with issues list in Chrome - Fixed bug with issues list in Chrome
- New Feature: Import team from another project - New Feature: Import team from another project
@ -28,7 +46,7 @@ v 3.0.0
- Reject ssh keys that break gitolite - Reject ssh keys that break gitolite
- [API] list one project hook - [API] list one project hook
- [API] edit project hook - [API] edit project hook
- [API] add project snippets list - [API] list project snippets
- [API] allow to authorize using private token in HTTP header - [API] allow to authorize using private token in HTTP header
- [API] add user creation - [API] add user creation

View File

@ -1,4 +1,4 @@
## Contribute to GitLab ## Contribute to GitLab
If you want to contribute to GitLab, follow this process: If you want to contribute to GitLab, follow this process:
@ -7,24 +7,20 @@ If you want to contribute to GitLab, follow this process:
3. Code 3. Code
4. Create a pull request 4. Create a pull request
We will only accept pull requests if: We will only accept pull requests if:
* Your code has proper tests and all tests pass * Your code has proper tests and all tests pass
* Your code can be merged w/o problems * Your code can be merged w/o problems
* It won't break existing functionality * It won't break existing functionality
* It's quality code * It's quality code
* We like it :) * We like it :)
## [You may need a developer VM](https://github.com/gitlabhq/developer-vm) For examples of feedback on pull requests please look at the [closed pull requests](https://github.com/gitlabhq/gitlabhq/pulls?direction=desc&page=1&sort=created&state=closed).
## Installation
Install the Gitlab development in a virtual machine with the [Gitlab Vagrant virtual machine](https://github.com/gitlabhq/gitlab-vagrant-vm). Installing it in a virtual machine makes it much easier to set up all the dependencies for integration testing.
## Running tests ## Running tests
To run the specs for GitLab, you need to run seeds for test db. For more information on running the tests please read the [development tips](https://github.com/gitlabhq/gitlabhq/blob/master/doc/development.md)
cd gitlabhq
rake db:seed_fu RAILS_ENV=test
Then you can run the test suite with rake:
rake gitlab:test

88
Gemfile
View File

@ -8,34 +8,35 @@ def linux_only(require_as)
RUBY_PLATFORM.include?('linux') && require_as RUBY_PLATFORM.include?('linux') && require_as
end end
gem "rails", "3.2.8" gem "rails", "3.2.9"
# Supported DBs # Supported DBs
gem "sqlite3", :group => :sqlite gem "sqlite3", group: :sqlite
gem "mysql2", :group => :mysql gem "mysql2", group: :mysql
gem "pg", :group => :postgres gem "pg", group: :postgres
# Auth # Auth
gem "devise", "~> 2.1.0" gem "devise", "~> 2.1.0"
gem 'omniauth' gem 'omniauth', "~> 1.1.1"
gem 'omniauth-google-oauth2' gem 'omniauth-google-oauth2'
gem 'omniauth-twitter' gem 'omniauth-twitter'
gem 'omniauth-github' gem 'omniauth-github'
# GITLAB patched libs # GITLAB patched libs
gem "grit", :git => "https://github.com/gitlabhq/grit.git", :ref => "7f35cb98ff17d534a07e3ce6ec3d580f67402837" gem "grit", git: "https://github.com/gitlabhq/grit.git", ref: '7f35cb98ff17d534a07e3ce6ec3d580f67402837'
gem "omniauth-ldap", :git => "https://github.com/gitlabhq/omniauth-ldap.git", :ref => "f038dd852d7bd473a557e385d5d7c2fd5dc1dc2e" gem "omniauth-ldap", git: "https://github.com/gitlabhq/omniauth-ldap.git", ref: 'f038dd852d7bd473a557e385d5d7c2fd5dc1dc2e'
gem 'yaml_db', :git => "https://github.com/gitlabhq/yaml_db.git" gem 'yaml_db', git: "https://github.com/gitlabhq/yaml_db.git", ref: '98e9a5dca43e3fedd3268c76a73af40d1bdf1dfd'
gem 'grack', :git => "https://github.com/gitlabhq/grack.git" gem 'grack', git: "https://github.com/gitlabhq/grack.git", ref: 'ba46f3b0845c6a09d488ae6abdce6ede37e227e8'
gem 'grit_ext', git: "https://github.com/gitlabhq/grit_ext.git", ref: '212fd40bea61f3c6a167223768e7295dc32bbc10'
# Gitolite client (for work with gitolite-admin repo) # Gitolite client (for work with gitolite-admin repo)
gem "gitolite", '1.1.0' gem "gitolite", '1.1.0'
# Syntax highlighter # Syntax highlighter
gem "pygments.rb", "0.3.1" gem "pygments.rb", git: "https://github.com/gitlabhq/pygments.rb.git", ref: '4db80c599067e2d5f23c5c243bf85b8ca0368ad4'
# Language detection # Language detection
gem "github-linguist", "~> 2.3.4" , :require => "linguist" gem "github-linguist", "~> 2.3.4" , require: "linguist"
# API # API
gem "grape", "~> 0.2.1" gem "grape", "~> 0.2.1"
@ -45,13 +46,13 @@ gem "grape", "~> 0.2.1"
gem "stamp" gem "stamp"
# Pagination # Pagination
gem "kaminari" gem "kaminari", "~> 0.14.1"
# HAML # HAML
gem "haml-rails" gem "haml-rails", "~> 0.3.5"
# Files attachments # Files attachments
gem "carrierwave" gem "carrierwave", "~> 0.7.1"
# Authorization # Authorization
gem "six" gem "six"
@ -63,59 +64,57 @@ gem "ffaker"
gem "seed-fu" gem "seed-fu"
# Markdown to HTML # Markdown to HTML
gem "redcarpet", "~> 2.1.1" gem "redcarpet", "~> 2.2.2"
gem "github-markup", "~> 0.7.4", require: 'github/markup' gem "github-markup", "~> 0.7.4", require: 'github/markup'
# Servers # Servers
gem "thin" gem "thin", '~> 1.5.0'
gem "unicorn" gem "unicorn", "~> 4.4.0"
# Issue tags # Issue tags
gem "acts-as-taggable-on", "2.3.1" gem "acts-as-taggable-on", "2.3.3"
# Decorators # Decorators
gem "draper" gem "draper", "~> 0.18.0"
# Background jobs # Background jobs
gem "resque", "~> 1.20.0" gem "resque", "~> 1.23.0"
gem 'resque_mailer' gem 'resque_mailer'
# HTTP requests # HTTP requests
gem "httparty" gem "httparty"
# Handle encodings
gem "charlock_holmes"
# Colored output to console # Colored output to console
gem "colored" gem "colored"
# GITLAB settings # GitLab settings
gem 'settingslogic' gem 'settingslogic'
# Misc # Misc
gem "foreman" gem "foreman"
gem 'gemoji', require: 'emoji/railtie'
gem "git" gem "git"
group :assets do group :assets do
gem "sass-rails", "3.2.5" gem "sass-rails", "~> 3.2.5"
gem "coffee-rails", "3.2.2" gem "coffee-rails", "~> 3.2.2"
gem "uglifier", "1.0.3" gem "uglifier", "~> 1.3.0"
gem "therubyracer" gem "therubyracer"
gem 'chosen-rails' gem 'chosen-rails', "0.9.8"
gem 'jquery-atwho-rails', '0.1.6' gem 'jquery-atwho-rails', "0.1.6"
gem "jquery-rails", "2.0.2" gem "jquery-rails", "2.1.3"
gem "jquery-ui-rails", "0.5.0" gem "jquery-ui-rails", "2.0.2"
gem "modernizr", "2.5.3" gem "modernizr", "2.6.2"
gem "raphael-rails", "1.5.2" gem "raphael-rails", "2.1.0"
gem 'bootstrap-sass', "2.0.4" gem 'bootstrap-sass', "2.2.1.1"
gem "font-awesome-sass-rails", "~> 2.0.0" gem "font-awesome-sass-rails", "~> 2.0.0"
gem "gemoji", "~> 1.2.1", require: 'emoji/railtie'
end end
group :development do group :development do
gem "annotate", git: "https://github.com/ctran/annotate_models.git"
gem "letter_opener" gem "letter_opener"
gem "annotate", :git => "https://github.com/ctran/annotate_models.git" gem 'quiet_assets', '~> 1.0.1'
gem 'rack-mini-profiler' gem 'rack-mini-profiler'
end end
@ -124,8 +123,6 @@ group :development, :test do
gem 'spinach-rails' gem 'spinach-rails'
gem "rspec-rails" gem "rspec-rails"
gem "capybara" gem "capybara"
gem "capybara-webkit"
gem "headless"
gem "pry" gem "pry"
gem "awesome_print" gem "awesome_print"
gem "database_cleaner" gem "database_cleaner"
@ -137,14 +134,17 @@ group :development, :test do
gem 'guard-spinach' gem 'guard-spinach'
# Notification # Notification
gem 'rb-fsevent', :require => darwin_only('rb-fsevent') gem 'rb-fsevent', require: darwin_only('rb-fsevent')
gem 'growl', :require => darwin_only('growl') gem 'growl', require: darwin_only('growl')
gem 'rb-inotify', :require => linux_only('rb-inotify') gem 'rb-inotify', require: linux_only('rb-inotify')
# PhantomJS driver for Capybara
gem 'poltergeist'
end end
group :test do group :test do
gem "simplecov", :require => false gem "simplecov", require: false
gem "shoulda-matchers" gem "shoulda-matchers", "1.3.0"
gem 'email_spec' gem 'email_spec'
gem 'resque_spec' gem 'resque_spec'
gem "webmock" gem "webmock"
@ -152,5 +152,5 @@ group :test do
end end
group :production do group :production do
gem "gitlab_meta", '3.0' gem "gitlab_meta", '3.1'
end end

View File

@ -1,12 +1,15 @@
GIT GIT
remote: https://github.com/ctran/annotate_models.git remote: https://github.com/ctran/annotate_models.git
revision: 18cd39ad01829deba5aa34634b8540d6675ab978 revision: be4e26825b521f0b2d86b181e2dff89901aa9b1e
specs: specs:
annotate (2.4.1.beta1) annotate (2.6.0.beta1)
activerecord (>= 2.3.0)
rake (>= 0.8.7)
GIT GIT
remote: https://github.com/gitlabhq/grack.git remote: https://github.com/gitlabhq/grack.git
revision: ba46f3b0845c6a09d488ae6abdce6ede37e227e8 revision: ba46f3b0845c6a09d488ae6abdce6ede37e227e8
ref: ba46f3b0845c6a09d488ae6abdce6ede37e227e8
specs: specs:
grack (1.0.0) grack (1.0.0)
rack (~> 1.4.1) rack (~> 1.4.1)
@ -21,6 +24,14 @@ GIT
mime-types (~> 1.15) mime-types (~> 1.15)
posix-spawn (~> 0.3.6) posix-spawn (~> 0.3.6)
GIT
remote: https://github.com/gitlabhq/grit_ext.git
revision: 212fd40bea61f3c6a167223768e7295dc32bbc10
ref: 212fd40bea61f3c6a167223768e7295dc32bbc10
specs:
grit_ext (0.6.0)
charlock_holmes (~> 0.6.9)
GIT GIT
remote: https://github.com/gitlabhq/omniauth-ldap.git remote: https://github.com/gitlabhq/omniauth-ldap.git
revision: f038dd852d7bd473a557e385d5d7c2fd5dc1dc2e revision: f038dd852d7bd473a557e385d5d7c2fd5dc1dc2e
@ -32,115 +43,126 @@ GIT
pyu-ruby-sasl (~> 0.0.3.1) pyu-ruby-sasl (~> 0.0.3.1)
rubyntlm (~> 0.1.1) rubyntlm (~> 0.1.1)
GIT
remote: https://github.com/gitlabhq/pygments.rb.git
revision: 4db80c599067e2d5f23c5c243bf85b8ca0368ad4
ref: 4db80c599067e2d5f23c5c243bf85b8ca0368ad4
specs:
pygments.rb (0.3.2)
posix-spawn (~> 0.3.6)
yajl-ruby (~> 1.1.0)
GIT GIT
remote: https://github.com/gitlabhq/yaml_db.git remote: https://github.com/gitlabhq/yaml_db.git
revision: 98e9a5dca43e3fedd3268c76a73af40d1bdf1dfd revision: 98e9a5dca43e3fedd3268c76a73af40d1bdf1dfd
ref: 98e9a5dca43e3fedd3268c76a73af40d1bdf1dfd
specs: specs:
yaml_db (0.2.2) yaml_db (0.2.2)
GEM GEM
remote: http://rubygems.org/ remote: http://rubygems.org/
specs: specs:
actionmailer (3.2.8) actionmailer (3.2.9)
actionpack (= 3.2.8) actionpack (= 3.2.9)
mail (~> 2.4.4) mail (~> 2.4.4)
actionpack (3.2.8) actionpack (3.2.9)
activemodel (= 3.2.8) activemodel (= 3.2.9)
activesupport (= 3.2.8) activesupport (= 3.2.9)
builder (~> 3.0.0) builder (~> 3.0.0)
erubis (~> 2.7.0) erubis (~> 2.7.0)
journey (~> 1.0.4) journey (~> 1.0.4)
rack (~> 1.4.0) rack (~> 1.4.0)
rack-cache (~> 1.2) rack-cache (~> 1.2)
rack-test (~> 0.6.1) rack-test (~> 0.6.1)
sprockets (~> 2.1.3) sprockets (~> 2.2.1)
activemodel (3.2.8) activemodel (3.2.9)
activesupport (= 3.2.8) activesupport (= 3.2.9)
builder (~> 3.0.0) builder (~> 3.0.0)
activerecord (3.2.8) activerecord (3.2.9)
activemodel (= 3.2.8) activemodel (= 3.2.9)
activesupport (= 3.2.8) activesupport (= 3.2.9)
arel (~> 3.0.2) arel (~> 3.0.2)
tzinfo (~> 0.3.29) tzinfo (~> 0.3.29)
activeresource (3.2.8) activeresource (3.2.9)
activemodel (= 3.2.8) activemodel (= 3.2.9)
activesupport (= 3.2.8) activesupport (= 3.2.9)
activesupport (3.2.8) activesupport (3.2.9)
i18n (~> 0.6) i18n (~> 0.6)
multi_json (~> 1.0) multi_json (~> 1.0)
acts-as-taggable-on (2.3.1) acts-as-taggable-on (2.3.3)
rails (~> 3.0) rails (~> 3.0)
addressable (2.2.8) addressable (2.3.2)
arel (3.0.2) arel (3.0.2)
awesome_print (1.0.2) awesome_print (1.1.0)
backports (2.6.5)
bcrypt-ruby (3.0.1) bcrypt-ruby (3.0.1)
blankslate (2.1.2.4) blankslate (3.1.2)
bootstrap-sass (2.0.4.0) bootstrap-sass (2.2.1.1)
builder (3.0.2) sass (~> 3.2)
capybara (1.1.2) builder (3.0.4)
capybara (1.1.3)
mime-types (>= 1.16) mime-types (>= 1.16)
nokogiri (>= 1.3.3) nokogiri (>= 1.3.3)
rack (>= 1.0.0) rack (>= 1.0.0)
rack-test (>= 0.5.4) rack-test (>= 0.5.4)
selenium-webdriver (~> 2.0) selenium-webdriver (~> 2.0)
xpath (~> 0.1.4) xpath (~> 0.1.4)
capybara-webkit (0.12.1) carrierwave (0.7.1)
capybara (>= 1.0.0, < 1.2)
json
carrierwave (0.6.2)
activemodel (>= 3.2.0) activemodel (>= 3.2.0)
activesupport (>= 3.2.0) activesupport (>= 3.2.0)
charlock_holmes (0.6.8) charlock_holmes (0.6.9)
childprocess (0.3.2) childprocess (0.3.6)
ffi (~> 1.0.6) ffi (~> 1.0, >= 1.0.6)
chosen-rails (0.9.8.3) chosen-rails (0.9.8)
railties (~> 3.0) railties (~> 3.0)
thor (~> 0.14) thor (~> 0.14)
coderay (1.0.6) coderay (1.0.8)
coffee-rails (3.2.2) coffee-rails (3.2.2)
coffee-script (>= 2.2.0) coffee-script (>= 2.2.0)
railties (~> 3.2.0) railties (~> 3.2.0)
coffee-script (2.2.0) coffee-script (2.2.0)
coffee-script-source coffee-script-source
execjs execjs
coffee-script-source (1.3.3) coffee-script-source (1.4.0)
colored (1.2) colored (1.2)
colorize (0.5.8) colorize (0.5.8)
crack (0.3.1) crack (0.3.1)
daemons (1.1.8) daemons (1.1.9)
database_cleaner (0.8.0) database_cleaner (0.9.1)
devise (2.1.2) devise (2.1.2)
bcrypt-ruby (~> 3.0) bcrypt-ruby (~> 3.0)
orm_adapter (~> 0.1) orm_adapter (~> 0.1)
railties (~> 3.1) railties (~> 3.1)
warden (~> 1.2.1) warden (~> 1.2.1)
diff-lcs (1.1.3) diff-lcs (1.1.3)
draper (0.17.0) draper (0.18.0)
actionpack (~> 3.2) actionpack (~> 3.2)
activesupport (~> 3.2) activesupport (~> 3.2)
email_spec (1.2.1) email_spec (1.4.0)
launchy (~> 2.1)
mail (~> 2.2) mail (~> 2.2)
rspec (~> 2.0)
erubis (2.7.0) erubis (2.7.0)
escape_utils (0.2.4) escape_utils (0.2.4)
eventmachine (0.12.10) eventmachine (1.0.0)
execjs (1.4.0) execjs (1.4.0)
multi_json (~> 1.0) multi_json (~> 1.0)
factory_girl (4.0.0) factory_girl (4.1.0)
activesupport (>= 3.0.0) activesupport (>= 3.0.0)
factory_girl_rails (4.0.0) factory_girl_rails (4.1.0)
factory_girl (~> 4.0.0) factory_girl (~> 4.1.0)
railties (>= 3.0.0) railties (>= 3.0.0)
faraday (0.8.4) faraday (0.8.4)
multipart-post (~> 1.1) multipart-post (~> 1.1)
ffaker (1.14.0) faye-websocket (0.4.6)
ffi (1.0.11) eventmachine (>= 0.12.0)
ffaker (1.15.0)
ffi (1.1.5)
font-awesome-sass-rails (2.0.0.0) font-awesome-sass-rails (2.0.0.0)
railties (>= 3.1.1) railties (>= 3.1.1)
sass-rails (>= 3.1.1) sass-rails (>= 3.1.1)
foreman (0.47.0) foreman (0.60.2)
thor (>= 0.13.6) thor (>= 0.13.6)
gemoji (1.1.1) gemoji (1.2.1)
gherkin-ruby (0.2.1) gherkin-ruby (0.2.1)
git (1.2.5) git (1.2.5)
github-linguist (2.3.4) github-linguist (2.3.4)
@ -149,80 +171,87 @@ GEM
mime-types (~> 1.19) mime-types (~> 1.19)
pygments.rb (>= 0.2.13) pygments.rb (>= 0.2.13)
github-markup (0.7.4) github-markup (0.7.4)
gitlab_meta (3.0) gitlab_meta (3.1)
gitolite (1.1.0) gitolite (1.1.0)
gratr19 (~> 0.4.4.1) gratr19 (~> 0.4.4.1)
grit (~> 2.5.0) grit (~> 2.5.0)
hashery (~> 1.5.0) hashery (~> 1.5.0)
grape (0.2.1) grape (0.2.2)
activesupport
hashie (~> 1.2) hashie (~> 1.2)
multi_json multi_json (>= 1.3.2)
multi_xml multi_xml
rack rack
rack-accept
rack-mount rack-mount
virtus
gratr19 (0.4.4.1) gratr19 (0.4.4.1)
growl (1.0.3) growl (1.0.3)
guard (1.3.2) guard (1.5.4)
listen (>= 0.4.2) listen (>= 0.4.2)
lumberjack (>= 1.0.2)
pry (>= 0.9.10)
thor (>= 0.14.6) thor (>= 0.14.6)
guard-rspec (1.2.1) guard-rspec (2.1.2)
guard (>= 1.1) guard (>= 1.1)
rspec (~> 2.11)
guard-spinach (0.0.2) guard-spinach (0.0.2)
guard (>= 1.1) guard (>= 1.1)
spinach spinach
haml (3.1.6) haml (3.1.7)
haml-rails (0.3.4) haml-rails (0.3.5)
actionpack (~> 3.0) actionpack (>= 3.1, < 4.1)
activesupport (~> 3.0) activesupport (>= 3.1, < 4.1)
haml (~> 3.0) haml (~> 3.1)
railties (~> 3.0) railties (>= 3.1, < 4.1)
hashery (1.5.0) hashery (1.5.0)
blankslate blankslate
hashie (1.2.0) hashie (1.2.0)
headless (0.3.1)
hike (1.2.1) hike (1.2.1)
httparty (0.8.3) http_parser.rb (0.5.3)
httparty (0.9.0)
multi_json (~> 1.0) multi_json (~> 1.0)
multi_xml multi_xml
httpauth (0.1) httpauth (0.2.0)
i18n (0.6.1) i18n (0.6.1)
journey (1.0.4) journey (1.0.4)
jquery-atwho-rails (0.1.6) jquery-atwho-rails (0.1.6)
jquery-rails (2.0.2) jquery-rails (2.1.3)
railties (>= 3.2.0, < 5.0) railties (>= 3.1.0, < 5.0)
thor (~> 0.14) thor (~> 0.14)
jquery-ui-rails (0.5.0) jquery-ui-rails (2.0.2)
jquery-rails jquery-rails
railties (>= 3.1.0) railties (>= 3.1.0)
json (1.7.5) json (1.7.5)
jwt (0.1.5) jwt (0.1.5)
multi_json (>= 1.0) multi_json (>= 1.0)
kaminari (0.14.0) kaminari (0.14.1)
actionpack (>= 3.0.0) actionpack (>= 3.0.0)
activesupport (>= 3.0.0) activesupport (>= 3.0.0)
kgio (2.7.4) kgio (2.7.4)
launchy (2.1.0) launchy (2.1.2)
addressable (~> 2.2.6) addressable (~> 2.3)
letter_opener (0.0.2) letter_opener (1.0.0)
launchy launchy (>= 2.0.4)
libv8 (3.3.10.4) libv8 (3.3.10.4)
libwebsocket (0.1.3) libwebsocket (0.1.6)
addressable websocket
listen (0.5.0) listen (0.5.3)
lumberjack (1.0.2)
mail (2.4.4) mail (2.4.4)
i18n (>= 0.4.0) i18n (>= 0.4.0)
mime-types (~> 1.16) mime-types (~> 1.16)
treetop (~> 1.4.8) treetop (~> 1.4.8)
method_source (0.7.1) method_source (0.8.1)
mime-types (1.19) mime-types (1.19)
modernizr (2.5.3) modernizr (2.6.2)
sprockets (~> 2.0) sprockets (~> 2.0)
multi_json (1.3.6) multi_json (1.3.7)
multi_xml (0.5.1) multi_xml (0.5.1)
multipart-post (1.1.5) multipart-post (1.1.5)
mysql2 (0.3.11) mysql2 (0.3.11)
net-ldap (0.2.2) net-ldap (0.2.2)
nokogiri (1.5.3) nokogiri (1.5.5)
oauth (0.4.7) oauth (0.4.7)
oauth2 (0.8.0) oauth2 (0.8.0)
faraday (~> 0.8) faraday (~> 0.8)
@ -230,7 +259,7 @@ GEM
jwt (~> 0.1.4) jwt (~> 0.1.4)
multi_json (~> 1.0) multi_json (~> 1.0)
rack (~> 1.2) rack (~> 1.2)
omniauth (1.1.0) omniauth (1.1.1)
hashie (~> 1.2) hashie (~> 1.2)
rack rack
omniauth-github (1.0.3) omniauth-github (1.0.3)
@ -242,28 +271,35 @@ GEM
omniauth-oauth (1.0.1) omniauth-oauth (1.0.1)
oauth oauth
omniauth (~> 1.0) omniauth (~> 1.0)
omniauth-oauth2 (1.1.0) omniauth-oauth2 (1.1.1)
oauth2 (~> 0.8.0) oauth2 (~> 0.8.0)
omniauth (~> 1.0) omniauth (~> 1.0)
omniauth-twitter (0.0.13) omniauth-twitter (0.0.14)
multi_json (~> 1.3) multi_json (~> 1.3)
omniauth-oauth (~> 1.0) omniauth-oauth (~> 1.0)
orm_adapter (0.3.0) orm_adapter (0.4.0)
pg (0.14.0) pg (0.14.1)
poltergeist (1.0.2)
capybara (~> 1.1)
childprocess (~> 0.3)
faye-websocket (~> 0.4, >= 0.4.4)
http_parser.rb (~> 0.5.3)
multi_json (~> 1.0)
polyglot (0.3.3) polyglot (0.3.3)
posix-spawn (0.3.6) posix-spawn (0.3.6)
pry (0.9.9.6) pry (0.9.10)
coderay (~> 1.0.5) coderay (~> 1.0.5)
method_source (~> 0.7.1) method_source (~> 0.8)
slop (>= 2.4.4, < 3) slop (~> 3.3.1)
pygments.rb (0.3.1)
posix-spawn (~> 0.3.6)
yajl-ruby (~> 1.1.0)
pyu-ruby-sasl (0.0.3.3) pyu-ruby-sasl (0.0.3.3)
quiet_assets (1.0.1)
railties (~> 3.1)
rack (1.4.1) rack (1.4.1)
rack-accept (0.4.5)
rack (>= 0.4)
rack-cache (1.2) rack-cache (1.2)
rack (>= 0.4) rack (>= 0.4)
rack-mini-profiler (0.1.9) rack-mini-profiler (0.1.23)
rack (>= 1.1.3) rack (>= 1.1.3)
rack-mount (0.8.3) rack-mount (0.8.3)
rack (>= 1.0.0) rack (>= 1.0.0)
@ -271,65 +307,66 @@ GEM
rack rack
rack-ssl (1.3.2) rack-ssl (1.3.2)
rack rack
rack-test (0.6.1) rack-test (0.6.2)
rack (>= 1.0) rack (>= 1.0)
rails (3.2.8) rails (3.2.9)
actionmailer (= 3.2.8) actionmailer (= 3.2.9)
actionpack (= 3.2.8) actionpack (= 3.2.9)
activerecord (= 3.2.8) activerecord (= 3.2.9)
activeresource (= 3.2.8) activeresource (= 3.2.9)
activesupport (= 3.2.8) activesupport (= 3.2.9)
bundler (~> 1.0) bundler (~> 1.0)
railties (= 3.2.8) railties (= 3.2.9)
rails-dev-tweaks (0.6.1) rails-dev-tweaks (0.6.1)
actionpack (~> 3.1) actionpack (~> 3.1)
railties (~> 3.1) railties (~> 3.1)
railties (3.2.8) railties (3.2.9)
actionpack (= 3.2.8) actionpack (= 3.2.9)
activesupport (= 3.2.8) activesupport (= 3.2.9)
rack-ssl (~> 1.3.2) rack-ssl (~> 1.3.2)
rake (>= 0.8.7) rake (>= 0.8.7)
rdoc (~> 3.4) rdoc (~> 3.4)
thor (>= 0.14.6, < 2.0) thor (>= 0.14.6, < 2.0)
raindrops (0.9.0) raindrops (0.10.0)
rake (0.9.2.2) rake (10.0.1)
raphael-rails (1.5.2) raphael-rails (2.1.0)
rb-fsevent (0.9.1) rb-fsevent (0.9.2)
rb-inotify (0.8.8) rb-inotify (0.8.8)
ffi (>= 0.5.0) ffi (>= 0.5.0)
rdoc (3.12) rdoc (3.12)
json (~> 1.4) json (~> 1.4)
redcarpet (2.1.1) redcarpet (2.2.2)
redis (2.2.2) redis (3.0.2)
redis-namespace (1.0.3) redis-namespace (1.2.1)
redis (< 3.0.0) redis (~> 3.0.0)
resque (1.20.0) resque (1.23.0)
multi_json (~> 1.0) multi_json (~> 1.0)
redis-namespace (~> 1.0.2) redis-namespace (~> 1.0)
sinatra (>= 0.9.2) sinatra (>= 0.9.2)
vegas (~> 0.1.2) vegas (~> 0.1.2)
resque_mailer (2.0.3) resque_mailer (2.1.0)
actionmailer (>= 3.0.0) actionmailer (~> 3.0)
resque (>= 1.2.3) resque_spec (0.12.5)
resque_spec (0.11.0)
resque (>= 1.19.0) resque (>= 1.19.0)
rspec (>= 2.5.0) rspec (>= 2.5.0)
rspec (2.10.0) rspec (2.12.0)
rspec-core (~> 2.10.0) rspec-core (~> 2.12.0)
rspec-expectations (~> 2.10.0) rspec-expectations (~> 2.12.0)
rspec-mocks (~> 2.10.0) rspec-mocks (~> 2.12.0)
rspec-core (2.10.1) rspec-core (2.12.0)
rspec-expectations (2.10.0) rspec-expectations (2.12.0)
diff-lcs (~> 1.1.3) diff-lcs (~> 1.1.3)
rspec-mocks (2.10.1) rspec-mocks (2.12.0)
rspec-rails (2.10.1) rspec-rails (2.12.0)
actionpack (>= 3.0) actionpack (>= 3.0)
activesupport (>= 3.0) activesupport (>= 3.0)
railties (>= 3.0) railties (>= 3.0)
rspec (~> 2.10.0) rspec-core (~> 2.12.0)
rspec-expectations (~> 2.12.0)
rspec-mocks (~> 2.12.0)
rubyntlm (0.1.1) rubyntlm (0.1.1)
rubyzip (0.9.8) rubyzip (0.9.9)
sass (3.1.19) sass (3.2.3)
sass-rails (3.2.5) sass-rails (3.2.5)
railties (~> 3.2.0) railties (~> 3.2.0)
sass (>= 3.1.10) sass (>= 3.1.10)
@ -337,25 +374,24 @@ GEM
seed-fu (2.2.0) seed-fu (2.2.0)
activerecord (~> 3.1) activerecord (~> 3.1)
activesupport (~> 3.1) activesupport (~> 3.1)
selenium-webdriver (2.22.2) selenium-webdriver (2.26.0)
childprocess (>= 0.2.5) childprocess (>= 0.2.5)
ffi (~> 1.0)
libwebsocket (~> 0.1.3) libwebsocket (~> 0.1.3)
multi_json (~> 1.0) multi_json (~> 1.0)
rubyzip rubyzip
settingslogic (2.0.8) settingslogic (2.0.8)
shoulda-matchers (1.3.0) shoulda-matchers (1.3.0)
activesupport (>= 3.0.0) activesupport (>= 3.0.0)
simplecov (0.6.4) simplecov (0.7.1)
multi_json (~> 1.0) multi_json (~> 1.0)
simplecov-html (~> 0.5.3) simplecov-html (~> 0.7.1)
simplecov-html (0.5.3) simplecov-html (0.7.1)
sinatra (1.3.2) sinatra (1.3.3)
rack (~> 1.3, >= 1.3.6) rack (~> 1.3, >= 1.3.6)
rack-protection (~> 1.2) rack-protection (~> 1.2)
tilt (~> 1.3, >= 1.3.3) tilt (~> 1.3, >= 1.3.3)
six (0.2.0) six (0.2.0)
slop (2.4.4) slop (3.3.3)
spinach (0.5.2) spinach (0.5.2)
colorize colorize
gherkin-ruby (~> 0.2.0) gherkin-ruby (~> 0.2.0)
@ -363,39 +399,43 @@ GEM
capybara (~> 1) capybara (~> 1)
railties (>= 3) railties (>= 3)
spinach (>= 0.4) spinach (>= 0.4)
sprockets (2.1.3) sprockets (2.2.1)
hike (~> 1.2) hike (~> 1.2)
multi_json (~> 1.0)
rack (~> 1.0) rack (~> 1.0)
tilt (~> 1.1, != 1.3.0) tilt (~> 1.1, != 1.3.0)
sqlite3 (1.3.6) sqlite3 (1.3.6)
stamp (0.1.6) stamp (0.3.0)
test_after_commit (0.0.1) test_after_commit (0.0.1)
therubyracer (0.10.1) therubyracer (0.10.2)
libv8 (~> 3.3.10) libv8 (~> 3.3.10)
thin (1.3.1) thin (1.5.0)
daemons (>= 1.0.9) daemons (>= 1.0.9)
eventmachine (>= 0.12.6) eventmachine (>= 0.12.6)
rack (>= 1.0.0) rack (>= 1.0.0)
thor (0.16.0) thor (0.16.0)
tilt (1.3.3) tilt (1.3.3)
treetop (1.4.10) treetop (1.4.12)
polyglot polyglot
polyglot (>= 0.3.1) polyglot (>= 0.3.1)
tzinfo (0.3.33) tzinfo (0.3.35)
uglifier (1.0.3) uglifier (1.3.0)
execjs (>= 0.3.0) execjs (>= 0.3.0)
multi_json (>= 1.0.2) multi_json (~> 1.0, >= 1.0.2)
unicorn (4.3.1) unicorn (4.4.0)
kgio (~> 2.6) kgio (~> 2.6)
rack rack
raindrops (~> 0.7) raindrops (~> 0.7)
vegas (0.1.11) vegas (0.1.11)
rack (>= 1.0.0) rack (>= 1.0.0)
virtus (0.5.2)
backports (~> 2.6.1)
warden (1.2.1) warden (1.2.1)
rack (>= 1.0) rack (>= 1.0)
webmock (1.8.7) webmock (1.9.0)
addressable (>= 2.2.7) addressable (>= 2.2.7)
crack (>= 0.1.7) crack (>= 0.1.7)
websocket (1.0.2)
xpath (0.1.4) xpath (0.1.4)
nokogiri (~> 1.3) nokogiri (~> 1.3)
yajl-ruby (1.1.0) yajl-ruby (1.1.0)
@ -404,71 +444,71 @@ PLATFORMS
ruby ruby
DEPENDENCIES DEPENDENCIES
acts-as-taggable-on (= 2.3.1) acts-as-taggable-on (= 2.3.3)
annotate! annotate!
awesome_print awesome_print
bootstrap-sass (= 2.0.4) bootstrap-sass (= 2.2.1.1)
capybara capybara
capybara-webkit carrierwave (~> 0.7.1)
carrierwave chosen-rails (= 0.9.8)
charlock_holmes coffee-rails (~> 3.2.2)
chosen-rails
coffee-rails (= 3.2.2)
colored colored
database_cleaner database_cleaner
devise (~> 2.1.0) devise (~> 2.1.0)
draper draper (~> 0.18.0)
email_spec email_spec
factory_girl_rails factory_girl_rails
ffaker ffaker
font-awesome-sass-rails (~> 2.0.0) font-awesome-sass-rails (~> 2.0.0)
foreman foreman
gemoji gemoji (~> 1.2.1)
git git
github-linguist (~> 2.3.4) github-linguist (~> 2.3.4)
github-markup (~> 0.7.4) github-markup (~> 0.7.4)
gitlab_meta (= 3.0) gitlab_meta (= 3.1)
gitolite (= 1.1.0) gitolite (= 1.1.0)
grack! grack!
grape (~> 0.2.1) grape (~> 0.2.1)
grit! grit!
grit_ext!
growl growl
guard-rspec guard-rspec
guard-spinach guard-spinach
haml-rails haml-rails (~> 0.3.5)
headless
httparty httparty
jquery-atwho-rails (= 0.1.6) jquery-atwho-rails (= 0.1.6)
jquery-rails (= 2.0.2) jquery-rails (= 2.1.3)
jquery-ui-rails (= 0.5.0) jquery-ui-rails (= 2.0.2)
kaminari kaminari (~> 0.14.1)
launchy launchy
letter_opener letter_opener
modernizr (= 2.5.3) modernizr (= 2.6.2)
mysql2 mysql2
omniauth omniauth (~> 1.1.1)
omniauth-github omniauth-github
omniauth-google-oauth2 omniauth-google-oauth2
omniauth-ldap! omniauth-ldap!
omniauth-twitter omniauth-twitter
pg pg
poltergeist
pry pry
pygments.rb (= 0.3.1) pygments.rb!
quiet_assets (~> 1.0.1)
rack-mini-profiler rack-mini-profiler
rails (= 3.2.8) rails (= 3.2.9)
rails-dev-tweaks rails-dev-tweaks
raphael-rails (= 1.5.2) raphael-rails (= 2.1.0)
rb-fsevent rb-fsevent
rb-inotify rb-inotify
redcarpet (~> 2.1.1) redcarpet (~> 2.2.2)
resque (~> 1.20.0) resque (~> 1.23.0)
resque_mailer resque_mailer
resque_spec resque_spec
rspec-rails rspec-rails
sass-rails (= 3.2.5) sass-rails (~> 3.2.5)
seed-fu seed-fu
settingslogic settingslogic
shoulda-matchers shoulda-matchers (= 1.3.0)
simplecov simplecov
six six
spinach-rails spinach-rails
@ -476,8 +516,8 @@ DEPENDENCIES
stamp stamp
test_after_commit test_after_commit
therubyracer therubyracer
thin thin (~> 1.5.0)
uglifier (= 1.0.3) uglifier (~> 1.3.0)
unicorn unicorn (~> 4.4.0)
webmock webmock
yaml_db! yaml_db!

View File

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

View File

@ -13,7 +13,7 @@ GitLab is a free project and repository management application
* Ubuntu/Debian * Ubuntu/Debian
* ruby 1.9.3+ * ruby 1.9.3+
* mysql or sqlite * MySQL
* git * git
* gitolite * gitolite
* redis * redis

25
ROADMAP.md Normal file
View File

@ -0,0 +1,25 @@
## GitLab Roadmap
### Common
* Help page for service tasks like repos import, backup etc
* Hide last push widget after following link
* Add comment events
* gitolite namespaces for projects per user/group. It will allow us same project names for different users
### Issues
* labels autocomplete via jquery autocomplete
* Import/Export issues
* Form: Assign to me link right to the selectbox
### Merge Request
* Save code fragments with MR comments
### Services
* Campfire integration service
* Hipchat integration service
* Travis CI integration service
* Jenkins CI integration service

View File

@ -1 +1 @@
3.0.3 3.1.0

Binary file not shown.

After

Width:  |  Height:  |  Size: 750 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 463 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 632 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 B

View File

@ -13,10 +13,13 @@
//= require jquery.history //= require jquery.history
//= require jquery.waitforimages //= require jquery.waitforimages
//= require jquery.atwho //= require jquery.atwho
//= require jquery.scrollto
//= require bootstrap //= require bootstrap
//= require modernizr //= require modernizr
//= require chosen-jquery //= require chosen-jquery
//= require raphael //= require raphael
//= require g.raphael-min
//= require g.bar-min
//= require branch-graph //= require branch-graph
//= require ace-src-noconflict/ace //= require ace-src-noconflict/ace
//= require_tree . //= require_tree .

View File

@ -1,57 +1,52 @@
# Creates the variables for setting up GFM auto-completion
window.GitLab ?= {}
GitLab.GfmAutoComplete ?= {}
###
Creates the variables for setting up GFM auto-completion
###
# Emoji # Emoji
window.autocompleteEmojiData = []; data = []
window.autocompleteEmojiTemplate = "<li data-value='${insert}'>${name} <img alt='${name}' height='20' src='${image}' width='20' /></li>"; template = "<li data-value='${insert}'>${name} <img alt='${name}' height='20' src='${image}' width='20' /></li>"
GitLab.GfmAutoComplete.Emoji = {data, template}
# Team Members # Team Members
window.autocompleteMembersUrl = ""; data = []
window.autocompleteMembersParams = url = '';
private_token: "" params = {private_token: '', page: 1}
page: 1 GitLab.GfmAutoComplete.Members = {data, url, params}
window.autocompleteMembersData = [];
# Add GFM auto-completion to all input fields, that accept GFM input.
GitLab.GfmAutoComplete.setup = ->
input = $('.js-gfm-input')
# Emoji
input.atWho ':',
data: GitLab.GfmAutoComplete.Emoji.data,
tpl: GitLab.GfmAutoComplete.Emoji.template
### # Team Members
Add GFM auto-completion to all input fields, that accept GFM input. input.atWho '@', (query, callback) ->
###
window.setupGfmAutoComplete = ->
###
Emoji
###
$('.gfm-input').atWho ':',
data: autocompleteEmojiData,
tpl: autocompleteEmojiTemplate
###
Team Members
###
$('.gfm-input').atWho '@', (query, callback) ->
(getMoreMembers = -> (getMoreMembers = ->
$.getJSON(autocompleteMembersUrl, autocompleteMembersParams) $.getJSON(GitLab.GfmAutoComplete.Members.url, GitLab.GfmAutoComplete.Members.params)
.success (members) -> .success (members) ->
# pick the data we need # pick the data we need
newMembersData = $.map members, (m) -> m.name newMembersData = $.map(members, (m) -> m.name )
# add the new page of data to the rest # add the new page of data to the rest
$.merge autocompleteMembersData, newMembersData $.merge(GitLab.GfmAutoComplete.Members.data, newMembersData)
# show the pop-up with a copy of the current data # show the pop-up with a copy of the current data
callback autocompleteMembersData[..] callback(GitLab.GfmAutoComplete.Members.data[..])
# are we past the last page? # are we past the last page?
if newMembersData.length == 0 if newMembersData.length is 0
# set static data and stop callbacks # set static data and stop callbacks
$('.gfm-input').atWho '@', input.atWho '@',
data: autocompleteMembersData data: GitLab.GfmAutoComplete.Members.data
callback: null callback: null
else else
# get next page # get next page
getMoreMembers() getMoreMembers()
# so the next request gets the next page # so the next request gets the next page
autocompleteMembersParams.page += 1; GitLab.GfmAutoComplete.Members.params.page += 1
).call(); ).call()

View File

@ -1,10 +0,0 @@
initGraphNav = ->
$('.graph svg').css 'position', 'relative'
$('body').bind 'keyup', (e) ->
if e.keyCode is 37 # left
$('.graph svg').animate left: '+=400'
else if e.keyCode is 39 # right
$('.graph svg').animate left: '-=400'
window.initGraphNav = initGraphNav

View File

@ -1,24 +1,22 @@
function switchToNewIssue(form){ function switchToNewIssue(){
$(".issues_content").hide("fade", { direction: "left" }, 150, function(){ $(".issues_content").hide("fade", { direction: "left" }, 150, function(){
$(".issues_content").after(form);
$('select#issue_assignee_id').chosen(); $('select#issue_assignee_id').chosen();
$('select#issue_milestone_id').chosen(); $('select#issue_milestone_id').chosen();
$("#new_issue_dialog").show("fade", { direction: "right" }, 150); $("#new_issue_dialog").show("fade", { direction: "right" }, 150);
$('.top-tabs .add_new').hide(); $('.top-tabs .add_new').hide();
disableButtonIfEmptyField("#issue_title", ".save-btn"); disableButtonIfEmptyField("#issue_title", ".save-btn");
setupGfmAutoComplete(); GitLab.GfmAutoComplete.setup();
}); });
} }
function switchToEditIssue(form){ function switchToEditIssue(){
$(".issues_content").hide("fade", { direction: "left" }, 150, function(){ $(".issues_content").hide("fade", { direction: "left" }, 150, function(){
$(".issues_content").after(form);
$('select#issue_assignee_id').chosen(); $('select#issue_assignee_id').chosen();
$('select#issue_milestone_id').chosen(); $('select#issue_milestone_id').chosen();
$("#edit_issue_dialog").show("fade", { direction: "right" }, 150); $("#edit_issue_dialog").show("fade", { direction: "right" }, 150);
$('.add_new').hide(); $('.add_new').hide();
disableButtonIfEmptyField("#issue_title", ".save-btn"); disableButtonIfEmptyField("#issue_title", ".save-btn");
setupGfmAutoComplete(); GitLab.GfmAutoComplete.setup();
}); });
} }
@ -33,18 +31,18 @@ function switchFromEditIssue(){
function backToIssues(){ function backToIssues(){
$("#edit_issue_dialog, #new_issue_dialog").hide("fade", { direction: "right" }, 150, function(){ $("#edit_issue_dialog, #new_issue_dialog").hide("fade", { direction: "right" }, 150, function(){
$(".issues_content").show("fade", { direction: "left" }, 150, function() { $(".issues_content").show("fade", { direction: "left" }, 150, function() {
$("#edit_issue_dialog").remove(); $("#edit_issue_dialog").html("");
$("#new_issue_dialog").remove(); $("#new_issue_dialog").html("");
$('.add_new').show(); $('.add_new').show();
}); });
}); });
} }
function initIssuesSearch() { function initIssuesSearch() {
var href = $('.issue_search').parent().attr('action'); var href = $('#issue_search_form').attr('action');
var last_terms = ''; var last_terms = '';
$('.issue_search').keyup(function() { $('#issue_search').keyup(function() {
var terms = $(this).val(); var terms = $(this).val();
var milestone_id = $('#milestone_id').val(); var milestone_id = $('#milestone_id').val();
var status = $('#status').val(); var status = $('#status').val();
@ -59,10 +57,6 @@ function initIssuesSearch() {
} }
} }
}); });
$('.delete-issue').live('ajax:success', function() {
$(this).closest('tr').fadeOut(); updatePage();
});
} }
/** /**

View File

@ -1,5 +0,0 @@
Loader =
html: (width) ->
$('<img>').attr src: '/assets/ajax-loader.gif', width: width
window.Loader = Loader

View File

@ -7,29 +7,36 @@ window.slugify = (text) ->
window.ajaxGet = (url) -> window.ajaxGet = (url) ->
$.ajax({type: "GET", url: url, dataType: "script"}) $.ajax({type: "GET", url: url, dataType: "script"})
# Disable button if text field is empty # Disable button if text field is empty
window.disableButtonIfEmptyField = (field_selector, button_selector) -> window.disableButtonIfEmptyField = (field_selector, button_selector) ->
field = $(field_selector) field = $(field_selector)
closest_submit = field.closest("form").find(button_selector) closest_submit = field.closest("form").find(button_selector)
closest_submit.disable() if field.val() is "" closest_submit.disable() if field.val() is ""
field.on "keyup", -> field.on "input", ->
if $(this).val() is "" if $(@).val() is ""
closest_submit.disable() closest_submit.disable()
else else
closest_submit.enable() closest_submit.enable()
$ -> $ ->
# Click a .one_click_select field, select the contents # Click a .one_click_select field, select the contents
$(".one_click_select").live 'click', -> $(this).select() $(".one_click_select").on 'click', -> $(@).select()
# Initialize chosen selects # Initialize chosen selects
$('select.chosen').chosen() $('select.chosen').chosen()
# Initialize tooltips
$('.has_tooltip').tooltip()
# Bottom tooltip
$('.has_bottom_tooltip').tooltip(placement: 'bottom')
# Disable form buttons while a form is submitting # Disable form buttons while a form is submitting
$('body').on 'ajax:complete, ajax:beforeSend, submit', 'form', (e) -> $('body').on 'ajax:complete, ajax:beforeSend, submit', 'form', (e) ->
buttons = $('[type="submit"]', this) buttons = $('[type="submit"]', @)
switch e.type switch e.type
when 'ajax:beforeSend', 'submit' when 'ajax:beforeSend', 'submit'
@ -38,7 +45,7 @@ $ ->
buttons.enable() buttons.enable()
# Show/Hide the profile menu when hovering the account box # Show/Hide the profile menu when hovering the account box
$('.account-box').hover -> $(this).toggleClass('hover') $('.account-box').hover -> $(@).toggleClass('hover')
# Focus search field by pressing 's' key # Focus search field by pressing 's' key
$(document).keypress (e) -> $(document).keypress (e) ->
@ -52,41 +59,22 @@ $ ->
# Commit show suppressed diff # Commit show suppressed diff
$(".supp_diff_link").bind "click", -> $(".supp_diff_link").bind "click", ->
$(this).next('table').show() $(@).next('table').show()
$(this).remove() $(@).remove()
# Note markdown preview
$(document).on 'click', '#preview-link', (e) ->
$('#preview-note').text('Loading...')
previewLinkText = if $(this).text() == 'Preview' then 'Edit' else 'Preview'
$(this).text(previewLinkText)
note = $('#note_note').val()
if note.trim().length == 0
$('#preview-note').text("Nothing to preview.")
else
$.post $(this).attr('href'), {note: note}, (data) ->
$('#preview-note').html(data)
$('#preview-note, #note_note').toggle()
e.preventDefault()
false
(($) -> (($) ->
_chosen = $.fn.chosen _chosen = $.fn.chosen
$.fn.extend chosen: (options) -> $.fn.extend chosen: (options) ->
default_options = search_contains: "true" default_options = search_contains: "true"
$.extend default_options, options $.extend default_options, options
_chosen.apply this, [default_options] _chosen.apply @, [default_options]
# Disable an element and add the 'disabled' Bootstrap class # Disable an element and add the 'disabled' Bootstrap class
$.fn.extend disable: -> $.fn.extend disable: ->
$(this).attr('disabled', 'disabled').addClass('disabled') $(@).attr('disabled', 'disabled').addClass('disabled')
# Enable an element and remove the 'disabled' Bootstrap class # Enable an element and remove the 'disabled' Bootstrap class
$.fn.extend enable: -> $.fn.extend enable: ->
$(this).removeAttr('disabled').removeClass('disabled') $(@).removeAttr('disabled').removeClass('disabled')
)(jQuery) )(jQuery)

View File

@ -115,4 +115,15 @@ var MergeRequest = {
$(".merge_in_progress").hide(); $(".merge_in_progress").hide();
$(".automerge_widget.already_cannot_be_merged").show(); $(".automerge_widget.already_cannot_be_merged").show();
} }
};
/*
* Filter merge requests
*/
function merge_requestsPage() {
$("#assignee_id").chosen();
$("#milestone_id").chosen();
$("#milestone_id, #assignee_id").on("change", function(){
$(this).closest("form").submit();
});
} }

View File

@ -5,3 +5,10 @@ $ ->
$('.milestone-issue-filter li').toggleClass('active') $('.milestone-issue-filter li').toggleClass('active')
$('.milestone-issue-filter tr[data-closed]').toggleClass('hide') $('.milestone-issue-filter tr[data-closed]').toggleClass('hide')
false false
$('.milestone-merge-requests-filter tr[data-closed]').addClass('hide')
$('.milestone-merge-requests-filter ul.nav li a').click ->
$('.milestone-merge-requests-filter li').toggleClass('active')
$('.milestone-merge-requests-filter tr[data-closed]').toggleClass('hide')
false

View File

@ -14,8 +14,8 @@ var NoteList = {
this.notes_path = path + ".js"; this.notes_path = path + ".js";
this.target_id = tid; this.target_id = tid;
this.target_type = tt; this.target_type = tt;
this.reversed = $("#notes-list").hasClass("reversed"); this.reversed = $("#notes-list").is(".reversed");
this.target_params = "&target_type=" + this.target_type + "&target_id=" + this.target_id; this.target_params = "target_type=" + this.target_type + "&target_id=" + this.target_id;
// get initial set of notes // get initial set of notes
this.getContent(); this.getContent();
@ -33,6 +33,8 @@ var NoteList = {
$(".note-form-holder").on("ajax:complete", function(){ $(".note-form-holder").on("ajax:complete", function(){
$(".submit_note").enable(); $(".submit_note").enable();
$('#preview-note').hide();
$('#note_note').show();
}) })
disableButtonIfEmptyField(".note-text", ".submit_note"); disableButtonIfEmptyField(".note-text", ".submit_note");
@ -52,6 +54,26 @@ var NoteList = {
$('.note_advanced_opts').show(); $('.note_advanced_opts').show();
}); });
} }
// Setup note preview
$(document).on('click', '#preview-link', function(e) {
$('#preview-note').text('Loading...');
$(this).text($(this).text() === "Edit" ? "Preview" : "Edit");
var note_text = $('#note_note').val();
if(note_text.trim().length === 0) {
$('#preview-note').text('Nothing to preview.');
} else {
$.post($(this).attr('href'), {note: note_text}).success(function(data) {
$('#preview-note').html(data);
});
}
$('#preview-note, #note_note').toggle();
e.preventDefault();
});
}, },
@ -69,7 +91,7 @@ var NoteList = {
$.ajax({ $.ajax({
type: "GET", type: "GET",
url: this.notes_path, url: this.notes_path,
data: "?" + this.target_params, data: this.target_params,
complete: function(){ $('.notes-status').removeClass("loading")}, complete: function(){ $('.notes-status').removeClass("loading")},
beforeSend: function() { $('.notes-status').addClass("loading") }, beforeSend: function() { $('.notes-status').addClass("loading") },
dataType: "script"}); dataType: "script"});
@ -131,7 +153,7 @@ var NoteList = {
$.ajax({ $.ajax({
type: "GET", type: "GET",
url: this.notes_path, url: this.notes_path,
data: "loading_more=1&" + (this.reversed ? "before_id" : "after_id") + "=" + this.bottom_id + this.target_params, data: this.target_params + "&loading_more=1&" + (this.reversed ? "before_id" : "after_id") + "=" + this.bottom_id,
complete: function(){ $('.notes-status').removeClass("loading")}, complete: function(){ $('.notes-status').removeClass("loading")},
beforeSend: function() { $('.notes-status').addClass("loading") }, beforeSend: function() { $('.notes-status').addClass("loading") },
dataType: "script"}); dataType: "script"});
@ -192,7 +214,7 @@ var NoteList = {
$.ajax({ $.ajax({
type: "GET", type: "GET",
url: this.notes_path, url: this.notes_path,
data: "loading_new=1&after_id=" + (this.reversed ? this.top_id : this.bottom_id) + this.target_params, data: this.target_params + "&loading_new=1&after_id=" + (this.reversed ? this.top_id : this.bottom_id),
dataType: "script"}); dataType: "script"});
}, },
@ -264,7 +286,7 @@ var PerLineNotes = {
$(this).closest("tr").after(form); $(this).closest("tr").after(form);
form.find("#note_line_code").val($(this).data("lineCode")); form.find("#note_line_code").val($(this).data("lineCode"));
form.show(); form.show();
return false; e.preventDefault();
}); });
disableButtonIfEmptyField(".line-note-text", ".submit_inline_note"); disableButtonIfEmptyField(".line-note-text", ".submit_inline_note");
@ -285,7 +307,7 @@ var PerLineNotes = {
// elements must really be removed for this to work reliably // elements must really be removed for this to work reliably
var trLine = trNote.prev(); var trLine = trNote.prev();
var trRpl = trNote.next(); var trRpl = trNote.next();
if (trLine.hasClass("line_holder") && trRpl.hasClass("reply")) { if (trLine.is(".line_holder") && trRpl.is(".reply")) {
trRpl.fadeOut(function() { $(this).remove(); }); trRpl.fadeOut(function() { $(this).remove(); });
} }
}); });

View File

@ -0,0 +1,10 @@
$ ->
$('.edit_user .application-theme input, .edit_user .code-preview-theme input').click ->
# Hide any previous submission feedback
$('.edit_user .update-feedback').hide()
# Submit the form
$('.edit_user').submit()
# Go up the hierarchy and show the corresponding submission feedback element
$(@).closest('fieldset').find('.update-feedback').show('highlight', {color: '#DFF0D8'}, 500)

View File

@ -22,3 +22,10 @@ $ ->
# Ref switcher # Ref switcher
$('.project-refs-select').on 'change', -> $('.project-refs-select').on 'change', ->
$(@).parents('form').submit() $(@).parents('form').submit()
class @GraphNav
@init: ->
$('.graph svg').css 'position', 'relative'
$('body').bind 'keyup', (e) ->
$('.graph svg').animate(left: '+=400') if e.keyCode is 37 # left
$('.graph svg').animate(left: '-=400') if e.keyCode is 39 # right

View File

@ -1,6 +0,0 @@
$ ->
$('#snippets-table .snippet').live 'click', (e) ->
if e.target.nodeName isnt 'A' and e.target.nodeName isnt 'INPUT'
location.href = $(@).attr 'url'
e.stopPropagation()
false

View File

@ -17,23 +17,40 @@ $ ->
"ajax:beforeSend": -> $('.tree_progress').addClass("loading") "ajax:beforeSend": -> $('.tree_progress').addClass("loading")
"ajax:complete": -> $('.tree_progress').removeClass("loading") "ajax:complete": -> $('.tree_progress').removeClass("loading")
# Maintain forward/back history while browsing the file tree # Maintain forward/back history while browsing the file tree
((window) ->
History = window.History
$ = window.jQuery
document = window.document
((window) -> # Check to see if History.js is enabled for our Browser
History = window.History unless History.enabled
$ = window.jQuery return false
document = window.document
# Check to see if History.js is enabled for our Browser $('#tree-slider .tree-item-file-name a, .breadcrumb li > a').live 'click', (e) ->
unless History.enabled History.pushState(null, null, $(@).attr('href'))
return false return false
$ -> History.Adapter.bind window, 'statechange', ->
$('#tree-slider .tree-item-file-name a, .breadcrumb li > a').live 'click', (e) -> state = History.getState()
History.pushState(null, null, $(@).attr('href')) window.ajaxGet(state.url)
return false )(window)
History.Adapter.bind window, 'statechange', -> # See if there are lines selected
state = History.getState() # "#L12" and "#L34-56" supported
window.ajaxGet(state.url) highlightBlobLines = ->
)(window) if window.location.hash isnt ""
matches = window.location.hash.match(/\#L(\d+)(\-(\d+))?/)
first_line = parseInt(matches?[1])
last_line = parseInt(matches?[3])
unless isNaN first_line
last_line = first_line if isNaN(last_line)
$("#tree-content-holder .highlight .line").removeClass("hll")
$("#LC#{line}").addClass("hll") for line in [first_line..last_line]
$("#L#{first_line}").ScrollTo()
# Highlight the correct lines on load
highlightBlobLines()
# Highlight the correct lines when the hash part of the URL changes
$(window).on 'hashchange', highlightBlobLines

View File

@ -20,18 +20,6 @@ body {
float:right; float:right;
} }
.profile_avatar_holder {
float:left;
width:60px;
height:60px;
margin-right:20px;
img {
width:60px;
height:60px;
background:#eee;
}
}
.visible_link, .visible_link,
.author_link { .author_link {
@ -596,25 +584,6 @@ li.note {
} }
} }
.themes_opts {
padding-left:20px;
label {
width:175px;
margin-right:40px;
.prev {
@extend .thumbnail;
height:120px;
width:175px;
margin-bottom:10px;
img {
width:180px;
}
}
}
}
.git_error_tips { .git_error_tips {
@extend .span6; @extend .span6;
text-align:left; text-align:left;
@ -628,10 +597,11 @@ li.note {
.error_message { .error_message {
@extend .cred; @extend .cred;
border-bottom: 1px solid #D21; border-left: 4px solid #E99;
padding-bottom:20px; padding: 10px;
text-align:center; margin-bottom: 10px;
margin-bottom:10px; background: #FEE;
padding-left: 20px;
} }
.oauth_select_holder { .oauth_select_holder {
@ -670,3 +640,16 @@ pre {
padding:0; padding:0;
} }
} }
.milestone .progress {
margin-bottom: 0;
margin-top:4px;
}
.float-link {
float:left;
margin-right:15px;
.s16 {
margin-right:5px;
}
}

View File

@ -94,6 +94,7 @@
&.very_small { &.very_small {
font-size:11px; font-size:11px;
padding:2px 6px; padding:2px 6px;
line-height: 16px;
margin:2px; margin:2px;
} }

View File

@ -26,8 +26,10 @@
.underlined { border-bottom: 1px solid #CCC; } .underlined { border-bottom: 1px solid #CCC; }
.no-borders { border:none; } .no-borders { border:none; }
.vlink { color: $link_color !important; } .vlink { color: $link_color !important; }
.underlined_link { text-decoration: underline; }
.borders { border: 1px solid #ccc; @include shade; } .borders { border: 1px solid #ccc; @include shade; }
.hint { font-style: italic; color: #999; } .hint { font-style: italic; color: #999; }
.light { color: #888 }
/** PILLS & TABS**/ /** PILLS & TABS**/
.nav-pills a:hover { background-color:#888; } .nav-pills a:hover { background-color:#888; }
@ -38,6 +40,7 @@
> a { > a {
padding:8px 20px; padding:8px 20px;
margin-right: 7px; margin-right: 7px;
line-height: 19px;
border-color: #EEE; border-color: #EEE;
color:#888; color:#888;
border-bottom: 1px solid #ddd; border-bottom: 1px solid #ddd;
@ -66,11 +69,12 @@
.alert-message.error { @extend .alert-error; } .alert-message.error { @extend .alert-error; }
/** AVATARS **/ /** AVATARS **/
img.avatar { float:left; margin-right:15px; width:40px; border:1px solid #ddd; padding:1px; } img.avatar { float:left; margin-right:12px; width:40px; border:1px solid #ddd; padding:1px; }
img.avatar.s16 { width:16px; height:16px; } img.avatar.s16 { width:16px; height:16px; margin-right:6px; }
img.avatar.s24 { width:24px; height:24px; } img.avatar.s24 { width:24px; height:24px; margin-right:8px; }
img.avatar.s32 { width:32px; height:32px; } img.avatar.s32 { width:32px; height:32px; margin-right:10px; }
img.lil_av { padding-left: 4px; padding-right:3px; } img.lil_av { padding-left: 4px; padding-right:3px; }
img.small { width: 80px; }
/** HELPERS **/ /** HELPERS **/
.nothing_here_message { text-align:center; padding:20px; color:#777; } .nothing_here_message { text-align:center; padding:20px; color:#777; }
@ -85,3 +89,5 @@ input[type='search'].search-text-input {
@include border-radius(4px); @include border-radius(4px);
border:1px solid #ccc; border:1px solid #ccc;
} }
fieldset legend { font-size: 17px; }

View File

@ -132,35 +132,74 @@
* Code file * Code file
*/ */
&.code { &.code {
padding:0; padding: 0;
td.code {
width: 100%;
.highlight {
margin-left: 55px;
overflow:auto;
overflow-y:hidden;
}
}
.highlight pre {
white-space: pre;
word-wrap:normal;
}
table.highlighttable { table.lines {
border: none; border: none;
} box-shadow: none;
body.project-page table.highlighttable td { border: none } margin: 0px;
table.highlighttable tr:hover { background:none;} padding: 0px;
table-layout: fixed;
table.highlighttable pre{ pre {
line-height:16px !important; background: none;
font-size:12px !important; border: none;
} font-family: 'Menlo', 'Liberation Mono', 'Consolas', 'Courier New', 'andale mono','lucida console',monospace;
font-size: 12px !important;
line-height: 16px !important;
margin: 0;
padding: 10px 0;
}
td {
border: none;
margin: 0;
padding: 0;
vertical-align: top;
table.highlighttable .linenodiv pre { &:first-child {
text-align: right; background: #eee;
padding-right: 4px; width: 50px;
color:#666; }
&:last-child {
}
}
tr:hover {
background: none;
}
pre.line_numbers {
color: #666;
padding: 10px 6px 10px 0;
text-align: right;
a {
color: #666;
i {
display: none;
font-size: 14px;
line-height: 14px;
}
&:hover i {
display: inherit;
}
}
}
.highlight {
border-left: 1px solid #DEE2E3;
overflow: auto;
overflow-y: hidden;
pre {
white-space: pre;
word-wrap: normal;
.line {
padding: 0 10px;
}
}
}
} }
} }
} }

View File

@ -21,7 +21,7 @@ ul {
.author { color: #999; } .author { color: #999; }
p { p {
padding-top:5px; padding-top: 1px;
margin:0; margin:0;
color:#222; color:#222;
img { img {
@ -31,3 +31,11 @@ ul {
} }
} }
} }
ol, ul {
&.styled {
li {
padding:2px;
}
}
}

View File

@ -34,6 +34,11 @@ table {
border-color:#f1f1f1; border-color:#f1f1f1;
line-height:28px; line-height:28px;
.s16 {
margin-top: 5px;
margin-right: 5px;
}
&:first-child { &:first-child {
border-left:1px solid #bbb; border-left:1px solid #bbb;
} }

View File

@ -2,8 +2,11 @@
* Headers * Headers
* *
*/ */
h1, h2, h3, h4, h5, h6 { margin: 0; }
h3, h4, h5, h6 { line-height: 36px; } h3, h4, h5, h6 { line-height: 36px; }
h5 { font-size:14px; } h5 { font-size:14px; }
h3.page_title { h3.page_title {
color:#456; color:#456;
font-size:20px; font-size:20px;
@ -11,6 +14,11 @@ h3.page_title {
line-height: 28px; line-height: 28px;
} }
h6 {
color: #888;
text-transform: uppercase;
}
/** CODE **/ /** CODE **/
pre { pre {
font-family:'Menlo', 'Liberation Mono', 'Consolas', 'Courier New', 'andale mono','lucida console',monospace; font-family:'Menlo', 'Liberation Mono', 'Consolas', 'Courier New', 'andale mono','lucida console',monospace;

View File

@ -1,9 +1,8 @@
.black .highlighttable { .black .lines .highlight {
td.linenos { border:none; } background: #333;
pre { color: #eee } pre { color: #eee; }
.highlight { background: #333; border-left:1px solid #555; }
.hll { background-color: #ffffff } .hll { display: block; background-color: darken($hover, 65%) }
.c { color: #888888; font-style: italic } /* Comment */ .c { color: #888888; font-style: italic } /* Comment */
.err { color: #a61717; background-color: #e3d2d2 } /* Error */ .err { color: #a61717; background-color: #e3d2d2 } /* Error */
.k { color: #CDA869; font-weight: bold } /* Keyword */ .k { color: #CDA869; font-weight: bold } /* Keyword */
@ -22,43 +21,43 @@
.gs { font-weight: bold } /* Generic.Strong */ .gs { font-weight: bold } /* Generic.Strong */
.gu { color: #606060 } /* Generic.Subheading */ .gu { color: #606060 } /* Generic.Subheading */
.gt { color: #aa0000 } /* Generic.Traceback */ .gt { color: #aa0000 } /* Generic.Traceback */
.highlight .kc{font-weight:bold;} /* Keyword.Constant */ .kc{font-weight:bold;} /* Keyword.Constant */
.highlight .kd{font-weight:bold;} /* Keyword.Declaration */ .kd{font-weight:bold;} /* Keyword.Declaration */
.highlight .kn{font-weight:bold;} /* Keyword.Namespace */ .kn{font-weight:bold;} /* Keyword.Namespace */
.highlight .kp{font-weight:bold;} /* Keyword.Pseudo */ .kp{font-weight:bold;} /* Keyword.Pseudo */
.highlight .kr{font-weight:bold;} /* Keyword.Reserved */ .kr{font-weight:bold;} /* Keyword.Reserved */
.highlight .kt{color:#458;font-weight:bold;} /* Keyword.Type */ .kt{color:#458;font-weight:bold;} /* Keyword.Type */
.m { color: #0000DD; font-weight: bold } /* Literal.Number */ .m { color: #0000DD; font-weight: bold } /* Literal.Number */
.p { color: #eee; } .p { color: #eee; }
.s { color: #0AD; background-color: transparent } /* Literal.String */ .s { color: #0AD; background-color: transparent } /* Literal.String */
.highlight .na{color:#008080;} /* Name.Attribute */ .na{color:#008080;} /* Name.Attribute */
.highlight .nb{color:#0086B3;} /* Name.Builtin */ .nb{color:#0086B3;} /* Name.Builtin */
.highlight .nc{color:#ccc;font-weight:bold;} /* Name.Class */ .nc{color:#ccc;font-weight:bold;} /* Name.Class */
.highlight .no{color:turquoise;} /* Name.Constant */ .no{color:turquoise;} /* Name.Constant */
.highlight .ni{color:#800080;} .ni{color:#800080;}
.highlight .ne{color:#900;font-weight:bold;} /* Name.Exception */ .ne{color:#900;font-weight:bold;} /* Name.Exception */
.highlight .nf{color:#ccc;font-weight:bold;} /* Name.Function */ .nf{color:#ccc;font-weight:bold;} /* Name.Function */
.highlight .nn{color:#79C3E0;font-weight:bold;} /* Name.Namespace */ .nn{color:#79C3E0;font-weight:bold;} /* Name.Namespace */
.highlight .nt{color:#fc5;} /* Name.Tag */ .nt{color:#fc5;} /* Name.Tag */
.highlight .nv{color:#FA4;} /* Name.Variable */ .nv{color:#FA4;} /* Name.Variable */
.py { color: #336699; font-weight: bold } /* Name.Property */ .py { color: #336699; font-weight: bold } /* Name.Property */
.ow { color: #008800 } /* Operator.Word */ .ow { color: #008800 } /* Operator.Word */
.w { color: #bbbbbb } /* Text.Whitespace */ .w { color: #bbbbbb } /* Text.Whitespace */
.mf { color: #7AC; font-weight: bold } /* Literal.Number.Float */ .mf { color: #7AC; font-weight: bold } /* Literal.Number.Float */
.mh { color: #7AC; font-weight: bold } /* Literal.Number.Hex */ .mh { color: #7AC; font-weight: bold } /* Literal.Number.Hex */
.highlight .mi {color:#099;} /* Literal.Number.Integer */ .mi {color:#099;} /* Literal.Number.Integer */
.mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */ .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */
.sb { color: #dd2200; background-color: transparent; } /* Literal.String.Backtick */ .sb { color: #dd2200; background-color: transparent; } /* Literal.String.Backtick */
.highlight .sc{color:#d14;} /* Literal.String.Char */ .sc{color:#d14;} /* Literal.String.Char */
.sd { color: #dd2200; background-color: transparent; } /* Literal.String.Doc */ .sd { color: #dd2200; background-color: transparent; } /* Literal.String.Doc */
.highlight .s2{color:orange;} /* Literal.String.Double */ .s2{color:orange;} /* Literal.String.Double */
.highlight .se{color:orange;} /* Literal.String.Escape */ .se{color:orange;} /* Literal.String.Escape */
.highlight .sh{color:orange;} /* Literal.String.Heredoc */ .sh{color:orange;} /* Literal.String.Heredoc */
.highlight .si{color:orange;} /* Literal.String.Interpol */ .si{color:orange;} /* Literal.String.Interpol */
.highlight .sx{color:orange;} /* Literal.String.Other */ .sx{color:orange;} /* Literal.String.Other */
.highlight .sr{color:orange;} /* Literal.String.Regex */ .sr{color:orange;} /* Literal.String.Regex */
.highlight .s1{color:orange;} /* Literal.String.Single */ .s1{color:orange;} /* Literal.String.Single */
.highlight .ss{color:orange;} /* Literal.String.Symbol */ .ss{color:orange;} /* Literal.String.Symbol */
.bp { color: #D58 } /* Name.Builtin.Pseudo */ .bp { color: #D58 } /* Name.Builtin.Pseudo */
.vc { color: #336699 } /* Name.Variable.Class */ .vc { color: #336699 } /* Name.Variable.Class */
.vg { color: #dd7700 } /* Name.Variable.Global */ .vg { color: #dd7700 } /* Name.Variable.Global */

View File

@ -1,141 +1,69 @@
table.highlighttable { .white .lines .highlight {
margin:0px;
padding:0px;
font-size:12px;
table-layout:fixed;
background: #EEE;
box-shadow: none;
border: none;
td.linenos {
background:#eee;
border-left:none;
}
td.code {
border-right:none;
}
}
td.code,
td.linenos{
padding:0;
margin:0;
border-top:0;
vertical-align:top;
}
.highlighttable .highlight{
background:none;
padding:10px 0px 0px 10px;
margin-left:0px;
border-left: 1px solid #DEE2E3;
background: white; background: white;
pre { color: #333; }
.hll { display: block; background-color: $hover }
.c { color: #888888; font-style: italic } /* Comment */
.err { color: #a61717; background-color: #e3d2d2 } /* Error */
.k { color: #000000; font-weight: bold } /* Keyword */
.cm { color: #888888 } /* Comment.Multiline */
.cp { color: #cc0000; font-weight: bold } /* Comment.Preproc */
.c1 { color: #888888 } /* Comment.Single */
.cs { color: #cc0000; font-weight: bold; background-color: #fff0f0 } /* Comment.Special */
.gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */
.ge { font-style: italic } /* Generic.Emph */
.gr { color: #aa0000 } /* Generic.Error */
.gh { color: #303030 } /* Generic.Heading */
.gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */
.go { color: #888888 } /* Generic.Output */
.gp { color: #555555 } /* Generic.Prompt */
.gs { font-weight: bold } /* Generic.Strong */
.gu { color: #606060 } /* Generic.Subheading */
.gt { color: #aa0000 } /* Generic.Traceback */
.kc{font-weight:bold;} /* Keyword.Constant */
.kd{font-weight:bold;} /* Keyword.Declaration */
.kn{font-weight:bold;} /* Keyword.Namespace */
.kp{font-weight:bold;} /* Keyword.Pseudo */
.kr{font-weight:bold;} /* Keyword.Reserved */
.kt{color:#458;font-weight:bold;} /* Keyword.Type */
.m { color: #0000DD; font-weight: bold } /* Literal.Number */
.s { color: #dd2200; background-color: #fff0f0 } /* Literal.String */
.na{color:#008080;} /* Name.Attribute */
.nb{color:#0086B3;} /* Name.Builtin */
.nc{color:#458;font-weight:bold;} /* Name.Class */
.no{color:#008080;} /* Name.Constant */
.ni{color:#800080;}
.ne{color:#900;font-weight:bold;} /* Name.Exception */
.nf{color:#900;font-weight:bold;} /* Name.Function */
.nn{color:#005;font-weight:bold;} /* Name.Namespace */
.nt{color:#000080;} /* Name.Tag */
.nv{color:#008080;} /* Name.Variable */
.py { color: #336699; font-weight: bold } /* Name.Property */
.ow { color: #008800 } /* Operator.Word */
.w { color: #bbbbbb } /* Text.Whitespace */
.mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */
.mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */
.mi {color:#099;} /* Literal.Number.Integer */
.mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */
.sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */
.sc{color:#d14;} /* Literal.String.Char */
.sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */
.s2{color:#d14;} /* Literal.String.Double */
.se{color:#d14;} /* Literal.String.Escape */
.sh{color:#d14;} /* Literal.String.Heredoc */
.si{color:#d14;} /* Literal.String.Interpol */
.sx{color:#d14;} /* Literal.String.Other */
.sr{color:#d14;} /* Literal.String.Regex */
.s1{color:#d14;} /* Literal.String.Single */
.ss{color:#d14;} /* Literal.String.Symbol */
.bp { color: #003388 } /* Name.Builtin.Pseudo */
.vc { color: #336699 } /* Name.Variable.Class */
.vg { color: #dd7700 } /* Name.Variable.Global */
.vi { color: #3333bb }
} }
.linenodiv pre, .shadow {
.highlighttable .highlight pre{
margin:0;
padding:0;
background:none;
border:none;
}
.linenodiv pre {
white-space:pre-line;
}
td.linenos {
/*background:#F7F7F7;*/
color:#666;
padding:10px 0px 0px 10px;
float:left;
width:45px;
border-right: 1px solid #ccc;
}
td.code .highlight {
overflow: auto;
}
table.highlighttable pre{
padding:0;
margin:0;
font-family: 'Menlo', 'Liberation Mono', 'Consolas', 'Courier New', 'andale mono','lucida console',monospace;
color: #333;
text-align:left;
}
.git-empty .highlight {
pre{
padding:15px;
line-height:2.0;
margin:0;
font-family: 'Menlo', 'Liberation Mono', 'Consolas', 'Courier New', 'andale mono','lucida console',monospace;
color: #333;
text-align:left;}
}
.shadow{
-webkit-box-shadow:0 5px 15px #000; -webkit-box-shadow:0 5px 15px #000;
-moz-box-shadow:0 5px 15px #000; -moz-box-shadow:0 5px 15px #000;
box-shadow:0 5px 15px #000; box-shadow:0 5px 15px #000;
} }
.hll { background-color: #ffffff }
.c { color: #888888; font-style: italic } /* Comment */
.err { color: #a61717; background-color: #e3d2d2 } /* Error */
.k { color: #000000; font-weight: bold } /* Keyword */
.cm { color: #888888 } /* Comment.Multiline */
.cp { color: #cc0000; font-weight: bold } /* Comment.Preproc */
.c1 { color: #888888 } /* Comment.Single */
.cs { color: #cc0000; font-weight: bold; background-color: #fff0f0 } /* Comment.Special */
.gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */
.ge { font-style: italic } /* Generic.Emph */
.gr { color: #aa0000 } /* Generic.Error */
.gh { color: #303030 } /* Generic.Heading */
.gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */
.go { color: #888888 } /* Generic.Output */
.gp { color: #555555 } /* Generic.Prompt */
.gs { font-weight: bold } /* Generic.Strong */
.gu { color: #606060 } /* Generic.Subheading */
.gt { color: #aa0000 } /* Generic.Traceback */
.highlight .kc{font-weight:bold;} /* Keyword.Constant */
.highlight .kd{font-weight:bold;} /* Keyword.Declaration */
.highlight .kn{font-weight:bold;} /* Keyword.Namespace */
.highlight .kp{font-weight:bold;} /* Keyword.Pseudo */
.highlight .kr{font-weight:bold;} /* Keyword.Reserved */
.highlight .kt{color:#458;font-weight:bold;} /* Keyword.Type */
.m { color: #0000DD; font-weight: bold } /* Literal.Number */
.s { color: #dd2200; background-color: #fff0f0 } /* Literal.String */
.highlight .na{color:#008080;} /* Name.Attribute */
.highlight .nb{color:#0086B3;} /* Name.Builtin */
.highlight .nc{color:#458;font-weight:bold;} /* Name.Class */
.highlight .no{color:#008080;} /* Name.Constant */
.highlight .ni{color:#800080;}
.highlight .ne{color:#900;font-weight:bold;} /* Name.Exception */
.highlight .nf{color:#900;font-weight:bold;} /* Name.Function */
.highlight .nn{color:#005;font-weight:bold;} /* Name.Namespace */
.highlight .nt{color:#000080;} /* Name.Tag */
.highlight .nv{color:#008080;} /* Name.Variable */
.py { color: #336699; font-weight: bold } /* Name.Property */
.ow { color: #008800 } /* Operator.Word */
.w { color: #bbbbbb } /* Text.Whitespace */
.mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */
.mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */
.highlight .mi {color:#099;} /* Literal.Number.Integer */
.mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */
.sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */
.highlight .sc{color:#d14;} /* Literal.String.Char */
.sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */
.highlight .s2{color:#d14;} /* Literal.String.Double */
.highlight .se{color:#d14;} /* Literal.String.Escape */
.highlight .sh{color:#d14;} /* Literal.String.Heredoc */
.highlight .si{color:#d14;} /* Literal.String.Interpol */
.highlight .sx{color:#d14;} /* Literal.String.Other */
.highlight .sr{color:#d14;} /* Literal.String.Regex */
.highlight .s1{color:#d14;} /* Literal.String.Single */
.highlight .ss{color:#d14;} /* Literal.String.Symbol */
.bp { color: #003388 } /* Name.Builtin.Pseudo */
.vc { color: #336699 } /* Name.Variable.Class */
.vg { color: #dd7700 } /* Name.Variable.Global */
.vi { color: #3333bb }

View File

@ -1,15 +1,21 @@
/** Override bootstrap variables **/
$baseFontSize: 13px !default;
$baseLineHeight: 18px !default;
@import "bootstrap"; @import "bootstrap";
@import "bootstrap-responsive"; @import "bootstrap-responsive";
@import 'font-awesome'; @import 'font-awesome';
/** GitLab colors **/ /** GitLab colors **/
$link_color:#3A89A3; $link_color: #3A89A3;
$blue_link: #2fa0bb; $blue_link: #2FA0BB;
$style_color: #474d57; $style_color: #474D57;
$hover: #D9EDF7; $hover: #D9EDF7;
$hover_border: #ADF;
/** GitLab Fonts **/ /** GitLab Fonts **/
@font-face { font-family: Korolev; src: font-url('korolev-medium-compressed.otf'); } @font-face { font-family: Korolev; src: font-url('korolev-medium-compressed.otf'); }
$monospace: 'Menlo', 'Liberation Mono', 'Consolas', 'Courier New', 'andale mono', 'lucida console', monospace;
/** MIXINS **/ /** MIXINS **/
@mixin shade { @mixin shade {
@ -19,9 +25,9 @@ $hover: #D9EDF7;
} }
@mixin solid_shade { @mixin solid_shade {
-moz-box-shadow: 0 0 0 3px #eee; -moz-box-shadow: 0 0 0 3px #f1f1f1;
-webkit-box-shadow: 0 0 0 3px #eee; -webkit-box-shadow: 0 0 0 3px #f1f1f1;
box-shadow: 0 0 0 3px #eee; box-shadow: 0 0 0 3px #f1f1f1;
} }
@mixin border-radius($radius) { @mixin border-radius($radius) {
@ -64,6 +70,14 @@ $hover: #D9EDF7;
background-image: -o-linear-gradient($from, $to); background-image: -o-linear-gradient($from, $to);
} }
@mixin bg-light-gray-gradient {
background:#f1f1f1;
background-image: -webkit-gradient(linear, 0 0, 0 30, color-stop(0.066, #f5f5f5), to(#e1e1e1));
background-image: -webkit-linear-gradient(#f5f5f5 6.6%, #e1e1e1);
background-image: -moz-linear-gradient(#f5f5f5 6.6%, #e1e1e1);
background-image: -o-linear-gradient(#f5f5f5 6.6%, #e1e1e1);
}
@mixin bg-gray-gradient { @mixin bg-gray-gradient {
background:#eee; background:#eee;
background-image: -webkit-gradient(linear, 0 0, 0 30, color-stop(0.066, #eee), to(#dfdfdf)); background-image: -webkit-gradient(linear, 0 0, 0 30, color-stop(0.066, #eee), to(#dfdfdf));
@ -104,14 +118,12 @@ $hover: #D9EDF7;
@import "themes/ui_basic.scss"; @import "themes/ui_basic.scss";
/** /**
* UI mars theme * UI themes:
*/ */
@import "themes/ui_mars.scss"; @import "themes/ui_mars.scss";
/**
* UI Modern theme
*/
@import "themes/ui_modern.scss"; @import "themes/ui_modern.scss";
@import "themes/ui_gray.scss";
@import "themes/ui_color.scss";
/** /**
* GitLab bootstrap. * GitLab bootstrap.
@ -145,6 +157,7 @@ $hover: #D9EDF7;
@import "sections/merge_requests.scss"; @import "sections/merge_requests.scss";
@import "sections/graph.scss"; @import "sections/graph.scss";
@import "sections/events.scss"; @import "sections/events.scss";
@import "sections/themes.scss";
/** /**
* This scss file redefine chozen selectbox styles for * This scss file redefine chozen selectbox styles for

View File

@ -19,41 +19,14 @@
margin-right: 10px; margin-right: 10px;
.chzn-drop { .chzn-drop {
margin:7px 0;
min-width: 400px; min-width: 400px;
border: 2px solid $blue_link;
@include border-radius(4px);
.chzn-results { .chzn-results {
max-height:300px; max-height:300px;
.group-result {
color: $blue_link;
}
.active-result {
&.highlighted {
background: $blue_link;
}
}
} }
.chzn-search input { .chzn-search input {
min-width:365px; min-width:365px;
} }
} }
.chzn-single {
@include bg-gray-gradient;
div {
background:transparent;
border-left:none;
}
span {
font-weight: normal;
}
}
} }
/** Fix for Search Dropdown Border **/ /** Fix for Search Dropdown Border **/
@ -65,4 +38,55 @@
box-shadow: none; box-shadow: none;
} }
} }
.chzn-drop {
margin:7px 0;
min-width: 200px;
border: 1px solid #bbb;
border-radius:0;
.chzn-results {
margin-top: 5px;
max-height:300px;
.group-result {
color: $style_color;
border-bottom: 1px solid #EEE;
padding: 8px;
}
.active-result {
border-radius: 0;
&.highlighted {
background: $hover;
color: $style_color;
}
&.result-selected {
background: #EEE;
border-left: 4px solid #CCC;
}
}
}
.chzn-search {
@include bg-gray-gradient;
input {
min-width:165px;
border-color: #CCC;
}
}
}
.chzn-single {
@include bg-light-gray-gradient;
div {
background:transparent;
border-left:none;
}
span {
font-weight: normal;
}
}
} }

View File

@ -47,12 +47,15 @@
padding-left: 32px; padding-left: 32px;
} }
.author, .author a,
.committer { .committer a {
font-size:14px; font-size:14px;
line-height:22px; line-height:22px;
text-shadow:0 1px 1px #fff; text-shadow:0 1px 1px #fff;
color:#777; color:#777;
&:hover {
color: #999;
}
} }
.avatar { .avatar {
@ -71,7 +74,9 @@
margin-bottom:1em; margin-bottom:1em;
.diff_file_header { .diff_file_header {
padding:7px 5px; @extend .clearfix;
padding: 5px 5px 5px 10px;
color: #555;
border-bottom:1px solid #CCC; border-bottom:1px solid #CCC;
background: #eee; background: #eee;
background-image: -webkit-gradient(linear, 0 0, 0 30, color-stop(0.066, #eee), to(#dfdfdf)); background-image: -webkit-gradient(linear, 0 0, 0 30, color-stop(0.066, #eee), to(#dfdfdf));
@ -79,8 +84,23 @@
background-image: -moz-linear-gradient(#eee 6.6%, #dfdfdf); background-image: -moz-linear-gradient(#eee 6.6%, #dfdfdf);
background-image: -o-linear-gradient(#eee 6.6%, #dfdfdf); background-image: -o-linear-gradient(#eee 6.6%, #dfdfdf);
span { > span {
font-family: $monospace;
font-size:14px; font-size:14px;
line-height: 30px;
}
a.view-commit{
font-weight: bold;
}
.commit-short-id{
font-family: $monospace;
font-size: smaller;
}
.file-mode{
font-family: $monospace;
} }
} }
.diff_file_content { .diff_file_content {
@ -89,7 +109,7 @@
background:#fff; background:#fff;
color:#333; color:#333;
font-size: 12px; font-size: 12px;
font-family: 'Menlo', 'Liberation Mono', 'Consolas', 'Courier New', 'andale mono','lucida console',monospace; font-family: $monospace;
.old{ .old{
span.idiff{ span.idiff{
background-color:#FAA; background-color:#FAA;
@ -110,22 +130,34 @@
.diff_file_content_image { .diff_file_content_image {
background:#eee; background:#eee;
text-align:center; text-align:center;
img { .image {
display: inline-block;
margin:50px; margin:50px;
padding:1px;
max-width:400px; max-width:400px;
&.diff_image_removed { img{
border: 1px solid #C00; background: url('trans_bg.gif');
} }
&.diff_image_added { &.diff_removed {
border: 1px solid #0C0;; img{
border: 1px solid #C00;
}
}
&.diff_added {
img{
border: 1px solid #0C0;
}
}
.image-info{
margin: 5px 0 0 0;
} }
} }
&.img_compared { &.img_compared {
img { .image {
max-width:300px; max-width:300px;
} }
} }
@ -222,26 +254,41 @@
float:left; float:left;
@extend .lined; @extend .lined;
min-width:65px; min-width:65px;
font-family: 'Menlo', 'Liberation Mono', 'Consolas', 'Courier New', 'andale mono','lucida console',monospace; font-family: $monospace;
} }
.commit-author-name { .commit-author-name {
color: #777; color: #777;
&:hover {
color: #999;
}
} }
} }
.diff_file_header a, .diff_file_header a,
.file_stats a { .file-stats a {
color:$style_color; color: $style_color;
} }
.file_stats { .file-stats {
span { .new-file{
img { i{
width:14px; color: #1BCF00;
float:left; }
margin-right:6px; }
padding:2px 0; .renamed-file{
i{
color: #FE9300;
}
}
.deleted-file{
i{
color: #FF0000;
}
}
.edit-file{
i{
color: #555;
} }
} }
} }
@ -253,5 +300,5 @@
font-size:13px; font-size:13px;
background: #474D57; background: #474D57;
color:#fff; color:#fff;
font-family: 'Menlo', 'Liberation Mono', 'Consolas', 'Courier New', 'andale mono','lucida console',monospace; font-family: $monospace;
} }

View File

@ -1,14 +1,48 @@
.file-editor { .file-editor {
#editor{ #editor{
border: none;
border-radius: 0;
height: 500px; height: 500px;
width: 100%; margin: 0;
padding: 0;
position: relative; position: relative;
width: 100%;
} }
.editor-commit-comment {
padding-top:20px; .cancel-btn {
color: #B94A48;
&:hover {
color: #B94A48;
}
}
.commit-button-annotation {
@extend .alert;
@extend .alert-info;
display: inline-block;
margin: 0;
padding: 2px;
> * {
float: left;
}
.commit-btn {
@extend .save-btn;
}
.message {
display: inline-block;
margin: 5px 8px 0 8px;
}
}
.commit_message-group {
margin-top: 20px;
label {
font-size: 16px;
line-height: 20px;
}
textarea { textarea {
width: 50%; @extend .span8;
margin-left: 20px;
} }
} }
} }

View File

@ -43,6 +43,7 @@
.event-body { .event-body {
p { p {
color:#555; color:#555;
padding-top: 5px;
} }
.event-info { .event-info {
color:#666; color:#666;
@ -115,3 +116,29 @@
margin: -3px; margin: -3px;
} }
} }
/**
* Event filter
*
*/
.event_filter {
position: absolute;
width: 40px;
margin-left: -50px;
.filter_icon {
float: left;
border-left: 3px solid #4bc;
padding: 7px;
background: #f9f9f9;
margin-bottom: 10px;
img {
width:20px;
}
&.inactive {
border-left: 3px solid #EEE;
opacity: 0.5;
}
}
}

View File

@ -3,18 +3,29 @@
* *
*/ */
header { header {
width:100%; &.navbar-gitlab {
padding:0; .navbar-inner {
margin:0; height:45px;
top:1px; padding: 5px;
left:0; background: #F1F1F1;
background: #F1F1F1; /* for non-css3 browsers */
border-bottom: 1px solid #ccc; .nav > li > a {
box-shadow: 0 -1px 0 white inset; color: $style_color;
-moz-box-shadow: 0 -1px 0 white inset; text-shadow: 0 1px 0 #fff;
-webkit-box-shadow: 0 -1px 0 white inset; font-size: 18px;
padding: 11px;
}
/** NAV block with links and profile **/
.nav {
float: right;
margin-right: 0;
}
}
}
z-index:10; z-index:10;
height:60px; /*height:60px;*/
/** /**
* *
@ -22,45 +33,26 @@ header {
* *
*/ */
.app_logo { .app_logo {
width:200px; width:170px;
float:left; float:left;
position:relative;
top:-5px;
a { a {
float:left; float:left;
padding: 0px;
h1 { h1 {
padding-top: 5px;
width:90px; width:90px;
background: url('logo_dark.png') no-repeat 0px -3px; background: url('logo_dark.png') no-repeat 0px 2px;
float:left; float:left;
margin-left:5px; margin-left:2px;
font-size:36px; font-size:30px;
line-height:36px; line-height:48px;
font-weight:normal; font-weight:normal;
color:$style_color; color:$style_color;
text-shadow: 0 1px 1px #FFF; text-shadow: 0 1px 1px #FFF;
padding-left:50px; padding-left:45px;
height:40px; height:40px;
font-family: 'Korolev', sans-serif; font-family: 'Korolev', sans-serif;
} }
}
.separator {
margin-left:20px;
float: left;
height: 60px;
width: 1px;
background: white;
border-left: 1px solid #DDD;
margin-top: -10px;
}
}
.container {
.top_panel_content {
margin:auto;
position:relative;
padding:15px 0;
} }
} }
@ -74,33 +66,23 @@ header {
float:left; float:left;
margin:0; margin:0;
margin-right:30px; margin-right:30px;
font-size:36px; font-size:30px;
line-height:36px; line-height:48px;
font-weight:normal; font-weight:normal;
color:$style_color; color:$style_color;
text-shadow: 0 1px 1px #FFF; text-shadow: 0 1px 1px #FFF;
font-family: 'Korolev', sans-serif; font-family: 'Korolev', sans-serif;
} }
.fbtn {
float: right;
margin-right:10px;
.btn {
margin-left:7px;
background: #F1F1F1;
border: 1px solid #CCC;
}
}
/** /**
* *
* Search box * Search box
* *
*/ */
.search { .search {
float: right;
margin-right: 45px; margin-right: 45px;
margin-left:10px;
margin-top: 2px;
.search-input { .search-input {
@extend .span2; @extend .span2;
@ -108,8 +90,13 @@ header {
background-repeat: no-repeat; background-repeat: no-repeat;
background-position: 10px; background-position: 10px;
padding-left:25px; padding-left:25px;
@include border-radius(5px); font-size: 13px;
border:1px solid #ccc; @include border-radius(3px);
border:1px solid #c6c6c6;
box-shadow:none;
&:focus {
@extend .span3;
}
} }
} }
@ -121,7 +108,7 @@ header {
.account-box { .account-box {
position: absolute; position: absolute;
right: 0; right: 0;
top: 13px; top: 6px;
z-index: 10000; z-index: 10000;
width: 128px; width: 128px;
font-size: 11px; font-size: 11px;
@ -129,13 +116,13 @@ header {
display: block; display: block;
cursor: pointer; cursor: pointer;
img { img {
@include border-radius(4px); @include border-radius(3px);
right: 5px; right: 5px;
position: absolute; position: absolute;
width: 28px; width: 28px;
height: 28px; height: 28px;
display: block; display: block;
top: 2px; top:1px;
&:after { &:after {
content: " "; content: " ";
display: block; display: block;
@ -162,12 +149,7 @@ header {
display: block; } } display: block; } }
.account-links { .account-links {
background: #79C3E0;
display: none;
border-radius: 5px; border-radius: 5px;
width: 100px;
margin-top: 0;
float: right;
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2); box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2);
position: relative; position: relative;
&:before { &:before {
@ -177,32 +159,33 @@ header {
position: absolute; position: absolute;
border: 5px solid transparent; border: 5px solid transparent;
border-color: rgba(255, 255, 255, 0); border-color: rgba(255, 255, 255, 0);
border-bottom-color: #333; border-bottom-color: #555;
text-indent: -9999px; text-indent: -9999px;
top: -10px; top: -10px;
line-height: 0; line-height: 0;
right: 10px; right: 10px;
z-index: 10; } z-index: 10; }
background: #333; background: #555;
display: none; display: none;
z-index: 100000; z-index: 100000;
border-radius: 5px; @include border-radius(4px);
width: 100px; width: 100px;
position: absolute; position: absolute;
right: 10px; right: 5px;
top: 42px; top: 38px;
margin-top: 0; margin-top: 0;
float: right; float: right;
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2); box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2);
a { a {
color: #EEE; color: #fff;
padding: 6px 10px; padding: 7px 10px;
display: block; display: block;
text-shadow: none; text-shadow: none;
border-bottom: 1px solid #555; border-bottom: 1px solid #666;
font-size: 12px;
&:hover { &:hover {
color:#eee; color:#fff;
background: #444; background: #333;
} }
} }
} }
@ -228,5 +211,52 @@ header {
border-bottom-right-radius: 5px; border-bottom-right-radius: 5px;
border-bottom-left-radius: 5px; border-bottom-left-radius: 5px;
border-bottom: 0; } } border-bottom: 0; } }
/*
* Dark header
*
*/
&.header-dark {
&.navbar-gitlab {
.navbar-inner {
background: #708090;
border-bottom: 1px solid #AAA;
.nav > li > a {
color: #fff;
text-shadow: 0 1px 0 #111;
}
}
}
.search {
.search-input {
background-color: #D2D5DA;
background-color: rgba(255, 255, 255, 0.5);
&:focus {
background-color: white;
}
}
}
.search-input::-webkit-input-placeholder {
color: #666;
}
.app_logo {
a {
h1 {
background: url('logo_white.png') no-repeat 0px 2px;
color:#fff;
text-shadow: 0 1px 1px #111;
}
}
}
.project_name {
color:#fff;
text-shadow: 0 1px 1px #111;
}
}
} }

View File

@ -44,7 +44,7 @@
img.avatar { img.avatar {
width:32px; width:32px;
margin-top:4px; margin-top:1px;
} }
} }
} }

View File

@ -71,7 +71,7 @@ li.merge_request {
padding:7px 10px; padding:7px 10px;
img.avatar { img.avatar {
width: 32px; width: 32px;
margin-top: 4px; margin-top: 1px;
} }
p { p {
padding: 0px; padding: 0px;
@ -121,3 +121,25 @@ li.merge_request {
.mr_direction_tip { .mr_direction_tip {
margin-top:40px margin-top:40px
} }
.merge_requests_form_box {
@extend .main_box;
.merge_requests_middle_box {
@extend .middle_box_content;
height:30px;
.merge_requests_assignee {
@extend .span6;
float:left;
}
.merge_requests_milestone {
@extend .span4;
float:left;
}
}
}
.status-badge {
height: 32px;
width: 100%;
@include border-radius(5px);
}

View File

@ -6,7 +6,7 @@ ul.main_menu {
border-radius: 4px; border-radius: 4px;
margin: auto; margin: auto;
margin:30px 0; margin:30px 0;
border:1px solid #AAA; border:1px solid #BBB;
height:37px; height:37px;
@include bg-gray-gradient; @include bg-gray-gradient;
position:relative; position:relative;

View File

@ -6,3 +6,17 @@
} }
} }
} }
.profile_avatar_holder {
float:left;
width:60px;
height:60px;
margin-right:20px;
img {
width:60px;
height:60px;
background:#fff;
padding: 1px;
border: 1px solid #ddd;
}
}

View File

@ -85,9 +85,18 @@
} }
.project_clone_holder { .project_clone_holder {
input[type="text"],
.btn {
font-size:12px;
line-height: 18px;
margin: 0;
padding: 3px 10px;
}
input[type="text"] { input[type="text"] {
border: 1px solid #BBB; border: 1px solid #BBB;
box-shadow: none; box-shadow: none;
margin-left: -1px;
} }
} }

View File

@ -0,0 +1,60 @@
.application-theme, .code-preview-theme {
.update-feedback {
color: #468847;
float: right;
}
}
.themes_opts {
padding-left:20px;
label {
width:175px;
margin-right:40px;
.prev {
@extend .thumbnail;
height:30px;
width:175px;
margin-bottom:10px;
&.classic {
background: #31363e;
}
&.default {
background: #f1f1f1;
}
&.modern {
background: #567;
}
&.gray {
background: #708090;
}
&.violet {
background: #657;
}
}
}
}
.code_highlight_opts {
padding-left:20px;
label {
width:220px;
margin-right:40px;
.prev {
@extend .thumbnail;
height:151px;
width:220px;
margin-bottom:10px;
}
}
}

View File

@ -57,10 +57,7 @@
padding-right: 8px; padding-right: 8px;
img.avatar { img.avatar {
border: 0 none; margin-top: 0;
float: none;
margin-right: 0;
padding: 0;
width: 16px; width: 16px;
} }
} }
@ -75,6 +72,15 @@
} }
} }
} }
.blame {
img.avatar {
border: 0 none;
float: none;
margin: 0;
padding: 0;
}
}
} }
.tree-btn-group { .tree-btn-group {

View File

@ -16,35 +16,21 @@
} }
} }
header { .app_logo {
.fbtn { .separator {
.btn { margin-left: 0;
background-color: #F8F8F8; margin-right: 0;
background-image: -webkit-gradient(linear,left top,left bottom,from(#F8F8F8),to(#ECECEC));
background-image: -webkit-linear-gradient(top,#F8F8F8,#ECECEC);
background-image: -moz-linear-gradient(top,#F8F8F8,#ECECEC);
background-image: -ms-linear-gradient(top,#F8F8F8,#ECECEC);
background-image: -o-linear-gradient(top,#F8F8F8,#ECECEC);
background-image: linear-gradient(top,#F8F8F8,#ECECEC);
filter: progid:DXImageTransform.Microsoft.gradient(startColorStr='#f8f8f8',EndColorStr='#ececec');
border-color: #C6C6C6;
margin-left:7px;
@include border-radius(3px);
box-shadow:none;
color:#666;
}
}
.search {
.search-input {
@include border-radius(3px);
border-color: #C6C6C6;
box-shadow:none;
}
}
.pic {
img {
@include border-radius(3px);
}
} }
} }
.separator {
float: left;
height: 60px;
width: 1px;
background: white;
border-left: 1px solid #DDD;
margin-top: -10px;
margin-left: 10px;
margin-right: 10px;
}
} }

View File

@ -0,0 +1,23 @@
/**
* 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 restyles
*
*/
.ui_color {
/*
* Application Header
*
*/
header {
@extend .header-dark;
&.navbar-gitlab {
.navbar-inner {
background: #657;
}
}
}
}

View File

@ -0,0 +1,23 @@
/**
* 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 restyles
*
*/
.ui_gray {
/*
* Application Header
*
*/
header {
@extend .header-dark;
&.navbar-gitlab {
.navbar-inner {
background: #708090;
}
}
}
}

View File

@ -14,45 +14,24 @@
* *
*/ */
header { header {
background: #474D57 url('bg-header.png') repeat-x bottom;
box-shadow:none;
border-bottom: 1px solid #444;
.fbtn { &.navbar-gitlab {
.btn { .navbar-inner {
i { background: #474D57 url('bg-header.png') repeat-x bottom;
position: relative; border-bottom: 1px solid #444;
top: 1px;
}
margin-left:8px;
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);
font-size: 12px;
&:hover {
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);
background-position:0 0;
color:#fff;
i {
@extend .icon-white;
}
}
border: 1px solid #31363E; .nav > li > a {
color:#D6DADF; color: #eee;
text-shadow: 0 -1px 0 #000000; text-shadow: 0 1px 0 #444;
}
} }
} }
.search { .search {
float: right; float: right;
margin-right: 45px; margin-right: 45px;
.search-input { .search-input {
border: 1px solid rgba(0, 0, 0, 0.7); 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: #D2D5DA;
background-color: rgba(255, 255, 255, 0.5); background-color: rgba(255, 255, 255, 0.5);
@ -67,8 +46,8 @@
.app_logo { .app_logo {
a { a {
h1 { h1 {
background: url('logo_white.png') no-repeat 0px -3px; background: url('logo_white.png') no-repeat 0px 2px;
color:#fff; color:#eee;
text-shadow: 0 1px 1px #111; text-shadow: 0 1px 1px #111;
} }
} }
@ -78,7 +57,7 @@
} }
.project_name { .project_name {
color:#fff; color:#eee;
text-shadow: 0 1px 1px #111; text-shadow: 0 1px 1px #111;
} }
} }

View File

@ -4,8 +4,7 @@
* *
* Next items should be placed there * Next items should be placed there
* - link colors * - link colors
* - header styles * - header restyles
* - main menu styles
* *
*/ */
.ui_modern { .ui_modern {
@ -14,120 +13,10 @@
* *
*/ */
header { header {
height:40px; @extend .header-dark;
background-image: -moz-linear-gradient(top, #333, #222); &.navbar-gitlab {
background-image: -ms-linear-gradient(top, #333, #222); .navbar-inner {
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#333), to(#222)); background: #567;
background-image: -webkit-linear-gradient(top, #333, #222);
background-image: -o-linear-gradient(top, #333, #222);
background-image: linear-gradient(top, #333, #222);
background-repeat: repeat-x;
background-repeat: repeat-x;
filter: progid:dximagetransform.microsoft.gradient(startColorstr='#333333', endColorstr='#222222', GradientType=0);
-webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.25), inset 0 -1px 0 rgba(0, 0, 0, 0.1);
-moz-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.25), inset 0 -1px 0 rgba(0, 0, 0, 0.1);
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.25), inset 0 -1px 0 rgba(0, 0, 0, 0.1);
.container .top_panel_content { padding: 5px 0; }
/**
*
* Logo holder
*
*/
.app_logo {
width:160px;
a {
h1 {
background: none;
color:#DDD;
font-size:30px;
text-shadow: 0 1px 1px #111;
padding-left: 0;
}
}
.separator {
width: 1px;
height: 40px;
margin: 0 10px;
overflow: hidden;
background: #222;
border-left: 1px solid #333;
}
}
.fbtn {
.btn {
i {
position: relative;
top: 2px;
}
background:none;
margin-left:8px;
font-size: 13px;
line-height: 19px;
color:#ccc;
&:hover {
color:#fff;
i {
@extend .icon-white;
}
}
border: none;
box-shadow:none;
text-shadow: 0 -1px 0 #000000;
border-left: 1px solid #333;
}
}
/**
*
* Search box
*
*/
.search {
float: right;
margin-right: 45px;
.search-input {
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);
&:focus {
background-color: white;
}
}
.search-input::-webkit-input-placeholder {
color: #666;
}
}
/**
*
* Project / Area name
*
*/
.project_name {
line-height:36px;
font-size:30px;
color:#DDD;
text-shadow: 0 1px 1px #111;
}
/**
*
* Account box
*
*/
.account-box {
top:6px;
img {
top:1px;
right: 5px;
width: 26px;
height: 26px;
} }
} }
} }

View File

@ -21,7 +21,7 @@ class CommitLoadContext < BaseContext
result[:notes_count] = line_notes.count + project.commit_notes(commit).count result[:notes_count] = line_notes.count + project.commit_notes(commit).count
begin begin
result[:suppress_diff] = true if commit.diffs.size > 200 && !params[:force_show_diff] result[:suppress_diff] = true if commit.diffs.size > Commit::DIFF_SAFE_SIZE && !params[:force_show_diff]
rescue Grit::Git::GitTimeout rescue Grit::Git::GitTimeout
result[:suppress_diff] = true result[:suppress_diff] = true
result[:status] = :huge_commit result[:status] = :huge_commit

View File

@ -1,3 +1,5 @@
# Build collection of Merge Requests
# based on filtering passed via params for @project
class MergeRequestsLoadContext < BaseContext class MergeRequestsLoadContext < BaseContext
def execute def execute
type = params[:f] type = params[:f]
@ -9,8 +11,21 @@ class MergeRequestsLoadContext < BaseContext
when 'closed' then merge_requests.closed when 'closed' then merge_requests.closed
when 'assigned-to-me' then merge_requests.opened.assigned(current_user) when 'assigned-to-me' then merge_requests.opened.assigned(current_user)
else merge_requests.opened else merge_requests.opened
end.page(params[:page]).per(20) end
merge_requests.includes(:author, :project).order("closed, created_at desc") merge_requests = merge_requests.page(params[:page]).per(20)
merge_requests = merge_requests.includes(:author, :project).order("closed, created_at desc")
# Filter by specific assignee_id (or lack thereof)?
if params[:assignee_id].present?
merge_requests = merge_requests.where(assignee_id: (params[:assignee_id] == '0' ? nil : params[:assignee_id]))
end
# Filter by specific milestone_id (or lack thereof)?
if params[:milestone_id].present?
merge_requests = merge_requests.where(milestone_id: (params[:milestone_id] == '0' ? nil : params[:milestone_id]))
end
merge_requests
end end
end end

View File

@ -13,6 +13,7 @@ class SearchContext
result[:projects] = Project.where(id: project_ids).search(query).limit(10) result[:projects] = Project.where(id: project_ids).search(query).limit(10)
result[:merge_requests] = MergeRequest.where(project_id: project_ids).search(query).limit(10) result[:merge_requests] = MergeRequest.where(project_id: project_ids).search(query).limit(10)
result[:issues] = Issue.where(project_id: project_ids).search(query).limit(10) result[:issues] = Issue.where(project_id: project_ids).search(query).limit(10)
result[:wiki_pages] = Wiki.where(project_id: project_ids).search(query).limit(10)
result result
end end
@ -20,7 +21,8 @@ class SearchContext
@result ||= { @result ||= {
projects: [], projects: [],
merge_requests: [], merge_requests: [],
issues: [] issues: [],
wiki_pages: []
} }
end end
end end

View File

@ -1,8 +1,13 @@
class Admin::DashboardController < AdminController class Admin::DashboardController < AdminController
def index def index
@workers = Resque.workers
@pending_jobs = Resque.size(:post_receive)
@projects = Project.order("created_at DESC").limit(10) @projects = Project.order("created_at DESC").limit(10)
@users = User.order("created_at DESC").limit(10) @users = User.order("created_at DESC").limit(10)
@resque_accessible = true
@workers = Resque.workers
@pending_jobs = Resque.size(:post_receive)
rescue Redis::InheritedError
@resque_accessible = false
end end
end end

View File

@ -4,7 +4,7 @@ class Admin::ProjectsController < AdminController
def index def index
@admin_projects = Project.scoped @admin_projects = Project.scoped
@admin_projects = @admin_projects.search(params[:name]) if params[:name].present? @admin_projects = @admin_projects.search(params[:name]) if params[:name].present?
@admin_projects = @admin_projects.page(params[:page]).per(20) @admin_projects = @admin_projects.order("name ASC").page(params[:page]).per(20)
end end
def show def show

View File

@ -98,6 +98,9 @@ class Admin::UsersController < AdminController
def destroy def destroy
@admin_user = User.find(params[:id]) @admin_user = User.find(params[:id])
if @admin_user.my_own_projects.count > 0
redirect_to admin_users_path, alert: "User is a project owner and can't be removed." and return
end
@admin_user.destroy @admin_user.destroy
respond_to do |format| respond_to do |format|

View File

@ -9,19 +9,28 @@ class ApplicationController < ActionController::Base
helper_method :abilities, :can? helper_method :abilities, :can?
rescue_from Gitlab::Gitolite::AccessDenied do |exception| rescue_from Gitlab::Gitolite::AccessDenied do |exception|
log_exception(exception)
render "errors/gitolite", layout: "errors", status: 500 render "errors/gitolite", layout: "errors", status: 500
end end
rescue_from Encoding::CompatibilityError do |exception| rescue_from Encoding::CompatibilityError do |exception|
log_exception(exception)
render "errors/encoding", layout: "errors", status: 500 render "errors/encoding", layout: "errors", status: 500
end end
rescue_from ActiveRecord::RecordNotFound do |exception| rescue_from ActiveRecord::RecordNotFound do |exception|
log_exception(exception)
render "errors/not_found", layout: "errors", status: 404 render "errors/not_found", layout: "errors", status: 404
end end
protected protected
def log_exception(exception)
application_trace = ActionDispatch::ExceptionWrapper.new(env, exception).application_trace
application_trace.map!{ |t| " #{t}\n" }
logger.error "\n#{exception.class.name} (#{exception.message}):\n#{application_trace.join}"
end
def reject_blocked! def reject_blocked!
if current_user && current_user.blocked if current_user && current_user.blocked
sign_out current_user sign_out current_user

View File

@ -1,7 +1,6 @@
# Controller for viewing a file's blame # Controller for viewing a file's blame
class BlobController < ProjectResourceController class BlobController < ProjectResourceController
include ExtractsPath include ExtractsPath
include Gitlab::Encode
# Authorize # Authorize
before_filter :authorize_read_project! before_filter :authorize_read_project!
@ -12,16 +11,9 @@ class BlobController < ProjectResourceController
def show def show
if @tree.is_blob? if @tree.is_blob?
if @tree.text?
encoding = detect_encoding(@tree.data)
mime_type = encoding ? "text/plain; charset=#{encoding}" : "text/plain"
else
mime_type = @tree.mime_type
end
send_data( send_data(
@tree.data, @tree.data,
type: mime_type, type: @tree.mime_type,
disposition: 'inline', disposition: 'inline',
filename: @tree.name filename: @tree.name
) )

View File

@ -1,12 +1,17 @@
class DashboardController < ApplicationController class DashboardController < ApplicationController
respond_to :html respond_to :html
before_filter :event_filter, only: :index
def index def index
@groups = Group.where(id: current_user.projects.pluck(:group_id)) @groups = Group.where(id: current_user.projects.pluck(:group_id))
@projects = current_user.projects_with_events @projects = current_user.projects_sorted_by_activity
@projects = @projects.page(params[:page]).per(30) @projects = @projects.page(params[:page]).per(30)
@events = Event.in_projects(current_user.project_ids).limit(20).offset(params[:offset] || 0) @events = Event.in_projects(current_user.project_ids)
@events = @event_filter.apply_filter(@events)
@events = @events.limit(20).offset(params[:offset] || 0)
@last_push = current_user.recent_push @last_push = current_user.recent_push
respond_to do |format| respond_to do |format|
@ -34,4 +39,8 @@ class DashboardController < ApplicationController
format.atom { render layout: false } format.atom { render layout: false }
end end
end end
def event_filter
@event_filter ||= EventFilter.new(params[:event_filter])
end
end end

View File

@ -54,7 +54,7 @@ class GroupsController < ApplicationController
end end
def projects def projects
@projects ||= current_user.projects_with_events.where(group_id: @group.id) @projects ||= current_user.projects_sorted_by_activity.where(group_id: @group.id)
end end
def project_ids def project_ids

View File

@ -31,7 +31,8 @@ class MilestonesController < ProjectResourceController
def show def show
@issues = @milestone.issues @issues = @milestone.issues
@users = @milestone.participants @users = UserDecorator.decorate(@milestone.participants)
@merge_requests = @milestone.merge_requests
respond_to do |format| respond_to do |format|
format.html format.html

View File

@ -9,7 +9,11 @@ class ProfileController < ApplicationController
def update def update
@user.update_attributes(params[:user]) @user.update_attributes(params[:user])
redirect_to :back
respond_to do |format|
format.html { redirect_to :back }
format.js
end
end end
def token def token
@ -22,7 +26,7 @@ class ProfileController < ApplicationController
flash[:notice] = "Password was successfully updated. Please login with it" flash[:notice] = "Password was successfully updated. Please login with it"
redirect_to new_user_session_path redirect_to new_user_session_path
else else
render action: "password" render 'account'
end end
end end

View File

@ -1,4 +1,4 @@
require Rails.root.join('lib', 'gitlab', 'graph_commit') require Rails.root.join('lib', 'gitlab', 'graph', 'json_builder')
class ProjectsController < ProjectResourceController class ProjectsController < ProjectResourceController
skip_before_filter :project, only: [:new, :create] skip_before_filter :project, only: [:new, :create]
@ -21,9 +21,10 @@ class ProjectsController < ProjectResourceController
@project = Project.create_by_user(params[:project], current_user) @project = Project.create_by_user(params[:project], current_user)
respond_to do |format| respond_to do |format|
flash[:notice] = 'Project was successfully created.' if @project.saved?
format.html do format.html do
if @project.saved? if @project.saved?
redirect_to(@project, notice: 'Project was successfully created.') redirect_to @project
else else
render action: "new" render action: "new"
end end
@ -79,7 +80,9 @@ class ProjectsController < ProjectResourceController
end end
def graph def graph
@days_json, @commits_json = Gitlab::GraphCommit.to_graph(project) graph = Gitlab::Graph::JsonBuilder.new(project)
@days_json, @commits_json = graph.days_json, graph.commits_json
end end
def destroy def destroy

View File

@ -1,5 +1,4 @@
class RefsController < ProjectResourceController class RefsController < ProjectResourceController
include Gitlab::Encode
# Authorize # Authorize
before_filter :authorize_read_project! before_filter :authorize_read_project!

View File

@ -16,9 +16,14 @@ class RepositoriesController < ProjectResourceController
@tags = @project.tags @tags = @project.tags
end end
def stats
@stats = Gitlab::GitStats.new(@project.repo, @project.root_ref)
@graph = @stats.graph
end
def archive def archive
unless can?(current_user, :download_code, @project) unless can?(current_user, :download_code, @project)
render_404 and return render_404 and return
end end

View File

@ -5,5 +5,6 @@ class SearchController < ApplicationController
@projects = result[:projects] @projects = result[:projects]
@merge_requests = result[:merge_requests] @merge_requests = result[:merge_requests]
@issues = result[:issues] @issues = result[:issues]
@wiki_pages = result[:wiki_pages]
end end
end end

View File

@ -0,0 +1,37 @@
class ServicesController < ProjectResourceController
# Authorize
before_filter :authorize_admin_project!
respond_to :html
def index
@gitlab_ci_service = @project.gitlab_ci_service
end
def edit
@service = @project.gitlab_ci_service
# Create if missing
@service = @project.create_gitlab_ci_service unless @service
end
def update
@service = @project.gitlab_ci_service
if @service.update_attributes(params[:service])
redirect_to edit_project_service_path(@project, :gitlab_ci)
else
render 'edit'
end
end
def test
commits = project.commits(project.default_branch, nil, 3)
data = project.post_receive_data(commits.last.id, commits.first.id, "refs/heads/#{project.default_branch}", current_user)
@service = project.gitlab_ci_service
@service.execute(data)
redirect_to :back
end
end

View File

@ -26,15 +26,14 @@ class TreeController < ProjectResourceController
end end
def update def update
file_editor = Gitlab::FileEditor.new(current_user, @project, @ref) edit_file_action = Gitlab::Satellite::EditFileAction.new(current_user, @project, @ref, @path)
update_status = file_editor.update( updated_successfully = edit_file_action.commit!(
@path,
params[:content], params[:content],
params[:commit_message], params[:commit_message],
params[:last_commit] params[:last_commit]
) )
if update_status if updated_successfully
redirect_to project_tree_path(@project, @id), notice: "Your changes have been successfully commited" redirect_to project_tree_path(@project, @id), notice: "Your changes have been successfully commited"
else else
flash[:notice] = "Your changes could not be commited, because the file has been changed" flash[:notice] = "Your changes could not be commited, because the file has been changed"

View File

@ -47,21 +47,15 @@ class CommitDecorator < ApplicationDecorator
# Otherwise it will link to the author email as specified in the commit. # Otherwise it will link to the author email as specified in the commit.
# #
# options: # options:
# avatar: true will prepend avatar image # avatar: true will prepend the avatar image
def author_link(options) # size: size of the avatar image in px
text = if options[:avatar] def author_link(options = {})
avatar = h.image_tag h.gravatar_icon(author_email), class: "avatar", width: 16 person_link(options.merge source: :author)
"#{avatar} #{author_name}" end
else
author_name
end
team_member = @project.try(:team_member_by_name_or_email, author_name, author_email)
if team_member.nil? # Just like #author_link but for the committer.
h.mail_to author_email, text.html_safe, class: "commit-author-link" def committer_link(options = {})
else person_link(options.merge source: :committer)
h.link_to text, h.project_team_member_path(@project, team_member), class: "commit-author-link"
end
end end
protected protected
@ -69,4 +63,30 @@ class CommitDecorator < ApplicationDecorator
def no_commit_message def no_commit_message
"--no commit message" "--no commit message"
end end
# Private: Returns a link to a person. If the person has a matching user and
# is a member of the current @project it will link to the team member page.
# Otherwise it will link to the person email as specified in the commit.
#
# options:
# source: one of :author or :committer
# avatar: true will prepend the avatar image
# size: size of the avatar image in px
def person_link(options = {})
source_name = send "#{options[:source]}_name".to_sym
source_email = send "#{options[:source]}_email".to_sym
text = if options[:avatar]
avatar = h.image_tag h.gravatar_icon(source_email, options[:size]), class: "avatar #{"s#{options[:size]}" if options[:size]}", width: options[:size]
%Q{#{avatar} <span class="commit-#{options[:source]}-name">#{source_name}</span>}
else
source_name
end
team_member = @project.try(:team_member_by_name_or_email, source_name, source_email)
if team_member.nil?
h.mail_to source_email, text.html_safe, class: "commit-#{options[:source]}-link"
else
h.link_to text, h.project_team_member_path(@project, team_member), class: "commit-#{options[:source]}-link"
end
end
end end

View File

@ -8,14 +8,14 @@ class TreeDecorator < ApplicationDecorator
#parts = parts[0...-1] if is_blob? #parts = parts[0...-1] if is_blob?
yield(h.link_to("..", "#", remote: true)) if parts.count > max_links yield(h.link_to("..", "#")) if parts.count > max_links
parts.each do |part| parts.each do |part|
part_path = File.join(part_path, part) unless part_path.empty? part_path = File.join(part_path, part) unless part_path.empty?
part_path = part if part_path.empty? part_path = part if part_path.empty?
next unless parts.last(2).include?(part) if parts.count > max_links next unless parts.last(2).include?(part) if parts.count > max_links
yield(h.link_to(h.truncate(part, length: 40), h.project_tree_path(project, h.tree_join(ref, part_path)), remote: true)) yield(h.link_to(h.truncate(part, length: 40), h.project_tree_path(project, h.tree_join(ref, part_path))))
end end
end end
end end

View File

@ -0,0 +1,11 @@
class UserDecorator < ApplicationDecorator
decorates :user
def avatar_image size = 16
h.image_tag h.gravatar_icon(self.email, size), class: "avatar #{"s#{size}"}", width: size
end
def tm_of(project)
project.team_member_by_id(self.id)
end
end

View File

@ -36,7 +36,7 @@ module ApplicationHelper
else else
gravatar_prefix = request.ssl? ? "https://secure" : "http://www" gravatar_prefix = request.ssl? ? "https://secure" : "http://www"
user_email.strip! user_email.strip!
"#{gravatar_prefix}.gravatar.com/avatar/#{Digest::MD5.hexdigest(user_email.downcase)}?s=#{size}&d=identicon" "#{gravatar_prefix}.gravatar.com/avatar/#{Digest::MD5.hexdigest(user_email.downcase)}?s=#{size}&d=mm"
end end
end end

View File

@ -57,12 +57,17 @@ module CommitsHelper
def image_diff_class(diff) def image_diff_class(diff)
if diff.deleted_file if diff.deleted_file
"diff_image_removed" "diff_removed"
elsif diff.new_file elsif diff.new_file
"diff_image_added" "diff_added"
else else
nil nil
end end
end end
def commit_to_html commit
if commit.model
escape_javascript(render 'commits/commit', commit: commit)
end
end
end end

View File

@ -33,4 +33,22 @@ module EventsHelper
image_tag event_image_path image_tag event_image_path
end end
end end
def event_filter_link key, tooltip
key = key.to_s
filter = @event_filter.options key
inactive = if @event_filter.active? key
nil
else
'inactive'
end
content_tag :div, class: "filter_icon #{inactive}" do
link_to dashboard_path(event_filter: filter), class: 'has_tooltip', 'data-original-title' => tooltip do
image_tag "event_filter_#{key}.png"
end
end
end
end end

View File

@ -38,4 +38,8 @@ module MergeRequestsHelper
classes << " merged" if mr.merged? classes << " merged" if mr.merged?
classes classes
end end
def ci_status_path
@project.gitlab_ci_service.commit_badge_path(@merge_request.last_commit.sha)
end
end end

View File

@ -10,5 +10,9 @@ module ProjectsHelper
def link_to_project project def link_to_project project
link_to project.name, project link_to project.name, project
end end
def tm_path team_member
project_team_member_path(@project, team_member)
end
end end

View File

@ -67,4 +67,29 @@ module TreeHelper
can?(current_user, :push_code, @project) can?(current_user, :push_code, @project)
end end
end end
# Breadcrumb links for a Project and, if applicable, a tree path
def breadcrumbs
return unless @project && @ref
# Add the root project link and the arrow icon
crumbs = content_tag(:li) do
content_tag(:span, nil, class: 'arrow') +
link_to(@project.name, project_commits_path(@project, @ref))
end
if @path
parts = @path.split('/')
parts.each_with_index do |part, i|
crumbs += content_tag(:span, '/', class: 'divider')
crumbs += content_tag(:li) do
# The text is just the individual part, but the link needs all the parts before it
link_to part, project_commits_path(@project, tree_join(@ref, parts[0..i].join('/')))
end
end
end
crumbs.html_safe
end
end end

View File

@ -1,9 +1,13 @@
class Commit class Commit
include ActiveModel::Conversion include ActiveModel::Conversion
include Gitlab::Encode
include StaticModel include StaticModel
extend ActiveModel::Naming extend ActiveModel::Naming
# Safe amount of files with diffs in one commit to render
# Used to prevent 500 error on huge commits by suppressing diff
#
DIFF_SAFE_SIZE = 100
attr_accessor :commit, :head, :refs attr_accessor :commit, :head, :refs
delegate :message, :authored_date, :committed_date, :parents, :sha, delegate :message, :authored_date, :committed_date, :parents, :sha,
@ -107,7 +111,7 @@ class Commit
end end
def safe_message def safe_message
@safe_message ||= utf8 message @safe_message ||= message
end end
def created_at def created_at
@ -119,7 +123,7 @@ class Commit
end end
def author_name def author_name
utf8 author.name author.name
end end
# Was this commit committed by a different person than the original author? # Was this commit committed by a different person than the original author?
@ -128,7 +132,7 @@ class Commit
end end
def committer_name def committer_name
utf8 committer.name committer.name
end end
def committer_email def committer_email

View File

@ -1,3 +1,19 @@
# == 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
# author_id :integer
#
class Event < ActiveRecord::Base class Event < ActiveRecord::Base
include PushEvent include PushEvent
@ -144,20 +160,3 @@ class Event < ActiveRecord::Base
end end
end end
end 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
# author_id :integer
#

View File

@ -0,0 +1,39 @@
# == Schema Information
#
# Table name: services
#
# id :integer not null, primary key
# type :string(255)
# title :string(255)
# token :string(255)
# project_id :integer not null
# created_at :datetime not null
# updated_at :datetime not null
# active :boolean default(FALSE), not null
# project_url :string(255)
#
class GitlabCiService < Service
attr_accessible :project_url
validates :project_url, presence: true, if: :activated?
validates :token, presence: true, if: :activated?
delegate :execute, to: :service_hook, prefix: nil
after_save :compose_service_hook, if: :activated?
def activated?
active
end
def compose_service_hook
hook = service_hook || build_service_hook
hook.url = [project_url, "/build", "?token=#{token}"].join("")
hook.save
end
def commit_badge_path sha
project_url + "/status?sha=#{sha}"
end
end

View File

@ -1,3 +1,15 @@
# == Schema Information
#
# Table name: groups
#
# id :integer not null, primary key
# name :string(255) not null
# code :string(255) not null
# owner_id :integer not null
# created_at :datetime not null
# updated_at :datetime not null
#
class Group < ActiveRecord::Base class Group < ActiveRecord::Base
attr_accessible :code, :name, :owner_id attr_accessible :code, :name, :owner_id
@ -22,16 +34,3 @@ class Group < ActiveRecord::Base
User.joins(:users_projects).where(users_projects: {project_id: project_ids}).uniq User.joins(:users_projects).where(users_projects: {project_id: project_ids}).uniq
end end
end end
# == Schema Information
#
# Table name: groups
#
# id :integer not null, primary key
# name :string(255) not null
# code :string(255) not null
# owner_id :integer not null
# created_at :datetime not null
# updated_at :datetime not null
#

View File

@ -1,3 +1,21 @@
# == Schema Information
#
# Table name: issues
#
# id :integer not null, primary key
# title :string(255)
# assignee_id :integer
# author_id :integer
# project_id :integer
# created_at :datetime not null
# updated_at :datetime not null
# closed :boolean default(FALSE), not null
# position :integer default(0)
# branch_name :string(255)
# description :text
# milestone_id :integer
#
class Issue < ActiveRecord::Base class Issue < ActiveRecord::Base
include IssueCommonality include IssueCommonality
include Votes include Votes
@ -7,30 +25,9 @@ class Issue < ActiveRecord::Base
acts_as_taggable_on :labels acts_as_taggable_on :labels
belongs_to :milestone
validates :description, length: { within: 0..2000 } validates :description, length: { within: 0..2000 }
def self.open_for(user) def self.open_for(user)
opened.assigned(user) opened.assigned(user)
end end
end end
# == Schema Information
#
# Table name: issues
#
# id :integer not null, primary key
# title :string(255)
# assignee_id :integer
# author_id :integer
# project_id :integer
# created_at :datetime not null
# updated_at :datetime not null
# closed :boolean default(FALSE), not null
# position :integer default(0)
# branch_name :string(255)
# description :text
# milestone_id :integer
#

View File

@ -1,3 +1,17 @@
# == Schema Information
#
# Table name: keys
#
# id :integer not null, primary key
# user_id :integer
# created_at :datetime not null
# updated_at :datetime not null
# key :text
# title :string(255)
# identifier :string(255)
# project_id :integer
#
require 'digest/md5' require 'digest/md5'
class Key < ActiveRecord::Base class Key < ActiveRecord::Base
@ -67,18 +81,3 @@ class Key < ActiveRecord::Base
Key.where(identifier: identifier).count == 0 Key.where(identifier: identifier).count == 0
end end
end end
# == Schema Information
#
# Table name: keys
#
# id :integer not null, primary key
# user_id :integer
# created_at :datetime not null
# updated_at :datetime not null
# key :text
# title :string(255)
# identifier :string(255)
# project_id :integer
#

View File

@ -1,10 +1,32 @@
# == Schema Information
#
# Table name: merge_requests
#
# id :integer not null, primary key
# target_branch :string(255) not null
# source_branch :string(255) not null
# project_id :integer not null
# author_id :integer
# assignee_id :integer
# title :string(255)
# closed :boolean default(FALSE), not null
# created_at :datetime not null
# updated_at :datetime not null
# st_commits :text(2147483647)
# st_diffs :text(2147483647)
# merged :boolean default(FALSE), not null
# state :integer default(1), not null
# milestone_id :integer
#
require Rails.root.join("app/models/commit") require Rails.root.join("app/models/commit")
require Rails.root.join("app/roles/static_model")
class MergeRequest < ActiveRecord::Base class MergeRequest < ActiveRecord::Base
include IssueCommonality include IssueCommonality
include Votes include Votes
attr_accessible :title, :assignee_id, :closed, :target_branch, :source_branch, attr_accessible :title, :assignee_id, :closed, :target_branch, :source_branch, :milestone_id,
:author_id_of_changes :author_id_of_changes
attr_accessor :should_remove_source_branch attr_accessor :should_remove_source_branch
@ -26,6 +48,10 @@ class MergeRequest < ActiveRecord::Base
where("source_branch LIKE :branch OR target_branch LIKE :branch", branch: branch_name) where("source_branch LIKE :branch OR target_branch LIKE :branch", branch: branch_name)
end end
def self.find_all_by_milestone(milestone)
where("milestone_id = :milestone_id", milestone_id: milestone)
end
def human_state def human_state
states = { states = {
CAN_BE_MERGED => "can_be_merged", CAN_BE_MERGED => "can_be_merged",
@ -60,7 +86,7 @@ class MergeRequest < ActiveRecord::Base
end end
def check_if_can_be_merged def check_if_can_be_merged
self.state = if Gitlab::Merge.new(self, self.author).can_be_merged? self.state = if Gitlab::Satellite::MergeAction.new(self.author, self).can_be_merged?
CAN_BE_MERGED CAN_BE_MERGED
else else
CANNOT_BE_MERGED CANNOT_BE_MERGED
@ -167,7 +193,7 @@ class MergeRequest < ActiveRecord::Base
end end
def automerge!(current_user) def automerge!(current_user)
if Gitlab::Merge.new(self, current_user).merge! && self.unmerged_commits.empty? if Gitlab::Satellite::MergeAction.new(current_user, self).merge! && self.unmerged_commits.empty?
self.merge!(current_user.id) self.merge!(current_user.id)
true true
end end
@ -193,24 +219,3 @@ class MergeRequest < ActiveRecord::Base
Note.where("(noteable_type = 'MergeRequest' AND noteable_id = :mr_id) OR (noteable_type = 'Commit' AND noteable_id IN (:commit_ids))", mr_id: id, commit_ids: commit_ids) Note.where("(noteable_type = 'MergeRequest' AND noteable_id = :mr_id) OR (noteable_type = 'Commit' AND noteable_id IN (:commit_ids))", mr_id: id, commit_ids: commit_ids)
end end
end end
# == Schema Information
#
# Table name: merge_requests
#
# id :integer not null, primary key
# target_branch :string(255) not null
# source_branch :string(255) not null
# project_id :integer not null
# author_id :integer
# assignee_id :integer
# title :string(255)
# closed :boolean default(FALSE), not null
# created_at :datetime not null
# updated_at :datetime not null
# st_commits :text(4294967295
# st_diffs :text(4294967295
# merged :boolean default(FALSE), not null
# state :integer default(1), not null
#

View File

@ -1,11 +1,27 @@
# == Schema Information
#
# Table name: milestones
#
# id :integer not null, primary key
# title :string(255) not null
# project_id :integer not null
# description :text
# due_date :date
# closed :boolean default(FALSE), not null
# created_at :datetime not null
# updated_at :datetime not null
#
class Milestone < ActiveRecord::Base class Milestone < ActiveRecord::Base
attr_accessible :title, :description, :due_date, :closed attr_accessible :title, :description, :due_date, :closed
belongs_to :project belongs_to :project
has_many :issues has_many :issues
has_many :merge_requests
validates :title, presence: true validates :title, presence: true
validates :project, presence: true validates :project, presence: true
validates :closed, inclusion: { in: [true, false] }
def self.active def self.active
where("due_date > ? OR due_date IS NULL", Date.today) where("due_date > ? OR due_date IS NULL", Date.today)
@ -15,8 +31,20 @@ class Milestone < ActiveRecord::Base
User.where(id: issues.pluck(:assignee_id)) User.where(id: issues.pluck(:assignee_id))
end end
def open_items_count
self.issues.opened.count + self.merge_requests.opened.count
end
def closed_items_count
self.issues.closed.count + self.merge_requests.closed.count
end
def total_items_count
self.issues.count + self.merge_requests.count
end
def percent_complete def percent_complete
((self.issues.closed.count * 100) / self.issues.count).abs ((closed_items_count * 100) / total_items_count).abs
rescue ZeroDivisionError rescue ZeroDivisionError
100 100
end end
@ -25,18 +53,3 @@ class Milestone < ActiveRecord::Base
"expires at #{due_date.stamp("Aug 21, 2011")}" if due_date "expires at #{due_date.stamp("Aug 21, 2011")}" if due_date
end end
end end
# == Schema Information
#
# Table name: milestones
#
# id :integer not null, primary key
# title :string(255) not null
# project_id :integer not null
# description :text
# due_date :date
# closed :boolean default(FALSE), not null
# created_at :datetime not null
# updated_at :datetime not null
#

View File

@ -1,3 +1,19 @@
# == Schema Information
#
# Table name: notes
#
# id :integer not null, primary key
# note :text
# noteable_id :string(255)
# noteable_type :string(255)
# author_id :integer
# created_at :datetime not null
# updated_at :datetime not null
# project_id :integer
# attachment :string(255)
# line_code :string(255)
#
require 'carrierwave/orm/activerecord' require 'carrierwave/orm/activerecord'
require 'file_size_validator' require 'file_size_validator'
@ -23,13 +39,13 @@ class Note < ActiveRecord::Base
mount_uploader :attachment, AttachmentUploader mount_uploader :attachment, AttachmentUploader
# Scopes # Scopes
scope :common, where(noteable_id: nil) scope :common, ->{ where(noteable_id: nil) }
scope :today, where("created_at >= :date", date: Date.today) scope :today, ->{ where("created_at >= :date", date: Date.today) }
scope :last_week, where("created_at >= :date", date: (Date.today - 7.days)) scope :last_week, ->{ where("created_at >= :date", date: (Date.today - 7.days)) }
scope :since, ->(day) { where("created_at >= :date", date: (day)) } scope :since, ->(day) { where("created_at >= :date", date: (day)) }
scope :fresh, order("created_at ASC, id ASC") scope :fresh, ->{ order("created_at ASC, id ASC") }
scope :inc_author_project, includes(:project, :author) scope :inc_author_project, ->{ includes(:project, :author) }
scope :inc_author, includes(:author) scope :inc_author, ->{ includes(:author) }
def self.create_status_change_note(noteable, author, status) def self.create_status_change_note(noteable, author, status)
create({ create({
@ -107,20 +123,3 @@ class Note < ActiveRecord::Base
note.start_with?('-1') || note.start_with?(':-1:') note.start_with?('-1') || note.start_with?(':-1:')
end end
end end
# == Schema Information
#
# Table name: notes
#
# id :integer not null, primary key
# note :text
# noteable_id :string(255)
# noteable_type :string(255)
# author_id :integer
# created_at :datetime not null
# updated_at :datetime not null
# project_id :integer
# attachment :string(255)
# line_code :string(255)
#

View File

@ -1,3 +1,24 @@
# == Schema Information
#
# Table name: projects
#
# id :integer not null, primary key
# name :string(255)
# path :string(255)
# description :text
# created_at :datetime not null
# updated_at :datetime not null
# private_flag :boolean default(TRUE), not null
# code :string(255)
# owner_id :integer
# default_branch :string(255)
# 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
# group_id :integer
#
require "grit" require "grit"
class Project < ActiveRecord::Base class Project < ActiveRecord::Base
@ -26,6 +47,7 @@ class Project < ActiveRecord::Base
has_many :wikis, dependent: :destroy has_many :wikis, dependent: :destroy
has_many :protected_branches, dependent: :destroy has_many :protected_branches, dependent: :destroy
has_one :last_event, class_name: 'Event', order: 'events.created_at DESC', foreign_key: 'project_id' has_one :last_event, class_name: 'Event', order: 'events.created_at DESC', foreign_key: 'project_id'
has_one :gitlab_ci_service, dependent: :destroy
delegate :name, to: :owner, allow_nil: true, prefix: true delegate :name, to: :owner, allow_nil: true, prefix: true
@ -104,8 +126,10 @@ class Project < ActiveRecord::Base
end end
def repo_name def repo_name
if path == "gitolite-admin" denied_paths = %w(gitolite-admin groups projects dashboard)
errors.add(:path, " like 'gitolite-admin' is not allowed")
if denied_paths.include?(path)
errors.add(:path, "like #{path} is not allowed")
end end
end end
@ -160,26 +184,12 @@ class Project < ActiveRecord::Base
def issues_labels def issues_labels
issues.tag_counts_on(:labels) issues.tag_counts_on(:labels)
end end
def services
[gitlab_ci_service].compact
end
def gitlab_ci?
gitlab_ci_service && gitlab_ci_service.active
end
end end
# == Schema Information
#
# Table name: projects
#
# id :integer not null, primary key
# name :string(255)
# path :string(255)
# description :text
# created_at :datetime not null
# updated_at :datetime not null
# private_flag :boolean default(TRUE), not null
# code :string(255)
# owner_id :integer
# default_branch :string(255)
# 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
# group_id :integer
#

View File

@ -1,16 +1,16 @@
class ProjectHook < WebHook
belongs_to :project
end
# == Schema Information # == Schema Information
# #
# Table name: web_hooks # Table name: web_hooks
# #
# id :integer not null, primary key # id :integer not null, primary key
# url :string(255) # url :string(255)
# project_id :integer # project_id :integer
# created_at :datetime not null # created_at :datetime not null
# updated_at :datetime not null # updated_at :datetime not null
# type :string(255) default("ProjectHook") # type :string(255) default("ProjectHook")
# service_id :integer
# #
class ProjectHook < WebHook
belongs_to :project
end

View File

@ -1,3 +1,14 @@
# == 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
#
class ProtectedBranch < ActiveRecord::Base class ProtectedBranch < ActiveRecord::Base
include GitHost include GitHost
@ -18,15 +29,3 @@ class ProtectedBranch < ActiveRecord::Base
project.commit(self.name) project.commit(self.name)
end end
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
#

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