Compare commits

..

27 Commits

Author SHA1 Message Date
Dmitriy Zaporozhets f4fafc4631 Merge pull request #2524 from sourcerer-mike/4-0-stable
Improve usability and quit spamming
2013-03-05 05:58:32 -08:00
Riyad Preukschas c84fcb265c Fix checking the init script in check.rake
Fixes #2671
2013-01-20 15:58:41 +01:00
Riyad Preukschas 042a561baf Merge pull request #2652 from jouve/fix_#2492
fix #2492
2013-01-17 18:57:11 -08:00
Cyril 7b6cbebaad fix #2492 2013-01-18 00:11:15 +01:00
Riyad Preukschas 9cf993972a Fix gitolite config checks for old Gitolite versions
Fixes #2608
2013-01-17 00:45:24 +01:00
Dmitriy Zaporozhets f254de7337 4.0.1 2013-01-15 17:14:53 +02:00
Riyad Preukschas 147dfd1656 Replace all stat command line calls with ruby equivalents 2013-01-12 01:25:21 +01:00
Riyad Preukschas f73dd4af5e Make method names clearer in check.rake 2013-01-12 01:25:19 +01:00
Riyad Preukschas ab12419633 Move OS detection to task helpers and add detection of OS X 2013-01-12 01:25:16 +01:00
Riyad Preukschas c312a8d7d1 Move checks after init script installation in docs 2013-01-11 19:01:41 +01:00
David Southard e523327355 update grammar in check application status section 2013-01-11 17:25:21 +01:00
Dmitriy Zaporozhets c9ae412e88 Merge pull request #2532 from dvanduzer/4-0-stable
updating rails to 3.2.11 in response to CVE-2013-0156
2013-01-09 10:22:14 -08:00
David Van Duzer 6e067482dc updating rails to 3.2.11 in response to CVE-2013-0156
See also:
https://github.com/gitlabhq/gitlabhq/issues/2526
http://www.securityfocus.com/bid/57187
2013-01-09 10:57:41 -07:00
Dmitriy Zaporozhets d40215746e Update docs to use 4-0-stable recipes 2013-01-09 19:48:03 +02:00
rmp 1abc70fbf6 Comment wont be mailed to team by default.
No more magic for deciding which comment is important or not.
2013-01-09 16:44:00 +01:00
rmp 3cccbf8a43 Possibility to open a new issue form after viewing another one.
While looking at an issue you no longer need to go back to the issue list for creating the next one.
2013-01-08 23:42:09 +01:00
rmp 2e7e6e6ee1 Disable automatic mailing to the group.
Most comments are not so essential for the whole team and plenty are private notes. It's recommended to disable those and enable by hand when a comment is important.
2013-01-08 23:40:09 +01:00
Riyad Preukschas 0e2880b740 Backport fixes to the check and info tasks 2013-01-07 21:32:29 +01:00
Dmitriy Zaporozhets 10b312abad Merge pull request #2494 from dvanduzer/4-0-stable
updating rails to 3.2.10 in response to CVE-2012-5664
2013-01-06 03:16:32 -08:00
David Van Duzer 260ab8d67a updating rails to 3.2.10 in response to CVE-2012-5664
See also:
https://github.com/gitlabhq/gitlabhq/issues/2464
http://www.securityfocus.com/bid/57084
2013-01-06 00:46:40 -07:00
Dmitriy Zaporozhets 708a0d421e Fixed and improved enable_naamespace migration task 2012-12-28 06:14:05 +03:00
Dmitriy Zaporozhets 779e95b503 Merge pull request #2401 from Philzen/4-0-stable
Fix for Postgresql Migration 3.1 --> 4.0
2012-12-27 06:59:28 -08:00
Phil. Austermann 91405d1f98 - Fix PostgreSql Migration issue to 4.0 (fixes https://github.com/gitlabhq/gitlabhq/issues/2398) 2012-12-27 11:03:54 +01:00
Dmitriy Zaporozhets 2edb16612f Cleanup service tasks 2012-12-27 11:18:05 +02:00
Dmitriy Zaporozhets c68540e9c9 Fix resque for postgres 2012-12-26 19:56:56 +02:00
Dmitriy Zaporozhets 19cb29e448 Fix MR count for group scope 2012-12-26 10:56:51 +02:00
Dmitriy Zaporozhets 45b6103997 Update projects in gitolite after namespace moved. Added rake task to cleanup garbage from gitolite 2012-12-24 20:06:37 +02:00
1092 changed files with 112497 additions and 23346 deletions

6
.gitignore vendored
View File

@ -2,7 +2,7 @@
.rbx/
db/*.sqlite3
db/*.sqlite3-journal
log/*.log*
log/*.log
tmp/
.sass-cache/
coverage/*
@ -19,12 +19,8 @@ config/gitlab.yml
config/database.yml
config/initializers/omniauth.rb
config/unicorn.rb
config/resque.yml
config/aws.yml
db/data.yml
.idea
.DS_Store
.chef
vendor/bundle/*
rails_best_practices_output.html
doc/code/*

2
.rspec
View File

@ -1 +1 @@
--colour --drb
--colour

View File

@ -1,4 +0,0 @@
# .simplecov
SimpleCov.start 'rails' do
merge_timeout 3600
end

View File

@ -1,14 +1,18 @@
language: ruby
env:
- DB=mysql TRAVIS=true
- DB=postgresql
- DB=mysql
before_install:
- sudo apt-get install libicu-dev -y
- wget -P /tmp http://phantomjs.googlecode.com/files/phantomjs-1.7.0-linux-i686.tar.bz2
- 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:
only:
- 'master'
rvm:
- 1.9.3-p392
- 1.9.3
services:
- mysql
- postgresql

View File

@ -1,83 +1,7 @@
v 5.1.0
- You can login with email or username now
- Corrected project transfer rollback when repository cannot be moved
- Move both repo and wiki when project transfer requrested
- Admin area: project editing was removed from admin namespace
- Access: admin user has now access to any project.
v 5.0.0
- Replaced gitolite with gitlab-shell
- Removed gitolite-related libraries
- State machine added
- Setup gitlab as git user
- Internal API
- Show team tab for empty projects
- Import repository feature
- Updated rails
- Use lambda for scopes
- Redesign admin area -> users
- Redesign admin area -> user
- Secure link to file attachments
- Add validations for Group and Team names
- Restyle team page for project
- Update capybara, rspec-rails, poltergeist to recent versions
- Wiki on git using Gollum
- Added Solarized Dark theme for code review
- Dont show user emails in autocomplete lists, profile pages
- Added settings tab for group, team, project
- Replace user popup with icons in header
- Handle project moving with gitlab-shell
- Added select2-rails for selectboxes with ajax data load
- Fixed search field on projects page
- Added teams to search autocomplete
- Move groups and teams on dashboard sidebar to sub-tabs
- API: improved return codes and docs. (Felix Gilcher, Sebastian Ziebell)
- Redesign wall to be more like chat
- Snippets, Wall features are disabled by default for new projects
v 4.2.0
- Teams
- User show page. Via /u/username
- Show help contents on pages for better navigation
- Async gitolite calls
- added satellites logs
- can_create_group, can_create_team booleans for User
- Process web hooks async
- GFM: Fix images escaped inside links
- Network graph improved
- Switchable branches for network graph
- API: Groups
- Fixed project download
v 4.1.0
- Optional Sign-Up
- Discussions
- Satellites outside of tmp
- Line numbers for blame
- Project public mode
- Public area with unauthorized access
- Load dashboard events with ajax
- remember dashboard filter in cookies
- replace resque with sidekiq
- fix routing issues
- cleanup rake tasks
- fix backup/restore
- scss cleanup
- show preview for note images
- improved network-graph
- get rid of app/roles/
- added new classes Team, Repository
- Reduce amount of gitolite calls
- Ability to add user in all group projects
- remove deprecated configs
- replaced Korolev font with open font
- restyled admin/dashboard page
- restyled admin/projects page
v 4.0.0
- Remove project code and path from API. Use id instead
- Return valid clonable url to repo for web hook
- Fixed backup issue
- Fixed backup issue
- Reorganized settings
- Fixed commits compare
- Refactored scss

View File

@ -1,53 +1,26 @@
# Contact & support
If you want quick help, head over to our [Support Forum](https://groups.google.com/forum/#!forum/gitlabhq).
Otherwise you can follow our [Issue Submission Guide](https://github.com/gitlabhq/gitlabhq/wiki/Issue-Submission-Guide) for a more systematic and thorough guide to solving your issues.
# Contribute to GitLab
This guide details how to use pull requests and the issues to improve GitLab.
## Recipes
## Closing policy for pull requests and issues
We collect user submitted installation scripts and config file templates for platforms we don't support officially.
We believe there is merit in allowing a certain amount of diversity.
You can get and submit your solution to running/configuring GitLab with your favorite OS/distro, database, web server, cloud hoster, configuration management tool, etc.
Pull requests and issues not in line with the guidelines listed in this document will be closed with just a link to this paragraph. GitLab is a popular open source project and the capacity to deal with issues and pull requests is limited. To get support for your problems please use other channels as detailed in [the getting help section of the readme](https://github.com/gitlabhq/gitlabhq#getting-help). Professional [support subscriptions](http://www.gitlab.com/subscription/) and [consulting services](http://www.gitlab.com/consultancy/) are available from [GitLab.com](http://www.gitlab.com/).
Help us improve the collection of [GitLab Recipes](https://github.com/gitlabhq/gitlab-recipes/)
## Pull requests
We welcome pull request with improvements to GitLab code and/or documentation. The issues we would really like a pull request for are listed with the [status 'accepting merge/pull requests' on our feedback forum](http://feedback.gitlab.com/forums/176466-general/status/796455) but other improvements are also welcome.
## Feature suggestions
### Pull request guidelines
Follow the [Issue Submission Guide](https://github.com/gitlabhq/gitlabhq/wiki/Issue-Submission-Guide) and support other peoples ideas or propose your own.
If you can please submit a pull request with the fix including tests. The workflow to make a pull request is as follows:
1. Fork the project on GitHub
1. Create a feature branch
1. Write tests and code
1. If you have multiple commits please combine them into one commit by [squashing them](http://git-scm.com/book/en/Git-Tools-Rewriting-History#Squashing-Commits)
1. Push the commit to your fork
1. Submit a pull request
## Code
We will accept pull requests if:
* The code has proper tests and all tests pass
* It can be merged without problems (if not please use: git rebase master)
* It doesn't break any existing functionality
* It's quality code that conforms to the [Rails style guide](https://github.com/bbatsov/rails-style-guide) and best practices
* The description includes a motive for your change and the method you used to achieve it
* It keeps the GitLab code base clean and well structured
* We think other users will need the same functionality
* If it makes changes to the UI the pull request should include screenshots
For examples of feedback on pull requests please look at already [closed pull requests](https://github.com/gitlabhq/gitlabhq/pulls?direction=desc&page=1&sort=created&state=closed).
## Issue tracker
The [issue tracker](https://github.com/gitlabhq/gitlabhq/issues) is only for obvious bugs or misbehavior in the master branch of GitLab. When submitting an issue please conform to the issue submission guidelines listed below.
Please send a pull request with a tested solution or a pull request with a failing test instead of opening an issue if you can. If you're unsure where to post, post to the [Support Forum](https://groups.google.com/forum/#!forum/gitlabhq) first. There are a lot of helpful GitLab users there who may be able to help you quickly. If your particular issue turns out to be a bug, it will find its way from there.
### Issue tracker guidelines
**Search** for similar entries before submitting your own, there's a good chance somebody else had the same issue or idea. Show your support with `:+1:` and/or join the discussion.
* Summarize your issue in one sentence (what goes wrong, what did you expect to happen)
* Describe your issue in detail
* How can we reproduce the issue on the [GitLab Vagrant virtual machine](https://github.com/gitlabhq/gitlab-vagrant-vm) (start with: vagrant destroy && vagrant up && vagrant ssh)
* Add the last commit sha1 of the GitLab version you used to replicate the issue
* Add logs or screen shots when possible
* Link to the line of code that might be responsible for the problem
* Describe your setup (use relevant parts from `sudo -u gitlab -H bundle exec rake gitlab:env:info`)
Follow our [Developer Guide](https://github.com/gitlabhq/gitlabhq/wiki/Developer-Guide) to set you up for hacking on GitLab.

View File

@ -1,4 +0,0 @@
load 'deploy'
load 'deploy/assets'
require 'bundler/capistrano'
load 'config/deploy'

90
Gemfile
View File

@ -1,4 +1,4 @@
source "https://rubygems.org"
source "http://rubygems.org"
def darwin_only(require_as)
RUBY_PLATFORM.include?('darwin') && require_as
@ -8,58 +8,50 @@ def linux_only(require_as)
RUBY_PLATFORM.include?('linux') && require_as
end
gem "rails", "3.2.13"
gem "rails", "3.2.11"
# Supported DBs
gem "mysql2", group: :mysql
gem "pg", group: :postgres
# Auth
gem "devise"
gem 'omniauth', "~> 1.1.3"
gem "devise", "~> 2.1.0"
gem 'omniauth', "~> 1.1.1"
gem 'omniauth-google-oauth2'
gem 'omniauth-twitter'
gem 'omniauth-github'
# Extracting information from a git repository
# Since gollum requires grit we cannot use gitlab-grit gem name any more. Use grit instead
gem "grit", '~> 2.5.0', git: 'https://github.com/gitlabhq/grit.git', ref: '42297cdcee16284d2e4eff23d41377f52fc28b9d'
gem 'grit_ext', '~> 0.8.1'
# GITLAB patched libs
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 'yaml_db', git: "https://github.com/gitlabhq/yaml_db.git", ref: '98e9a5dca43e3fedd3268c76a73af40d1bdf1dfd'
gem 'grack', git: "https://github.com/gitlabhq/grack.git", ref: 'ba46f3b0845c6a09d488ae6abdce6ede37e227e8'
gem 'grit_ext', git: "https://github.com/gitlabhq/grit_ext.git", ref: '8e6afc2da821354774aa4d1ee8a1aa2082f84a3e'
# Ruby/Rack Git Smart-HTTP Server Handler
gem 'gitlab-grack', '~> 1.0.0', require: 'grack'
# LDAP Auth
gem 'gitlab_omniauth-ldap', '1.0.2', require: "omniauth-ldap"
# Dump db to yml file. Mostly used to migrate from sqlite to mysql
gem 'gitlab_yaml_db', '1.0.0', require: "yaml_db"
# Gitolite client (for work with gitolite-admin repo)
gem "gitolite", '1.1.0'
# Syntax highlighter
gem "gitlab-pygments.rb", '~> 0.3.2', require: 'pygments.rb'
gem "pygments.rb", git: "https://github.com/gitlabhq/pygments.rb.git", branch: "master"
# Language detection
gem "github-linguist", "~> 2.3.4" , require: "linguist"
# API
gem "grape", "~> 0.3.1"
gem "grape-entity", "~> 0.2.0"
gem "grape", "~> 0.2.1"
# Format dates and times
# based on human-friendly examples
gem "stamp"
# Enumeration fields
gem 'enumerize'
# Pagination
gem "kaminari", "~> 0.14.1"
# HAML
gem "haml-rails"
gem "haml-rails", "~> 0.3.5"
# Files attachments
gem "carrierwave"
gem "carrierwave", "~> 0.7.1"
# Authorization
gem "six"
@ -75,21 +67,18 @@ gem "redcarpet", "~> 2.2.2"
gem "github-markup", "~> 0.7.4", require: 'github/markup'
# Servers
gem "unicorn"
# State machine
gem "state_machine"
gem "thin", '~> 1.5.0'
gem "unicorn", "~> 4.4.0"
# Issue tags
gem "acts-as-taggable-on", "2.3.3"
# Decorators
gem "draper"
gem "draper", "~> 0.18.0"
# Background jobs
gem 'slim'
gem 'sinatra', require: nil
gem 'sidekiq'
gem "resque", "~> 1.23.0"
gem 'resque_mailer'
# HTTP requests
gem "httparty"
@ -100,20 +89,10 @@ gem "colored"
# GitLab settings
gem 'settingslogic'
# Wiki
# - Use latest master to resolve Gem dependency with Pygemnts
# github-linquist needs pygments 0.4.2 but Gollum 2.4.11
# requires pygments 0.3.2. The latest master Gollum has been updated
# to use pygments 0.4.2. Change this after next Gollum release.
gem "gollum", "~> 2.4.0", git: "https://github.com/gollum/gollum.git", ref: "5dcd3c8c8f"
# Misc
gem "foreman"
gem "git"
# Cache
gem "redis-rails"
group :assets do
gem "sass-rails", "~> 3.2.5"
gem "coffee-rails", "~> 3.2.2"
@ -121,16 +100,14 @@ group :assets do
gem "therubyracer"
gem 'chosen-rails', "0.9.8"
gem 'select2-rails'
gem 'jquery-atwho-rails', "0.1.7"
gem "jquery-rails", "2.1.3"
gem "jquery-ui-rails", "2.0.2"
gem "modernizr", "2.6.2"
gem "raphael-rails", git: "https://github.com/gitlabhq/raphael-rails.git"
gem "raphael-rails", "1.5.2"
gem 'bootstrap-sass', "2.2.1.1"
gem "font-awesome-sass-rails", "~> 3.0.0"
gem "font-awesome-sass-rails", "~> 2.0.0"
gem "gemoji", "~> 1.2.1", require: 'emoji/railtie'
gem "gon"
end
group :development do
@ -138,28 +115,16 @@ group :development do
gem "letter_opener"
gem 'quiet_assets', '~> 1.0.1'
gem 'rack-mini-profiler'
# Better errors handler
gem 'better_errors'
gem 'binding_of_caller'
gem 'rails_best_practices'
# Docs generator
gem "sdoc"
# thin instead webrick
gem 'thin'
end
group :development, :test do
gem 'coveralls', require: false
gem 'rails-dev-tweaks'
gem 'spinach-rails'
gem "rspec-rails"
gem "capybara"
gem "pry"
gem "awesome_print"
gem "database_cleaner"
gem "database_cleaner", ref: "f89c34300e114be99532f14c115b2799a3380ac6", git: "https://github.com/bmabey/database_cleaner.git"
gem "launchy"
gem 'factory_girl_rails'
@ -173,19 +138,18 @@ group :development, :test do
gem 'rb-inotify', require: linux_only('rb-inotify')
# PhantomJS driver for Capybara
gem 'poltergeist', '1.1.0'
gem 'spork', '~> 1.0rc'
gem 'poltergeist', git: 'https://github.com/jonleighton/poltergeist.git', ref: '5c2e092001074a8cf09f332d3714e9ba150bc8ca'
end
group :test do
gem "simplecov", require: false
gem "shoulda-matchers", "1.3.0"
gem 'email_spec'
gem 'resque_spec'
gem "webmock"
gem 'test_after_commit'
end
group :production do
gem "gitlab_meta", '5.0'
gem "gitlab_meta", '4.0'
end

View File

@ -1,3 +1,10 @@
GIT
remote: https://github.com/bmabey/database_cleaner.git
revision: f89c34300e114be99532f14c115b2799a3380ac6
ref: f89c34300e114be99532f14c115b2799a3380ac6
specs:
database_cleaner (0.9.1)
GIT
remote: https://github.com/ctran/annotate_models.git
revision: be4e26825b521f0b2d86b181e2dff89901aa9b1e
@ -6,10 +13,18 @@ GIT
activerecord (>= 2.3.0)
rake (>= 0.8.7)
GIT
remote: https://github.com/gitlabhq/grack.git
revision: ba46f3b0845c6a09d488ae6abdce6ede37e227e8
ref: ba46f3b0845c6a09d488ae6abdce6ede37e227e8
specs:
grack (1.0.0)
rack (~> 1.4.1)
GIT
remote: https://github.com/gitlabhq/grit.git
revision: 42297cdcee16284d2e4eff23d41377f52fc28b9d
ref: 42297cdcee16284d2e4eff23d41377f52fc28b9d
revision: 7f35cb98ff17d534a07e3ce6ec3d580f67402837
ref: 7f35cb98ff17d534a07e3ce6ec3d580f67402837
specs:
grit (2.5.0)
diff-lcs (~> 1.1)
@ -17,95 +32,110 @@ GIT
posix-spawn (~> 0.3.6)
GIT
remote: https://github.com/gitlabhq/raphael-rails.git
revision: cb2c92a040b9b941a5f1aa1ea866cc26e944fe58
remote: https://github.com/gitlabhq/grit_ext.git
revision: 8e6afc2da821354774aa4d1ee8a1aa2082f84a3e
ref: 8e6afc2da821354774aa4d1ee8a1aa2082f84a3e
specs:
raphael-rails (2.1.0)
grit_ext (0.6.1)
charlock_holmes (~> 0.6.9)
GIT
remote: https://github.com/gollum/gollum.git
revision: 5dcd3c8c8f68158e43ff79861279088ee56d0ebe
ref: 5dcd3c8c8f
remote: https://github.com/gitlabhq/omniauth-ldap.git
revision: f038dd852d7bd473a557e385d5d7c2fd5dc1dc2e
ref: f038dd852d7bd473a557e385d5d7c2fd5dc1dc2e
specs:
gollum (2.4.11)
github-markdown (~> 0.5.3)
github-markup (>= 0.7.5, < 1.0.0)
grit (~> 2.5.0)
mustache (>= 0.99.4, < 1.0.0)
nokogiri (~> 1.5.6)
pygments.rb (~> 0.4.2)
sanitize (~> 2.0.3)
sinatra (~> 1.3.5)
stringex (~> 1.5.1)
useragent (~> 0.4.16)
omniauth-ldap (1.0.2)
net-ldap (~> 0.2.2)
omniauth (~> 1.0)
pyu-ruby-sasl (~> 0.0.3.1)
rubyntlm (~> 0.1.1)
GIT
remote: https://github.com/gitlabhq/pygments.rb.git
revision: db1da0343adf86b49bdc3add04d02d2e80438d38
branch: master
specs:
pygments.rb (0.3.2)
posix-spawn (~> 0.3.6)
yajl-ruby (~> 1.1.0)
GIT
remote: https://github.com/gitlabhq/yaml_db.git
revision: 98e9a5dca43e3fedd3268c76a73af40d1bdf1dfd
ref: 98e9a5dca43e3fedd3268c76a73af40d1bdf1dfd
specs:
yaml_db (0.2.2)
GIT
remote: https://github.com/jonleighton/poltergeist.git
revision: 5c2e092001074a8cf09f332d3714e9ba150bc8ca
ref: 5c2e092001074a8cf09f332d3714e9ba150bc8ca
specs:
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)
GEM
remote: https://rubygems.org/
remote: http://rubygems.org/
specs:
actionmailer (3.2.13)
actionpack (= 3.2.13)
mail (~> 2.5.3)
actionpack (3.2.13)
activemodel (= 3.2.13)
activesupport (= 3.2.13)
actionmailer (3.2.11)
actionpack (= 3.2.11)
mail (~> 2.4.4)
actionpack (3.2.11)
activemodel (= 3.2.11)
activesupport (= 3.2.11)
builder (~> 3.0.0)
erubis (~> 2.7.0)
journey (~> 1.0.4)
rack (~> 1.4.5)
rack (~> 1.4.0)
rack-cache (~> 1.2)
rack-test (~> 0.6.1)
sprockets (~> 2.2.1)
activemodel (3.2.13)
activesupport (= 3.2.13)
activemodel (3.2.11)
activesupport (= 3.2.11)
builder (~> 3.0.0)
activerecord (3.2.13)
activemodel (= 3.2.13)
activesupport (= 3.2.13)
activerecord (3.2.11)
activemodel (= 3.2.11)
activesupport (= 3.2.11)
arel (~> 3.0.2)
tzinfo (~> 0.3.29)
activeresource (3.2.13)
activemodel (= 3.2.13)
activesupport (= 3.2.13)
activesupport (3.2.13)
i18n (= 0.6.1)
activeresource (3.2.11)
activemodel (= 3.2.11)
activesupport (= 3.2.11)
activesupport (3.2.11)
i18n (~> 0.6)
multi_json (~> 1.0)
acts-as-taggable-on (2.3.3)
rails (~> 3.0)
addressable (2.3.2)
arel (3.0.2)
awesome_print (1.1.0)
backports (2.6.7)
backports (2.6.5)
bcrypt-ruby (3.0.1)
better_errors (0.3.2)
coderay (>= 1.0.0)
erubis (>= 2.7.0)
binding_of_caller (0.7.1)
debug_inspector (>= 0.0.1)
blankslate (3.1.2)
bootstrap-sass (2.2.1.1)
sass (~> 3.2)
builder (3.0.4)
capybara (2.0.2)
capybara (1.1.3)
mime-types (>= 1.16)
nokogiri (>= 1.3.3)
rack (>= 1.0.0)
rack-test (>= 0.5.4)
selenium-webdriver (~> 2.0)
xpath (~> 1.0.0)
carrierwave (0.8.0)
xpath (~> 0.1.4)
carrierwave (0.7.1)
activemodel (>= 3.2.0)
activesupport (>= 3.2.0)
celluloid (0.12.4)
facter (>= 1.6.12)
timers (>= 1.0.0)
charlock_holmes (0.6.9)
childprocess (0.3.8)
ffi (~> 1.0, >= 1.0.11)
childprocess (0.3.6)
ffi (~> 1.0, >= 1.0.6)
chosen-rails (0.9.8)
railties (~> 3.0)
thor (~> 0.14)
code_analyzer (0.3.1)
sexp_processor
coderay (1.0.9)
coderay (1.0.8)
coffee-rails (3.2.2)
coffee-script (>= 2.2.0)
railties (~> 3.2.0)
@ -115,54 +145,40 @@ GEM
coffee-script-source (1.4.0)
colored (1.2)
colorize (0.5.8)
connection_pool (1.0.0)
coveralls (0.6.2)
colorize
multi_json (~> 1.3)
rest-client
simplecov (>= 0.7)
thor
crack (0.3.2)
crack (0.3.1)
daemons (1.1.9)
database_cleaner (0.9.1)
debug_inspector (0.0.2)
descendants_tracker (0.0.1)
devise (2.2.3)
devise (2.1.2)
bcrypt-ruby (~> 3.0)
orm_adapter (~> 0.1)
railties (~> 3.1)
warden (~> 1.2.1)
diff-lcs (1.2.1)
draper (1.1.0)
actionpack (>= 3.0)
activesupport (>= 3.0)
request_store (~> 1.0.3)
diff-lcs (1.1.3)
draper (0.18.0)
actionpack (~> 3.2)
activesupport (~> 3.2)
email_spec (1.4.0)
launchy (~> 2.1)
mail (~> 2.2)
enumerize (0.5.1)
activesupport (>= 3.2)
erubis (2.7.0)
escape_utils (0.2.4)
eventmachine (1.0.0)
execjs (1.4.0)
multi_json (~> 1.0)
facter (1.6.18)
factory_girl (4.1.0)
activesupport (>= 3.0.0)
factory_girl_rails (4.1.0)
factory_girl (~> 4.1.0)
railties (>= 3.0.0)
faraday (0.8.6)
faraday (0.8.4)
multipart-post (~> 1.1)
faye-websocket (0.4.7)
faye-websocket (0.4.6)
eventmachine (>= 0.12.0)
ffaker (1.15.0)
ffi (1.4.0)
font-awesome-sass-rails (3.0.0.1)
ffi (1.1.5)
font-awesome-sass-rails (2.0.0.0)
railties (>= 3.1.1)
sass-rails (>= 3.1.1)
foreman (0.61.0)
foreman (0.60.2)
thor (>= 0.13.6)
gemoji (1.2.1)
gherkin-ruby (0.2.1)
@ -172,62 +188,48 @@ GEM
escape_utils (~> 0.2.3)
mime-types (~> 1.19)
pygments.rb (>= 0.2.13)
github-markdown (0.5.3)
github-markup (0.7.5)
gitlab-grack (1.0.0)
rack (~> 1.4.1)
gitlab-pygments.rb (0.3.2)
posix-spawn (~> 0.3.6)
yajl-ruby (~> 1.1.0)
gitlab_meta (5.0)
gitlab_omniauth-ldap (1.0.2)
net-ldap (~> 0.2.2)
omniauth (~> 1.0)
pyu-ruby-sasl (~> 0.0.3.1)
rubyntlm (~> 0.1.1)
gitlab_yaml_db (1.0.0)
gon (4.0.2)
grape (0.3.2)
github-markup (0.7.4)
gitlab_meta (4.0)
gitolite (1.1.0)
gratr19 (~> 0.4.4.1)
grit (~> 2.5.0)
hashery (~> 1.5.0)
grape (0.2.2)
activesupport
builder
hashie (>= 1.2.0)
hashie (~> 1.2)
multi_json (>= 1.3.2)
multi_xml (>= 0.5.2)
multi_xml
rack
rack-accept
rack-mount
virtus
grape-entity (0.2.0)
activesupport
multi_json (>= 1.3.2)
grit_ext (0.8.1)
charlock_holmes (~> 0.6.9)
gratr19 (0.4.4.1)
growl (1.0.3)
guard (1.6.2)
listen (>= 0.6.0)
guard (1.5.4)
listen (>= 0.4.2)
lumberjack (>= 1.0.2)
pry (>= 0.9.10)
terminal-table (>= 1.4.3)
thor (>= 0.14.6)
guard-rspec (2.5.1)
guard-rspec (2.1.2)
guard (>= 1.1)
rspec (~> 2.11)
guard-spinach (0.0.2)
guard (>= 1.1)
spinach
haml (4.0.0)
tilt
haml-rails (0.4)
haml (3.1.7)
haml-rails (0.3.5)
actionpack (>= 3.1, < 4.1)
activesupport (>= 3.1, < 4.1)
haml (>= 3.1, < 4.1)
haml (~> 3.1)
railties (>= 3.1, < 4.1)
hashery (1.5.0)
blankslate
hashie (1.2.0)
hike (1.2.1)
http_parser.rb (0.5.3)
httparty (0.10.2)
httparty (0.9.0)
multi_json (~> 1.0)
multi_xml (>= 0.5.2)
multi_xml
httpauth (0.2.0)
i18n (0.6.1)
journey (1.0.4)
@ -238,46 +240,47 @@ GEM
jquery-ui-rails (2.0.2)
jquery-rails
railties (>= 3.1.0)
json (1.7.7)
json (1.7.6)
jwt (0.1.5)
multi_json (>= 1.0)
kaminari (0.14.1)
actionpack (>= 3.0.0)
activesupport (>= 3.0.0)
kgio (2.8.0)
kgio (2.7.4)
launchy (2.1.2)
addressable (~> 2.3)
letter_opener (1.0.0)
launchy (>= 2.0.4)
libv8 (3.11.8.17)
listen (0.7.3)
lumberjack (1.0.3)
mail (2.5.3)
libv8 (3.3.10.4)
libwebsocket (0.1.6)
websocket
listen (0.5.3)
lumberjack (1.0.2)
mail (2.4.4)
i18n (>= 0.4.0)
mime-types (~> 1.16)
treetop (~> 1.4.8)
method_source (0.8.1)
mime-types (1.21)
mime-types (1.19)
modernizr (2.6.2)
sprockets (~> 2.0)
multi_json (1.7.2)
multi_xml (0.5.3)
multi_json (1.5.0)
multi_xml (0.5.1)
multipart-post (1.1.5)
mustache (0.99.4)
mysql2 (0.3.11)
net-ldap (0.2.2)
nokogiri (1.5.6)
nokogiri (1.5.5)
oauth (0.4.7)
oauth2 (0.8.1)
oauth2 (0.8.0)
faraday (~> 0.8)
httpauth (~> 0.1)
jwt (~> 0.1.4)
multi_json (~> 1.0)
rack (~> 1.2)
omniauth (1.1.3)
omniauth (1.1.1)
hashie (~> 1.2)
rack
omniauth-github (1.1.0)
omniauth-github (1.0.3)
omniauth (~> 1.0)
omniauth-oauth2 (~> 1.1)
omniauth-google-oauth2 (0.1.13)
@ -294,23 +297,16 @@ GEM
omniauth-oauth (~> 1.0)
orm_adapter (0.4.0)
pg (0.14.1)
poltergeist (1.1.0)
capybara (~> 2.0, >= 2.0.1)
faye-websocket (~> 0.4, >= 0.4.4)
http_parser.rb (~> 0.5.3)
polyglot (0.3.3)
posix-spawn (0.3.6)
pry (0.9.12)
pry (0.9.10)
coderay (~> 1.0.5)
method_source (~> 0.8)
slop (~> 3.4)
pygments.rb (0.4.2)
posix-spawn (~> 0.3.6)
yajl-ruby (~> 1.1.0)
slop (~> 3.3.1)
pyu-ruby-sasl (0.0.3.3)
quiet_assets (1.0.1)
railties (~> 3.1)
rack (1.4.5)
rack (1.4.3)
rack-accept (0.4.5)
rack (>= 0.4)
rack-cache (1.2)
@ -319,182 +315,139 @@ GEM
rack (>= 1.1.3)
rack-mount (0.8.3)
rack (>= 1.0.0)
rack-protection (1.4.0)
rack-protection (1.2.0)
rack
rack-ssl (1.3.3)
rack-ssl (1.3.2)
rack
rack-test (0.6.2)
rack (>= 1.0)
rails (3.2.13)
actionmailer (= 3.2.13)
actionpack (= 3.2.13)
activerecord (= 3.2.13)
activeresource (= 3.2.13)
activesupport (= 3.2.13)
rails (3.2.11)
actionmailer (= 3.2.11)
actionpack (= 3.2.11)
activerecord (= 3.2.11)
activeresource (= 3.2.11)
activesupport (= 3.2.11)
bundler (~> 1.0)
railties (= 3.2.13)
railties (= 3.2.11)
rails-dev-tweaks (0.6.1)
actionpack (~> 3.1)
railties (~> 3.1)
rails_best_practices (1.13.4)
activesupport
awesome_print
code_analyzer
colored
erubis
i18n
ruby-progressbar
railties (3.2.13)
actionpack (= 3.2.13)
activesupport (= 3.2.13)
railties (3.2.11)
actionpack (= 3.2.11)
activesupport (= 3.2.11)
rack-ssl (~> 1.3.2)
rake (>= 0.8.7)
rdoc (~> 3.4)
thor (>= 0.14.6, < 2.0)
raindrops (0.10.0)
rake (10.0.4)
rake (10.0.3)
raphael-rails (1.5.2)
rb-fsevent (0.9.2)
rb-inotify (0.8.8)
ffi (>= 0.5.0)
rdoc (3.12.2)
rdoc (3.12)
json (~> 1.4)
redcarpet (2.2.2)
redis (3.0.3)
redis-actionpack (3.2.3)
actionpack (~> 3.2.3)
redis-rack (~> 1.4.0)
redis-store (~> 1.1.0)
redis-activesupport (3.2.3)
activesupport (~> 3.2.3)
redis-store (~> 1.1.0)
redis (3.0.2)
redis-namespace (1.2.1)
redis (~> 3.0.0)
redis-rack (1.4.2)
rack (~> 1.4.1)
redis-store (~> 1.1.0)
redis-rails (3.2.3)
redis-actionpack (~> 3.2.3)
redis-activesupport (~> 3.2.3)
redis-store (~> 1.1.0)
redis-store (1.1.3)
redis (>= 2.2.0)
ref (1.0.4)
request_store (1.0.5)
rest-client (1.6.7)
mime-types (>= 1.16)
rspec (2.13.0)
rspec-core (~> 2.13.0)
rspec-expectations (~> 2.13.0)
rspec-mocks (~> 2.13.0)
rspec-core (2.13.1)
rspec-expectations (2.13.0)
diff-lcs (>= 1.1.3, < 2.0)
rspec-mocks (2.13.0)
rspec-rails (2.13.0)
resque (1.23.0)
multi_json (~> 1.0)
redis-namespace (~> 1.0)
sinatra (>= 0.9.2)
vegas (~> 0.1.2)
resque_mailer (2.1.0)
actionmailer (~> 3.0)
resque_spec (0.12.5)
resque (>= 1.19.0)
rspec (>= 2.5.0)
rspec (2.12.0)
rspec-core (~> 2.12.0)
rspec-expectations (~> 2.12.0)
rspec-mocks (~> 2.12.0)
rspec-core (2.12.0)
rspec-expectations (2.12.0)
diff-lcs (~> 1.1.3)
rspec-mocks (2.12.0)
rspec-rails (2.12.0)
actionpack (>= 3.0)
activesupport (>= 3.0)
railties (>= 3.0)
rspec-core (~> 2.13.0)
rspec-expectations (~> 2.13.0)
rspec-mocks (~> 2.13.0)
ruby-progressbar (1.0.2)
rspec-core (~> 2.12.0)
rspec-expectations (~> 2.12.0)
rspec-mocks (~> 2.12.0)
rubyntlm (0.1.1)
rubyzip (0.9.9)
sanitize (2.0.3)
nokogiri (>= 1.4.4, < 1.6)
sass (3.2.7)
sass-rails (3.2.6)
sass (3.2.3)
sass-rails (3.2.5)
railties (~> 3.2.0)
sass (>= 3.1.10)
tilt (~> 1.3)
sdoc (0.3.20)
json (>= 1.1.3)
rdoc (~> 3.10)
seed-fu (2.2.0)
activerecord (~> 3.1)
activesupport (~> 3.1)
select2-rails (3.3.1)
sass-rails (>= 3.2)
thor (~> 0.14)
selenium-webdriver (2.30.0)
selenium-webdriver (2.26.0)
childprocess (>= 0.2.5)
libwebsocket (~> 0.1.3)
multi_json (~> 1.0)
rubyzip
websocket (~> 1.0.4)
settingslogic (2.0.9)
sexp_processor (4.2.0)
settingslogic (2.0.8)
shoulda-matchers (1.3.0)
activesupport (>= 3.0.0)
sidekiq (2.8.0)
celluloid (~> 0.12.0)
connection_pool (~> 1.0)
multi_json (~> 1)
redis (~> 3)
redis-namespace
simplecov (0.7.1)
multi_json (~> 1.0)
simplecov-html (~> 0.7.1)
simplecov-html (0.7.1)
sinatra (1.3.5)
rack (~> 1.4)
rack-protection (~> 1.3)
sinatra (1.3.3)
rack (~> 1.3, >= 1.3.6)
rack-protection (~> 1.2)
tilt (~> 1.3, >= 1.3.3)
six (0.2.0)
slim (1.3.6)
temple (~> 0.5.5)
tilt (~> 1.3.3)
slop (3.4.4)
spinach (0.7.0)
slop (3.3.3)
spinach (0.5.2)
colorize
gherkin-ruby (~> 0.2.0)
spinach-rails (0.2.0)
capybara (~> 2.0.0)
spinach-rails (0.1.8)
capybara (~> 1)
railties (>= 3)
spinach (>= 0.4)
spork (1.0.0rc3)
sprockets (2.2.2)
hike (~> 1.2)
multi_json (~> 1.0)
rack (~> 1.0)
tilt (~> 1.1, != 1.3.0)
stamp (0.5.0)
state_machine (1.1.2)
stringex (1.5.1)
temple (0.5.5)
terminal-table (1.4.5)
stamp (0.3.0)
test_after_commit (0.0.1)
therubyracer (0.11.4)
libv8 (~> 3.11.8.12)
ref
therubyracer (0.10.2)
libv8 (~> 3.3.10)
thin (1.5.0)
daemons (>= 1.0.9)
eventmachine (>= 0.12.6)
rack (>= 1.0.0)
thor (0.18.0)
tilt (1.3.6)
timers (1.1.0)
thor (0.16.0)
tilt (1.3.3)
treetop (1.4.12)
polyglot
polyglot (>= 0.3.1)
tzinfo (0.3.37)
tzinfo (0.3.35)
uglifier (1.3.0)
execjs (>= 0.3.0)
multi_json (~> 1.0, >= 1.0.2)
unicorn (4.6.2)
unicorn (4.4.0)
kgio (~> 2.6)
rack
raindrops (~> 0.7)
useragent (0.4.16)
virtus (0.5.4)
vegas (0.1.11)
rack (>= 1.0.0)
virtus (0.5.2)
backports (~> 2.6.1)
descendants_tracker (~> 0.0.1)
warden (1.2.1)
rack (>= 1.0)
webmock (1.9.0)
addressable (>= 2.2.7)
crack (>= 0.1.7)
websocket (1.0.7)
xpath (1.0.0)
websocket (1.0.2)
xpath (0.1.4)
nokogiri (~> 1.3)
yajl-ruby (1.1.0)
@ -505,43 +458,34 @@ DEPENDENCIES
acts-as-taggable-on (= 2.3.3)
annotate!
awesome_print
better_errors
binding_of_caller
bootstrap-sass (= 2.2.1.1)
capybara
carrierwave
carrierwave (~> 0.7.1)
chosen-rails (= 0.9.8)
coffee-rails (~> 3.2.2)
colored
coveralls
database_cleaner
devise
draper
database_cleaner!
devise (~> 2.1.0)
draper (~> 0.18.0)
email_spec
enumerize
factory_girl_rails
ffaker
font-awesome-sass-rails (~> 3.0.0)
font-awesome-sass-rails (~> 2.0.0)
foreman
gemoji (~> 1.2.1)
git
github-linguist (~> 2.3.4)
github-markup (~> 0.7.4)
gitlab-grack (~> 1.0.0)
gitlab-pygments.rb (~> 0.3.2)
gitlab_meta (= 5.0)
gitlab_omniauth-ldap (= 1.0.2)
gitlab_yaml_db (= 1.0.0)
gollum (~> 2.4.0)!
gon
grape (~> 0.3.1)
grape-entity (~> 0.2.0)
grit (~> 2.5.0)!
grit_ext (~> 0.8.1)
gitlab_meta (= 4.0)
gitolite (= 1.1.0)
grack!
grape (~> 0.2.1)
grit!
grit_ext!
growl
guard-rspec
guard-spinach
haml-rails
haml-rails (~> 0.3.5)
httparty
jquery-atwho-rails (= 0.1.7)
jquery-rails (= 2.1.3)
@ -551,42 +495,39 @@ DEPENDENCIES
letter_opener
modernizr (= 2.6.2)
mysql2
omniauth (~> 1.1.3)
omniauth (~> 1.1.1)
omniauth-github
omniauth-google-oauth2
omniauth-ldap!
omniauth-twitter
pg
poltergeist (= 1.1.0)
poltergeist!
pry
pygments.rb!
quiet_assets (~> 1.0.1)
rack-mini-profiler
rails (= 3.2.13)
rails (= 3.2.11)
rails-dev-tweaks
rails_best_practices
raphael-rails!
raphael-rails (= 1.5.2)
rb-fsevent
rb-inotify
redcarpet (~> 2.2.2)
redis-rails
resque (~> 1.23.0)
resque_mailer
resque_spec
rspec-rails
sass-rails (~> 3.2.5)
sdoc
seed-fu
select2-rails
settingslogic
shoulda-matchers (= 1.3.0)
sidekiq
simplecov
sinatra
six
slim
spinach-rails
spork (~> 1.0rc)
stamp
state_machine
test_after_commit
therubyracer
thin
thin (~> 1.5.0)
uglifier (~> 1.3.0)
unicorn
unicorn (~> 4.4.0)
webmock
yaml_db!

View File

@ -1,2 +1,2 @@
web: bundle exec unicorn_rails -p $PORT
worker: bundle exec sidekiq -q post_receive,mailer,system_hook,project_web_hook,common,default,gitlab_shell
web: bundle exec rails s -p $PORT
worker: bundle exec rake environment resque:work QUEUE=* VVERBOSE=1

165
README.md
View File

@ -1,161 +1,44 @@
## GitLab: self hosted Git management software
# Welcome to GitLab [![build status](https://secure.travis-ci.org/gitlabhq/gitlabhq.png)](https://travis-ci.org/gitlabhq/gitlabhq) [![build status](https://secure.travis-ci.org/gitlabhq/grit.png)](https://travis-ci.org/gitlabhq/grit) [![Code Climate](https://codeclimate.com/badge.png)](https://codeclimate.com/github/gitlabhq/gitlabhq) [![Dependency Status](https://gemnasium.com/gitlabhq/gitlabhq.png)](https://gemnasium.com/gitlabhq/gitlabhq)
![logo](https://raw.github.com/gitlabhq/gitlabhq/master/public/gitlab_logo.png)
GitLab is a free project and repository management application
### GitLab allows you to
* keep your code secure on your own server
* manage repositories, users and access permissions
* communicate through issues, line-comments and wiki pages
* perform code review with merge requests
### GitLab is
## Application details
* powered by Ruby on Rails
* completely free and open source (MIT license)
* used by more than 10.000 organizations to keep their code secure
* based on Ruby on Rails
* distributed under the MIT License
* works with gitolite
### Code status
## Requirements
* [![build status](http://ci.gitlab.org/projects/1/status?ref=master)](http://ci.gitlab.org/projects/1?ref=master) ci.gitlab.org (master branch)
* [![build status](https://secure.travis-ci.org/gitlabhq/gitlabhq.png)](https://travis-ci.org/gitlabhq/gitlabhq) travis-ci.org (master branch)
* [![Code Climate](https://codeclimate.com/github/gitlabhq/gitlabhq.png)](https://codeclimate.com/github/gitlabhq/gitlabhq)
* [![Dependency Status](https://gemnasium.com/gitlabhq/gitlabhq.png)](https://gemnasium.com/gitlabhq/gitlabhq)
* [![Coverage Status](https://coveralls.io/repos/gitlabhq/gitlabhq/badge.png?branch=master)](https://coveralls.io/r/gitlabhq/gitlabhq)
### Resources
* GitLab.org community site: [Homepage](http://gitlab.org) [Screenshots](http://gitlab.org/screenshots/) [Blog](http://blog.gitlab.org/) [Demo](http://demo.gitlabhq.com/users/sign_in)
* GitLab.com commercial services: [Homepage](http://www.gitlab.com/) [Subscription](http://www.gitlab.com/subscription/) [Consultancy](http://www.gitlab.com/consultancy/) [GitLab Cloud](http://www.gitlab.com/cloud/) [Blog](http://blog.gitlab.com/)
* GitLab CI: [Readme](https://github.com/gitlabhq/gitlab-ci/blob/master/README.md) of the GitLab open-source continuous integration server
### Requirements
* Ubuntu/Debian**
* ruby 1.9.3
* Ubuntu/Debian
* ruby 1.9.3+
* MySQL
* git
* gitlab-shell
* gitolite
* redis
** More details are in the [requirements doc](https://github.com/gitlabhq/gitlabhq/blob/master/doc/install/requirements.md)
## Install
### Installation
Checkout wiki pages for installation information, migration, etc.
#### Official production installation
## Community
Follow the installation guide for production server.
[Google Group](https://groups.google.com/group/gitlabhq)
* [Installation guide for latest stable release (5.0)](https://github.com/gitlabhq/gitlabhq/blob/5-0-stable/doc/install/installation.md) - **Recommended**
## Contacts
* [Installation guide for the current master branch (5.1)](https://github.com/gitlabhq/gitlabhq/blob/master/doc/install/installation.md)
Twitter:
* @gitlabhq
* @dzaporozhets
#### Official development installation
Email
If you want to contribute, please first read our [Contributing Guidelines](https://github.com/gitlabhq/gitlabhq/blob/master/CONTRIBUTING.md) and then we suggest you to use the Vagrant virtual machine project to get an environment working with all dependencies.
* m@gitlabhq.com
* [Vagrant virtual machine](https://github.com/gitlabhq/gitlab-vagrant-vm)
## Contribute
#### Unsupported production installation
* [GitLab recipes](https://github.com/gitlabhq/gitlab-recipes) for setup on different platforms
* [Unofficial installation guides](https://github.com/gitlabhq/gitlab-public-wiki/wiki/Unofficial-Installation-Guides)
* [BitNami one-click installers](http://bitnami.com/stack/gitlab)
* [TurnKey Linux virtual appliance](http://www.turnkeylinux.org/gitlab)
### New versions and upgrading
Each month on the 22th a new version is released together with an upgrade guide.
* [Upgrade guides](https://github.com/gitlabhq/gitlabhq/wiki)
* [Changelog](https://github.com/gitlabhq/gitlabhq/blob/master/CHANGELOG)
* [Roadmap](https://github.com/gitlabhq/gitlabhq/blob/master/ROADMAP.md)
### Getting started
1. The Installation guide contains instructions to download an init script and run that on boot. With the init script you can also start GitLab
sudo service gitlab start
or
sudo /etc/init.d/gitlab restart
2. Start it with [Foreman](https://github.com/ddollar/foreman) in development mode
bundle exec foreman start -p 3000
or start it manually
bundle exec rails s
bundle exec rake sidekiq:start
### Running the tests
* Seed the database
bundle exec rake db:setup RAILS_ENV=test
bundle exec rake db:seed_fu RAILS_ENV=test
* Run all tests
bundle exec rake gitlab:test
* Rspec unit and functional tests
bundle exec rake spec
* Spinach integration tests
bundle exec rake spinach
### GitLab interfaces
* [GitLab API](https://github.com/gitlabhq/gitlabhq/blob/master/doc/api/README.md)
* [Rake tasks](https://github.com/gitlabhq/gitlabhq/tree/master/doc/raketasks)
* [Directory structure](https://github.com/gitlabhq/gitlabhq/blob/master/doc/install/structure.md)
* [Databases](https://github.com/gitlabhq/gitlabhq/blob/master/doc/install/databases.md)
### Getting help
* [Troubleshooting guide](https://github.com/gitlabhq/gitlab-public-wiki/wiki/Trouble-Shooting-Guide) contains solutions to common problems.
* [Support forum](https://groups.google.com/forum/#!forum/gitlabhq) is the best place to ask questions. For example you can use it if you have questions about: permission denied errors, invisible repos, can't clone/pull/push or with web hooks that don't fire. Please search for similar issues before posting your own, there's a good chance somebody else had the same issue you have now and had it resolved. There are a lot of helpful GitLab users there who may be able to help you quickly. If your particular issue turns out to be a bug, it will find its way from there to a fix.
* [Feedback and suggestions forum](http://gitlab.uservoice.com/forums/176466-general) is the place to propose and discuss new features for GitLab.
* [Support subscription](http://www.gitlab.com/subscription/) connect you to the knowledge of GitLab experts that will resolve your issues and answer your questions.
* [Consultancy](http://www.gitlab.com/consultancy/) allows you hire GitLab exports for installations, upgrades and customizations.
* [Contributing guide](https://github.com/gitlabhq/gitlabhq/blob/master/CONTRIBUTING.md) describes how to submit pull requests and issues. Pull requests and issues not in line with the guidelines in this document will be closed without comment.
### Getting in touch
* [Core team](https://github.com/gitlabhq?tab=members)
* [Contributors](https://github.com/gitlabhq/gitlabhq/graphs/contributors)
* [Leader](https://github.com/randx)
* [Contact page](http://gitlab.org/contact/)
[Development Tips](https://github.com/gitlabhq/gitlabhq/blob/master/doc/development.md)
Want to help - send a pull request.
We'll accept good pull requests.

View File

@ -1,5 +1,25 @@
## GitLab Roadmap
### v5.1 April 22
### Common
* Not decided yet.
* 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 @@
5.1.0pre
4.0.1

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 781 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 177 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 295 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 749 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 302 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 691 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 674 B

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.

After

Width:  |  Height:  |  Size: 463 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 632 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 596 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 450 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 357 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

View File

@ -1,53 +0,0 @@
@Api =
users_path: "/api/:version/users.json"
user_path: "/api/:version/users/:id.json"
notes_path: "/api/:version/projects/:id/notes.json"
# Get 20 (depends on api) recent notes
# and sort the ascending from oldest to newest
notes: (project_id, callback) ->
url = Api.buildUrl(Api.notes_path)
url = url.replace(':id', project_id)
$.ajax(
url: url,
data:
private_token: gon.api_token
gfm: true
recent: true
dataType: "json"
).done (notes) ->
notes.sort (a, b) ->
return a.id - b.id
callback(notes)
user: (user_id, callback) ->
url = Api.buildUrl(Api.user_path)
url = url.replace(':id', user_id)
$.ajax(
url: url
data:
private_token: gon.api_token
dataType: "json"
).done (user) ->
callback(user)
# Return users list. Filtered by query
# Only active users retrieved
users: (query, callback) ->
url = Api.buildUrl(Api.users_path)
$.ajax(
url: url
data:
private_token: gon.api_token
search: query
per_page: 20
active: true
dataType: "json"
).done (users) ->
callback(users)
buildUrl: (url) ->
return url.replace(':version', gon.api_version)

View File

@ -17,7 +17,6 @@
//= require bootstrap
//= require modernizr
//= require chosen-jquery
//= require select2
//= require raphael
//= require g.raphael-min
//= require g.bar-min

View File

@ -1,5 +0,0 @@
$ ->
$("body").on "click", ".js-details-target", ->
container = $(@).closest(".js-details-container")
container.toggleClass("open")

View File

@ -1,13 +0,0 @@
$ ->
$("body").on "click", ".js-toggler-target", ->
container = $(@).closest(".js-toggler-container")
container.toggleClass("on")
$("body").on "click", ".js-toggle-visibility-link", (e) ->
$(@).find('i').
toggleClass('icon-chevron-down').
toggleClass('icon-chevron-up')
container = $(".js-toggle-visibility-container")
container.toggleClass("hide")
e.preventDefault()

View File

@ -1,309 +0,0 @@
class BranchGraph
constructor: (@element, @options) ->
@preparedCommits = {}
@mtime = 0
@mspace = 0
@parents = {}
@colors = ["#000"]
@offsetX = 120
@offsetY = 20
@unitTime = 30
@unitSpace = 10
@load()
load: ->
$.ajax
url: @options.url
method: "get"
dataType: "json"
success: $.proxy((data) ->
$(".loading", @element).hide()
@prepareData data.days, data.commits
@buildGraph()
, this)
prepareData: (@days, @commits) ->
@collectParents()
for c in @commits
c.isParent = true if c.id of @parents
@preparedCommits[c.id] = c
@collectColors()
collectParents: ->
for c in @commits
@mtime = Math.max(@mtime, c.time)
@mspace = Math.max(@mspace, c.space)
for p in c.parents
@parents[p[0]] = true
@mspace = Math.max(@mspace, p[1])
collectColors: ->
k = 0
while k < @mspace
@colors.push Raphael.getColor(.8)
# Skipping a few colors in the spectrum to get more contrast between colors
Raphael.getColor()
Raphael.getColor()
k++
buildGraph: ->
graphHeight = $(@element).height()
graphWidth = $(@element).width()
ch = Math.max(graphHeight, @offsetY + @unitTime * @mtime + 150)
cw = Math.max(graphWidth, @offsetX + @unitSpace * @mspace + 300)
@r = r = Raphael(@element.get(0), cw, ch)
top = r.set()
cuday = 0
cumonth = ""
barHeight = Math.max(graphHeight, @unitTime * @days.length + 320)
r.rect(0, 0, 26, barHeight).attr fill: "#222"
r.rect(26, 0, 20, barHeight).attr fill: "#444"
for day, mm in @days
if cuday isnt day[0]
# Dates
r.text(36, @offsetY + @unitTime * mm, day[0])
.attr(
font: "12px Monaco, monospace"
fill: "#DDD"
)
cuday = day[0]
if cumonth isnt day[1]
# Months
r.text(13, @offsetY + @unitTime * mm, day[1])
.attr(
font: "12px Monaco, monospace"
fill: "#EEE"
)
cumonth = day[1]
for commit in @commits
x = @offsetX + @unitSpace * (@mspace - commit.space)
y = @offsetY + @unitTime * commit.time
@drawDot(x, y, commit)
@drawLines(x, y, commit)
@appendLabel(x, y, commit.refs) if commit.refs
@appendAnchor(top, commit, x, y)
@markCommit(x, y, commit, graphHeight)
top.toFront()
@bindEvents()
bindEvents: ->
drag = {}
element = @element
dragger = (event) ->
element.scrollLeft drag.sl - (event.clientX - drag.x)
element.scrollTop drag.st - (event.clientY - drag.y)
element.on mousedown: (event) ->
drag =
x: event.clientX
y: event.clientY
st: element.scrollTop()
sl: element.scrollLeft()
$(window).on "mousemove", dragger
$(window).on
mouseup: ->
$(window).off "mousemove", dragger
keydown: (event) ->
# left
element.scrollLeft element.scrollLeft() - 50 if event.keyCode is 37
# top
element.scrollTop element.scrollTop() - 50 if event.keyCode is 38
# right
element.scrollLeft element.scrollLeft() + 50 if event.keyCode is 39
# bottom
element.scrollTop element.scrollTop() + 50 if event.keyCode is 40
appendLabel: (x, y, refs) ->
r = @r
shortrefs = refs
# Truncate if longer than 15 chars
shortrefs = shortrefs.substr(0, 15) + "" if shortrefs.length > 17
text = r.text(x + 4, y, shortrefs).attr(
"text-anchor": "start"
font: "10px Monaco, monospace"
fill: "#FFF"
title: refs
)
textbox = text.getBBox()
# Create rectangle based on the size of the textbox
rect = r.rect(x, y - 7, textbox.width + 5, textbox.height + 5, 4).attr(
fill: "#000"
"fill-opacity": .5
stroke: "none"
)
triangle = r.path(["M", x - 5, y, "L", x - 15, y - 4, "L", x - 15, y + 4, "Z"]).attr(
fill: "#000"
"fill-opacity": .5
stroke: "none"
)
label = r.set(rect, text)
label.transform(["t", -rect.getBBox().width - 15, 0])
# Set text to front
text.toFront()
appendAnchor: (top, commit, x, y) ->
r = @r
options = @options
anchor = r.circle(x, y, 10).attr(
fill: "#000"
opacity: 0
cursor: "pointer"
).click(->
window.open options.commit_url.replace("%s", commit.id), "_blank"
).hover(->
@tooltip = r.commitTooltip(x + 5, y, commit)
top.push @tooltip.insertBefore(this)
, ->
@tooltip and @tooltip.remove() and delete @tooltip
)
top.push anchor
drawDot: (x, y, commit) ->
r = @r
r.circle(x, y, 3).attr(
fill: @colors[commit.space]
stroke: "none"
)
r.rect(@offsetX + @unitSpace * @mspace + 10, y - 10, 20, 20).attr(
fill: "url(#{commit.author.icon})"
stroke: @colors[commit.space]
"stroke-width": 2
)
r.text(@offsetX + @unitSpace * @mspace + 35, y, commit.message.split("\n")[0]).attr(
"text-anchor": "start"
font: "14px Monaco, monospace"
)
drawLines: (x, y, commit) ->
r = @r
for parent, i in commit.parents
parentCommit = @preparedCommits[parent[0]]
parentY = @offsetY + @unitTime * parentCommit.time
parentX1 = @offsetX + @unitSpace * (@mspace - parentCommit.space)
parentX2 = @offsetX + @unitSpace * (@mspace - parent[1])
# Set line color
if parentCommit.space <= commit.space
color = @colors[commit.space]
else
color = @colors[parentCommit.space]
# Build line shape
if parent[1] is commit.space
offset = [0, 5]
arrow = "l-2,5,4,0,-2,-5,0,5"
else if parent[1] < commit.space
offset = [3, 3]
arrow = "l5,0,-2,4,-3,-4,4,2"
else
offset = [-3, 3]
arrow = "l-5,0,2,4,3,-4,-4,2"
# Start point
route = ["M", x + offset[0], y + offset[1]]
# Add arrow if not first parent
if i > 0
route.push(arrow)
# Circumvent if overlap
if commit.space isnt parentCommit.space or commit.space isnt parent[1]
route.push(
"L", parentX2, y + 10,
"L", parentX2, parentY - 5,
)
# End point
route.push("L", parentX1, parentY)
r
.path(route)
.attr(
stroke: color
"stroke-width": 2)
markCommit: (x, y, commit, graphHeight) ->
if commit.id is @options.commit_id
r = @r
r.path(["M", x + 5, y, "L", x + 15, y + 4, "L", x + 15, y - 4, "Z"]).attr(
fill: "#000"
"fill-opacity": .5
stroke: "none"
)
# Displayed in the center
@element.scrollTop(y - graphHeight / 2)
Raphael::commitTooltip = (x, y, commit) ->
boxWidth = 300
boxHeight = 200
icon = @image(commit.author.icon, x, y, 20, 20)
nameText = @text(x + 25, y + 10, commit.author.name)
idText = @text(x, y + 35, commit.id)
messageText = @text(x, y + 50, commit.message)
textSet = @set(icon, nameText, idText, messageText).attr(
"text-anchor": "start"
font: "12px Monaco, monospace"
)
nameText.attr(
font: "14px Arial"
"font-weight": "bold"
)
idText.attr fill: "#AAA"
@textWrap messageText, boxWidth - 50
rect = @rect(x - 10, y - 10, boxWidth, 100, 4).attr(
fill: "#FFF"
stroke: "#000"
"stroke-linecap": "round"
"stroke-width": 2
)
tooltip = @set(rect, textSet)
rect.attr(
height: tooltip.getBBox().height + 10
width: tooltip.getBBox().width + 10
)
tooltip.transform ["t", 20, 20]
tooltip
Raphael::textWrap = (t, width) ->
content = t.attr("text")
abc = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
t.attr text: abc
letterWidth = t.getBBox().width / abc.length
t.attr text: content
words = content.split(" ")
x = 0
s = []
for word in words
if x + (word.length * letterWidth) > width
s.push "\n"
x = 0
x += word.length * letterWidth
s.push word + " "
t.attr text: s.join("")
b = t.getBBox()
h = Math.abs(b.y2) - Math.abs(b.y) + 1
t.attr y: b.y + h
@BranchGraph = BranchGraph

View File

@ -1,7 +0,0 @@
class CommitFile
constructor: (file) ->
if $('.image', file).length
new ImageFile(file)
this.CommitFile = CommitFile

View File

@ -1,128 +0,0 @@
class ImageFile
# Width where images must fits in, for 2-up this gets divided by 2
@availWidth = 900
@viewModes = ['two-up', 'swipe']
constructor: (@file) ->
# Determine if old and new file has same dimensions, if not show 'two-up' view
this.requestImageInfo $('.two-up.view .frame.deleted img', @file), (deletedWidth, deletedHeight) =>
this.requestImageInfo $('.two-up.view .frame.added img', @file), (width, height) =>
if width == deletedWidth && height == deletedHeight
this.initViewModes()
else
this.initView('two-up')
initViewModes: ->
viewMode = ImageFile.viewModes[0]
$('.view-modes', @file).removeClass 'hide'
$('.view-modes-menu', @file).on 'click', 'li', (event) =>
unless $(event.currentTarget).hasClass('active')
this.activateViewMode(event.currentTarget.className)
this.activateViewMode(viewMode)
activateViewMode: (viewMode) ->
$('.view-modes-menu li', @file)
.removeClass('active')
.filter(".#{viewMode}").addClass 'active'
$(".view:visible:not(.#{viewMode})", @file).fadeOut 200, =>
$(".view.#{viewMode}", @file).fadeIn(200)
this.initView viewMode
initView: (viewMode) ->
this.views[viewMode].call(this)
prepareFrames = (view) ->
maxWidth = 0
maxHeight = 0
$('.frame', view).each (index, frame) =>
width = $(frame).width()
height = $(frame).height()
maxWidth = if width > maxWidth then width else maxWidth
maxHeight = if height > maxHeight then height else maxHeight
.css
width: maxWidth
height: maxHeight
[maxWidth, maxHeight]
views:
'two-up': ->
$('.two-up.view .wrap', @file).each (index, wrap) =>
$('img', wrap).each ->
currentWidth = $(this).width()
if currentWidth > ImageFile.availWidth / 2
$(this).width ImageFile.availWidth / 2
this.requestImageInfo $('img', wrap), (width, height) ->
$('.image-info .meta-width', wrap).text "#{width}px"
$('.image-info .meta-height', wrap).text "#{height}px"
$('.image-info', wrap).removeClass('hide')
'swipe': ->
maxWidth = 0
maxHeight = 0
$('.swipe.view', @file).each (index, view) =>
[maxWidth, maxHeight] = prepareFrames(view)
$('.swipe-frame', view).css
width: maxWidth + 16
height: maxHeight + 28
$('.swipe-wrap', view).css
width: maxWidth + 1
height: maxHeight + 2
$('.swipe-bar', view).css
left: 0
.draggable
axis: 'x'
containment: 'parent'
drag: (event) ->
$('.swipe-wrap', view).width (maxWidth + 1) - $(this).position().left
stop: (event) ->
$('.swipe-wrap', view).width (maxWidth + 1) - $(this).position().left
'onion-skin': ->
maxWidth = 0
maxHeight = 0
dragTrackWidth = $('.drag-track', @file).width() - $('.dragger', @file).width()
$('.onion-skin.view', @file).each (index, view) =>
[maxWidth, maxHeight] = prepareFrames(view)
$('.onion-skin-frame', view).css
width: maxWidth + 16
height: maxHeight + 28
$('.swipe-wrap', view).css
width: maxWidth + 1
height: maxHeight + 2
$('.dragger', view).css
left: dragTrackWidth
.draggable
axis: 'x'
containment: 'parent'
drag: (event) ->
$('.frame.added', view).css('opacity', $(this).position().left / dragTrackWidth)
stop: (event) ->
$('.frame.added', view).css('opacity', $(this).position().left / dragTrackWidth)
requestImageInfo: (img, callback) ->
domImg = img.get(0)
if domImg.complete
callback.call(this, domImg.naturalWidth, domImg.naturalHeight)
else
img.on 'load', =>
callback.call(this, domImg.naturalWidth, domImg.naturalHeight)
this.ImageFile = ImageFile

View File

@ -0,0 +1,59 @@
var CommitsList = {
ref:null,
limit:0,
offset:0,
disable:false,
init:
function(ref, limit) {
$(".day-commits-table li.commit").live('click', function(e){
if(e.target.nodeName != "A") {
location.href = $(this).attr("url");
e.stopPropagation();
return false;
}
});
this.ref=ref;
this.limit=limit;
this.offset=limit;
this.initLoadMore();
$('.loading').show();
},
getOld:
function() {
$('.loading').show();
$.ajax({
type: "GET",
url: location.href,
data: "limit=" + this.limit + "&offset=" + this.offset + "&ref=" + this.ref,
complete: function(){ $('.loading').hide()},
dataType: "script"});
},
append:
function(count, html) {
$("#commits_list").append(html);
if(count > 0) {
this.offset += count;
} else {
this.disable = true;
}
},
initLoadMore:
function() {
$(document).endlessScroll({
bottomPixels: 400,
fireDelay: 1000,
fireOnce:true,
ceaseFire: function() {
return CommitsList.disable;
},
callback: function(i) {
CommitsList.getOld();
}
});
}
}

View File

@ -1,54 +0,0 @@
class CommitsList
@data =
ref: null
limit: 0
offset: 0
@disable = false
@showProgress: ->
$('.loading').show()
@hideProgress: ->
$('.loading').hide()
@init: (ref, limit) ->
$(".day-commits-table li.commit").live 'click', (event) ->
if event.target.nodeName != "A"
location.href = $(this).attr("url")
e.stopPropagation()
return false
@data.ref = ref
@data.limit = limit
@data.offset = limit
this.initLoadMore()
this.showProgress();
@getOld: ->
this.showProgress()
$.ajax
type: "GET"
url: location.href
data: @data
complete: this.hideProgress
dataType: "script"
@append: (count, html) ->
$("#commits-list").append(html)
if count > 0
@data.offset += count
else
@disable = true
@initLoadMore: ->
$(document).endlessScroll
bottomPixels: 400
fireDelay: 1000
fireOnce: true
ceaseFire: =>
@disable
callback: =>
this.getOld()
this.CommitsList = CommitsList

View File

@ -1,39 +0,0 @@
window.dashboardPage = ->
Pager.init 20, true
initSidebarTab()
$(".event_filter_link").bind "click", (event) ->
event.preventDefault()
toggleFilter $(this)
reloadActivities()
reloadActivities = ->
$(".content_list").html ''
Pager.init 20, true
toggleFilter = (sender) ->
sender.parent().toggleClass "inactive"
event_filters = $.cookie("event_filter")
filter = sender.attr("id").split("_")[0]
if event_filters
event_filters = event_filters.split(",")
else
event_filters = new Array()
index = event_filters.indexOf(filter)
if index is -1
event_filters.push filter
else
event_filters.splice index, 1
$.cookie "event_filter", event_filters.join(",")
initSidebarTab = ->
key = "dashboard_sidebar_filter"
# store selection in cookie
$('.dash-sidebar-tabs a').on 'click', (e) ->
$.cookie(key, $(e.target).attr('id'))
# show tab from cookie
sidebar_filter = $.cookie(key)
$("#" + sidebar_filter).tab('show') if sidebar_filter

View File

@ -1,7 +0,0 @@
Array.prototype.first = function() {
return this[0];
}
Array.prototype.last = function() {
return this[this.length-1];
}

View File

@ -1,9 +0,0 @@
$.fn.showAndHide = ->
$(@).show().
delay(3000).
fadeOut()
$.fn.enableButton = ->
$(@).removeAttr('disabled').
removeClass('disabled')

View File

@ -11,7 +11,7 @@ function initIssuesSearch() {
last_terms = terms;
if (terms.length >= 2 || terms.length == 0) {
$.get(href, { 'status': status, 'terms': terms, 'milestone_id': milestone_id }, function(response) {
$.get(href, { 'f': status, 'terms': terms, 'milestone_id': milestone_id }, function(response) {
$('#issues-table').html(response);
});
}

View File

@ -1,181 +0,0 @@
/**
* Timeago is a jQuery plugin that makes it easy to support automatically
* updating fuzzy timestamps (e.g. "4 minutes ago" or "about 1 day ago").
*
* @name timeago
* @version 1.1.0
* @requires jQuery v1.2.3+
* @author Ryan McGeary
* @license MIT License - http://www.opensource.org/licenses/mit-license.php
*
* For usage and examples, visit:
* http://timeago.yarp.com/
*
* Copyright (c) 2008-2013, Ryan McGeary (ryan -[at]- mcgeary [*dot*] org)
*/
(function (factory) {
if (typeof define === 'function' && define.amd) {
// AMD. Register as an anonymous module.
define(['jquery'], factory);
} else {
// Browser globals
factory(jQuery);
}
}(function ($) {
$.timeago = function(timestamp) {
if (timestamp instanceof Date) {
return inWords(timestamp);
} else if (typeof timestamp === "string") {
return inWords($.timeago.parse(timestamp));
} else if (typeof timestamp === "number") {
return inWords(new Date(timestamp));
} else {
return inWords($.timeago.datetime(timestamp));
}
};
var $t = $.timeago;
$.extend($.timeago, {
settings: {
refreshMillis: 60000,
allowFuture: false,
strings: {
prefixAgo: null,
prefixFromNow: null,
suffixAgo: "ago",
suffixFromNow: "from now",
seconds: "less than a minute",
minute: "about a minute",
minutes: "%d minutes",
hour: "about an hour",
hours: "about %d hours",
day: "a day",
days: "%d days",
month: "about a month",
months: "%d months",
year: "about a year",
years: "%d years",
wordSeparator: " ",
numbers: []
}
},
inWords: function(distanceMillis) {
var $l = this.settings.strings;
var prefix = $l.prefixAgo;
var suffix = $l.suffixAgo;
if (this.settings.allowFuture) {
if (distanceMillis < 0) {
prefix = $l.prefixFromNow;
suffix = $l.suffixFromNow;
}
}
var seconds = Math.abs(distanceMillis) / 1000;
var minutes = seconds / 60;
var hours = minutes / 60;
var days = hours / 24;
var years = days / 365;
function substitute(stringOrFunction, number) {
var string = $.isFunction(stringOrFunction) ? stringOrFunction(number, distanceMillis) : stringOrFunction;
var value = ($l.numbers && $l.numbers[number]) || number;
return string.replace(/%d/i, value);
}
var words = seconds < 45 && substitute($l.seconds, Math.round(seconds)) ||
seconds < 90 && substitute($l.minute, 1) ||
minutes < 45 && substitute($l.minutes, Math.round(minutes)) ||
minutes < 90 && substitute($l.hour, 1) ||
hours < 24 && substitute($l.hours, Math.round(hours)) ||
hours < 42 && substitute($l.day, 1) ||
days < 30 && substitute($l.days, Math.round(days)) ||
days < 45 && substitute($l.month, 1) ||
days < 365 && substitute($l.months, Math.round(days / 30)) ||
years < 1.5 && substitute($l.year, 1) ||
substitute($l.years, Math.round(years));
var separator = $l.wordSeparator || "";
if ($l.wordSeparator === undefined) { separator = " "; }
return $.trim([prefix, words, suffix].join(separator));
},
parse: function(iso8601) {
var s = $.trim(iso8601);
s = s.replace(/\.\d+/,""); // remove milliseconds
s = s.replace(/-/,"/").replace(/-/,"/");
s = s.replace(/T/," ").replace(/Z/," UTC");
s = s.replace(/([\+\-]\d\d)\:?(\d\d)/," $1$2"); // -04:00 -> -0400
return new Date(s);
},
datetime: function(elem) {
var iso8601 = $t.isTime(elem) ? $(elem).attr("datetime") : $(elem).attr("title");
return $t.parse(iso8601);
},
isTime: function(elem) {
// jQuery's `is()` doesn't play well with HTML5 in IE
return $(elem).get(0).tagName.toLowerCase() === "time"; // $(elem).is("time");
}
});
// functions that can be called via $(el).timeago('action')
// init is default when no action is given
// functions are called with context of a single element
var functions = {
init: function(){
var refresh_el = $.proxy(refresh, this);
refresh_el();
var $s = $t.settings;
if ($s.refreshMillis > 0) {
setInterval(refresh_el, $s.refreshMillis);
}
},
update: function(time){
$(this).data('timeago', { datetime: $t.parse(time) });
refresh.apply(this);
}
};
$.fn.timeago = function(action, options) {
var fn = action ? functions[action] : functions.init;
if(!fn){
throw new Error("Unknown function name '"+ action +"' for timeago");
}
// each over objects here and call the requested function
this.each(function(){
fn.call(this, options);
});
return this;
};
function refresh() {
var data = prepareData(this);
if (!isNaN(data.datetime)) {
$(this).text(inWords(data.datetime));
}
return this;
}
function prepareData(element) {
element = $(element);
if (!element.data("timeago")) {
element.data("timeago", { datetime: $t.datetime(element) });
var text = $.trim(element.text());
if (text.length > 0 && !($t.isTime(element) && element.attr("title"))) {
element.attr("title", text);
}
}
return element.data("timeago");
}
function inWords(date) {
return $t.inWords(distance(date));
}
function distance(date) {
return (new Date().getTime() - date.getTime());
}
// fix for IE6 suckage
document.createElement("abbr");
document.createElement("time");
}));

View File

@ -1,211 +0,0 @@
function md5 (str) {
// http://kevin.vanzonneveld.net
// + original by: Webtoolkit.info (http://www.webtoolkit.info/)
// + namespaced by: Michael White (http://getsprink.com)
// + tweaked by: Jack
// + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
// + input by: Brett Zamir (http://brett-zamir.me)
// + bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
// - depends on: utf8_encode
// * example 1: md5('Kevin van Zonneveld');
// * returns 1: '6e658d4bfcb59cc13f96c14450ac40b9'
var xl;
var rotateLeft = function (lValue, iShiftBits) {
return (lValue << iShiftBits) | (lValue >>> (32 - iShiftBits));
};
var addUnsigned = function (lX, lY) {
var lX4, lY4, lX8, lY8, lResult;
lX8 = (lX & 0x80000000);
lY8 = (lY & 0x80000000);
lX4 = (lX & 0x40000000);
lY4 = (lY & 0x40000000);
lResult = (lX & 0x3FFFFFFF) + (lY & 0x3FFFFFFF);
if (lX4 & lY4) {
return (lResult ^ 0x80000000 ^ lX8 ^ lY8);
}
if (lX4 | lY4) {
if (lResult & 0x40000000) {
return (lResult ^ 0xC0000000 ^ lX8 ^ lY8);
} else {
return (lResult ^ 0x40000000 ^ lX8 ^ lY8);
}
} else {
return (lResult ^ lX8 ^ lY8);
}
};
var _F = function (x, y, z) {
return (x & y) | ((~x) & z);
};
var _G = function (x, y, z) {
return (x & z) | (y & (~z));
};
var _H = function (x, y, z) {
return (x ^ y ^ z);
};
var _I = function (x, y, z) {
return (y ^ (x | (~z)));
};
var _FF = function (a, b, c, d, x, s, ac) {
a = addUnsigned(a, addUnsigned(addUnsigned(_F(b, c, d), x), ac));
return addUnsigned(rotateLeft(a, s), b);
};
var _GG = function (a, b, c, d, x, s, ac) {
a = addUnsigned(a, addUnsigned(addUnsigned(_G(b, c, d), x), ac));
return addUnsigned(rotateLeft(a, s), b);
};
var _HH = function (a, b, c, d, x, s, ac) {
a = addUnsigned(a, addUnsigned(addUnsigned(_H(b, c, d), x), ac));
return addUnsigned(rotateLeft(a, s), b);
};
var _II = function (a, b, c, d, x, s, ac) {
a = addUnsigned(a, addUnsigned(addUnsigned(_I(b, c, d), x), ac));
return addUnsigned(rotateLeft(a, s), b);
};
var convertToWordArray = function (str) {
var lWordCount;
var lMessageLength = str.length;
var lNumberOfWords_temp1 = lMessageLength + 8;
var lNumberOfWords_temp2 = (lNumberOfWords_temp1 - (lNumberOfWords_temp1 % 64)) / 64;
var lNumberOfWords = (lNumberOfWords_temp2 + 1) * 16;
var lWordArray = new Array(lNumberOfWords - 1);
var lBytePosition = 0;
var lByteCount = 0;
while (lByteCount < lMessageLength) {
lWordCount = (lByteCount - (lByteCount % 4)) / 4;
lBytePosition = (lByteCount % 4) * 8;
lWordArray[lWordCount] = (lWordArray[lWordCount] | (str.charCodeAt(lByteCount) << lBytePosition));
lByteCount++;
}
lWordCount = (lByteCount - (lByteCount % 4)) / 4;
lBytePosition = (lByteCount % 4) * 8;
lWordArray[lWordCount] = lWordArray[lWordCount] | (0x80 << lBytePosition);
lWordArray[lNumberOfWords - 2] = lMessageLength << 3;
lWordArray[lNumberOfWords - 1] = lMessageLength >>> 29;
return lWordArray;
};
var wordToHex = function (lValue) {
var wordToHexValue = "",
wordToHexValue_temp = "",
lByte, lCount;
for (lCount = 0; lCount <= 3; lCount++) {
lByte = (lValue >>> (lCount * 8)) & 255;
wordToHexValue_temp = "0" + lByte.toString(16);
wordToHexValue = wordToHexValue + wordToHexValue_temp.substr(wordToHexValue_temp.length - 2, 2);
}
return wordToHexValue;
};
var x = [],
k, AA, BB, CC, DD, a, b, c, d, S11 = 7,
S12 = 12,
S13 = 17,
S14 = 22,
S21 = 5,
S22 = 9,
S23 = 14,
S24 = 20,
S31 = 4,
S32 = 11,
S33 = 16,
S34 = 23,
S41 = 6,
S42 = 10,
S43 = 15,
S44 = 21;
str = this.utf8_encode(str);
x = convertToWordArray(str);
a = 0x67452301;
b = 0xEFCDAB89;
c = 0x98BADCFE;
d = 0x10325476;
xl = x.length;
for (k = 0; k < xl; k += 16) {
AA = a;
BB = b;
CC = c;
DD = d;
a = _FF(a, b, c, d, x[k + 0], S11, 0xD76AA478);
d = _FF(d, a, b, c, x[k + 1], S12, 0xE8C7B756);
c = _FF(c, d, a, b, x[k + 2], S13, 0x242070DB);
b = _FF(b, c, d, a, x[k + 3], S14, 0xC1BDCEEE);
a = _FF(a, b, c, d, x[k + 4], S11, 0xF57C0FAF);
d = _FF(d, a, b, c, x[k + 5], S12, 0x4787C62A);
c = _FF(c, d, a, b, x[k + 6], S13, 0xA8304613);
b = _FF(b, c, d, a, x[k + 7], S14, 0xFD469501);
a = _FF(a, b, c, d, x[k + 8], S11, 0x698098D8);
d = _FF(d, a, b, c, x[k + 9], S12, 0x8B44F7AF);
c = _FF(c, d, a, b, x[k + 10], S13, 0xFFFF5BB1);
b = _FF(b, c, d, a, x[k + 11], S14, 0x895CD7BE);
a = _FF(a, b, c, d, x[k + 12], S11, 0x6B901122);
d = _FF(d, a, b, c, x[k + 13], S12, 0xFD987193);
c = _FF(c, d, a, b, x[k + 14], S13, 0xA679438E);
b = _FF(b, c, d, a, x[k + 15], S14, 0x49B40821);
a = _GG(a, b, c, d, x[k + 1], S21, 0xF61E2562);
d = _GG(d, a, b, c, x[k + 6], S22, 0xC040B340);
c = _GG(c, d, a, b, x[k + 11], S23, 0x265E5A51);
b = _GG(b, c, d, a, x[k + 0], S24, 0xE9B6C7AA);
a = _GG(a, b, c, d, x[k + 5], S21, 0xD62F105D);
d = _GG(d, a, b, c, x[k + 10], S22, 0x2441453);
c = _GG(c, d, a, b, x[k + 15], S23, 0xD8A1E681);
b = _GG(b, c, d, a, x[k + 4], S24, 0xE7D3FBC8);
a = _GG(a, b, c, d, x[k + 9], S21, 0x21E1CDE6);
d = _GG(d, a, b, c, x[k + 14], S22, 0xC33707D6);
c = _GG(c, d, a, b, x[k + 3], S23, 0xF4D50D87);
b = _GG(b, c, d, a, x[k + 8], S24, 0x455A14ED);
a = _GG(a, b, c, d, x[k + 13], S21, 0xA9E3E905);
d = _GG(d, a, b, c, x[k + 2], S22, 0xFCEFA3F8);
c = _GG(c, d, a, b, x[k + 7], S23, 0x676F02D9);
b = _GG(b, c, d, a, x[k + 12], S24, 0x8D2A4C8A);
a = _HH(a, b, c, d, x[k + 5], S31, 0xFFFA3942);
d = _HH(d, a, b, c, x[k + 8], S32, 0x8771F681);
c = _HH(c, d, a, b, x[k + 11], S33, 0x6D9D6122);
b = _HH(b, c, d, a, x[k + 14], S34, 0xFDE5380C);
a = _HH(a, b, c, d, x[k + 1], S31, 0xA4BEEA44);
d = _HH(d, a, b, c, x[k + 4], S32, 0x4BDECFA9);
c = _HH(c, d, a, b, x[k + 7], S33, 0xF6BB4B60);
b = _HH(b, c, d, a, x[k + 10], S34, 0xBEBFBC70);
a = _HH(a, b, c, d, x[k + 13], S31, 0x289B7EC6);
d = _HH(d, a, b, c, x[k + 0], S32, 0xEAA127FA);
c = _HH(c, d, a, b, x[k + 3], S33, 0xD4EF3085);
b = _HH(b, c, d, a, x[k + 6], S34, 0x4881D05);
a = _HH(a, b, c, d, x[k + 9], S31, 0xD9D4D039);
d = _HH(d, a, b, c, x[k + 12], S32, 0xE6DB99E5);
c = _HH(c, d, a, b, x[k + 15], S33, 0x1FA27CF8);
b = _HH(b, c, d, a, x[k + 2], S34, 0xC4AC5665);
a = _II(a, b, c, d, x[k + 0], S41, 0xF4292244);
d = _II(d, a, b, c, x[k + 7], S42, 0x432AFF97);
c = _II(c, d, a, b, x[k + 14], S43, 0xAB9423A7);
b = _II(b, c, d, a, x[k + 5], S44, 0xFC93A039);
a = _II(a, b, c, d, x[k + 12], S41, 0x655B59C3);
d = _II(d, a, b, c, x[k + 3], S42, 0x8F0CCC92);
c = _II(c, d, a, b, x[k + 10], S43, 0xFFEFF47D);
b = _II(b, c, d, a, x[k + 1], S44, 0x85845DD1);
a = _II(a, b, c, d, x[k + 8], S41, 0x6FA87E4F);
d = _II(d, a, b, c, x[k + 15], S42, 0xFE2CE6E0);
c = _II(c, d, a, b, x[k + 6], S43, 0xA3014314);
b = _II(b, c, d, a, x[k + 13], S44, 0x4E0811A1);
a = _II(a, b, c, d, x[k + 4], S41, 0xF7537E82);
d = _II(d, a, b, c, x[k + 11], S42, 0xBD3AF235);
c = _II(c, d, a, b, x[k + 2], S43, 0x2AD7D2BB);
b = _II(b, c, d, a, x[k + 9], S44, 0xEB86D391);
a = addUnsigned(a, AA);
b = addUnsigned(b, BB);
c = addUnsigned(c, CC);
d = addUnsigned(d, DD);
}
var temp = wordToHex(a) + wordToHex(b) + wordToHex(c) + wordToHex(d);
return temp.toLowerCase();
}

View File

@ -1,70 +0,0 @@
function utf8_encode (argString) {
// http://kevin.vanzonneveld.net
// + original by: Webtoolkit.info (http://www.webtoolkit.info/)
// + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
// + improved by: sowberry
// + tweaked by: Jack
// + bugfixed by: Onno Marsman
// + improved by: Yves Sucaet
// + bugfixed by: Onno Marsman
// + bugfixed by: Ulrich
// + bugfixed by: Rafal Kukawski
// + improved by: kirilloid
// + bugfixed by: kirilloid
// * example 1: utf8_encode('Kevin van Zonneveld');
// * returns 1: 'Kevin van Zonneveld'
if (argString === null || typeof argString === "undefined") {
return "";
}
var string = (argString + ''); // .replace(/\r\n/g, "\n").replace(/\r/g, "\n");
var utftext = '',
start, end, stringl = 0;
start = end = 0;
stringl = string.length;
for (var n = 0; n < stringl; n++) {
var c1 = string.charCodeAt(n);
var enc = null;
if (c1 < 128) {
end++;
} else if (c1 > 127 && c1 < 2048) {
enc = String.fromCharCode(
(c1 >> 6) | 192,
( c1 & 63) | 128
);
} else if (c1 & 0xF800 != 0xD800) {
enc = String.fromCharCode(
(c1 >> 12) | 224,
((c1 >> 6) & 63) | 128,
( c1 & 63) | 128
);
} else { // surrogate pairs
if (c1 & 0xFC00 != 0xD800) { throw new RangeError("Unmatched trail surrogate at " + n); }
var c2 = string.charCodeAt(++n);
if (c2 & 0xFC00 != 0xDC00) { throw new RangeError("Unmatched lead surrogate at " + (n-1)); }
c1 = ((c1 & 0x3FF) << 10) + (c2 & 0x3FF) + 0x10000;
enc = String.fromCharCode(
(c1 >> 18) | 240,
((c1 >> 12) & 63) | 128,
((c1 >> 6) & 63) | 128,
( c1 & 63) | 128
);
}
if (enc !== null) {
if (end > start) {
utftext += string.slice(start, end);
}
utftext += enc;
start = end = n + 1;
}
}
if (end > start) {
utftext += string.slice(start, stringl);
}
return utftext;
}

View File

@ -7,8 +7,6 @@ window.slugify = (text) ->
window.ajaxGet = (url) ->
$.ajax({type: "GET", url: url, dataType: "script"})
window.showAndHide = (selector) ->
window.errorMessage = (message) ->
ehtml = $("<p>")
ehtml.addClass("error_message")
@ -34,22 +32,10 @@ window.disableButtonIfEmptyField = (field_selector, button_selector) ->
else
closest_submit.enable()
window.sanitize = (str) ->
return str.replace(/<(?:.|\n)*?>/gm, '')
window.linkify = (str) ->
exp = /(\b(https?|ftp|file):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/ig
return str.replace(exp,"<a href='$1'>$1</a>")
$ ->
# Click a .one_click_select field, select the contents
$(".one_click_select").on 'click', -> $(@).select()
# Click a .appear-link, appear-data fadeout
$(".appear-link").on 'click', ->
$('.appear-data').fadeIn()
# Initialize chosen selects
$('select.chosen').chosen()
@ -59,17 +45,11 @@ $ ->
# Bottom tooltip
$('.has_bottom_tooltip').tooltip(placement: 'bottom')
# Form submitter
$('.trigger-submit').on 'change', ->
$(@).parents('form').submit()
$("abbr.timeago").timeago()
# Flash
if (flash = $(".flash-container")).length > 0
flash.click -> $(@).fadeOut()
flash.show()
setTimeout (-> flash.fadeOut()), 3000
if (flash = $("#flash-container")).length > 0
flash.click -> $(@).slideUp("slow")
flash.slideDown "slow"
setTimeout (-> flash.slideUp("slow")), 3000
# Disable form buttons while a form is submitting
$('body').on 'ajax:complete, ajax:beforeSend, submit', 'form', (e) ->

View File

@ -0,0 +1,132 @@
var MergeRequest = {
diffs_loaded: false,
commits_loaded: false,
opts: false,
init:
function(opts) {
var self = this;
self.opts = opts;
self.initTabs();
self.initMergeWidget();
$(".mr_show_all_commits").bind("click", function() {
self.showAllCommits();
});
},
initMergeWidget:
function() {
var self = this;
self.showState(self.opts.current_state);
if($(".automerge_widget").length && self.opts.check_enable){
$.get(self.opts.url_to_automerge_check, function(data){
self.showState(data.state);
}, "json");
}
if(self.opts.ci_enable){
$.get(self.opts.url_to_ci_check, function(data){
self.showCiState(data.status);
}, "json");
}
},
initTabs:
function() {
$(".mr_nav_tabs a").live("click", function() {
$(".mr_nav_tabs a").parent().removeClass("active");
$(this).parent().addClass("active");
});
var current_tab;
if(this.opts.action == "diffs") {
current_tab = $(".mr_nav_tabs .merge-diffs-tab");
} else {
current_tab = $(".mr_nav_tabs .merge-notes-tab");
}
current_tab.parent().addClass("active");
this.initNotesTab();
this.initDiffTab();
},
initNotesTab:
function() {
$(".mr_nav_tabs a.merge-notes-tab").live("click", function(e) {
$(".merge-request-diffs").hide();
$(".merge_request_notes").show();
var mr_path = $(".merge-notes-tab").attr("data-url");
history.pushState({ path: mr_path }, '', mr_path);
e.preventDefault();
});
},
initDiffTab:
function() {
$(".mr_nav_tabs a.merge-diffs-tab").live("click", function(e) {
if(!MergeRequest.diffs_loaded) {
MergeRequest.loadDiff();
}
$(".merge_request_notes").hide();
$(".merge-request-diffs").show();
var mr_diff_path = $(".merge-diffs-tab").attr("data-url");
history.pushState({ path: mr_diff_path }, '', mr_diff_path);
e.preventDefault();
});
},
showState:
function(state){
$(".automerge_widget").hide();
$(".automerge_widget." + state).show();
},
showCiState:
function(state){
$(".ci_widget").hide();
$(".ci_widget.ci-" + state).show();
},
loadDiff:
function() {
$(".dashboard-loader").show();
$.ajax({
type: "GET",
url: $(".merge-diffs-tab").attr("data-url"),
beforeSend: function(){ $('.status').addClass("loading")},
complete: function(){
MergeRequest.diffs_loaded = true;
$(".merge_request_notes").hide();
$('.status').removeClass("loading");
},
dataType: "script"});
},
showAllCommits:
function() {
$(".first_mr_commits").remove();
$(".all_mr_commits").removeClass("hide");
},
already_cannot_be_merged:
function(){
$(".automerge_widget").hide();
$(".merge_in_progress").hide();
$(".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

@ -1,101 +0,0 @@
#
# * Filter merge requests
#
@merge_requestsPage = ->
$('#assignee_id').chosen()
$('#milestone_id').chosen()
$('#milestone_id, #assignee_id').on 'change', ->
$(this).closest('form').submit()
class MergeRequest
constructor: (@opts) ->
this.$el = $('.merge-request')
@diffs_loaded = false
@commits_loaded = false
this.activateTab(@opts.action)
this.bindEvents()
this.initMergeWidget()
this.$('.show-all-commits').on 'click', =>
this.showAllCommits()
# Local jQuery finder
$: (selector) ->
this.$el.find(selector)
initMergeWidget: ->
this.showState( @opts.current_status )
if this.$('.automerge_widget').length and @opts.check_enable
$.get @opts.url_to_automerge_check, (data) =>
this.showState( data.merge_status )
, 'json'
if @opts.ci_enable
$.get @opts.url_to_ci_check, (data) =>
this.showCiState data.status
, 'json'
bindEvents: ->
this.$('.nav-tabs').on 'click', 'a', (event) =>
a = $(event.currentTarget)
href = a.attr('href')
History.replaceState {path: href}, document.title, href
event.preventDefault()
this.$('.nav-tabs').on 'click', 'li', (event) =>
this.activateTab($(event.currentTarget).data('action'))
this.$('.accept_merge_request').on 'click', ->
$('.automerge_widget.can_be_merged').hide()
$('.merge-in-progress').show()
activateTab: (action) ->
this.$('.nav-tabs li').removeClass 'active'
this.$('.tab-content').hide()
switch action
when 'diffs'
this.$('.nav-tabs .diffs-tab').addClass 'active'
this.loadDiff() unless @diffs_loaded
this.$('.diffs').show()
else
this.$('.nav-tabs .notes-tab').addClass 'active'
this.$('.notes').show()
showState: (state) ->
$('.automerge_widget').hide()
$('.automerge_widget.' + state).show()
showCiState: (state) ->
$('.ci_widget').hide()
$('.ci_widget.ci-' + state).show()
loadDiff: (event) ->
$('.dashboard-loader').show()
$.ajax
type: 'GET'
url: this.$('.nav-tabs .diffs-tab a').attr('href')
beforeSend: =>
this.$('.status').addClass 'loading'
complete: =>
@diffs_loaded = true
this.$('.status').removeClass 'loading'
dataType: 'script'
showAllCommits: ->
this.$('.first-commits').remove()
this.$('.all-commits').removeClass 'hide'
alreadyOrCannotBeMerged: ->
this.$('.automerge_widget').hide()
this.$('.merge-in-progress').hide()
this.$('.automerge_widget.already_cannot_be_merged').show()
this.MergeRequest = MergeRequest

View File

@ -1,14 +1,14 @@
$ ->
$('.milestone-issue-filter li[data-closed]').addClass('hide')
$('.milestone-issue-filter tr[data-closed]').addClass('hide')
$('.milestone-issue-filter ul.nav li a').click ->
$('.milestone-issue-filter li').toggleClass('active')
$('.milestone-issue-filter li[data-closed]').toggleClass('hide')
$('.milestone-issue-filter tr[data-closed]').toggleClass('hide')
false
$('.milestone-merge-requests-filter li[data-closed]').addClass('hide')
$('.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 li[data-closed]').toggleClass('hide')
$('.milestone-merge-requests-filter tr[data-closed]').toggleClass('hide')
false

View File

@ -4,304 +4,77 @@ var NoteList = {
target_params: null,
target_id: 0,
target_type: null,
top_id: 0,
bottom_id: 0,
loading_more_disabled: false,
reversed: false,
init: function(tid, tt, path) {
NoteList.notes_path = path + ".js";
NoteList.target_id = tid;
NoteList.target_type = tt;
NoteList.target_params = "target_type=" + NoteList.target_type + "&target_id=" + NoteList.target_id;
init:
function(tid, tt, path) {
this.notes_path = path + ".js";
this.target_id = tid;
this.target_type = tt;
this.reversed = $("#notes-list").is(".reversed");
this.target_params = "target_type=" + this.target_type + "&target_id=" + this.target_id;
NoteList.setupMainTargetNoteForm();
// get initial set of notes
this.getContent();
// get initial set of notes
NoteList.getContent();
// add a new diff note
$(document).on("click",
".js-add-diff-note-button",
NoteList.addDiffNote);
// reply to diff/discussion notes
$(document).on("click",
".js-discussion-reply-button",
NoteList.replyToDiscussionNote);
// setup note preview
$(document).on("click",
".js-note-preview-button",
NoteList.previewNote);
// update the file name when an attachment is selected
$(document).on("change",
".js-note-attachment-input",
NoteList.updateFormAttachment);
// hide diff note form
$(document).on("click",
".js-close-discussion-note-form",
NoteList.removeDiscussionNoteForm);
// remove a note (in general)
$(document).on("click",
".js-note-delete",
NoteList.removeNote);
// reset main target form after submit
$(document).on("ajax:complete",
".js-main-target-form",
NoteList.resetMainTargetForm);
$(document).on("click",
".js-choose-note-attachment-button",
NoteList.chooseNoteAttachment);
$(document).on("click",
".js-show-outdated-discussion",
function(e) { $(this).next('.outdated-discussion').show(); e.preventDefault() });
},
/**
* When clicking on buttons
*/
/**
* Called when clicking on the "add a comment" button on the side of a diff line.
*
* Inserts a temporary row for the form below the line.
* Sets up the form and shows it.
*/
addDiffNote: function(e) {
e.preventDefault();
// find the form
var form = $(".js-new-note-form");
var row = $(this).closest("tr");
var nextRow = row.next();
// does it already have notes?
if (nextRow.is(".notes_holder")) {
$.proxy(NoteList.replyToDiscussionNote,
nextRow.find(".js-discussion-reply-button")
).call();
} else {
// add a notes row and insert the form
row.after('<tr class="notes_holder js-temp-notes-holder"><td class="notes_line" colspan="2"></td><td class="notes_content"></td></tr>');
form.clone().appendTo(row.next().find(".notes_content"));
// show the form
NoteList.setupDiscussionNoteForm($(this), row.next().find("form"));
}
},
/**
* Called when clicking the "Choose File" button.
*
* Opesn the file selection dialog.
*/
chooseNoteAttachment: function() {
var form = $(this).closest("form");
form.find(".js-note-attachment-input").click();
},
/**
* Shows the note preview.
*
* Lets the server render GFM into Html and displays it.
*
* Note: uses the Toggler behavior to toggle preview/edit views/buttons
*/
previewNote: function(e) {
e.preventDefault();
var form = $(this).closest("form");
var preview = form.find('.js-note-preview');
var noteText = form.find('.js-note-text').val();
if(noteText.trim().length === 0) {
preview.text('Nothing to preview.');
} else {
preview.text('Loading...');
$.post($(this).data('url'), {note: noteText})
.success(function(previewData) {
preview.html(previewData);
$("#notes-list, #new-notes-list").on("ajax:success", ".delete-note", function() {
$(this).closest('li').fadeOut(function() {
$(this).remove();
NoteList.updateVotes();
});
}
},
});
/**
* Called in response to "cancel" on a diff note form.
*
* Shows the reply button again.
* Removes the form and if necessary it's temporary row.
*/
removeDiscussionNoteForm: function() {
var form = $(this).closest("form");
var row = form.closest("tr");
$(".note-form-holder").on("ajax:before", function(){
$(".submit_note").disable();
})
// show the reply button (will only work for replys)
form.prev(".js-discussion-reply-button").show();
$(".note-form-holder").on("ajax:complete", function(){
$(".submit_note").enable();
$('#preview-note').hide();
$('#note_note').show();
})
if (row.is(".js-temp-notes-holder")) {
// remove temporary row for diff lines
row.remove();
} else {
// only remove the form
form.remove();
}
},
disableButtonIfEmptyField(".note-text", ".submit_note");
/**
* Called in response to deleting a note of any kind.
*
* Removes the actual note from view.
* Removes the whole discussion if the last note is being removed.
*/
removeNote: function() {
var note = $(this).closest(".note");
var notes = note.closest(".notes");
$("#note_attachment").change(function(e){
var val = $('.input-file').val();
var filename = val.replace(/^.*[\\\/]/, '');
$(".file_name").text(filename);
});
// check if this is the last note for this line
if (notes.find(".note").length === 1) {
// for discussions
notes.closest(".discussion").remove();
// for diff lines
notes.closest("tr").remove();
}
note.remove();
NoteList.updateVotes();
},
/**
* Called when clicking on the "reply" button for a diff line.
*
* Shows the note form below the notes.
*/
replyToDiscussionNote: function() {
// find the form
var form = $(".js-new-note-form");
// hide reply button
$(this).hide();
// insert the form after the button
form.clone().insertAfter($(this));
// show the form
NoteList.setupDiscussionNoteForm($(this), $(this).next("form"));
},
/**
* Helper for inserting and setting up note forms.
*/
/**
* Called in response to creating a note failing validation.
*
* Adds the rendered errors to the respective form.
* If "discussionId" is null or undefined, the main target form is assumed.
*/
errorsOnForm: function(errorsHtml, discussionId) {
// find the form
if (discussionId) {
var form = $("form[rel='"+discussionId+"']");
} else {
var form = $(".js-main-target-form");
}
form.find(".js-errors").remove();
form.prepend(errorsHtml);
form.find(".js-note-text").focus();
},
/**
* Shows the diff/discussion form and does some setup on it.
*
* Sets some hidden fields in the form.
*
* Note: dataHolder must have the "discussionId", "lineCode", "noteableType"
* and "noteableId" data attributes set.
*/
setupDiscussionNoteForm: function(dataHolder, form) {
// setup note target
form.attr("rel", dataHolder.data("discussionId"));
form.find("#note_commit_id").val(dataHolder.data("commitId"));
form.find("#note_line_code").val(dataHolder.data("lineCode"));
form.find("#note_noteable_type").val(dataHolder.data("noteableType"));
form.find("#note_noteable_id").val(dataHolder.data("noteableId"));
NoteList.setupNoteForm(form);
form.find(".js-note-text").focus();
},
/**
* Shows the main form and does some setup on it.
*
* Sets some hidden fields in the form.
*/
setupMainTargetNoteForm: function() {
// find the form
var form = $(".js-new-note-form");
// insert the form after the button
form.clone().replaceAll($(".js-main-target-form"));
form = form.prev("form");
// show the form
NoteList.setupNoteForm(form);
// fix classes
form.removeClass("js-new-note-form");
form.addClass("js-main-target-form");
// remove unnecessary fields and buttons
form.find("#note_line_code").remove();
form.find(".js-close-discussion-note-form").remove();
},
/**
* General note form setup.
*
* * deactivates the submit button when text is empty
* * hides the preview button when text is empty
* * setup GFM auto complete
* * show the form
*/
setupNoteForm: function(form) {
disableButtonIfEmptyField(form.find(".js-note-text"), form.find(".js-comment-button"));
form.removeClass("js-new-note-form");
// setup preview buttons
form.find(".js-note-edit-button, .js-note-preview-button")
.tooltip({ placement: 'left' });
previewButton = form.find(".js-note-preview-button");
form.find(".js-note-text").on("input", function() {
if ($(this).val().trim() !== "") {
previewButton.removeClass("turn-off").addClass("turn-on");
} else {
previewButton.removeClass("turn-on").addClass("turn-off");
if(this.reversed) {
var textarea = $(".note-text");
$('.note_advanced_opts').hide();
textarea.css("height", "40px");
textarea.on("focus", function(){
$(this).css("height", "80px");
$('.note_advanced_opts').show();
});
}
});
// remove notify commit author checkbox for non-commit notes
if (form.find("#note_noteable_type").val() !== "Commit") {
form.find(".js-notify-commit-author").remove();
}
// Setup note preview
$(document).on('click', '#preview-link', function(e) {
$('#preview-note').text('Loading...');
GitLab.GfmAutoComplete.setup();
$(this).text($(this).text() === "Edit" ? "Preview" : "Edit");
form.show();
},
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();
});
},
/**
@ -311,93 +84,162 @@ var NoteList = {
/**
* Gets an initial set of notes.
* Gets an inital set of notes.
*/
getContent: function() {
$.ajax({
url: NoteList.notes_path,
data: NoteList.target_params,
complete: function(){ $('.js-notes-busy').removeClass("loading")},
beforeSend: function() { $('.js-notes-busy').addClass("loading") },
dataType: "script"
});
},
getContent:
function() {
$.ajax({
type: "GET",
url: this.notes_path,
data: this.target_params,
complete: function(){ $('.notes-status').removeClass("loading")},
beforeSend: function() { $('.notes-status').addClass("loading") },
dataType: "script"});
},
/**
* Called in response to getContent().
* Replaces the content of #notes-list with the given html.
*/
setContent: function(newNoteIds, html) {
$("#notes-list").html(html);
},
setContent:
function(first_id, last_id, html) {
this.top_id = first_id;
this.bottom_id = last_id;
$("#notes-list").html(html);
// init infinite scrolling
this.initLoadMore();
// init getting new notes
if (this.reversed) {
this.initRefreshNew();
}
},
/**
* Adds a single common note to #notes-list.
*/
appendNewNote: function(id, html) {
$("#notes-list").append(html);
NoteList.updateVotes();
},
/**
* Adds a single discussion note to #notes-list.
* Handle loading more notes when scrolling to the bottom of the page.
* The id of the last note in the list is in this.bottom_id.
*
* Also removes the corresponding form.
* Set up refreshing only new notes after all notes have been loaded.
*/
appendNewDiscussionNote: function(discussionId, diffRowHtml, noteHtml) {
var form = $("form[rel='"+discussionId+"']");
var row = form.closest("tr");
// is this the first note of discussion?
if (row.is(".js-temp-notes-holder")) {
// insert the note and the reply button after the temp row
row.after(diffRowHtml);
// remove the note (will be added again below)
row.next().find(".note").remove();
}
// append new note to all matching discussions
$(".notes[rel='"+discussionId+"']").append(noteHtml);
// cleanup after successfully creating a diff/discussion note
$.proxy(NoteList.removeDiscussionNoteForm, form).call();
},
/**
* Called in response the main target form has been successfully submitted.
*
* Removes any errors.
* Resets text and preview.
* Resets buttons.
* Initializes loading more notes when scrolling to the bottom of the page.
*/
resetMainTargetForm: function(){
var form = $(this);
// remove validation errors
form.find(".js-errors").remove();
// reset text and preview
var previewContainer = form.find(".js-toggler-container.note_text_and_preview");
if (previewContainer.is(".on")) {
previewContainer.removeClass("on");
}
form.find(".js-note-text").val("").trigger("input");
},
initLoadMore:
function() {
$(document).endlessScroll({
bottomPixels: 400,
fireDelay: 1000,
fireOnce:true,
ceaseFire: function() {
return NoteList.loading_more_disabled;
},
callback: function(i) {
NoteList.getMore();
}
});
},
/**
* Called after an attachment file has been selected.
*
* Updates the file name for the selected attachment.
* Gets an additional set of notes.
*/
updateFormAttachment: function() {
var form = $(this).closest("form");
getMore:
function() {
// only load more notes if there are no "new" notes
$('.loading').show();
$.ajax({
type: "GET",
url: this.notes_path,
data: this.target_params + "&loading_more=1&" + (this.reversed ? "before_id" : "after_id") + "=" + this.bottom_id,
complete: function(){ $('.notes-status').removeClass("loading")},
beforeSend: function() { $('.notes-status').addClass("loading") },
dataType: "script"});
},
// get only the basename
var filename = $(this).val().replace(/^.*[\\\/]/, '');
/**
* Called in response to getMore().
* Append notes to #notes-list.
*/
appendMoreNotes:
function(id, html) {
if(id != this.bottom_id) {
this.bottom_id = id;
$("#notes-list").append(html);
}
},
form.find(".js-attachment-filename").text(filename);
},
/**
* Called in response to getMore().
* Disables loading more notes when scrolling to the bottom of the page.
* Initalizes refreshing new notes.
*/
finishedLoadingMore:
function() {
this.loading_more_disabled = true;
// from now on only get new notes
if (!this.reversed) {
this.initRefreshNew();
}
// make sure we are up to date
this.updateVotes();
},
/**
* Handle refreshing and adding of new notes.
*
* New notes are all notes that are created after the site has been loaded.
* The "old" notes are in #notes-list the "new" ones will be in #new-notes-list.
* The id of the last "old" note is in this.bottom_id.
*/
/**
* Initializes getting new notes every n seconds.
*/
initRefreshNew:
function() {
setInterval("NoteList.getNew()", 10000);
},
/**
* Gets the new set of notes.
*/
getNew:
function() {
$.ajax({
type: "GET",
url: this.notes_path,
data: this.target_params + "&loading_new=1&after_id=" + (this.reversed ? this.top_id : this.bottom_id),
dataType: "script"});
},
/**
* Called in response to getNew().
* Replaces the content of #new-notes-list with the given html.
*/
replaceNewNotes:
function(html) {
$("#new-notes-list").html(html);
this.updateVotes();
},
/**
* Adds a single note to #new-notes-list.
*/
appendNewNote:
function(id, html) {
if (this.reversed) {
$("#new-notes-list").prepend(html);
} else {
$("#new-notes-list").append(html);
}
this.updateVotes();
},
/**
* Recalculates the votes and updates them (if they are displayed at all).
@ -407,24 +249,67 @@ var NoteList = {
* Might produce inaccurate results when not all notes have been loaded and a
* recalculation is triggered (e.g. when deleting a note).
*/
updateVotes: function() {
var votes = $("#votes .votes");
var notes = $("#notes-list .note .vote");
updateVotes:
function() {
var votes = $("#votes .votes");
var notes = $("#notes-list, #new-notes-list").find(".note .vote");
// only update if there is a vote display
if (votes.size()) {
var upvotes = notes.filter(".upvote").size();
var downvotes = notes.filter(".downvote").size();
var votesCount = upvotes + downvotes;
var upvotesPercent = votesCount ? (100.0 / votesCount * upvotes) : 0;
var downvotesPercent = votesCount ? (100.0 - upvotesPercent) : 0;
// only update if there is a vote display
if (votes.size()) {
var upvotes = notes.filter(".upvote").size();
var downvotes = notes.filter(".downvote").size();
var votesCount = upvotes + downvotes;
var upvotesPercent = votesCount ? (100.0 / votesCount * upvotes) : 0;
var downvotesPercent = votesCount ? (100.0 - upvotesPercent) : 0;
// change vote bar lengths
votes.find(".bar-success").css("width", upvotesPercent+"%");
votes.find(".bar-danger").css("width", downvotesPercent+"%");
// replace vote numbers
votes.find(".upvotes").text(votes.find(".upvotes").text().replace(/\d+/, upvotes));
votes.find(".downvotes").text(votes.find(".downvotes").text().replace(/\d+/, downvotes));
// change vote bar lengths
votes.find(".bar-success").css("width", upvotesPercent+"%");
votes.find(".bar-danger").css("width", downvotesPercent+"%");
// replace vote numbers
votes.find(".upvotes").text(votes.find(".upvotes").text().replace(/\d+/, upvotes));
votes.find(".downvotes").text(votes.find(".downvotes").text().replace(/\d+/, downvotes));
}
}
}
};
var PerLineNotes = {
init:
function() {
/**
* Called when clicking on the "add note" or "reply" button for a diff line.
*
* Shows the note form below the line.
* Sets some hidden fields in the form.
*/
$(".diff_file_content").on("click", ".line_note_link, .line_note_reply_link", function(e) {
var form = $(".per_line_form");
$(this).closest("tr").after(form);
form.find("#note_line_code").val($(this).data("lineCode"));
form.show();
e.preventDefault();
});
disableButtonIfEmptyField(".line-note-text", ".submit_inline_note");
/**
* Called in response to successfully deleting a note on a diff line.
*
* Removes the actual note from view.
* Removes the reply button if the last note for that line has been removed.
*/
$(".diff_file_content").on("ajax:success", ".delete-note", function() {
var trNote = $(this).closest("tr");
trNote.fadeOut(function() {
$(this).remove();
});
// check if this is the last note for this line
// elements must really be removed for this to work reliably
var trLine = trNote.prev();
var trRpl = trNote.next();
if (trLine.is(".line_holder") && trRpl.is(".reply")) {
trRpl.fadeOut(function() { $(this).remove(); });
}
});
}
}

View File

@ -0,0 +1,49 @@
var Pager = {
limit:0,
offset:0,
disable:false,
init:
function(limit) {
this.limit=limit;
this.offset=limit;
this.initLoadMore();
},
getOld:
function() {
$('.loading').show();
$.ajax({
type: "GET",
url: location.href,
data: "limit=" + this.limit + "&offset=" + this.offset,
complete: function(){ $('.loading').hide()},
dataType: "script"});
},
append:
function(count, html) {
$(".content_list").append(html);
if(count > 0) {
this.offset += count;
} else {
this.disable = true;
}
},
initLoadMore:
function() {
$(document).endlessScroll({
bottomPixels: 400,
fireDelay: 1000,
fireOnce:true,
ceaseFire: function() {
return Pager.disable;
},
callback: function(i) {
$('.loading').show();
Pager.getOld();
}
});
}
}

View File

@ -1,42 +0,0 @@
@Pager =
limit: 0
offset: 0
disable: false
init: (limit, preload) ->
@limit = limit
if preload
@offset = 0
@getOld()
else
@offset = limit
@initLoadMore()
getOld: ->
$(".loading").show()
$.ajax
type: "GET"
url: location.href
data: "limit=" + @limit + "&offset=" + @offset
complete: ->
$(".loading").hide()
dataType: "script"
append: (count, html) ->
$(".content_list").append html
if count > 0
@offset += count
else
@disable = true
initLoadMore: ->
$(document).endlessScroll
bottomPixels: 400
fireDelay: 1000
fireOnce: true
ceaseFire: ->
Pager.disable
callback: (i) ->
$(".loading").show()
Pager.getOld()

View File

@ -15,8 +15,6 @@ $ ->
$(this).find('.update-failed').hide()
$('.update-username form').on 'ajax:complete', ->
$(this).find('.btn-save').enableButton()
$(this).find('.save-btn').removeAttr('disabled')
$(this).find('.save-btn').removeClass('disabled')
$(this).find('.loading-gif').hide()
$('.update-notifications').on 'ajax:complete', ->
$(this).find('.btn-save').enableButton()

View File

@ -18,18 +18,3 @@ $ ->
# Ref switcher
$('.project-refs-select').on 'change', ->
$(@).parents('form').submit()
$('#project_issues_enabled').change ->
if ($(this).is(':checked') == true)
$('#project_issues_tracker').removeAttr('disabled')
else
$('#project_issues_tracker').attr('disabled', 'disabled')
$('#project_issues_tracker').change()
$('#project_issues_tracker').change ->
if ($(this).val() == gon.default_issues_tracker || $(this).is(':disabled'))
$('#project_issues_tracker_id').attr('disabled', 'disabled')
else
$('#project_issues_tracker_id').removeAttr('disabled')

View File

@ -6,12 +6,17 @@ $ ->
$('span.log_loading:first').removeClass('hide')
$('#tree-slider .tree-item-file-name a, .breadcrumb li > a').live "click", ->
$("#tree-content-holder").hide("slide", { direction: "left" }, 400)
$("#tree-content-holder").hide("slide", { direction: "left" }, 150)
# Make the entire tree-item row clickable, but not if clicking another link (like a commit message)
$("#tree-slider .tree-item").live 'click', (e) ->
$('.tree-item-file-name a', this).trigger('click') if (e.target.nodeName != "A")
# Show/Hide the loading spinner
$('#tree-slider .tree-item-file-name a, .breadcrumb a, .project-refs-form').live
"ajax:beforeSend": -> $('.tree_progress').addClass("loading")
"ajax:complete": -> $('.tree_progress').removeClass("loading")
# Maintain forward/back history while browsing the file tree
((window) ->
History = window.History
@ -28,12 +33,7 @@ $ ->
History.Adapter.bind window, 'statechange', ->
state = History.getState()
$.ajax({
url: state.url,
dataType: 'script',
beforeSend: -> $('.tree_progress').addClass("loading"),
complete: -> $('.tree_progress').removeClass("loading")
})
window.ajaxGet(state.url)
)(window)
# See if there are lines selected

View File

@ -1,36 +0,0 @@
$ ->
userFormatResult = (user) ->
avatar = gon.gravatar_url
avatar = avatar.replace('%{hash}', md5(user.email))
avatar = avatar.replace('%{size}', '24')
markup = "<div class='user-result'>"
markup += "<div class='user-image'><img class='avatar s24' src='" + avatar + "'></div>"
markup += "<div class='user-name'>" + user.name + "</div>"
markup += "<div class='user-username'>" + user.username + "</div>"
markup += "</div>"
markup
userFormatSelection = (user) ->
user.name
$('.ajax-users-select').select2
placeholder: "Search for a user"
multiple: $('.ajax-users-select').hasClass('multiselect')
minimumInputLength: 0
query: (query) ->
Api.users query.term, (users) ->
data = { results: users }
query.callback(data)
initSelection: (element, callback) ->
id = $(element).val()
if id isnt ""
Api.user(id, callback)
formatResult: userFormatResult
formatSelection: userFormatSelection
dropdownCssClass: "ajax-users-dropdown"
escapeMarkup: (m) -> # we do not want to escape markup since we are displaying html in results
m

View File

@ -1,83 +0,0 @@
@Wall =
note_ids: []
project_id: null
init: (project_id) ->
Wall.project_id = project_id
Wall.getContent()
Wall.initRefresh()
Wall.initForm()
#
# Gets an initial set of notes.
#
getContent: ->
Api.notes Wall.project_id, (notes) ->
$.each notes, (i, note) ->
# render note if it not present in loaded list
# or skip if rendered
if $.inArray(note.id, Wall.note_ids) == -1
Wall.note_ids.push(note.id)
Wall.renderNote(note)
Wall.scrollDown()
$("abbr.timeago").timeago()
initRefresh: ->
setInterval("Wall.refresh()", 10000)
refresh: ->
Wall.getContent()
scrollDown: ->
notes = $('ul.notes')
$('body, html').scrollTop(notes.height())
initForm: ->
form = $('.wall-note-form')
form.find("#target_type").val('wall')
form.on 'ajax:success', ->
Wall.refresh()
form.find(".js-note-text").val("").trigger("input")
form.on 'ajax:complete', ->
form.find(".js-comment-button").removeAttr('disabled')
form.find(".js-comment-button").removeClass('disabled')
form.on "click", ".js-choose-note-attachment-button", ->
form.find(".js-note-attachment-input").click()
form.on "change", ".js-note-attachment-input", ->
filename = $(this).val().replace(/^.*[\\\/]/, '')
form.find(".js-attachment-filename").text(filename)
form.find('.note_text').keydown (e) ->
if e.ctrlKey && e.keyCode == 13
form.find('.js-comment-button').submit()
form.show()
renderNote: (note) ->
template = Wall.noteTemplate()
template = template.replace('{{author_name}}', note.author.name)
template = template.replace('{{created_at}}', note.created_at)
template = template.replace('{{text}}', linkify(sanitize(note.body)))
if note.attachment
file = '<i class="icon-paper-clip"/><a href="/files/note/' + note.id + '/' + note.attachment + '">' + note.attachment + '</a>'
else
file = ''
template = template.replace('{{file}}', file)
$('ul.notes').append(template)
noteTemplate: ->
return '<li>
<strong class="wall-author">{{author_name}}</strong>
<span class="wall-text">
{{text}}
<span class="wall-file">{{file}}</span>
</span>
<abbr class="timeago" title="{{created_at}}">{{created_at}}</abbr>
</li>'

View File

@ -5,7 +5,6 @@
*= require jquery.ui.gitlab
*= require jquery.atwho
*= require chosen
*= require select2
*= require_self
*/
@ -15,7 +14,7 @@
@import "gitlab_bootstrap.scss";
@import "common.scss";
@import "selects.scss";
@import "ref_select.scss";
@import "sections/header.scss";
@import "sections/nav.scss";
@ -33,13 +32,9 @@
@import "sections/profile.scss";
@import "sections/login.scss";
@import "sections/editor.scss";
@import "sections/admin.scss";
@import "sections/wiki.scss";
@import "sections/wall.scss";
@import "highlight/white.scss";
@import "highlight/dark.scss";
@import "highlight/solarized_dark.scss";
/**
* UI themes:
@ -50,8 +45,3 @@
@import "themes/ui_gray.scss";
@import "themes/ui_color.scss";
/**
* Styles for JS behaviors.
*/
@import "behaviors.scss";

View File

@ -1,14 +0,0 @@
// Details
//--------
.js-details-container .content { display: none; }
.js-details-container .content.hide { display: block; }
.js-details-container.open .content { display: block; }
.js-details-container.open .content.hide { display: none; }
// Toggler
//--------
.js-toggler-container .turn-on { display: inherit; }
.js-toggler-container .turn-off { display: none; }
.js-toggler-container.on .turn-on { display: none; }
.js-toggler-container.on .turn-off { display: inherit; }

View File

@ -1,7 +1,3 @@
html {
overflow-y: scroll;
}
/** LAYOUT **/
body {
@ -67,17 +63,27 @@ table a code {
}
/** FLASH message **/
.flash-container {
#flash-container {
height: 50px;
position: fixed;
z-index: 10001;
top: 0px;
width: 100%;
margin-bottom: 15px;
overflow: hidden;
background: white;
cursor: pointer;
border-bottom: 1px solid #ccc;
text-align: center;
display: none;
.alert {
cursor: pointer;
margin: 0;
text-align: center;
border-radius: 0;
span {
font-size: 14px;
}
h4 {
color: #666;
font-size: 18px;
line-height: 38px;
padding-top: 5px;
margin: 2px;
font-weight: normal;
}
}
@ -111,10 +117,34 @@ span.update-author {
}
.label {
padding: 0px 4px;
font-size: 10px;
font-style: normal;
background-color: $link_color;
background-color: #474D57;
&.label-tag {
background: none;
border: none;
padding: 4px 6px;
color: #444;
text-shadow: 0 0 1px #fff;
&.grouped {
float: left;
margin-right: 6px;
padding: 6px;
}
}
&.label-issue {
background-color: #eee;
border: 1px solid #ccc;
padding: 4px 6px;
color: #444;
text-shadow: 0 0 1px #fff;
&.grouped {
float: left;
margin-right: 6px;
padding: 6px;
}
}
&.label-success {
background-color: #8D8;
@ -173,6 +203,17 @@ ul.breadcrumb {
font-weight: bold;
font-size: 14px;
}
.arrow {
background: url("images.png") no-repeat -85px -77px;
width: 19px;
height: 16px;
float: left;
position: relative;
left: -10px;
padding: 0;
margin: 0;
}
}
input[type=text] {
@ -182,6 +223,10 @@ input[type=text] {
}
}
input.git_clone_url {
width: 325px;
}
.merge-request-form-holder {
select {
width: 300px;
@ -252,20 +297,8 @@ p.time {
}
}
.search-holder {
label, input {
height: 30px;
padding: 0;
font-size: 14px;
}
label {
line-height: 30px;
color: #666;
}
}
.highlight_word {
border-bottom: 2px solid #F90;
background: #EEDC94;
}
.status_info {
@ -313,6 +346,10 @@ li.note {
li {
border-bottom:none !important;
}
.file {
padding-left: 20px;
background:url("icon-attachment.png") no-repeat left center;
}
}
}
@ -358,7 +395,6 @@ li.note {
font-size: 48px;
padding: 20px;
text-align: center;
font-weight: normal;
}
}
}
@ -389,7 +425,7 @@ li.note {
.supp_diff_link,
.show-all-commits {
.mr_show_all_commits {
cursor: pointer;
}
@ -433,19 +469,6 @@ li.note {
}
}
.warning_message {
border-left: 4px solid #ed9;
color: #b90;
padding: 10px;
margin-bottom: 10px;
background: #ffffe6;
padding-left: 20px;
&.centered {
text-align: center;
}
}
.oauth_select_holder {
padding: 20px;
img {
@ -533,25 +556,3 @@ h1.http_status_code {
}
}
}
img.emoji {
height: 20px;
vertical-align: middle;
width: 20px;
}
.appear-data {
display: none;
}
.label-branch {
@include border-radius(4px);
padding: 2px 4px;
border: none;
font-size: 14px;
background: #474D57;
color: #fff;
font-family: $monospace_font;
text-shadow: 0 1px 1px #111;
font-weight: normal;
}

View File

@ -17,8 +17,6 @@ $baseLineHeight: 18px !default;
@import "gitlab_bootstrap/variables.scss";
@import "gitlab_bootstrap/fonts.scss";
@import "gitlab_bootstrap/mixins.scss";
@import "gitlab_bootstrap/avatar.scss";
@import "gitlab_bootstrap/nav.scss";
@import "gitlab_bootstrap/common.scss";
@import "gitlab_bootstrap/typography.scss";
@import "gitlab_bootstrap/buttons.scss";

View File

@ -1,8 +0,0 @@
/** AVATARS **/
img.avatar { float: left; margin-right: 12px; width: 40px; border: 1px solid #ddd; padding: 1px; }
img.avatar.s16 { width: 16px; height: 16px; margin-right: 6px; }
img.avatar.s24 { width: 24px; height: 24px; margin-right: 8px; }
img.avatar.s32 { width: 32px; height: 32px; margin-right: 10px; }
img.avatar.s90 { width: 90px; height: 90px; margin-right: 15px; }
img.lil_av { padding-left: 4px; padding-right: 3px; }
img.small { width: 80px; }

View File

@ -1,33 +1,23 @@
/**
* ===================================
* Contain UI block elements:
* .ui-box - for any block & widgets
* Contain 3 main UI block elements:
* .main_box - for show pages
* .ui-box - for simple block & widgets
* ===================================
*/
/**
* UI Block
* UI box element
* contains top, middle, bottom blocks
*
*/
.ui-box {
background: #F9F9F9;
margin-bottom: 25px;
border: 1px solid #CCC;
.main_box {
@extend .borders;
@extend .prepend-top-20;
@extend .append-bottom-20;
border-width: 1px;
@include solid-shade;
&.ui-box-show {
margin:20px 0;
background: #FFF;
}
&.ui-box-danger {
.title {
@include linear-gradient(#F26E5E, #bd362f);
color: #fff;
text-shadow: 0 1px 1px #900;
font-weight: bold;
}
}
img { max-width: 100%; }
@ -37,30 +27,31 @@
}
}
.ui-box-head,
.ui-box-body,
.ui-box-bottom {
.top_box_content,
.middle_box_content,
.bottom_box_content {
padding: 15px;
word-wrap: break-word;
.clearfix {
pre {
background: none !important;
margin: 0;
border: none;
padding: 0;
}
}
.ui-box-head {
.top_box_content {
.box-title {
color: $style_color;
font-size: 18px;
font-weight: normal;
line-height: 28px;
}
h3 {
margin: 0;
}
}
.ui-box-body {
.middle_box_content {
@include border-radius(0);
border: none;
font-size: 12px;
background-color: #f5f5f5;
@ -68,9 +59,24 @@
border-top: 1px solid #eee;
}
.ui-box-bottom {
.bottom_box_content {
border-top: 1px solid #eee;
}
}
/**
* Big UI Block for show page content
*
*/
.ui-box {
background: #F9F9F9;
margin-bottom: 25px;
border: 1px solid #eaeaea;
@include border-radius(4px);
border-color: #CCC;
@include solid-shade;
&.white {
background: #fff;
@ -80,52 +86,47 @@
margin: 0;
}
.title {
h5, .title {
padding: 0 10px;
@include border-radius(4px 4px 0 0);
@include bg-gray-gradient;
border-bottom: 1px solid #CCC;
color: #456;
font-size: 16px;
text-shadow: 0 1px 1px #fff;
padding: 0px 10px;
line-height: 36px;
font-size: 14px;
font-weight: normal;
border-top: 1px solid #eaeaea;
border-bottom: 1px solid #bbb;
> a {
text-shadow: 0 1px 1px #fff;
}
form {
margin-bottom: 0;
margin-top: 0;
&.small {
line-height: 28px;
font-size: 14px;
line-height: 28px;
text-shadow: 0 1px 1px white;
}
.btn {
position: relative;
top: -2px;
form {
padding: 9px 0;
margin: 0px;
}
.nav-pills {
> li {
> a {
padding: 13px;
margin: 0;
font-size: 13px;
}
&.active {
> a {
background: #D5D5D5;
color: $style_color;
@include border-radius(0);
border-radius: 0;
border-left: 1px solid #CCC;
border-right: 1px solid #CCC;
}
li {
padding: 3px 0;
&.active a { background-color: $style_color; }
a {
@include border-radius(7px);
}
}
}
}
.bottom {
@include bg-gray-gradient;
@include border-radius(0 0 4px 4px);
border-bottom: none;
border-top: 1px solid #bbb;
}
&.padded {
h5, .title {
margin: -20px;
@ -142,7 +143,6 @@
color: #777;
}
}
.row_title {
font-weight: bold;
color: #444;
@ -152,22 +152,7 @@
}
}
.form-holder {
padding-top: 20px;
form {
margin-bottom: 0;
legend {
text-indent: 10px;
}
.form-actions {
margin-bottom: 0;
}
}
}
}
.tab-pane {
.ui-box {
margin: 3px 3px 25px 3px;
.ui-box-body {
padding: 10px;
}
}

View File

@ -1,16 +1,13 @@
.btn {
@include linear-gradient(#f1f1f1, #e1e1e1);
text-shadow: 0 1px 1px #FFF;
border-color: #BBB;
@include linear-gradient(#f7f7f7, #d5d5d5);
border-color: #aaa;
&:hover {
background: #f1f1f1;
@include linear-gradient(#fAfAfA, #f1f1f1);
border-color: #AAA;
@include bg-gray-gradient;
border-color: #bbb;
color: #333;
}
&.btn-primary {
&.primary {
background: #2a79A3;
@include linear-gradient(#47A7b7, #2585b5);
border-color: #2A79A3;
@ -57,18 +54,21 @@
}
}
&.btn-create {
&.save-btn {
@extend .wide;
@extend .success;
@extend .primary;
}
&.btn-save {
@extend .wide;
@extend .btn-primary;
&.cancel-btn {
float: right;
}
&.btn-close,
&.btn-remove {
&.wide {
padding-left: 30px;
padding-right: 30px;
}
&.danger {
@extend .btn-danger;
border-color: #BD362F;
@ -78,13 +78,8 @@
}
}
&.btn-cancel {
float: right;
}
&.wide {
padding-left: 20px;
padding-right: 20px;
&.danger {
@extend .btn-danger;
}
&.small {
@ -96,7 +91,7 @@
background-color: #ccc;
}
&.btn-tiny {
&.very_small {
font-size: 11px;
padding: 2px 6px;
line-height: 16px;

View File

@ -2,7 +2,6 @@
.cgray { color:gray }
.cred { color:#D12F19 }
.cgreen { color:#4a2 }
.cblue { color:#29A }
.cblack { color:#111 }
.cdark { color:#444 }
.cwhite { color:#fff!important }
@ -10,6 +9,7 @@
/** COMMON CLASSES **/
.left { float:left }
.right { float:right!important }
.append-bottom-10 { margin-bottom:10px }
.append-bottom-20 { margin-bottom:20px }
.prepend-top-10 { margin-top:10px }
@ -17,21 +17,61 @@
.padded { padding:20px }
.ipadded { padding:20px!important }
.lborder { border-left:1px solid #eee }
.no-padding { padding:0 !important; }
.underlined { border-bottom: 1px solid #CCC; }
.no-borders { border: none; }
.vlink { color: $link_color !important; }
.underlined_link { text-decoration: underline; }
.borders { border: 1px solid #ccc; @include shade; }
.hint { font-style: italic; color: #999; }
.light { color: #888 }
.tiny { font-weight: normal }
.vtop { vertical-align: top; }
/** ALERT MESSAGES **/
.alert.alert-disabled {
background: #EEE;
color: #777;
border-color: #DDD;
/** PILLS & TABS**/
.nav-pills a:hover { background-color: #888; }
.nav-pills .active a { background-color: $style_color; }
.nav-pills > .active > a > i[class^="icon-"] { background: inherit; }
.nav-tabs > li > a, .nav-pills > li > a { color: $style_color; }
.nav.nav-tabs {
li {
> a {
padding: 8px 20px;
margin-right: 7px;
line-height: 19px;
border-color: #EEE;
color: #888;
border-bottom: 1px solid #ddd;
.badge {
background-color: #eee;
color: #888;
text-shadow: 0 1px 1px #fff;
}
i[class^="icon-"] {
line-height: 14px;
}
}
&.active {
> a {
border-color: #CCC;
border-bottom: 1px solid #fff;
color: #333;
}
}
}
}
.well { padding: 15px; }
/** ALERT MESSAGES **/
.alert-message { @extend .alert; }
.alert-messag.success { @extend .alert-success; }
.alert-message.error { @extend .alert-error; }
/** AVATARS **/
img.avatar { float: left; margin-right: 12px; width: 40px; border: 1px solid #ddd; padding: 1px; }
img.avatar.s16 { width: 16px; height: 16px; margin-right: 6px; }
img.avatar.s24 { width: 24px; height: 24px; margin-right: 8px; }
img.avatar.s32 { width: 32px; height: 32px; margin-right: 10px; }
img.lil_av { padding-left: 4px; padding-right: 3px; }
img.small { width: 80px; }
/** HELPERS **/
.nothing_here_message {
@ -73,7 +113,3 @@ fieldset legend { font-size: 17px; }
border-bottom: 2px solid $style_color;
}
}
.tab-content {
overflow: visible;
}

View File

@ -37,6 +37,24 @@
background: #fff;
font-size: 11px;
&.wiki {
font-size: 13px;
code {
padding: 0 4px;
}
padding: 20px;
h1 { font-size: 26px; line-height: 46px; }
h2 { font-size: 22px; line-height: 42px; }
h3 { font-size: 20px; line-height: 40px; }
h4 { font-size: 18px; line-height: 32px; }
h5 { font-size: 16px; line-height: 26px; }
.white .highlight pre {
background: #f5f5f5;
}
}
&.image_file {
background: #eee;
text-align: center;
@ -46,11 +64,6 @@
}
}
&.wiki {
padding: 20px;
font-size: 13px;
}
&.blob_file {
}
@ -135,7 +148,7 @@
pre {
border: none;
border-radius: 0;
font-family: $monospace_font;
font-family: 'Menlo', 'Liberation Mono', 'Consolas', 'Courier New', 'andale mono','lucida console',monospace;
font-size: 12px !important;
line-height: 16px !important;
margin: 0;
@ -162,7 +175,6 @@
color: #666;
padding: 10px 6px 10px 0;
text-align: right;
background: #EEE;
a {
color: #666;

View File

@ -1,2 +1,7 @@
@font-face{
font-family: Korolev;
src: font-url('korolev-medium-compressed.otf');
}
/** Typo **/
$monospace_font: 'Menlo', 'Liberation Mono', 'Consolas', 'Courier New', 'andale mono', 'lucida console', monospace;
$monospace: 'Menlo', 'Liberation Mono', 'Consolas', 'Courier New', 'andale mono', 'lucida console', monospace;

View File

@ -23,12 +23,14 @@
border-bottom: 1px solid #ADF;
}
&:last-child {
border-bottom: none;
&:first-child {
@include border-radius(4px 4px 0 0);
border-top: none;
}
&.bottom {
background: #f5f5f5;
}
&:last-child {
@include border-radius(0 0 4px 4px);
border: none;
}
.author { color: #999; }

View File

@ -24,14 +24,6 @@
background-image: -o-linear-gradient($from, $to);
}
@mixin transition($transition) {
-webkit-transition: $transition;
-moz-transition: $transition;
-ms-transition: $transition;
-o-transition: $transition;
transition: $transition;
}
/**
* Prefilled mixins
* Mixins with fixed values
@ -70,19 +62,8 @@
@mixin header-font {
color: $style_color;
text-shadow: 0 1px 1px #FFF;
font-size: 18px;
line-height: 40px;
font-family: 'Korolev', sans-serif;
font-size: 28px;
line-height: 48px;
font-weight: normal;
letter-spacing: -1px;
}
@mixin md-typography {
code { padding: 0 4px; }
p { font-size: 13px; }
h1 { font-size: 26px; line-height: 40px; margin: 10px 0;}
h2 { font-size: 22px; line-height: 40px; margin: 10px 0;}
h3 { font-size: 18px; line-height: 40px; margin: 10px 0;}
h4 { font-size: 16px; line-height: 20px; margin: 10px 0;}
h5 { font-size: 14px; line-height: 20px; margin: 10px 0;}
h6 { font-size: 12px; line-height: 20px; margin: 10px 0;}
}

View File

@ -1,65 +0,0 @@
/**
* nav-pills
*
*/
.nav-pills {
.active a {
background: $primary_color;
}
> li > a {
@include border-radius(0);
}
&.nav-stacked {
> li > a {
border-left: 4px solid #EEE;
padding: 12px;
}
> .active > a {
border-color: #29B;
border-radius: 0;
background: #F1F1F1;
color: $style_color;
font-weight: bold;
}
}
}
.nav-pills > .active > a > i[class^="icon-"] { background: inherit; }
/**
* nav-tabs
*
*/
.nav-tabs > li > a, .nav-pills > li > a { color: $style_color; }
.nav.nav-tabs {
li {
> a {
padding: 8px 20px;
margin-right: 7px;
line-height: 20px;
border-color: #EEE;
color: #888;
border-bottom: 1px solid #ddd;
.badge {
background-color: #eee;
color: #888;
text-shadow: 0 1px 1px #fff;
}
i[class^="icon-"] {
line-height: 14px;
}
}
&.active {
> a {
border-color: #CCC;
border-bottom: 1px solid #fff;
color: #333;
}
}
}
&.nav-small-tabs > li > a { padding: 6px 9px; }
}

View File

@ -11,12 +11,6 @@ table {
}
}
&.headless {
tr:first-child td{
border-top: 1px solid #CCC;
}
}
th {
font-weight: bold;
vertical-align: middle;
@ -31,7 +25,7 @@ table {
}
th, td {
padding: 10px;
padding: 8px;
line-height: 18px;
text-align: left;
}

View File

@ -21,7 +21,7 @@ h6 {
/** CODE **/
pre {
font-family: $monospace_font;
font-family:'Menlo', 'Liberation Mono', 'Consolas', 'Courier New', 'andale mono','lucida console',monospace;
&.dark {
background: #333;
@ -79,23 +79,5 @@ a:focus {
}
.monospace {
font-family: $monospace_font;
}
/**
* Wiki typography
*
*/
.wiki {
@include md-typography;
font-size: 13px;
line-height: 20px;
.white .highlight pre { background: #f5f5f5; }
ul { margin: 0 0 9px 25px !important; }
}
.md {
@include md-typography;
font-family: 'Menlo', 'Liberation Mono', 'Consolas', 'Courier New', 'andale mono','lucida console',monospace;
}

View File

@ -1,13 +1,5 @@
/**
* General Colors
*/
/** Colors **/
$primary_color: #2FA0BB;
$link_color: #3A89A3;
$style_color: #474D57;
$hover: #D9EDF7;
/**
* Commit Diff Colors
*/
$added: #63c363;
$deleted: #f77;

View File

@ -1,7 +1,8 @@
.black .highlight {
background-color: #333;
pre {
background-color: #333;
color: #eee;
background: inherit;
}
.hll { display: block; background-color: darken($hover, 65%) }

View File

@ -1,77 +0,0 @@
.solarized-dark .highlight {
pre {
background-color: #002B36;
color: #eee;
}
.hll { background-color: #073642 }
.c { color: #586E75 } /* Comment */
.err { color: #93A1A1 } /* Error */
.g { color: #93A1A1 } /* Generic */
.k { color: #859900 } /* Keyword */
.l { color: #93A1A1 } /* Literal */
.n { color: #93A1A1 } /* Name */
.o { color: #859900 } /* Operator */
.x { color: #CB4B16 } /* Other */
.p { color: #93A1A1 } /* Punctuation */
.cm { color: #586E75 } /* Comment.Multiline */
.cp { color: #859900 } /* Comment.Preproc */
.c1 { color: #586E75 } /* Comment.Single */
.cs { color: #859900 } /* Comment.Special */
.gd { color: #2AA198 } /* Generic.Deleted */
.ge { color: #93A1A1; font-style: italic } /* Generic.Emph */
.gr { color: #DC322F } /* Generic.Error */
.gh { color: #CB4B16 } /* Generic.Heading */
.gi { color: #859900 } /* Generic.Inserted */
.go { color: #93A1A1 } /* Generic.Output */
.gp { color: #93A1A1 } /* Generic.Prompt */
.gs { color: #93A1A1; font-weight: bold } /* Generic.Strong */
.gu { color: #CB4B16 } /* Generic.Subheading */
.gt { color: #93A1A1 } /* Generic.Traceback */
.kc { color: #CB4B16 } /* Keyword.Constant */
.kd { color: #268BD2 } /* Keyword.Declaration */
.kn { color: #859900 } /* Keyword.Namespace */
.kp { color: #859900 } /* Keyword.Pseudo */
.kr { color: #268BD2 } /* Keyword.Reserved */
.kt { color: #DC322F } /* Keyword.Type */
.ld { color: #93A1A1 } /* Literal.Date */
.m { color: #2AA198 } /* Literal.Number */
.s { color: #2AA198 } /* Literal.String */
.na { color: #93A1A1 } /* Name.Attribute */
.nb { color: #B58900 } /* Name.Builtin */
.nc { color: #268BD2 } /* Name.Class */
.no { color: #CB4B16 } /* Name.Constant */
.nd { color: #268BD2 } /* Name.Decorator */
.ni { color: #CB4B16 } /* Name.Entity */
.ne { color: #CB4B16 } /* Name.Exception */
.nf { color: #268BD2 } /* Name.Function */
.nl { color: #93A1A1 } /* Name.Label */
.nn { color: #93A1A1 } /* Name.Namespace */
.nx { color: #93A1A1 } /* Name.Other */
.py { color: #93A1A1 } /* Name.Property */
.nt { color: #268BD2 } /* Name.Tag */
.nv { color: #268BD2 } /* Name.Variable */
.ow { color: #859900 } /* Operator.Word */
.w { color: #93A1A1 } /* Text.Whitespace */
.mf { color: #2AA198 } /* Literal.Number.Float */
.mh { color: #2AA198 } /* Literal.Number.Hex */
.mi { color: #2AA198 } /* Literal.Number.Integer */
.mo { color: #2AA198 } /* Literal.Number.Oct */
.sb { color: #586E75 } /* Literal.String.Backtick */
.sc { color: #2AA198 } /* Literal.String.Char */
.sd { color: #93A1A1 } /* Literal.String.Doc */
.s2 { color: #2AA198 } /* Literal.String.Double */
.se { color: #CB4B16 } /* Literal.String.Escape */
.sh { color: #93A1A1 } /* Literal.String.Heredoc */
.si { color: #2AA198 } /* Literal.String.Interpol */
.sx { color: #2AA198 } /* Literal.String.Other */
.sr { color: #DC322F } /* Literal.String.Regex */
.s1 { color: #2AA198 } /* Literal.String.Single */
.ss { color: #2AA198 } /* Literal.String.Symbol */
.bp { color: #268BD2 } /* Name.Builtin.Pseudo */
.vc { color: #268BD2 } /* Name.Variable.Class */
.vg { color: #268BD2 } /* Name.Variable.Global */
.vi { color: #268BD2 } /* Name.Variable.Instance */
.il { color: #2AA198 } /* Literal.Number.Integer.Long */
}

View File

@ -1,18 +1,3 @@
.ajax-users-select {
width: 400px;
}
.user-result {
.user-image {
float: left;
}
.user-name {
}
.user-username {
color: #999;
}
}
/** Branch/tag selector **/
.project-refs-form {
margin: 0;
@ -103,26 +88,3 @@
}
}
}
/** Select2 styling **/
.select2-container .select2-choice {
background: #f1f1f1;
background-image: -webkit-gradient(linear, 0 0, 0 30, color-stop(0.066, whitesmoke), to(#e1e1e1));
background-image: -webkit-linear-gradient(whitesmoke 6.6%, #e1e1e1);
background-image: -moz-linear-gradient(whitesmoke 6.6%, #e1e1e1);
background-image: -o-linear-gradient(whitesmoke 6.6%, #e1e1e1);
}
.select2-container .select2-choice div {
border: none;
background: none;
}
.select2-drop {
padding-top: 8px;
}
.select2-no-results, .select2-searching {
padding: 7px;
color: #666;
}

View File

@ -1,5 +0,0 @@
.admin-filter form {
label { width: 110px; }
.controls { margin-left: 130px; }
.form-actions { padding-left: 130px; background: #fff }
}

View File

@ -1,20 +1,79 @@
/**
* Commit file
*/
.commit-committer-link,
.commit-author-link {
font-size: 13px;
color: #555;
&:hover {
color: #999;
.commit-box {
@extend .main_box;
.commit-head {
@extend .top_box_content;
.commit-title {
line-height: 26px;
margin: 0;
}
.commit-description {
font-size: 14px;
border: none;
background-color: white;
padding-top: 10px;
}
.browse-button {
@extend .btn;
@extend .btn-small;
float: right;
}
}
.commit-info {
@extend .middle_box_content;
@extend .clearfix;
.sha-block {
text-align: right;
&:first-child {
padding-bottom: 6px;
}
a {
border-bottom: 1px solid #aaa;
margin-left: 9px;
}
}
&.merge-commit .sha-block {
clear: right;
}
.committer {
padding-left: 32px;
}
.author a,
.committer a {
font-size: 14px;
line-height: 22px;
text-shadow: 0 1px 1px #fff;
color: #777;
&:hover {
color: #999;
}
}
.avatar {
margin-right: 10px;
}
}
}
.file {
/**
*
* COMMIT SHOw
*
*/
.diff_file {
border: 1px solid #CCC;
margin-bottom: 1em;
.header {
.diff_file_header {
@extend .clearfix;
padding: 5px 5px 5px 10px;
color: #555;
@ -26,35 +85,32 @@
background-image: -moz-linear-gradient(#eee 6.6%, #dfdfdf);
background-image: -o-linear-gradient(#eee 6.6%, #dfdfdf);
a{
color: $style_color;
}
> span {
font-family: $monospace_font;
font-family: $monospace;
font-size: 14px;
line-height: 30px;
}
a.view-file{
a.view-commit{
font-weight: bold;
}
.commit-short-id{
font-family: $monospace_font;
font-family: $monospace;
font-size: smaller;
}
.file-mode{
font-family: $monospace_font;
font-family: $monospace;
}
}
.content {
.diff_file_content {
overflow: auto;
overflow-y: hidden;
background: #FFF;
background: #fff;
color: #333;
font-size: 12px;
font-family: $monospace;
.old{
span.idiff{
background-color: #FAA;
@ -67,277 +123,114 @@
}
table {
font-family: $monospace_font;
border: none;
margin: 0px;
padding: 0px;
td {
line-height: 18px;
}
}
}
.diff_file_content_image {
background: #eee;
text-align: center;
.image {
display: inline-block;
margin: 50px;
max-width: 400px;
img{
background: url('trans_bg.gif');
}
&.diff_removed {
img{
border: 1px solid #C00;
}
}
&.diff_added {
img{
border: 1px solid #0C0;
}
}
.image-info{
margin: 5px 0 0 0;
}
}
&.img_compared {
.image {
max-width: 300px;
}
}
}
}
.diff_file_content{
table {
border: none;
margin: 0px;
padding: 0px;
tr {
td {
font-size: 12px;
}
}
.old_line, .new_line {
margin: 0px;
padding: 0px;
border: none;
background: #EEE;
color: #666;
padding: 0px 5px;
border-right: 1px solid #ccc;
text-align: right;
min-width: 35px;
max-width: 35px;
}
.old_line, .new_line {
margin: 0px;
padding: 0px;
border: none;
background: #EEE;
color: #666;
padding: 0px 5px;
border-right: 1px solid #ccc;
text-align: right;
min-width: 35px;
max-width: 35px;
width: 35px;
moz-user-select: none;
-khtml-user-select: none;
user-select: none;
a {
float: left;
width: 35px;
@include user-select(none);
a {
float: left;
width: 35px;
font-weight: normal;
color: #666;
&:hover {
text-decoration: underline;
}
}
}
.line_content {
display: block;
white-space: pre;
height: 18px;
margin: 0px;
padding: 0px;
border: none;
&.new {
background: #CFD;
}
&.old {
background: #FDD;
}
&.matched {
color: #ccc;
background: #fafafa;
}
}
}
.image {
background: #ddd;
text-align: center;
padding: 30px;
.wrap{
display: inline-block;
}
.frame {
display: inline-block;
background-color: #fff;
line-height: 0;
img{
border: 1px solid #FFF;
background: url('trans_bg.gif');
}
&.deleted {
border: 1px solid $deleted;
}
&.added {
border: 1px solid $added;
}
}
.image-info{
font-size: 12px;
margin: 5px 0 0 0;
color: grey;
}
.view.swipe{
position: relative;
.swipe-frame{
display: block;
margin: auto;
position: relative;
}
.swipe-wrap{
overflow: hidden;
border-left: 1px solid #999;
position: absolute;
display: block;
top: 13px;
right: 7px;
}
.frame{
top: 0;
right: 0;
position: absolute;
&.deleted{
margin: 0;
display: block;
top: 13px;
right: 7px;
}
}
.swipe-bar{
display: block;
height: 100%;
width: 15px;
z-index: 100;
position: absolute;
cursor: pointer;
&:hover{
.top-handle{
background-position: -15px 3px;
}
.bottom-handle{
background-position: -15px -11px;
}
};
.top-handle{
display: block;
height: 14px;
width: 15px;
position: absolute;
top: 0px;
background: url('swipemode_sprites.gif') 0 3px no-repeat;
}
.bottom-handle{
display: block;
height: 14px;
width: 15px;
position: absolute;
bottom: 0px;
background: url('swipemode_sprites.gif') 0 -11px no-repeat;
}
}
} //.view.swipe
.view.onion-skin{
.onion-skin-frame{
display: block;
margin: auto;
position: relative;
}
.frame.added, .frame.deleted {
position: absolute;
display: block;
top: 0px;
left: 0px;
}
.controls{
display: block;
height: 14px;
width: 300px;
z-index: 100;
position: absolute;
bottom: 0px;
left: 50%;
margin-left: -150px;
.drag-track{
display: block;
position: absolute;
left: 12px;
height: 10px;
width: 276px;
background: url('onion_skin_sprites.gif') -4px -20px repeat-x;
}
.dragger {
display: block;
position: absolute;
left: 0px;
top: 0px;
height: 14px;
width: 14px;
background: url('onion_skin_sprites.gif') 0px -34px repeat-x;
cursor: pointer;
}
.transparent {
display: block;
position: absolute;
top: 2px;
right: 0px;
height: 10px;
width: 10px;
background: url('onion_skin_sprites.gif') -2px 0px no-repeat;
}
.opaque {
display: block;
position: absolute;
top: 2px;
left: 0px;
height: 10px;
width: 10px;
background: url('onion_skin_sprites.gif') -2px -10px no-repeat;
}
}
} //.view.onion-skin
}
.view-modes{
padding: 10px;
text-align: center;
background-image: -webkit-gradient(linear, 0 0, 0 30, color-stop(0.066, #eee), to(#dfdfdf));
background-image: -webkit-linear-gradient(#eee 6.6%, #dfdfdf);
background-image: -moz-linear-gradient(#eee 6.6%, #dfdfdf);
background-image: -o-linear-gradient(#eee 6.6%, #dfdfdf);
ul, li{
list-style: none;
margin: 0;
padding: 0;
display: inline-block;
}
li{
color: grey;
border-left: 1px solid #c1c1c1;
padding: 0 12px 0 16px;
cursor: pointer;
&:first-child{
border-left: none;
}
&:hover{
font-weight: normal;
color: #666;
&:hover {
text-decoration: underline;
}
&.active{
&:hover{
text-decoration: none;
}
cursor: default;
color: #333;
}
&.disabled{
display: none;
}
}
}
.line_content {
white-space: pre;
height: 14px;
margin: 0px;
padding: 0px;
border: none;
&.new {
background: #CFD;
}
&.old {
background: #FDD;
}
&.matched {
color: #ccc;
background: #fafafa;
}
}
}
/** COMMIT BLOCK **/
.commit-title{
display: block;
}
.commit-title{
margin-bottom: 10px;
}
.commit-author, .commit-committer{
display: block;
color: #999;
font-weight: normal;
font-style: italic;
}
.commit-author strong, .commit-committer strong{
font-weight: bold;
font-style: normal;
}
.commit-title{display: block;}
.commit-title{margin-bottom: 10px}
.commit-author, .commit-committer{display: block;color: #999; font-weight: normal; font-style: italic;}
.commit-author strong, .commit-committer strong{font-weight: bold; font-style: normal;}
/**
* COMMIT ROW
*/
/** COMMIT ROW **/
.commit {
.browse_code_link_holder {
@extend .span2;
float: right;
}
@ -360,10 +253,18 @@
float: left;
@extend .lined;
min-width: 65px;
font-family: $monospace_font;
font-family: $monospace;
}
.commit-author-name {
color: #777;
&:hover {
color: #999;
}
}
}
.diff_file_header a,
.file-stats a {
color: $style_color;
}
@ -397,7 +298,7 @@
font-size: 13px;
background: #474D57;
color: #fff;
font-family: $monospace_font;
font-family: $monospace;
}
@ -413,9 +314,3 @@
padding: 4px;
background-color: #EEE;
}
.commit-description {
background: none;
border: none;
margin: 0;
}

View File

@ -40,33 +40,13 @@
}
}
.event-body {
.commit p {
p {
color: #555;
padding-top: 5px;
}
.event-info {
color: #666;
}
.event-note {
color: #555;
margin-top: 5px;
margin-left: 40px;
.note-file-attach {
.note-image-attach {
margin-top: 4px;
margin-left: 0px;
max-width: 200px;
}
}
}
.event-note-icon {
color: #777;
float: left;
font-size: 16px;
line-height: 16px;
margin-right: 5px;
}
}
.avatar {
position: relative;
@ -134,7 +114,7 @@
.btn-new-mr {
@extend .btn-info;
@extend .small;
@extend .pull-right;
@extend .right;
margin: -3px;
}
}
@ -146,25 +126,21 @@
.event_filter {
position: absolute;
width: 40px;
margin-left: -55px;
margin-left: -50px;
.filter_icon {
a {
text-align:center;
border-left: 3px solid #29B;
background: #f9f9f9;
margin-bottom: 10px;
float: left;
padding: 9px 7px;
font-size: 18px;
width: 26px;
float: left;
border-left: 3px solid #4bc;
padding: 7px;
background: #f9f9f9;
margin-bottom: 10px;
img {
width: 20px;
}
&.inactive {
a {
color: #DDD;
border-left: 3px solid #EEE;
}
border-left: 3px solid #EEE;
opacity: 0.5;
}
}
}

View File

@ -12,7 +12,7 @@
.graph {
background: #f1f1f1;
cursor: move;
height: 500px;
height: 70%;
overflow: hidden;
}
}

View File

@ -5,16 +5,15 @@
header {
&.navbar-gitlab {
.navbar-inner {
height: 40px;
padding: 3px;
height: 45px;
padding: 5px;
background: #F1F1F1;
filter: none;
.nav > li > a {
color: $style_color;
text-shadow: 0 1px 0 #fff;
font-size: 16px;
padding: 10px;
font-size: 18px;
padding: 11px;
}
/** NAV block with links and profile **/
@ -26,6 +25,7 @@ header {
}
z-index: 10;
/*height: 60px;*/
/**
*
@ -33,30 +33,22 @@ header {
*
*/
.app_logo {
width: 170px;
float: left;
margin-right: 9px;
position: relative;
top: -5px;
padding-top: 5px;
a {
float: left;
padding: 0px;
margin: 0 6px;
h1 {
background: url('logo-black.png') no-repeat center 1px;
background-size: 38px;
width: 90px;
background: url('logo_dark.png') no-repeat 0px 2px;
float: left;
margin-left: 2px;
padding-left: 45px;
height: 40px;
width: 40px;
@include header-font;
text-indent: -9999px;
}
}
&:hover {
background-color: #EEE;
}
}
/**
@ -68,27 +60,19 @@ header {
position: relative;
float: left;
margin: 0;
margin-left: 10px;
margin-right: 30px;
@include header-font;
}
.profile-pic {
position: relative;
top: -4px;
img {
width: 26px;
@include border-radius(4px);
}
}
/**
*
* Search box
*
*/
.search {
margin-right: 10px;
margin-right: 45px;
margin-left: 10px;
margin-top: 2px;
.search-input {
@extend .span2;
@ -100,13 +84,121 @@ header {
@include border-radius(3px);
border: 1px solid #c6c6c6;
box-shadow: none;
@include transition(all 0.15s ease-in 0s);
&:focus {
@extend .span3;
}
}
}
/**
*
* Account box
*
*/
.account-box {
position: absolute;
right: 0;
top: 6px;
z-index: 10000;
width: 128px;
font-size: 11px;
float: right;
display: block;
cursor: pointer;
img {
@include border-radius(3px);
right: 5px;
position: absolute;
width: 28px;
height: 28px;
display: block;
top: 1px;
&:after {
content: " ";
display: block;
position: absolute;
top: 0;
right: 0;
left: 0;
bottom: 0;
float: right;
@include border-radius(5px);
border: 1px solid rgba(255, 255, 255, 0.1);
border-bottom: 0;
background: -webkit-gradient(linear, 0% 0%, 0% 100%, from(rgba(255, 255, 255, 0.15)), to(rgba(0, 0, 0, 0.25))),
-webkit-gradient(linear, left top, right bottom, color-stop(0, rgba(255, 255, 255, 0)), color-stop(0.5, rgba(255, 255, 255, 0.1)), color-stop(0.501, rgba(255, 255, 255, 0)), color-stop(1, rgba(255, 255, 255, 0)));
background: -moz-linear-gradient(top, rgba(255, 255, 255, 0.15), rgba(0, 0, 0, 0.25)),
-moz-linear-gradient(left top, rgba(255, 255, 255, 0), rgba(255, 255, 255, 0.1) 50%, rgba(255, 255, 255, 0) 50%, rgba(255, 255, 255, 0));
background: linear-gradient(top, rgba(255, 255, 255, 0.15), rgba(0, 0, 0, 0.25)),
linear-gradient(left top, rgba(255, 255, 255, 0), rgba(255, 255, 255, 0.1) 50%, rgba(255, 255, 255, 0) 50%, rgba(255, 255, 255, 0));
-webkit-background-origin: border-box;
-moz-background-origin: border;
background-origin: border-box; } } }
.account-box {
&.hover {
height: 138px; }
&:hover > .account-links {
display: block; } }
.account-links {
@include border-radius(5px);
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2);
position: relative;
&:before {
content: ".";
width: 0;
height: 0;
position: absolute;
border: 5px solid transparent;
border-color: rgba(255, 255, 255, 0);
border-bottom-color: #555;
text-indent: -9999px;
top: -10px;
line-height: 0;
right: 10px;
z-index: 10; }
background: #555;
display: none;
z-index: 100000;
@include border-radius(4px);
width: 130px;
position: absolute;
right: 5px;
top: 38px;
margin-top: 0;
float: right;
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2);
a {
color: #fff;
padding: 12px 15px;
display: block;
text-shadow: none;
border-bottom: 1px solid #666;
font-size: 12px;
&:hover {
color: #fff;
background: #333;
}
}
}
.account-box.hover .arrow-up {
top: 41px;
right: 6px;
position: absolute; }
.account-links a {
&:first-child {
@include border-radius(5px 5px 0 0);
}
&:last-child {
@include border-radius(0 0 5px 5px);
border-bottom: 0;
}
}
/*
* Dark header
@ -129,7 +221,6 @@ header {
.search-input {
background-color: #D2D5DA;
background-color: rgba(255, 255, 255, 0.5);
border: 1px solid #AAA;
&:focus {
background-color: white;
@ -142,38 +233,16 @@ header {
.app_logo {
a {
h1 {
background: url('logo-white.png') no-repeat center 1px;
background-size: 38px;
background: url('logo_white.png') no-repeat 0px 2px;
color: #fff;
text-shadow: 0 1px 1px #111;
}
}
}
.project_name {
a {
color: #FFF;
}
color: #fff;
text-shadow: 0 1px 1px #111;
}
}
.app_logo {
.separator {
margin-left: 0;
margin-right: 0;
}
}
.separator {
float: left;
height: 46px;
width: 1px;
background: white;
border-left: 1px solid #DDD;
margin-top: -3px;
margin-left: 10px;
margin-right: 10px;
}
}

View File

@ -1,6 +1,34 @@
.issue_form_box {
@extend .main_box;
.issue_title {
@extend .top_box_content;
.clearfix {
margin-bottom: 0px;
input {
@extend .span8;
}
}
}
.issue_middle_block {
@extend .middle_box_content;
height: 30px;
.issue_assignee {
@extend .span6;
float: left;
}
.issue_milestone {
@extend .span4;
float: left;
}
}
.issue_description {
@extend .bottom_box_content;
}
}
.issues_table {
.issue {
padding: 10px;
padding: 7px 10px;
.issue_check {
float: left;
@ -54,34 +82,38 @@ input.check_all_issues {
}
}
@media (min-width: 800px) { .issues_filters select { width: 160px; } }
@media (min-width: 800px) { .issues_filters select { width: 160px; } }
@media (min-width: 1000px) { .issues_filters select { width: 200px; } }
@media (min-width: 1200px) { .issues_filters select { width: 220px; } }
@media (min-width: 800px) { .issues_bulk_update select { width: 120px; } }
@media (min-width: 1200px) { .issues_bulk_update select { width: 160px; } }
#issues-table-holder {
.issues_filters {
form {
padding: 0;
margin: 0;
margin-top:7px
}
}
.issues_bulk_update {
margin: 0;
form {
float:left;
padding: 0;
margin: 0;
margin-top:7px
}
.update_selected_issues {
position: relative;
top:5px;
top:-2px;
margin-left: 4px;
float: left;
}
.update_issues_text {
padding: 3px;
line-height: 28px;
line-height: 18px;
float: left;
color: #479;
}
}
}

View File

@ -1,7 +1,7 @@
/* Login Page */
body.login-page{
background: #EEE;
.container .content { padding-top: 5%; }
body.login-page{
padding-top: 10%;
background: #f1f1f1;
}
.login-box{
@ -31,9 +31,4 @@ body.login-page{
margin-bottom: 20px;
}
.login-box input.text.middle{
border-top: 0;
margin-bottom:0px;
}
.login-box a.forgot{float: right; padding-top: 6px}

View File

@ -1,3 +1,17 @@
/**
* MR form
*
*/
.mr_branch_box {
@extend .ui-box;
margin-bottom: 20px;
.body {
background: #f1f1f1;
}
}
/**
* MR -> show: Automerge widget
@ -33,7 +47,6 @@
}
label {
color: #444;
text-align: left
}
}
@ -43,7 +56,7 @@
}
}
.merge-request .nav-tabs{
.mr_nav_tabs {
li {
a {
font-weight: bold;
@ -54,7 +67,7 @@
}
li.merge_request {
padding: 10px;
padding: 7px 10px;
img.avatar {
width: 32px;
margin-top: 1px;
@ -65,11 +78,21 @@ li.merge_request {
}
}
.merge-in-progress {
.merge_in_progress {
@extend .padded;
@extend .append-bottom-10;
}
.label_branch {
@include border-radius(4px);
padding: 2px 4px;
border: none;
font-size: 14px;
background: #474D57;
color: #fff;
font-family: 'Menlo', 'Liberation Mono', 'Consolas', 'Courier New', 'andale mono','lucida console',monospace;
}
.mr_source_commit,
.mr_target_commit {
.commit {
@ -97,3 +120,19 @@ li.merge_request {
.mr_direction_tip {
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;
}
}
}

View File

@ -1,64 +1,70 @@
.main-nav {
/*
* Main Menu of Application
*
*/
ul.main_menu {
margin: auto;
margin: 30px 0;
margin-top: 10px;
border-bottom: 1px solid #E1E1E1;
ul {
margin: auto;
height: 39px;
border-bottom: 1px solid #DDD;
height: 37px;
position: relative;
overflow: hidden;
.count {
position: relative;
top: 3px;
overflow: hidden;
.count {
position: relative;
top: -1px;
display: inline-block;
height: 15px;
margin: 0 0 0 5px;
padding: 0 8px 1px 8px;
height: auto;
font-size: 0.82em;
line-height: 14px;
text-align: center;
color: #777;
}
.label {
background: $hover;
text-shadow: none;
color: $style_color;
}
li {
list-style-type: none;
margin: 0;
display: table-cell;
width: 1%;
&.active {
border-bottom: 3px solid #777;
a {
color: $style_color;
font-weight: bolder;
}
top: -1px;
display: inline-block;
height: 15px;
margin: 0 0 0 5px;
padding: 0 8px 1px 8px;
height: auto;
font-size: 0.82em;
line-height: 14px;
text-align: center;
color: #777;
}
.label {
background: $hover;
text-shadow: none;
color: $style_color;
}
li {
list-style-type: none;
margin: 0;
display: table-cell;
width: 1%;
&.active {
border-bottom: 2px solid #474D57;
a {
color: $style_color;
}
}
&.home {
a {
i {
font-size: 20px;
position: relative;
top: 4px;
}
&.home {
a {
background: url(home_icon.PNG) no-repeat center center;
text-indent:-9999px;
min-width: 20px;
img {
position: relative;
top: 4px;
}
}
}
a {
display: block;
text-align: center;
font-weight: normal;
height: 36px;
line-height: 34px;
color: #777;
text-shadow: 0 1px 1px white;
padding: 0 10px;
}
}
a {
display: block;
text-align: center;
font-weight: normal;
height: 35px;
line-height: 36px;
color: #777;
text-shadow: 0 1px 1px white;
padding: 0 10px;
}
}
/*
* End of Main Menu
*
*/

View File

@ -1,301 +1,233 @@
/**
* Notes
*
*/
ul.notes {
#notes-list,
#new-notes-list {
display: block;
list-style: none;
margin: 0px;
padding: 0px;
.discussion-header,
.note-header {
@extend .cgray;
padding-top: 5px;
padding-bottom: 15px;
.avatar {
float: left;
margin-right: 10px;
}
.discussion-last-update,
.note-last-update {
font-style: italic;
}
.author {
color: $style_color;
font-weight: bold;
&:hover {
color: $primary_color;
}
}
}
.discussion {
padding: 8px 0;
overflow: hidden;
display: block;
position:relative;
.discussion-body {
margin-left: 50px;
.file,
.discussion-hidden,
.notes {
@extend .borders;
background-color: #F9F9F9;
}
.file .notes {
/* reset */
background: inherit;
border: none;
@include box-shadow(none);
}
.discussion-hidden .note {
@extend .cgray;
padding: 8px;
text-align: center;
}
.notes .note {
border-color: #ddd;
padding: 8px;
}
.reply-btn {
margin-top: 8px;
}
}
}
.note {
padding: 8px 0;
overflow: hidden;
display: block;
position:relative;
p { color: $style_color; }
.avatar {
margin-top: 3px;
}
.attachment {
font-size: 14px;
margin-top: -20px;
}
.note-body {
@include md-typography;
margin-left: 45px;
}
.note-header {
padding-bottom: 5px;
}
}
// paint top or bottom borders depending on notes direction
&:not(.reversed) .note,
&:not(.reversed) .discussion {
border-bottom: 1px solid #eee;
}
&.reversed .note,
&.reversed .discussion {
border-top: 1px solid #eee;
}
}
.file .notes_holder {
font-family: $sansFontFamily;
font-size: 13px;
line-height: 18px;
td {
border: 1px solid #ddd;
border-left: none;
&.notes_line {
text-align: center;
padding: 10px 0;
}
&.notes_content {
background-color: $white;
border-width: 1px 0;
padding-top: 0;
}
}
.reply-btn {
margin-top: 8px;
}
}
/**
* Actions for Discussions/Notes
*/
.discussion,
.note {
&.note:hover {
.note-actions { display: block; }
}
.discussion-header:hover {
.discussion-actions { display: block; }
}
.discussion-actions,
.note-actions {
display: none;
float: right;
[class^="icon-"],
[class*="icon-"] {
font-size: 16px;
line-height: 16px;
vertical-align: middle;
}
a {
@extend .cgray;
&:hover {
color: $primary_color;
&.danger { @extend .cred; }
}
}
}
}
.file .note .note-actions {
right: 0;
top: 0;
}
/**
* Line note button on the side of diffs
*/
.file tr.line_holder {
.add-diff-note {
background: url("diff_note_add.png") no-repeat left 0;
height: 22px;
margin-left: -65px;
position: absolute;
width: 22px;
z-index: 10;
// "hide" it by default
opacity: 0.0;
filter: alpha(opacity=0);
&:hover {
opacity: 1.0;
filter: alpha(opacity=100);
}
}
// "show" the icon also if we just hover somewhere over the line
&:hover > td {
background: $hover !important;
.add-diff-note {
opacity: 1.0;
filter: alpha(opacity=100);
}
}
}
/**
* Note Form
*/
.comment-btn {
@extend .btn-create;
}
.reply-btn {
@extend .btn-primary;
}
.file .content tr.line_holder:hover > td { background: $hover !important; }
.file .content tr.line_holder:hover > td .line_note_link {
opacity: 1.0;
filter: alpha(opacity=100);
}
.file,
.discussion {
.new_note {
margin: 8px 5px 8px 0;
}
}
.new_note {
display: none;
.buttons {
.issue_notes,
.wiki_notes {
.note_content {
float: left;
margin-top: 8px;
}
.clearfix {
margin-bottom: 0;
}
.note_text_and_preview {
// makes the "absolute" position for links relative to this
position: relative;
// preview/edit buttons
> a {
font-size: 24px;
padding: 4px;
position: absolute;
right: 10px;
}
.note_preview {
background: #f5f5f5;
border: 1px solid #ddd;
@include border-radius(4px);
min-height: 80px;
padding: 4px 6px;
}
.note_text {
border: 1px solid #DDD;
box-shadow: none;
font-size: 14px;
height: 80px;
width: 98.6%;
}
width: 400px;
}
}
/* loading indicator */
.notes-busy {
/* Note textare */
#note_note {
height: 80px;
width: 99%;
font-size: 14px;
}
#new_note {
.attach_holder {
display: none;
}
}
.preview_note {
margin: 2px;
border: 1px solid #ddd;
padding: 10px;
min-height: 60px;
background: #f5f5f5;
}
.note {
padding: 8px 0;
overflow: hidden;
display: block;
position: relative;
img {float: left; margin-right: 10px;}
img.emoji {float: none;margin: 0;}
.note-author cite{font-style: italic;}
p { color: $style_color; }
.note-author { color: $style_color;}
.note-title { margin-left: 45px; padding-top: 5px;}
.avatar {
margin-top: 3px;
}
.delete-note {
display: none;
position: absolute;
right: 0;
top: 0;
}
&:hover {
.delete-note { display: block; }
}
}
#notes-list:not(.reversed) .note,
#new-notes-list:not(.reversed) .note {
border-bottom: 1px solid #eee;
}
#notes-list.reversed .note,
#new-notes-list.reversed .note {
border-top: 1px solid #eee;
}
/* mark vote notes */
.voting_notes .note {
padding: 8px 0;
}
.notes-status {
margin: 18px;
}
.note-image-attach {
@extend .span4;
@extend .thumbnail;
margin-left: 45px;
p.notify_controls input{
margin: 5px;
}
.common-note-form {
margin: 0;
height: 140px;
background: #F9F9F9;
padding: 3px;
padding-bottom: 25px;
border: 1px solid #DDD;
p.notify_controls span{
font-weight: 700;
}
tr.line_notes_row {
border-bottom: 1px solid #DDD;
border-left: 7px solid #2A79A3;
.note-form-actions {
background: #F9F9F9;
height: 45px;
padding: 0 5px;
.note-form-option {
margin-top: 10px;
margin-left: 30px;
@extend .pull-left;
&.reply {
background: #eee;
border-left: 7px solid #2A79A3;
border-top: 1px solid #ddd;
td {
padding: 7px 10px;
}
a.line_note_reply_link {
border: 1px solid #eaeaea;
@include border-radius(4px);
padding: 3px 10px;
margin-left: 5px;
color: white;
background: #2A79A3;
border-color: #2A79A3;
}
}
.js-notify-commit-author {
float: left;
ul {
margin: 0;
li {
padding: 0;
border: none;
}
}
}
.line_notes_row, .per_line_form { font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; }
.per_line_form {
background: #f5f5f5;
border-top: 1px solid #eee;
form { margin: 0; }
td {
border-bottom: 1px solid #ddd;
}
.note_actions {
margin: 0;
padding-top: 10px;
.buttons {
float: left;
width: 300px;
}
.options {
.labels {
float: left;
padding-left: 10px;
label {
padding: 6px 0;
margin: 0;
width: 120px;
}
}
}
}
}
td .line_note_link {
position: absolute;
margin-left:-70px;
margin-top:-10px;
z-index: 10;
background: url("comment_add.png") no-repeat left 0;
width: 32px;
height: 32px;
opacity: 0.0;
filter: alpha(opacity=0);
&:hover {
opacity: 1.0;
filter: alpha(opacity=100);
}
}
.diff_file_content tr.line_holder:hover > td { background: $hover !important; }
.diff_file_content tr.line_holder:hover > td .line_note_link {
opacity: 1.0;
filter: alpha(opacity=100);
}
.new_note {
.input-file {
font: 500px monospace;
opacity: 0;
filter: alpha(opacity=0);
position: absolute;
z-index: 1;
top: 0;
right: 0;
padding: 0;
margin: 0;
}
.note_advanced_opts {
h6 {
line-height: 32px;
padding-right: 15px;
}
}
.attachments {
position: relative;
width: 350px;
height: 50px;
overflow: hidden;
margin:0 0 5px !important;
.input_file {
.file_upload {
position: absolute;
right: 14px;
top: 7px;
}
.file_name {
line-height: 30px;
width: 240px;
height: 28px;
overflow: hidden;
}
.input-file {
width: 260px;
height: 41px;
float: right;
}
}
}
}
.note-text {
border: 1px solid #aaa;
box-shadow: none;
}

View File

@ -4,16 +4,20 @@
}
.side {
@extend .pull-right;
@extend .right;
.ui-box {
margin: 3px;
> .title {
padding: 2px 15px;
.groups_box,
.projects_box {
> h5 {
color: $style_color;
font-size: 16px;
text-shadow: 0 1px 1px #fff;
padding: 2px 10px;
line-height: 32px;
font-size: 14px;
}
.nav-projects-tabs li { padding: 0; }
.well-list {
li { padding: 15px; }
.arrow {
float: right;
padding: 10px;
@ -42,6 +46,9 @@
line-height: 20px;
padding: 8px;
}
label {
color: #888;
}
.btn {
padding: 6px 10px;
margin-left: 10px;
@ -81,7 +88,6 @@
border: 1px solid #BBB;
box-shadow: none;
margin-left: -1px;
background: #FFF;
}
}
@ -103,7 +109,7 @@ ul.nav.nav-projects-tabs {
li {
a {
padding: 6px 25px;
padding: 4px 20px;
margin-top: 2px;
border-color: #DDD;
background-color: #EEE;
@ -117,20 +123,3 @@ ul.nav.nav-projects-tabs {
}
}
}
.team_member_row form {
margin: 0px;
}
.public-projects {
li {
margin-top: 8px;
margin-bottom: 5px;
border-bottom: 1px solid #eee;
.description {
margin-left: 22px;
color: #aaa;
}
}
}

View File

@ -80,18 +80,6 @@
margin: 0;
padding: 0;
}
td.blame-commit {
background: #f9f9f9;
min-width: 350px;
}
td.blame-numbers {
pre {
color: #AAA;
white-space: pre;
}
background: #f1f1f1;
border-left: 1px solid #DDD;
}
}
}
@ -102,7 +90,3 @@
}
}
.tree-ref-holder {
float: left;
margin-top: 5px;
}

View File

@ -1,55 +0,0 @@
.wall-page {
.wall-note-form {
@extend .span12;
margin: 0;
height: 140px;
background: #F9F9F9;
position: fixed;
bottom: 0px;
padding: 3px;
padding-bottom: 25px;
border: 1px solid #DDD;
}
.notes {
margin-bottom: 160px;
background: #FFE;
border: 1px solid #EED;
> li {
@extend .clearfix;
border-bottom: 1px solid #EED;
padding: 10px;
}
.wall-author {
color: #666;
float: left;
font-size: 12px;
width: 120px;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
}
.wall-text {
border-left: 1px solid #CCC;
margin-left: 10px;
padding-left: 10px;
float: left;
width: 75%;
}
.wall-file {
margin-left: 8px;
background: #EEE;
}
abbr {
float: right;
color: #AAA;
border: none;
}
}
}

View File

@ -1,6 +0,0 @@
h3.page_title .edit-wiki-header {
width: 780px;
margin-left: auto;
margin-right: auto;
padding-right: 7px;
}

View File

@ -4,8 +4,21 @@
*
*/
.ui_basic {
.app_logo {
.separator {
margin-left: 0;
margin-right: 0;
}
}
.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

@ -17,15 +17,6 @@
&.navbar-gitlab {
.navbar-inner {
background: #657;
.app_logo {
&:hover {
background-color: #6A5A7A;
}
}
.separator {
background: #546;
border-left: 1px solid #706080;
}
}
}
}

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