Merge branch 'ce-7-to-ee' into 'master'
Pull recent master from CE into EE Fixes #113
@@ -21,6 +21,7 @@ config/gitlab.yml
|
||||
config/database.yml
|
||||
config/initializers/omniauth.rb
|
||||
config/initializers/rack_attack.rb
|
||||
config/initializers/smtp_settings.rb
|
||||
config/unicorn.rb
|
||||
config/resque.yml
|
||||
config/aws.yml
|
||||
|
||||
@@ -17,3 +17,10 @@ targets:
|
||||
- libicu52
|
||||
- libpcre3
|
||||
- git
|
||||
centos-6:
|
||||
build_dependencies:
|
||||
- libicu-devel
|
||||
dependencies:
|
||||
- libicu
|
||||
- pcre
|
||||
- git
|
||||
|
||||
@@ -3,18 +3,22 @@ env:
|
||||
global:
|
||||
- TRAVIS=true
|
||||
matrix:
|
||||
- TASK=spinach DB=mysql
|
||||
- TASK=spinach_project DB=mysql
|
||||
- TASK=spinach_other DB=mysql
|
||||
- TASK=spec:api DB=mysql
|
||||
- TASK=spec:feature DB=mysql
|
||||
- TASK=spec:other DB=mysql
|
||||
- TASK=jasmine:ci DB=mysql
|
||||
- TASK=spinach DB=postgresql
|
||||
- TASK=spinach_project DB=postgresql
|
||||
- TASK=spinach_other DB=postgresql
|
||||
- TASK=spec:api DB=postgresql
|
||||
- TASK=spec:feature DB=postgresql
|
||||
- TASK=spec:other DB=postgresql
|
||||
- TASK=jasmine:ci DB=postgresql
|
||||
before_install:
|
||||
- sudo apt-get install libicu-dev -y
|
||||
install:
|
||||
- "bundle install --deployment --without production"
|
||||
branches:
|
||||
only:
|
||||
- 'master'
|
||||
|
||||
@@ -1,3 +1,52 @@
|
||||
v 7.0.0
|
||||
- The CPU no longer overheats when you hold down the spacebar
|
||||
- Improve edit file UI
|
||||
- Add ability to upload group avatar when create
|
||||
- Protected branch cannot be removed
|
||||
- Developers can remove normal branches with UI
|
||||
- Remove branch via API (sponsored by O'Reilly Media)
|
||||
- Move protected branches page to Project settings area
|
||||
- Redirect to Files view when create new branch via UI
|
||||
- Drag and drop upload of image in every markdown-area (Earle Randolph Bunao and Neil Francis Calabroso)
|
||||
- Refactor the markdown relative links processing
|
||||
- Make it easier to implement other CI services for GitLab
|
||||
- Group masters can create projects in group
|
||||
- Deprecate ruby 1.9.3 support
|
||||
- Only masters can rewrite/remove git tags
|
||||
- Add X-Frame-Options SAMEORIGIN to Nginx config so Sidekiq admin is visible
|
||||
- UI improvements
|
||||
- Case-insensetive search for issues
|
||||
- Update to rails 4.1
|
||||
- Improve performance of application for projects and groups with a lot of members
|
||||
- Formally support Ruby 2.1
|
||||
- Include Nginx gitlab-ssl config
|
||||
- Add manual language detection for highlight.js
|
||||
- Added example.com/:username routing
|
||||
- Show notice if your profile is public
|
||||
- UI improvements for mobile devices
|
||||
- Improve diff rendering performance
|
||||
- Drag-n-drop for issues and merge requests between states at milestone page
|
||||
- Fix '0 commits' message for huge repositories on project home page
|
||||
- Prevent 500 error page when visit commit page from large repo
|
||||
- Add notice about huge push over http to unicorn config
|
||||
- File action in satellites uses default 30 seconds timeout instead of old 10 seconds one
|
||||
- Overall performance improvements
|
||||
- Skip init script check on omnibus-gitlab
|
||||
- Be more selective when killing stray Sidekiqs
|
||||
- Check LDAP user filter during sign-in
|
||||
- Remove wall feature (no data loss - you can take it from database)
|
||||
- Dont expose user emails via API unless you are admin
|
||||
- Detect issues closed by Merge Request description
|
||||
- Better email subject lines from email on push service (Alex Elman)
|
||||
- Enable identicon for gravatar be default
|
||||
|
||||
v 6.9.2
|
||||
- Revert the commit that broke the LDAP user filter
|
||||
|
||||
v 6.9.1
|
||||
- Fix scroll to highlighted line
|
||||
- Fix the pagination on load for commits page
|
||||
|
||||
v 6.9.0
|
||||
- Store Rails cache data in the Redis `cache:gitlab` namespace
|
||||
- Adjust MySQL limits for existing installations
|
||||
@@ -18,6 +67,8 @@ v 6.9.0
|
||||
- Accept merge request via API (sponsored by O'Reilly Media)
|
||||
- Add more access checks during API calls
|
||||
- Block SSH access for 'disabled' Active Directory users
|
||||
- Labels for merge requests (Drew Blessing)
|
||||
- Threaded emails by setting a Message-ID (Philip Blatter)
|
||||
|
||||
v 6.8.1
|
||||
- Bump required gitlab-shell version to 1.9.3
|
||||
|
||||
@@ -24,16 +24,11 @@ Issues and merge requests should be in English and contain appropriate language
|
||||
|
||||
To get support for your particular problem please use the channels as detailed in the [getting help section of the readme](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/README.md#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/).
|
||||
|
||||
The [issue tracker](https://gitlab.com/gitlab-org/gitlab-ce/issues) is only for obvious errors in the latest [stable or development release of GitLab](MAINTENANCE.md).
|
||||
If something is wrong but it is not a regression compared to older versions of GitLab please do not open an issue but a feature request.
|
||||
When submitting an issue please conform to the issue submission guidelines listed below.
|
||||
Not all issues will be addressed and your issue is more likely to be addressed if you submit a merge request which partially or fully addresses the issue.
|
||||
The [issue tracker](https://gitlab.com/gitlab-org/gitlab-ce/issues) is only for obvious errors in the latest [stable or development release of GitLab](MAINTENANCE.md). If something is wrong but it is not a regression compared to older versions of GitLab please do not open an issue but a feature request. When submitting an issue please conform to the issue submission guidelines listed below. Not all issues will be addressed and your issue is more likely to be addressed if you submit a merge request which partially or fully addresses the issue.
|
||||
|
||||
Issues can be filed either at [gitlab.com](https://gitlab.com/gitlab-org/gitlab-ce/issues) or [github.com](https://github.com/gitlabhq/gitlabhq/issues).
|
||||
|
||||
Do not use the issue tracker for feature requests.
|
||||
We have a specific [feature request forum](http://feedback.gitlab.com) for this purpose.
|
||||
Please keep feature requests as small and simple as possible, complex ones might be edited to make them small and simple.
|
||||
Do not use the issue tracker for feature requests. We have a specific [feature request forum](http://feedback.gitlab.com) for this purpose. Please keep feature requests as small and simple as possible, complex ones might be edited to make them small and simple.
|
||||
|
||||
Please send a merge request with a tested solution or a merge request with a failing test instead of opening an issue if you can. If you're unsure where to post, post to the [mailing list](https://groups.google.com/forum/#!forum/gitlabhq) or [Stack Overflow](http://stackoverflow.com/questions/tagged/gitlab) 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.
|
||||
|
||||
@@ -42,16 +37,16 @@ Please send a merge request with a tested solution or a merge request with a fai
|
||||
**[Search the issues](https://gitlab.com/gitlab-org/gitlab-ce/issues)** for similar entries before submitting your own, there's a good chance somebody else had the same issue. Show your support with `:+1:` and/or join the discussion. Please submit issues in the following format (as the first post):
|
||||
|
||||
1. **Summary:** Summarize your issue in one sentence (what goes wrong, what did you expect to happen)
|
||||
2. **Steps to reproduce:** How can we reproduce the issue, preferably on the [GitLab development virtual machine with vagrant](https://gitlab.com/gitlab-org/cookbook-gitlab/blob/master/doc/development.md) (start your issue with: `vagrant destroy && vagrant up && vagrant ssh`)
|
||||
3. **Expected behavior:** Describe your issue in detail
|
||||
4. **Observed behavior**
|
||||
5. **Relevant logs and/or screenshots:** Please use code blocks (\`\`\`) to format console output, logs, and code as it's very hard to read otherwise.
|
||||
6. **Output of checks**
|
||||
1. **Steps to reproduce:** How can we reproduce the issue, preferably on the [GitLab development virtual machine with vagrant](https://gitlab.com/gitlab-org/cookbook-gitlab/blob/master/doc/development.md) (start your issue with: `vagrant destroy && vagrant up && vagrant ssh`)
|
||||
1. **Expected behavior:** Describe your issue in detail
|
||||
1. **Observed behavior**
|
||||
1. **Relevant logs and/or screenshots:** Please use code blocks (\`\`\`) to format console output, logs, and code as it's very hard to read otherwise.
|
||||
1. **Output of checks**
|
||||
* Results of GitLab [Application Check](doc/install/installation.md#check-application-status) (`sudo -u git -H bundle exec rake gitlab:check RAILS_ENV=production`); we will only investigate if the tests are passing
|
||||
* Version of GitLab you are running; we will only investigate issues in the latest stable and development releases as per the [maintenance policy](MAINTENANCE.md)
|
||||
* Add the last commit sha1 of the GitLab version you used to replicate the issue (obtainable from the help page)
|
||||
* Describe your setup (use relevant parts from `sudo -u git -H bundle exec rake gitlab:env:info RAILS_ENV=production`)
|
||||
7. **Possible fixes**: If you can, link to the line of code that might be responsible for the problem
|
||||
1. **Possible fixes**: If you can, link to the line of code that might be responsible for the problem
|
||||
|
||||
## Merge requests
|
||||
|
||||
@@ -78,7 +73,7 @@ If you can, please submit a merge request with the fix or improvements including
|
||||
1. Be prepared to answer questions and incorporate feedback even if requests for this arrive weeks or months after your MR submittion
|
||||
1. If your MR touches code that executes shell commands, make sure it adheres to the [shell command guidelines]( doc/development/shell_commands.md).
|
||||
|
||||
The **official merge window** is in the beginning of the month from the 1st to the 7th day of the month. The best time to submit a MR and get feedback fast. Before this time the GitLab.com team is still dealing with work that is created by the monthly release such as assisting subscribers with upgrade issues, the release of Enterprise Edition and the upgrade of GitLab Cloud. After the 7th it is already getting closer to the release date of the next version. This means there is less time to fix the issues created by merging large new features.
|
||||
The **official merge window** is in the beginning of the month from the 1st to the 7th day of the month. The best time to submit a MR and get feedback fast. Before this time the GitLab B.V. team is still dealing with work that is created by the monthly release such as assisting subscribers with upgrade issues, the release of Enterprise Edition and the upgrade of GitLab Cloud. After the 7th it is already getting closer to the release date of the next version. This means there is less time to fix the issues created by merging large new features.
|
||||
|
||||
Please keep the change in a single MR **as small as possible**. If you want to contribute a large feature think very hard what the minimum viable change is. Can you split functionality? Can you only submit the backend/API code? Can you start with a very simple UI? The smaller a MR is the more likely it is it will be merged, after that you can send more MR's to enhance it.
|
||||
|
||||
@@ -87,10 +82,10 @@ For examples of feedback on merge requests please look at already [closed merge
|
||||
**Please format your merge request description as follows:**
|
||||
|
||||
1. What does this MR do?
|
||||
2. Are there points in the code the reviewer needs to double check?
|
||||
3. Why was this MR needed?
|
||||
4. What are the relevant issue numbers / [Feature requests](http://feedback.gitlab.com/)?
|
||||
5. Screenshots (If appropiate)
|
||||
1. Are there points in the code the reviewer needs to double check?
|
||||
1. Why was this MR needed?
|
||||
1. What are the relevant issue numbers / [Feature requests](http://feedback.gitlab.com/)?
|
||||
1. Screenshots (If appropiate)
|
||||
|
||||
## Contribution acceptance criteria
|
||||
|
||||
@@ -106,11 +101,16 @@ For examples of feedback on merge requests please look at already [closed merge
|
||||
1. It conforms to the following style guides
|
||||
|
||||
## Style guides
|
||||
1. [Ruby](https://github.com/bbatsov/ruby-style-guide)
|
||||
1. [Rails](https://github.com/bbatsov/rails-style-guide)
|
||||
1. [Formatting](https://github.com/thoughtbot/guides/tree/master/style#formatting)
|
||||
1. [Naming](https://github.com/thoughtbot/guides/tree/master/style#naming)
|
||||
1. [Testing](https://github.com/thoughtbot/guides/tree/master/style#testing)
|
||||
1. [CoffeeScript](https://github.com/thoughtbot/guides/tree/master/style#coffeescript)
|
||||
1. [Shell commands](doc/development/shell_commands.md)
|
||||
1. [Markdown](http://www.cirosantilli.com/markdown-styleguide)
|
||||
|
||||
1. [Ruby](https://github.com/bbatsov/ruby-style-guide).
|
||||
Important sections include [Source Code Layout](https://github.com/bbatsov/ruby-style-guide#source-code-layout)
|
||||
and [Naming](https://github.com/bbatsov/ruby-style-guide#naming). Use:
|
||||
- multi-line method chaining style **Option B**: dot `.` on previous line
|
||||
- string literal quoting style **Option A**: single quoted by default
|
||||
1. [Rails](https://github.com/bbatsov/rails-style-guide)
|
||||
1. [Testing](https://github.com/thoughtbot/guides/tree/master/style#testing)
|
||||
1. [CoffeeScript](https://github.com/thoughtbot/guides/tree/master/style#coffeescript)
|
||||
1. [Shell commands](doc/development/shell_commands.md) created by GitLab contributors to enhance security
|
||||
1. [Markdown](http://www.cirosantilli.com/markdown-styleguide)
|
||||
|
||||
This is also the style used by linting tools such as [Rubocop](https://github.com/bbatsov/rubocop), PullReview[https://www.pullreview.com/] and [Hound CI](https://houndci.com).
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
1.9.5
|
||||
@@ -8,11 +8,14 @@ def linux_only(require_as)
|
||||
RUBY_PLATFORM.include?('linux') && require_as
|
||||
end
|
||||
|
||||
gem "rails", "~> 4.0.0"
|
||||
gem "rails", "~> 4.1.0"
|
||||
|
||||
gem "protected_attributes"
|
||||
gem 'rails-observers'
|
||||
|
||||
# Make links from text
|
||||
gem 'rails_autolink', '~> 1.1'
|
||||
|
||||
# Default values for AR models
|
||||
gem "default_value_for", "~> 3.0.0"
|
||||
|
||||
@@ -30,7 +33,7 @@ gem 'omniauth-github'
|
||||
|
||||
# Extracting information from a git repository
|
||||
# Provide access to Gitlab::Git library
|
||||
gem "gitlab_git", '~> 5.8'
|
||||
gem "gitlab_git", '~> 6.0'
|
||||
|
||||
# Ruby/Rack Git Smart-HTTP Server Handler
|
||||
gem 'gitlab-grack', '~> 2.0.0.pre', require: 'grack'
|
||||
@@ -51,9 +54,6 @@ gem "grape", "~> 0.6.1"
|
||||
gem "grape-entity", "~> 0.4.2"
|
||||
gem 'rack-cors', require: 'rack/cors'
|
||||
|
||||
# Email validation
|
||||
gem "email_validator", "~> 1.4.0", :require => 'email_validator/strict'
|
||||
|
||||
# Format dates and times
|
||||
# based on human-friendly examples
|
||||
gem "stamp"
|
||||
@@ -70,6 +70,9 @@ gem "haml-rails"
|
||||
# Files attachments
|
||||
gem "carrierwave"
|
||||
|
||||
# Drag and Drop UI
|
||||
gem 'dropzonejs-rails'
|
||||
|
||||
# for aws storage
|
||||
gem "fog", "~> 1.14", group: :aws
|
||||
gem "unf", group: :aws
|
||||
@@ -83,6 +86,7 @@ gem "seed-fu"
|
||||
# Markdown to HTML
|
||||
gem "redcarpet", "~> 2.2.2"
|
||||
gem "github-markup"
|
||||
gem "org-ruby" # For rendering .org files
|
||||
|
||||
# Diffs
|
||||
gem 'diffy', '~> 3.0.3'
|
||||
@@ -153,6 +157,9 @@ gem "rack-attack"
|
||||
# Ace editor
|
||||
gem 'ace-rails-ap'
|
||||
|
||||
# Semantic UI Sass for Sidebar
|
||||
gem 'semantic-ui-sass', '~> 0.16.1.0'
|
||||
|
||||
gem "sass-rails", '~> 4.0.2'
|
||||
gem "coffee-rails"
|
||||
gem "uglifier"
|
||||
@@ -164,6 +171,7 @@ gem 'select2-rails'
|
||||
gem 'jquery-atwho-rails', "~> 0.3.3"
|
||||
gem "jquery-rails"
|
||||
gem "jquery-ui-rails"
|
||||
gem "jquery-scrollto-rails"
|
||||
gem "raphael-rails", "~> 2.1.2"
|
||||
gem 'bootstrap-sass', '~> 3.0'
|
||||
gem "font-awesome-rails", '~> 3.2'
|
||||
@@ -195,7 +203,7 @@ group :development, :test do
|
||||
# gem 'rails-dev-tweaks'
|
||||
gem 'spinach-rails'
|
||||
gem "rspec-rails"
|
||||
gem "capybara"
|
||||
gem "capybara", '~> 2.2.1'
|
||||
gem "pry"
|
||||
gem "awesome_print"
|
||||
gem "database_cleaner"
|
||||
@@ -203,7 +211,7 @@ group :development, :test do
|
||||
gem 'factory_girl_rails'
|
||||
|
||||
# Prevent occasions where minitest is not bundled in packaged versions of ruby (see #3826)
|
||||
gem 'minitest', '~> 4.7.0'
|
||||
gem 'minitest', '~> 5.3.0'
|
||||
|
||||
# Generate Fake data
|
||||
gem "ffaker"
|
||||
@@ -218,9 +226,9 @@ group :development, :test do
|
||||
gem 'rb-inotify', require: linux_only('rb-inotify')
|
||||
|
||||
# PhantomJS driver for Capybara
|
||||
gem 'poltergeist', '~> 1.4.1'
|
||||
gem 'poltergeist', '~> 1.5.1'
|
||||
|
||||
gem 'jasmine', '2.0.0.rc5'
|
||||
gem 'jasmine', '2.0.2'
|
||||
|
||||
gem "spring", '1.1.1'
|
||||
gem "spring-commands-rspec", '1.0.1'
|
||||
@@ -236,5 +244,5 @@ group :test do
|
||||
end
|
||||
|
||||
group :production do
|
||||
gem "gitlab_meta", '6.0'
|
||||
gem "gitlab_meta", '7.0'
|
||||
end
|
||||
|
||||
@@ -2,37 +2,39 @@ GEM
|
||||
remote: https://rubygems.org/
|
||||
specs:
|
||||
ace-rails-ap (2.0.1)
|
||||
actionmailer (4.0.5)
|
||||
actionpack (= 4.0.5)
|
||||
actionmailer (4.1.1)
|
||||
actionpack (= 4.1.1)
|
||||
actionview (= 4.1.1)
|
||||
mail (~> 2.5.4)
|
||||
actionpack (4.0.5)
|
||||
activesupport (= 4.0.5)
|
||||
builder (~> 3.1.0)
|
||||
erubis (~> 2.7.0)
|
||||
actionpack (4.1.1)
|
||||
actionview (= 4.1.1)
|
||||
activesupport (= 4.1.1)
|
||||
rack (~> 1.5.2)
|
||||
rack-test (~> 0.6.2)
|
||||
activemodel (4.0.5)
|
||||
activesupport (= 4.0.5)
|
||||
builder (~> 3.1.0)
|
||||
activerecord (4.0.5)
|
||||
activemodel (= 4.0.5)
|
||||
activerecord-deprecated_finders (~> 1.0.2)
|
||||
activesupport (= 4.0.5)
|
||||
arel (~> 4.0.0)
|
||||
activerecord-deprecated_finders (1.0.3)
|
||||
activesupport (4.0.5)
|
||||
actionview (4.1.1)
|
||||
activesupport (= 4.1.1)
|
||||
builder (~> 3.1)
|
||||
erubis (~> 2.7.0)
|
||||
activemodel (4.1.1)
|
||||
activesupport (= 4.1.1)
|
||||
builder (~> 3.1)
|
||||
activerecord (4.1.1)
|
||||
activemodel (= 4.1.1)
|
||||
activesupport (= 4.1.1)
|
||||
arel (~> 5.0.0)
|
||||
activesupport (4.1.1)
|
||||
i18n (~> 0.6, >= 0.6.9)
|
||||
minitest (~> 4.2)
|
||||
multi_json (~> 1.3)
|
||||
json (~> 1.7, >= 1.7.7)
|
||||
minitest (~> 5.1)
|
||||
thread_safe (~> 0.1)
|
||||
tzinfo (~> 0.3.37)
|
||||
tzinfo (~> 1.1)
|
||||
acts-as-taggable-on (2.4.1)
|
||||
rails (>= 3, < 5)
|
||||
addressable (2.3.5)
|
||||
annotate (2.6.0)
|
||||
activerecord (>= 2.3.0)
|
||||
rake (>= 0.8.7)
|
||||
arel (4.0.2)
|
||||
arel (5.0.1.20140414130214)
|
||||
asciidoctor (0.1.4)
|
||||
awesome_print (1.2.0)
|
||||
axiom-types (0.0.5)
|
||||
@@ -46,8 +48,8 @@ GEM
|
||||
debug_inspector (>= 0.0.1)
|
||||
bootstrap-sass (3.0.3.0)
|
||||
sass (~> 3.2)
|
||||
builder (3.1.4)
|
||||
capybara (2.1.0)
|
||||
builder (3.2.2)
|
||||
capybara (2.2.1)
|
||||
mime-types (>= 1.16)
|
||||
nokogiri (>= 1.3.3)
|
||||
rack (>= 1.0.0)
|
||||
@@ -60,7 +62,7 @@ GEM
|
||||
celluloid (0.15.2)
|
||||
timers (~> 1.1.0)
|
||||
charlock_holmes (0.6.9.4)
|
||||
cliver (0.2.2)
|
||||
cliver (0.3.2)
|
||||
code_analyzer (0.4.3)
|
||||
sexp_processor
|
||||
coderay (1.1.0)
|
||||
@@ -87,7 +89,7 @@ GEM
|
||||
d3_rails (3.1.10)
|
||||
railties (>= 3.1.0)
|
||||
daemons (1.1.9)
|
||||
database_cleaner (1.2.0)
|
||||
database_cleaner (1.3.0)
|
||||
debug_inspector (0.0.2)
|
||||
default_value_for (3.0.0)
|
||||
activerecord (>= 3.2.0, < 5.0)
|
||||
@@ -103,11 +105,11 @@ GEM
|
||||
diffy (3.0.3)
|
||||
docile (1.1.1)
|
||||
dotenv (0.9.0)
|
||||
dropzonejs-rails (0.4.14)
|
||||
rails (> 3.1)
|
||||
email_spec (1.5.0)
|
||||
launchy (~> 2.1)
|
||||
mail (~> 2.2)
|
||||
email_validator (1.4.0)
|
||||
activemodel
|
||||
emoji (1.0.1)
|
||||
json
|
||||
enumerize (0.7.0)
|
||||
@@ -162,7 +164,7 @@ GEM
|
||||
multi_json
|
||||
gitlab-grack (2.0.0.pre)
|
||||
rack (~> 1.5.1)
|
||||
gitlab-grit (2.6.7)
|
||||
gitlab-grit (2.6.9)
|
||||
charlock_holmes (~> 0.6)
|
||||
diff-lcs (~> 1.1)
|
||||
mime-types (~> 1.15)
|
||||
@@ -173,13 +175,13 @@ GEM
|
||||
mime-types (~> 1.19)
|
||||
gitlab_emoji (0.0.1.1)
|
||||
emoji (~> 1.0.1)
|
||||
gitlab_git (5.8.0)
|
||||
gitlab_git (6.0.0)
|
||||
activesupport (~> 4.0)
|
||||
charlock_holmes (~> 0.6)
|
||||
gitlab-grit (~> 2.6)
|
||||
gitlab-linguist (~> 3.0)
|
||||
rugged (~> 0.19.0)
|
||||
gitlab_meta (6.0)
|
||||
gitlab_meta (7.0)
|
||||
gitlab_omniauth-ldap (1.0.4)
|
||||
net-ldap (~> 0.3.1)
|
||||
omniauth (~> 1.0)
|
||||
@@ -221,13 +223,13 @@ GEM
|
||||
guard-spinach (0.0.2)
|
||||
guard (>= 1.1)
|
||||
spinach
|
||||
haml (4.0.4)
|
||||
haml (4.0.5)
|
||||
tilt
|
||||
haml-rails (0.5.1)
|
||||
actionpack (~> 4.0.0)
|
||||
activesupport (~> 4.0.0)
|
||||
haml-rails (0.5.3)
|
||||
actionpack (>= 4.0.1)
|
||||
activesupport (>= 4.0.1)
|
||||
haml (>= 3.1, < 5.0)
|
||||
railties (~> 4.0.0)
|
||||
railties (>= 4.0.1)
|
||||
hashie (2.0.5)
|
||||
hike (1.2.3)
|
||||
hipchat (0.14.0)
|
||||
@@ -240,16 +242,18 @@ GEM
|
||||
httpauth (0.2.0)
|
||||
i18n (0.6.9)
|
||||
ice_nine (0.10.0)
|
||||
jasmine (2.0.0.rc5)
|
||||
jasmine-core (~> 2.0.0.rc5)
|
||||
jasmine (2.0.2)
|
||||
jasmine-core (~> 2.0.0)
|
||||
phantomjs
|
||||
rack (>= 1.2.1)
|
||||
rake
|
||||
jasmine-core (2.0.0.rc5)
|
||||
jasmine-core (2.0.0)
|
||||
jquery-atwho-rails (0.3.3)
|
||||
jquery-rails (3.1.0)
|
||||
railties (>= 3.0, < 5.0)
|
||||
thor (>= 0.14, < 2.0)
|
||||
jquery-scrollto-rails (1.4.3)
|
||||
railties (> 3.1, < 5.0)
|
||||
jquery-turbolinks (2.0.1)
|
||||
railties (>= 3.1.0)
|
||||
turbolinks
|
||||
@@ -277,18 +281,18 @@ GEM
|
||||
treetop (~> 1.4.8)
|
||||
method_source (0.8.2)
|
||||
mime-types (1.25.1)
|
||||
mini_portile (0.5.3)
|
||||
minitest (4.7.5)
|
||||
multi_json (1.10.0)
|
||||
mini_portile (0.6.0)
|
||||
minitest (5.3.4)
|
||||
multi_json (1.10.1)
|
||||
multi_xml (0.5.5)
|
||||
multipart-post (1.2.0)
|
||||
mysql2 (0.3.11)
|
||||
mysql2 (0.3.16)
|
||||
net-ldap (0.3.1)
|
||||
net-scp (1.1.2)
|
||||
net-ssh (>= 2.6.5)
|
||||
net-ssh (2.8.0)
|
||||
nokogiri (1.6.1)
|
||||
mini_portile (~> 0.5.0)
|
||||
nokogiri (1.6.2.1)
|
||||
mini_portile (= 0.6.0)
|
||||
nprogress-rails (0.1.2.3)
|
||||
oauth (0.4.7)
|
||||
oauth2 (0.8.1)
|
||||
@@ -315,12 +319,14 @@ GEM
|
||||
omniauth-twitter (1.0.1)
|
||||
multi_json (~> 1.3)
|
||||
omniauth-oauth (~> 1.0)
|
||||
org-ruby (0.9.6)
|
||||
rubypants (>= 0.2.0)
|
||||
orm_adapter (0.5.0)
|
||||
pg (0.15.1)
|
||||
phantomjs (1.9.2.0)
|
||||
poltergeist (1.4.1)
|
||||
capybara (~> 2.1.0)
|
||||
cliver (~> 0.2.1)
|
||||
poltergeist (1.5.1)
|
||||
capybara (~> 2.1)
|
||||
cliver (~> 0.3.1)
|
||||
multi_json (~> 1.0)
|
||||
websocket-driver (>= 0.2.0)
|
||||
polyglot (0.3.4)
|
||||
@@ -349,16 +355,20 @@ GEM
|
||||
rack
|
||||
rack-test (0.6.2)
|
||||
rack (>= 1.0)
|
||||
rails (4.0.5)
|
||||
actionmailer (= 4.0.5)
|
||||
actionpack (= 4.0.5)
|
||||
activerecord (= 4.0.5)
|
||||
activesupport (= 4.0.5)
|
||||
rails (4.1.1)
|
||||
actionmailer (= 4.1.1)
|
||||
actionpack (= 4.1.1)
|
||||
actionview (= 4.1.1)
|
||||
activemodel (= 4.1.1)
|
||||
activerecord (= 4.1.1)
|
||||
activesupport (= 4.1.1)
|
||||
bundler (>= 1.3.0, < 2.0)
|
||||
railties (= 4.0.5)
|
||||
sprockets-rails (~> 2.0.0)
|
||||
railties (= 4.1.1)
|
||||
sprockets-rails (~> 2.0)
|
||||
rails-observers (0.1.2)
|
||||
activemodel (~> 4.0)
|
||||
rails_autolink (1.1.6)
|
||||
rails (> 3.1)
|
||||
rails_best_practices (1.14.4)
|
||||
activesupport
|
||||
awesome_print
|
||||
@@ -368,13 +378,13 @@ GEM
|
||||
i18n
|
||||
require_all
|
||||
ruby-progressbar
|
||||
railties (4.0.5)
|
||||
actionpack (= 4.0.5)
|
||||
activesupport (= 4.0.5)
|
||||
railties (4.1.1)
|
||||
actionpack (= 4.1.1)
|
||||
activesupport (= 4.1.1)
|
||||
rake (>= 0.8.7)
|
||||
thor (>= 0.18.1, < 2.0)
|
||||
raindrops (0.12.0)
|
||||
rake (10.3.1)
|
||||
rake (10.3.2)
|
||||
raphael-rails (2.1.2)
|
||||
rb-fsevent (0.9.3)
|
||||
rb-inotify (0.9.2)
|
||||
@@ -423,6 +433,7 @@ GEM
|
||||
rspec-mocks (~> 2.14.0)
|
||||
ruby-progressbar (1.2.0)
|
||||
rubyntlm (0.1.1)
|
||||
rubypants (0.2.0)
|
||||
rugged (0.19.0)
|
||||
safe_yaml (0.9.7)
|
||||
sanitize (2.1.0)
|
||||
@@ -436,11 +447,13 @@ GEM
|
||||
sdoc (0.3.20)
|
||||
json (>= 1.1.3)
|
||||
rdoc (~> 3.10)
|
||||
seed-fu (2.3.0)
|
||||
activerecord (>= 3.1, < 4.1)
|
||||
activesupport (>= 3.1, < 4.1)
|
||||
seed-fu (2.3.1)
|
||||
activerecord (>= 3.1, < 4.2)
|
||||
activesupport (>= 3.1, < 4.2)
|
||||
select2-rails (3.5.2)
|
||||
thor (~> 0.14)
|
||||
semantic-ui-sass (0.16.1.0)
|
||||
sass (~> 3.2)
|
||||
settingslogic (2.0.9)
|
||||
sexp_processor (4.4.0)
|
||||
shoulda-matchers (2.1.0)
|
||||
@@ -484,7 +497,7 @@ GEM
|
||||
multi_json (~> 1.0)
|
||||
rack (~> 1.0)
|
||||
tilt (~> 1.1, != 1.3.0)
|
||||
sprockets-rails (2.0.1)
|
||||
sprockets-rails (2.1.3)
|
||||
actionpack (>= 3.0)
|
||||
activesupport (>= 3.0)
|
||||
sprockets (~> 2.8)
|
||||
@@ -503,7 +516,7 @@ GEM
|
||||
eventmachine (>= 1.0.0)
|
||||
rack (>= 1.0.0)
|
||||
thor (0.19.1)
|
||||
thread_safe (0.3.3)
|
||||
thread_safe (0.3.4)
|
||||
tilt (1.4.1)
|
||||
timers (1.1.0)
|
||||
tinder (1.9.3)
|
||||
@@ -525,7 +538,8 @@ GEM
|
||||
eventmachine (>= 0.12.8)
|
||||
http_parser.rb (~> 0.5.1)
|
||||
simple_oauth (~> 0.1.4)
|
||||
tzinfo (0.3.39)
|
||||
tzinfo (1.2.1)
|
||||
thread_safe (~> 0.1)
|
||||
uglifier (2.3.2)
|
||||
execjs (>= 0.3.0)
|
||||
json (>= 1.8.0)
|
||||
@@ -550,7 +564,7 @@ GEM
|
||||
webmock (1.16.0)
|
||||
addressable (>= 2.2.7)
|
||||
crack (>= 0.3.2)
|
||||
websocket-driver (0.3.1)
|
||||
websocket-driver (0.3.3)
|
||||
xpath (2.0.0)
|
||||
nokogiri (~> 1.3)
|
||||
|
||||
@@ -566,7 +580,7 @@ DEPENDENCIES
|
||||
better_errors
|
||||
binding_of_caller
|
||||
bootstrap-sass (~> 3.0)
|
||||
capybara
|
||||
capybara (~> 2.2.1)
|
||||
carrierwave
|
||||
coffee-rails
|
||||
colored
|
||||
@@ -577,8 +591,8 @@ DEPENDENCIES
|
||||
devise (= 3.0.4)
|
||||
devise-async (= 0.8.0)
|
||||
diffy (~> 3.0.3)
|
||||
dropzonejs-rails
|
||||
email_spec
|
||||
email_validator (~> 1.4.0)
|
||||
enumerize
|
||||
factory_girl_rails
|
||||
ffaker
|
||||
@@ -591,8 +605,8 @@ DEPENDENCIES
|
||||
gitlab-grack (~> 2.0.0.pre)
|
||||
gitlab-linguist (~> 3.0.0)
|
||||
gitlab_emoji (~> 0.0.1.1)
|
||||
gitlab_git (~> 5.8)
|
||||
gitlab_meta (= 6.0)
|
||||
gitlab_git (~> 6.0)
|
||||
gitlab_meta (= 7.0)
|
||||
gitlab_omniauth-ldap (= 1.0.4)
|
||||
gollum-lib (~> 3.0.0)
|
||||
gon (~> 5.0.0)
|
||||
@@ -604,15 +618,16 @@ DEPENDENCIES
|
||||
haml-rails
|
||||
hipchat (~> 0.14.0)
|
||||
httparty
|
||||
jasmine (= 2.0.0.rc5)
|
||||
jasmine (= 2.0.2)
|
||||
jquery-atwho-rails (~> 0.3.3)
|
||||
jquery-rails
|
||||
jquery-scrollto-rails
|
||||
jquery-turbolinks
|
||||
jquery-ui-rails
|
||||
kaminari (~> 0.15.1)
|
||||
launchy
|
||||
letter_opener
|
||||
minitest (~> 4.7.0)
|
||||
minitest (~> 5.3.0)
|
||||
mysql2
|
||||
net-ldap
|
||||
nprogress-rails
|
||||
@@ -620,16 +635,18 @@ DEPENDENCIES
|
||||
omniauth-github
|
||||
omniauth-google-oauth2
|
||||
omniauth-twitter
|
||||
org-ruby
|
||||
pg
|
||||
poltergeist (~> 1.4.1)
|
||||
poltergeist (~> 1.5.1)
|
||||
protected_attributes
|
||||
pry
|
||||
quiet_assets (~> 1.0.1)
|
||||
rack-attack
|
||||
rack-cors
|
||||
rack-mini-profiler
|
||||
rails (~> 4.0.0)
|
||||
rails (~> 4.1.0)
|
||||
rails-observers
|
||||
rails_autolink (~> 1.1)
|
||||
rails_best_practices
|
||||
raphael-rails (~> 2.1.2)
|
||||
rb-fsevent
|
||||
@@ -642,6 +659,7 @@ DEPENDENCIES
|
||||
sdoc
|
||||
seed-fu
|
||||
select2-rails
|
||||
semantic-ui-sass (~> 0.16.1.0)
|
||||
settingslogic
|
||||
shoulda-matchers (~> 2.1.0)
|
||||
sidekiq (= 2.17.0)
|
||||
|
||||
@@ -1,24 +1,14 @@
|
||||
# GitLab Maintenance Policy
|
||||
|
||||
GitLab is a fast moving and evolving project. We currently don't have the
|
||||
resources to support many releases concurrently. We support exactly one stable
|
||||
release at any given time.
|
||||
GitLab is a fast moving and evolving project. We currently don't have the resources to support many releases concurrently. We support exactly one stable release at any given time.
|
||||
|
||||
GitLab follows the [Semantic Versioning](http://semver.org/) for its releases:
|
||||
`(Major).(Minor).(Patch)`.
|
||||
GitLab follows the [Semantic Versioning](http://semver.org/) for its releases: `(Major).(Minor).(Patch)`.
|
||||
|
||||
* **Major version**: Whenever there is something significant or any backwards
|
||||
incompatible changes are introduced to the public API.
|
||||
* **Minor version**: When new, backwards compatible functionality is introduced
|
||||
to the public API or a minor feature is introduced, or when a set of smaller
|
||||
features is rolled out.
|
||||
* **Patch number**: When backwards compatible bug fixes are introduced that fix
|
||||
incorrect behavior.
|
||||
- **Major version**: Whenever there is something significant or any backwards incompatible changes are introduced to the public API.
|
||||
- **Minor version**: When new, backwards compatible functionality is introduced to the public API or a minor feature is introduced, or when a set of smaller features is rolled out.
|
||||
- **Patch number**: When backwards compatible bug fixes are introduced that fix incorrect behavior.
|
||||
|
||||
The current stable release will receive security patches and bug fixes
|
||||
(eg. `5.0` -> `5.0.1`). Feature releases will mark the next supported stable
|
||||
release where the minor version is increased numerically by increments of one
|
||||
(eg. `5.0 -> 5.1`).
|
||||
The current stable release will receive security patches and bug fixes (eg. `5.0` -> `5.0.1`). Feature releases will mark the next supported stable release where the minor version is increased numerically by increments of one (eg. `5.0 -> 5.1`).
|
||||
|
||||
We encourage everyone to run the latest stable release to ensure that you can easily upgrade to the most secure and feature rich GitLab experience. In order to make sure you can easily run the most recent stable release, we are working hard to keep the update process simple and reliable.
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ Below we describe the contributing process to GitLab for two reasons. So that co
|
||||
- Monitors all issues for feedback (but especially ones commented on since automatically watching them)
|
||||
- Closes issues with no feedback from the reporter for two weeks
|
||||
|
||||
### Merge request officers
|
||||
### Merge marshal
|
||||
|
||||
- Responds to merge requests the issue team mentions them in and monitors for new merge requests
|
||||
- Provides feedback to the merge request submitter to improve the merge request (style, tests, etc.)
|
||||
@@ -24,9 +24,9 @@ Below we describe the contributing process to GitLab for two reasons. So that co
|
||||
## Priorities of the issue team
|
||||
|
||||
1. Mentioning people (critical)
|
||||
2. Workflow labels (normal)
|
||||
3. Functional labels (minor)
|
||||
4. Assigning issues (avoid if possible)
|
||||
1. Workflow labels (normal)
|
||||
1. Functional labels (minor)
|
||||
1. Assigning issues (avoid if possible)
|
||||
|
||||
## Mentioning people
|
||||
|
||||
@@ -36,11 +36,11 @@ The most important thing is making sure valid issues receive feedback from the d
|
||||
|
||||
Workflow labels are purposely not very detailed since that would be hard to keep updated as you would need to reevaluate them after every comment. We optionally use functional labels on demand when want to group related issues to get an overview (for example all issues related to RVM, to tackle them in one go) and to add details to the issue.
|
||||
|
||||
- _Awaiting feedback_: Feedback pending from the reporter
|
||||
- _Awaiting confirmation of fix_: The issue should already be solved in **master** (generally you can avoid this workflow item and just close the issue right away)
|
||||
- _Attached MR_: There is a MR attached and the discussion should happen there
|
||||
- We need to let issues stay in sync with the MR's. We can do this with a "Closing #XXXX" or "Fixes #XXXX" comment in the MR. We can't close the issue when there is a merge request because sometimes a MR is not good and we just close the MR, then the issue must stay.
|
||||
- _Awaiting developer action/feedback_: Issue needs to be fixed or clarified by a developer
|
||||
- *Awaiting feedback*: Feedback pending from the reporter
|
||||
- *Awaiting confirmation of fix*: The issue should already be solved in **master** (generally you can avoid this workflow item and just close the issue right away)
|
||||
- *Attached MR*: There is a MR attached and the discussion should happen there
|
||||
- We need to let issues stay in sync with the MR's. We can do this with a "Closing #XXXX" or "Fixes #XXXX" comment in the MR. We can't close the issue when there is a merge request because sometimes a MR is not good and we just close the MR, then the issue must stay.
|
||||
- *Awaiting developer action/feedback*: Issue needs to be fixed or clarified by a developer
|
||||
|
||||
## Functional labels
|
||||
|
||||
@@ -51,12 +51,13 @@ These labels describe what development specialities are involved such as: Postgr
|
||||
If an issue is complex and needs the attention of a specific person, assignment is a good option but assigning issues might discourage other people from contributing to that issue. We need all the contributions we can get so this should never be discouraged. Also, an assigned person might not have time for a few weeks, so others should feel free to takeover.
|
||||
|
||||
## Label colors
|
||||
- Light orange `#fef2c0`: workflow labels for issue team members (awaiting feedback, awaiting confirmation of fix)
|
||||
- Bright orange `#eb6420`: workflow labels for core team members (attached MR, awaiting developer action/feedback)
|
||||
- Light blue `#82C5FF`: functional labels
|
||||
- Green labels `#009800`: issues that can generally be ignored. For example, issues given the following labels normally can be closed immediately:
|
||||
- Feature request (see copy & paste response: [Feature requests](#feature-requests))
|
||||
- Support (see copy & paste response: [Support requests and configuration questions](#support-requests-and-configuration-questions)
|
||||
|
||||
- Light orange `#fef2c0`: workflow labels for issue team members (awaiting feedback, awaiting confirmation of fix)
|
||||
- Bright orange `#eb6420`: workflow labels for core team members (attached MR, awaiting developer action/feedback)
|
||||
- Light blue `#82C5FF`: functional labels
|
||||
- Green labels `#009800`: issues that can generally be ignored. For example, issues given the following labels normally can be closed immediately:
|
||||
- Feature request (see copy & paste response: [Feature requests](#feature-requests))
|
||||
- Support (see copy & paste response: [Support requests and configuration questions](#support-requests-and-configuration-questions)
|
||||
|
||||
## Be kind
|
||||
|
||||
@@ -102,8 +103,4 @@ This merge request has been closed because a request for more information has no
|
||||
|
||||
### Accepting merge requests
|
||||
|
||||
Is there a request on [the feature request forum](http://feedback.gitlab.com/forums/176466-general) that is similar to this?
|
||||
If so, can you make a comment with a link to it?
|
||||
Please be aware that new functionality that is not marked [accepting merge/pull requests](http://feedback.gitlab.com/forums/176466-general/status/796455) on the forum might not make it into GitLab.
|
||||
You might be asked to make changes and even after implementing them your feature might still be declined.
|
||||
If you want to reduce the chance of this happening please have a discussion in the forum first.
|
||||
Is there a request on [the feature request forum](http://feedback.gitlab.com/forums/176466-general) that is similar to this? If so, can you make a comment with a link to it? Please be aware that new functionality that is not marked [accepting merge/pull requests](http://feedback.gitlab.com/forums/176466-general/status/796455) on the forum might not make it into GitLab. You might be asked to make changes and even after implementing them your feature might still be declined. If you want to reduce the chance of this happening please have a discussion in the forum first.
|
||||
|
||||
@@ -1,138 +1,129 @@
|
||||
## GitLab: self hosted Git management software
|
||||
# GitLab
|
||||
|
||||
## Open source software to collaborate on code
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
### Gitlab is open source software to collaborate on code
|
||||
- Manage Git repositories with fine grained access controls that keep your code secure
|
||||
- Perform code reviews and enhance collaboration with merge requests
|
||||
- Each project can also have an issue tracker and a wiki
|
||||
- Used by more than 100,000 organizations, GitLab is the most popular solution to manage Git repositories on-premises
|
||||
- Completely free and open source (MIT Expat license)
|
||||
- Powered by Ruby on Rails
|
||||
|
||||
* Manage git repositories with fine grained access controls that keep your code secure
|
||||
* Perform code reviews and enhance collaboration with merge requests
|
||||
* Each project can also have an issue tracker and a wiki
|
||||
* Used by more than 100,000 organizations, GitLab is the most popular solution to manage git repositories on-premises
|
||||
* Completely free and open source (MIT Expat license)
|
||||
* Powered by Ruby on Rails
|
||||
## Canonical source
|
||||
|
||||
### Canonical source
|
||||
- The source of GitLab Community Edition is [hosted on GitLab.com](https://gitlab.com/gitlab-org/gitlab-ce/) and there are mirrors to make [contributing](CONTRIBUTING.md) as easy as possible.
|
||||
|
||||
* The source of GitLab Community Edition is [hosted on GitLab.com](https://gitlab.com/gitlab-org/gitlab-ce/) and there are mirrors to make [contributing](CONTRIBUTING.md) as easy as possible.
|
||||
## Code status
|
||||
|
||||
### Code status
|
||||
- [](https://ci.gitlab.org/projects/1?ref=master) on ci.gitlab.org (master branch)
|
||||
|
||||
* [](https://ci.gitlab.org/projects/1?ref=master) on ci.gitlab.org (master branch)
|
||||
- [](https://codeclimate.com/github/gitlabhq/gitlabhq)
|
||||
|
||||
* [](https://codeclimate.com/github/gitlabhq/gitlabhq)
|
||||
- [](https://coveralls.io/r/gitlabhq/gitlabhq)
|
||||
|
||||
* [](https://coveralls.io/r/gitlabhq/gitlabhq)
|
||||
- [](https://www.pullreview.com/gitlab.gitlab.com/gitlab-org/gitlab-ce/reviews/master)
|
||||
|
||||
* [](https://www.pullreview.com/gitlab.gitlab.com/gitlab-org/gitlab-ce/reviews/master)
|
||||
## Website
|
||||
|
||||
### Resources
|
||||
On [www.gitlab.com](https://www.gitlab.com/) you can find more information about:
|
||||
|
||||
* [GitLab.com](https://www.gitlab.com/) includes information about [subscriptions](https://www.gitlab.com/subscription/), [consultancy](https://www.gitlab.com/consultancy/), the [community](https://www.gitlab.com/community/) and the [hosted GitLab Cloud](https://www.gitlab.com/cloud/).
|
||||
- [Subscriptions](https://www.gitlab.com/subscription/)
|
||||
- [Consultancy](https://www.gitlab.com/consultancy/)
|
||||
- [Community](https://www.gitlab.com/community/)
|
||||
- [Hosted GitLab.com](https://www.gitlab.com/gitlab-com/) use GitLab as a free service
|
||||
- [GitLab Enterprise Edition](https://www.gitlab.com/gitlab-ee/) with additional features aimed at larger organizations.
|
||||
- [GitLab CI](https://www.gitlab.com/gitlab-ci/) a continuous integration (CI) server that is easy to integrate with GitLab.
|
||||
|
||||
* [GitLab Enterprise Edition](https://www.gitlab.com/gitlab-ee/) offers additional features aimed at larger organizations.
|
||||
## Third-party applications
|
||||
|
||||
* [GitLab CI](https://www.gitlab.com/gitlab-ci/) is a continuous integration (CI) server that is easy to integrate with GitLab.
|
||||
Access GitLab from multiple platforms with applications below.
|
||||
These applications are maintained by contributors, GitLab B.V. does not offer support for them.
|
||||
|
||||
* Unofficial third-party [iPhone app](http://gitlabcontrol.com/), [Android app](https://play.google.com/store/apps/details?id=com.bd.gitlab&hl=en) and [command line client](https://github.com/drewblessing/gitlab-cli) and [Ruby API wrapper](https://github.com/NARKOZ/gitlab) for GitLab.
|
||||
- [iPhone app](http://gitlabcontrol.com/)
|
||||
- [Android app](https://play.google.com/store/apps/details?id=com.bd.gitlab&hl=en)
|
||||
- [Chrome app](https://chrome.google.com/webstore/detail/chrome-gitlab-notifier/eageapgbnjicdjjihgclpclilenjbobi)
|
||||
- [Command line client](https://github.com/drewblessing/gitlab-cli)
|
||||
- [Ruby API wrapper](https://github.com/NARKOZ/gitlab)
|
||||
|
||||
### Requirements
|
||||
## Requirements
|
||||
|
||||
* Ubuntu/Debian/CentOS/RHEL**
|
||||
* ruby 1.9.3+
|
||||
* git 1.7.10+
|
||||
* redis 2.0+
|
||||
* MySQL or PostgreSQL
|
||||
- Ubuntu/Debian/CentOS/RHEL**
|
||||
- ruby 2.0+
|
||||
- git 1.7.10+
|
||||
- redis 2.0+
|
||||
- MySQL or PostgreSQL
|
||||
|
||||
** More details are in the [requirements doc](doc/install/requirements.md)
|
||||
** More details are in the [requirements doc](doc/install/requirements.md).
|
||||
|
||||
### Installation
|
||||
## Installation
|
||||
|
||||
#### Official installation methods
|
||||
Please see [the installation page on the GitLab website](https://www.gitlab.com/installation/).
|
||||
|
||||
* [GitLab packages](https://www.gitlab.com/downloads/) **recommended** These packages contain GitLab and all its depencies (Ruby, PostgreSQL, Redis, Nginx, Unicorn, etc.). They are made with [omnibus-gitlab](https://gitlab.com/gitlab-org/omnibus-gitlab/blob/master/README.md) that also contains the installation instructions.
|
||||
### New versions
|
||||
|
||||
* [GitLab Chef Cookbook](https://gitlab.com/gitlab-org/cookbook-gitlab/blob/master/README.md) This cookbook can be used both for development installations and production installations. If you want to [contribute](CONTRIBUTE.md) to GitLab we suggest you follow the [development installation](https://gitlab.com/gitlab-org/cookbook-gitlab/blob/master/doc/development.md) instructions to install all testing dependencies.
|
||||
Since 2011 a minor or major version of GitLab is released on the 22nd of every month. Patch and security releases come out when needed. New features are detailed on the [blog](https://www.gitlab.com/blog/) and in the [changelog](CHANGELOG). For more information about the release process see the release [documentation](https://gitlab.com/gitlab-org/gitlab-ce/tree/master/doc/release). Features that will likely be in the next releases can be found on the [feature request forum](http://feedback.gitlab.com/forums/176466-general) with the status [started](http://feedback.gitlab.com/forums/176466-general/status/796456) and [completed](http://feedback.gitlab.com/forums/176466-general/status/796457).
|
||||
|
||||
* [Manual installation guide](doc/install/installation.md) This guide to set up a production server on Ubuntu offers detailed and complete step-by-step instructions.
|
||||
### Upgrading
|
||||
|
||||
#### Third party one-click installers
|
||||
For updating the the Omnibus installation please see the [update documentation](https://gitlab.com/gitlab-org/omnibus-gitlab/blob/master/doc/update.md). For manual installations there is an [upgrader script](doc/update/upgrader.md) and there are [upgrade guides](doc/update).
|
||||
|
||||
* [Digital Ocean 1-Click Application Install](https://www.digitalocean.com/blog_posts/host-your-git-repositories-in-55-seconds-with-gitlab) Have a new server up in 55 seconds. Digital Ocean uses SSD disks which is great for an IO intensive app such as GitLab. We recommend selecting a droplet with [1GB of memory](https://github.com/gitlabhq/gitlabhq/blob/master/doc/install/requirements.md).
|
||||
|
||||
* [BitNami one-click installers](http://bitnami.com/stack/gitlab) This package contains both GitLab and GitLab CI. It is available as installer, virtual machine or for cloud hosting providers (Amazon Web Services/Azure/etc.).
|
||||
|
||||
* [Cloud 66 deployment and management](http://blog.cloud66.com/installing-gitlab-ubuntu/) Use Cloud 66 to deploy GitLab to your own server or any cloud (eg. DigitalOcean, AWS, Rackspace, GCE) and then manage it with database backups, scaling and more.
|
||||
|
||||
#### Unofficial installation methods
|
||||
|
||||
* [GitLab recipes](https://gitlab.com/gitlab-org/gitlab-recipes/) repository with unofficial guides for using GitLab with different software (operating systems, webservers, etc.) than the official version.
|
||||
|
||||
* [Installation guides](https://github.com/gitlabhq/gitlab-public-wiki/wiki/Unofficial-Installation-Guides) public wiki with unofficial guides to install GitLab on different operating systems.
|
||||
|
||||
### New versions and upgrading
|
||||
|
||||
Since 2011 GitLab is released on the 22nd of every month. Every new release includes an [upgrade guide](doc/update) and new features are detailed in the [Changelog](CHANGELOG).
|
||||
|
||||
It is recommended to follow a monthly upgrade schedule. Security releases come out when needed. For more information about the release process see the documentation for [monthly](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/doc/release/monthly.md) and [security](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/doc/release/security.md) releases.
|
||||
|
||||
* Features that will be in the next releases are listed on the [feature request forum](http://feedback.gitlab.com/forums/176466-general) with the status [started](http://feedback.gitlab.com/forums/176466-general/status/796456) and [completed](http://feedback.gitlab.com/forums/176466-general/status/796457).
|
||||
|
||||
### Run in production mode
|
||||
## Run in production mode
|
||||
|
||||
The Installation guide contains instructions on how to download an init script and run it automatically on boot. You can also start the init script manually:
|
||||
|
||||
sudo service gitlab start
|
||||
|
||||
or by directly calling the script
|
||||
or by directly calling the script:
|
||||
|
||||
sudo /etc/init.d/gitlab start
|
||||
|
||||
Please login with root / 5iveL!fe
|
||||
Please login with `root` / `5iveL!fe`.
|
||||
|
||||
### Run in development mode
|
||||
## Install a development environment
|
||||
|
||||
Consider setting up the development environment with [the cookbook](https://gitlab.com/gitlab-org/cookbook-gitlab/blob/master/README.md#installation).
|
||||
|
||||
Copy the example development unicorn configuration file
|
||||
We recommend setting up your development environment with [the cookbook](https://gitlab.com/gitlab-org/cookbook-gitlab/blob/master/README.md#installation). If you do not use the cookbook you might need to copy the example development unicorn configuration file
|
||||
|
||||
cp config/unicorn.rb.example.development config/unicorn.rb
|
||||
|
||||
## Run in development mode
|
||||
|
||||
Start it with [Foreman](https://github.com/ddollar/foreman)
|
||||
|
||||
bundle exec foreman start -p 3000
|
||||
|
||||
or start each component separately
|
||||
or start each component separately:
|
||||
|
||||
bundle exec rails s
|
||||
script/background_jobs start
|
||||
bin/background_jobs start
|
||||
|
||||
And surf to [localhost:3000](http://localhost:3000/) and login with root / 5iveL!fe
|
||||
And surf to [localhost:3000](http://localhost:3000/) and login with `root` / `5iveL!fe`.
|
||||
|
||||
### Run the tests
|
||||
## Run the tests
|
||||
|
||||
* Run all tests
|
||||
- Run all tests:
|
||||
|
||||
bundle exec rake test
|
||||
|
||||
* [RSpec](http://rspec.info/) unit and functional tests
|
||||
- [RSpec](http://rspec.info/) unit and functional tests.
|
||||
|
||||
All RSpec tests: bundle exec rake spec
|
||||
All RSpec tests: `bundle exec rake spec`
|
||||
|
||||
Single RSpec file: bundle exec rspec spec/controllers/commit_controller_spec.rb
|
||||
Single RSpec file: `bundle exec rspec spec/controllers/commit_controller_spec.rb`
|
||||
|
||||
* [Spinach](https://github.com/codegram/spinach) integration tests
|
||||
- [Spinach](https://github.com/codegram/spinach) integration tests.
|
||||
|
||||
All Spinach tests: bundle exec rake spinach
|
||||
All Spinach tests: `bundle exec rake spinach`
|
||||
|
||||
Single Spinach test: bundle exec spinach features/project/issues/milestones.feature
|
||||
Single Spinach test: `bundle exec spinach features/project/issues/milestones.feature`
|
||||
|
||||
|
||||
### Documentation
|
||||
## Documentation
|
||||
|
||||
All documentation can be found on [doc.gitlab.com/ce/](http://doc.gitlab.com/ce/).
|
||||
|
||||
### Getting help
|
||||
## Getting help
|
||||
|
||||
Please see [Getting help for GitLab](https://www.gitlab.com/getting-help/) on our website for the many options to get help.
|
||||
|
||||
|
Before Width: | Height: | Size: 737 B |
|
Before Width: | Height: | Size: 219 B |
|
Before Width: | Height: | Size: 1.6 KiB |
|
Before Width: | Height: | Size: 319 B |
|
Before Width: | Height: | Size: 536 B |
|
Before Width: | Height: | Size: 463 B |
|
Before Width: | Height: | Size: 812 B |
|
Before Width: | Height: | Size: 641 B |
@@ -13,7 +13,7 @@
|
||||
#= require jquery.history
|
||||
#= require jquery.waitforimages
|
||||
#= require jquery.atwho
|
||||
#= require jquery.scrollto
|
||||
#= require jquery.scrollTo
|
||||
#= require jquery.blockUI
|
||||
#= require turbolinks
|
||||
#= require jquery.turbolinks
|
||||
@@ -29,6 +29,8 @@
|
||||
#= require underscore
|
||||
#= require nprogress
|
||||
#= require nprogress-turbolinks
|
||||
#= require dropzone
|
||||
#= require semantic-ui/sidebar
|
||||
#= require_tree .
|
||||
|
||||
window.slugify = (text) ->
|
||||
|
||||
@@ -1,8 +1,4 @@
|
||||
$ ->
|
||||
$("body").on "click", ".js-toggler-target", ->
|
||||
container = $(@).closest(".js-toggler-container")
|
||||
container.toggleClass("on")
|
||||
|
||||
# Toggle button. Show/hide content inside parent container.
|
||||
# Button does not change visibility. If button has icon - it changes chevron style.
|
||||
#
|
||||
|
||||
@@ -26,7 +26,7 @@ class BlobView
|
||||
unless isNaN first_line
|
||||
$("#tree-content-holder .highlight .line").removeClass("hll")
|
||||
$("#LC#{line}").addClass("hll") for line in [first_line..last_line]
|
||||
$("#L#{first_line}").ScrollTo() unless e?
|
||||
$.scrollTo("#L#{first_line}") unless e?
|
||||
|
||||
# parse selected lines from hash
|
||||
# always return first and last line (initialized to NaN)
|
||||
|
||||
@@ -12,7 +12,7 @@ class CommitsList
|
||||
$('.loading').hide()
|
||||
|
||||
@init: (ref, limit) ->
|
||||
$(".day-commits-table li.commit").live 'click', (event) ->
|
||||
$("body").on "click", ".day-commits-table li.commit", (event) ->
|
||||
if event.target.nodeName != "A"
|
||||
location.href = $(this).attr("url")
|
||||
e.stopPropagation()
|
||||
|
||||
@@ -4,7 +4,7 @@ class Dashboard
|
||||
|
||||
$(".dash-filter").keyup ->
|
||||
terms = $(this).val()
|
||||
uiBox = $(this).parents('.ui-box').first()
|
||||
uiBox = $(this).parents('.panel').first()
|
||||
if terms == "" || terms == undefined
|
||||
uiBox.find(".dash-list li").show()
|
||||
else
|
||||
|
||||
@@ -21,6 +21,8 @@ class Dispatcher
|
||||
Issues.init()
|
||||
when 'projects:issues:show'
|
||||
new Issue()
|
||||
when 'projects:milestones:show'
|
||||
new Milestone()
|
||||
when 'projects:issues:new', 'projects:merge_requests:new'
|
||||
GitLab.GfmAutoComplete.setup()
|
||||
when 'dashboard:show'
|
||||
@@ -32,8 +34,6 @@ class Dispatcher
|
||||
new Activities()
|
||||
when 'projects:new', 'projects:edit'
|
||||
new Project()
|
||||
when 'projects:walls:show'
|
||||
new Wall(project_id)
|
||||
when 'projects:teams:members:index'
|
||||
new TeamMembers()
|
||||
when 'groups:members'
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
|
||||
initChecks: ->
|
||||
$(".check_all_issues").click ->
|
||||
$(".selected_issue").attr "checked", @checked
|
||||
$(".selected_issue").prop("checked", @checked)
|
||||
Issues.checkChanged()
|
||||
|
||||
$(".selected_issue").bind "change", Issues.checkChanged
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
formatLink = (str) ->
|
||||
""
|
||||
|
||||
$(document).ready ->
|
||||
alertClass = "alert alert-danger alert-dismissable div-dropzone-alert"
|
||||
alertAttr = "class=\"close\" data-dismiss=\"alert\"" + "aria-hidden=\"true\""
|
||||
divHover = "<div class=\"div-dropzone-hover\"></div>"
|
||||
divSpinner = "<div class=\"div-dropzone-spinner\"></div>"
|
||||
divAlert = "<div class=\"" + alertClass + "\"></div>"
|
||||
iconPicture = "<i class=\"icon-picture div-dropzone-icon\"></i>"
|
||||
iconSpinner = "<i class=\"icon-spinner icon-spin div-dropzone-icon\"></i>"
|
||||
btnAlert = "<button type=\"button\"" + alertAttr + ">×</button>"
|
||||
project_image_path_upload = window.project_image_path_upload or null
|
||||
|
||||
$("textarea.markdown-area").wrap "<div class=\"div-dropzone\"></div>"
|
||||
|
||||
$(".div-dropzone").parent().addClass "div-dropzone-wrapper"
|
||||
|
||||
$(".div-dropzone").append divHover
|
||||
$(".div-dropzone-hover").append iconPicture
|
||||
$(".div-dropzone").append divSpinner
|
||||
$(".div-dropzone-spinner").append iconSpinner
|
||||
|
||||
|
||||
dropzone = $(".div-dropzone").dropzone(
|
||||
url: project_image_path_upload
|
||||
dictDefaultMessage: ""
|
||||
clickable: true
|
||||
paramName: "markdown_img"
|
||||
maxFilesize: 10
|
||||
uploadMultiple: false
|
||||
acceptedFiles: "image/jpg,image/jpeg,image/gif,image/png"
|
||||
headers:
|
||||
"X-CSRF-Token": $("meta[name=\"csrf-token\"]").attr("content")
|
||||
|
||||
previewContainer: false
|
||||
|
||||
processing: ->
|
||||
$(".div-dropzone-alert").alert "close"
|
||||
|
||||
dragover: ->
|
||||
$(".div-dropzone > textarea").addClass "div-dropzone-focus"
|
||||
$(".div-dropzone-hover").css "opacity", 0.7
|
||||
return
|
||||
|
||||
dragleave: ->
|
||||
$(".div-dropzone > textarea").removeClass "div-dropzone-focus"
|
||||
$(".div-dropzone-hover").css "opacity", 0
|
||||
return
|
||||
|
||||
drop: ->
|
||||
$(".div-dropzone > textarea").removeClass "div-dropzone-focus"
|
||||
$(".div-dropzone-hover").css "opacity", 0
|
||||
$(".div-dropzone > textarea").focus()
|
||||
return
|
||||
|
||||
success: (header, response) ->
|
||||
child = $(dropzone[0]).children("textarea")
|
||||
$(child).val $(child).val() + formatLink(response.link) + "\n"
|
||||
return
|
||||
|
||||
error: (temp, errorMessage) ->
|
||||
checkIfMsgExists = $(".error-alert").children().length
|
||||
if checkIfMsgExists is 0
|
||||
$(".error-alert").append divAlert
|
||||
$(".div-dropzone-alert").append btnAlert + errorMessage
|
||||
return
|
||||
|
||||
sending: ->
|
||||
$(".div-dropzone-spinner").css "opacity", 0.7
|
||||
return
|
||||
|
||||
complete: ->
|
||||
$(".dz-preview").remove()
|
||||
$(".markdown-area").trigger "input"
|
||||
$(".div-dropzone-spinner").css "opacity", 0
|
||||
return
|
||||
)
|
||||
|
||||
$(".markdown-selector").click (e) ->
|
||||
e.preventDefault()
|
||||
$(".div-dropzone").click()
|
||||
return
|
||||
|
||||
return
|
||||
@@ -43,7 +43,7 @@ class MergeRequest
|
||||
, 'json'
|
||||
|
||||
bindEvents: ->
|
||||
this.$('.nav-tabs').on 'click', 'a', (event) =>
|
||||
this.$('.merge-request-tabs').on 'click', 'a', (event) =>
|
||||
a = $(event.currentTarget)
|
||||
|
||||
href = a.attr('href')
|
||||
@@ -51,7 +51,7 @@ class MergeRequest
|
||||
|
||||
event.preventDefault()
|
||||
|
||||
this.$('.nav-tabs').on 'click', 'li', (event) =>
|
||||
this.$('.merge-request-tabs').on 'click', 'li', (event) =>
|
||||
this.activateTab($(event.currentTarget).data('action'))
|
||||
|
||||
this.$('.accept_merge_request').on 'click', ->
|
||||
@@ -71,15 +71,15 @@ class MergeRequest
|
||||
this.$('.remove_source_branch_widget.failed').show()
|
||||
|
||||
activateTab: (action) ->
|
||||
this.$('.nav-tabs li').removeClass 'active'
|
||||
this.$('.merge-request-tabs li').removeClass 'active'
|
||||
this.$('.tab-content').hide()
|
||||
switch action
|
||||
when 'diffs'
|
||||
this.$('.nav-tabs .diffs-tab').addClass 'active'
|
||||
this.$('.merge-request-tabs .diffs-tab').addClass 'active'
|
||||
this.loadDiff() unless @diffs_loaded
|
||||
this.$('.diffs').show()
|
||||
else
|
||||
this.$('.nav-tabs .notes-tab').addClass 'active'
|
||||
this.$('.merge-request-tabs .notes-tab').addClass 'active'
|
||||
this.$('.notes').show()
|
||||
|
||||
showState: (state) ->
|
||||
@@ -107,7 +107,7 @@ class MergeRequest
|
||||
loadDiff: (event) ->
|
||||
$.ajax
|
||||
type: 'GET'
|
||||
url: this.$('.nav-tabs .diffs-tab a').attr('href')
|
||||
url: this.$('.merge-request-tabs .diffs-tab a').attr('href')
|
||||
beforeSend: =>
|
||||
this.$('.status').addClass 'loading'
|
||||
complete: =>
|
||||
|
||||
@@ -0,0 +1,119 @@
|
||||
class Milestone
|
||||
@updateIssue: (li, issue_url, data) ->
|
||||
$.ajax
|
||||
type: "PUT"
|
||||
url: issue_url
|
||||
data: data
|
||||
success: (data) ->
|
||||
if data.saved == true
|
||||
if data.assignee_avatar_url
|
||||
img_tag = $('<img/>')
|
||||
img_tag.attr('src', data.assignee_avatar_url)
|
||||
img_tag.addClass('avatar s16')
|
||||
$(li).find('.assignee-icon').html(img_tag)
|
||||
else
|
||||
$(li).find('.assignee-icon').html('')
|
||||
$(li).effect 'highlight'
|
||||
else
|
||||
new Flash("Issue update failed", 'alert')
|
||||
dataType: "json"
|
||||
|
||||
@sortIssues: (data) ->
|
||||
sort_issues_url = location.href + "/sort_issues"
|
||||
|
||||
$.ajax
|
||||
type: "PUT"
|
||||
url: sort_issues_url
|
||||
data: data
|
||||
success: (data) ->
|
||||
if data.saved != true
|
||||
new Flash("Issues update failed", 'alert')
|
||||
dataType: "json"
|
||||
|
||||
@sortMergeRequests: (data) ->
|
||||
sort_mr_url = location.href + "/sort_merge_requests"
|
||||
|
||||
$.ajax
|
||||
type: "PUT"
|
||||
url: sort_mr_url
|
||||
data: data
|
||||
success: (data) ->
|
||||
if data.saved != true
|
||||
new Flash("MR update failed", 'alert')
|
||||
dataType: "json"
|
||||
|
||||
@updateMergeRequest: (li, merge_request_url, data) ->
|
||||
$.ajax
|
||||
type: "PUT"
|
||||
url: merge_request_url
|
||||
data: data
|
||||
success: (data) ->
|
||||
if data.saved == true
|
||||
$(li).effect 'highlight'
|
||||
else
|
||||
new Flash("Issue update failed", 'alert')
|
||||
dataType: "json"
|
||||
|
||||
constructor: ->
|
||||
@bindIssuesSorting()
|
||||
@bindMergeRequestSorting()
|
||||
|
||||
bindIssuesSorting: ->
|
||||
$("#issues-list-unassigned, #issues-list-ongoing, #issues-list-closed").sortable(
|
||||
connectWith: ".issues-sortable-list",
|
||||
dropOnEmpty: true,
|
||||
items: "li:not(.ui-sort-disabled)",
|
||||
update: (event, ui) ->
|
||||
data = $(this).sortable("serialize")
|
||||
Milestone.sortIssues(data)
|
||||
|
||||
receive: (event, ui) ->
|
||||
new_state = $(this).data('state')
|
||||
issue_id = ui.item.data('iid')
|
||||
issue_url = ui.item.data('url')
|
||||
|
||||
data = switch new_state
|
||||
when 'ongoing'
|
||||
"issue[assignee_id]=" + gon.current_user_id
|
||||
when 'unassigned'
|
||||
"issue[assignee_id]="
|
||||
when 'closed'
|
||||
"issue[state_event]=close"
|
||||
|
||||
if $(ui.sender).data('state') == "closed"
|
||||
data += "&issue[state_event]=reopen"
|
||||
|
||||
Milestone.updateIssue(ui.item, issue_url, data)
|
||||
|
||||
).disableSelection()
|
||||
|
||||
bindMergeRequestSorting: ->
|
||||
$("#merge_requests-list-unassigned, #merge_requests-list-ongoing, #merge_requests-list-closed").sortable(
|
||||
connectWith: ".merge_requests-sortable-list",
|
||||
dropOnEmpty: true,
|
||||
items: "li:not(.ui-sort-disabled)",
|
||||
update: (event, ui) ->
|
||||
data = $(this).sortable("serialize")
|
||||
Milestone.sortMergeRequests(data)
|
||||
|
||||
receive: (event, ui) ->
|
||||
new_state = $(this).data('state')
|
||||
merge_request_id = ui.item.data('iid')
|
||||
merge_request_url = ui.item.data('url')
|
||||
|
||||
data = switch new_state
|
||||
when 'ongoing'
|
||||
"merge_request[assignee_id]=" + gon.current_user_id
|
||||
when 'unassigned'
|
||||
"merge_request[assignee_id]="
|
||||
when 'closed'
|
||||
"merge_request[state_event]=close"
|
||||
|
||||
if $(ui.sender).data('state') == "closed"
|
||||
data += "&merge_request[state_event]=reopen"
|
||||
|
||||
Milestone.updateMergeRequest(ui.item, merge_request_url, data)
|
||||
|
||||
).disableSelection()
|
||||
|
||||
@Milestone = Milestone
|
||||
@@ -32,6 +32,9 @@ class Notes
|
||||
# Preview button
|
||||
$(document).on "click", ".js-note-preview-button", @previewNote
|
||||
|
||||
# Preview button
|
||||
$(document).on "click", ".js-note-write-button", @writeNote
|
||||
|
||||
# reset main target form after submit
|
||||
$(document).on "ajax:complete", ".js-main-target-form", @resetMainTargetForm
|
||||
|
||||
@@ -68,6 +71,7 @@ class Notes
|
||||
$(document).off "click", ".js-note-delete"
|
||||
$(document).off "click", ".js-note-attachment-delete"
|
||||
$(document).off "click", ".js-note-preview-button"
|
||||
$(document).off "click", ".js-note-write-button"
|
||||
$(document).off "ajax:complete", ".js-main-target-form"
|
||||
$(document).off "click", ".js-choose-note-attachment-button"
|
||||
$(document).off "click", ".js-discussion-reply-button"
|
||||
@@ -144,16 +148,36 @@ class Notes
|
||||
# cleanup after successfully creating a diff/discussion note
|
||||
@removeDiscussionNoteForm(form)
|
||||
|
||||
###
|
||||
Shows write note textarea.
|
||||
###
|
||||
writeNote: (e) ->
|
||||
e.preventDefault()
|
||||
form = $(this).closest("form")
|
||||
# toggle tabs
|
||||
form.find(".js-note-write-button").parent().addClass "active"
|
||||
form.find(".js-note-preview-button").parent().removeClass "active"
|
||||
|
||||
# toggle content
|
||||
form.find(".note-write-holder").show()
|
||||
form.find(".note-preview-holder").hide()
|
||||
|
||||
###
|
||||
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: (e) ->
|
||||
e.preventDefault()
|
||||
form = $(this).closest("form")
|
||||
# toggle tabs
|
||||
form.find(".js-note-write-button").parent().removeClass "active"
|
||||
form.find(".js-note-preview-button").parent().addClass "active"
|
||||
|
||||
# toggle content
|
||||
form.find(".note-write-holder").hide()
|
||||
form.find(".note-preview-holder").show()
|
||||
|
||||
preview = form.find(".js-note-preview")
|
||||
noteText = form.find(".js-note-text").val()
|
||||
if noteText.trim().length is 0
|
||||
@@ -179,8 +203,7 @@ class Notes
|
||||
form.find(".js-errors").remove()
|
||||
|
||||
# reset text and preview
|
||||
previewContainer = form.find(".js-toggler-container.note_text_and_preview")
|
||||
previewContainer.removeClass "on" if previewContainer.is(".on")
|
||||
form.find(".js-note-write-button").click()
|
||||
form.find(".js-note-text").val("").trigger "input"
|
||||
|
||||
###
|
||||
@@ -230,7 +253,7 @@ class Notes
|
||||
form.removeClass "js-new-note-form"
|
||||
|
||||
# setup preview buttons
|
||||
form.find(".js-note-edit-button, .js-note-preview-button").tooltip placement: "left"
|
||||
form.find(".js-note-write-button, .js-note-preview-button").tooltip placement: "left"
|
||||
previewButton = form.find(".js-note-preview-button")
|
||||
form.find(".js-note-text").on "input", ->
|
||||
if $(this).val().trim() isnt ""
|
||||
|
||||
@@ -38,12 +38,8 @@
|
||||
projectUserFormatResult: (user) ->
|
||||
if user.avatar_url
|
||||
avatar = user.avatar_url
|
||||
else if gon.gravatar_enabled
|
||||
avatar = gon.gravatar_url
|
||||
avatar = avatar.replace('%{hash}', md5(user.email))
|
||||
avatar = avatar.replace('%{size}', '24')
|
||||
else
|
||||
avatar = gon.relative_url_root + "/assets/no_avatar.png"
|
||||
avatar = gon.default_avatar_url
|
||||
|
||||
if user.id == ''
|
||||
avatarMarkup = ''
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
responsive_resize = ->
|
||||
current_width = $(window).width()
|
||||
if current_width < 985
|
||||
$('.responsive-side').addClass("ui right wide sidebar")
|
||||
else
|
||||
$('.responsive-side').removeClass("ui right wide sidebar")
|
||||
|
||||
$ ->
|
||||
# Depending on window size, set the sidebar offscreen.
|
||||
responsive_resize()
|
||||
|
||||
$('.sidebar-expand-button').click ->
|
||||
$('.ui.sidebar')
|
||||
.sidebar({overlay: true})
|
||||
.sidebar('toggle')
|
||||
|
||||
# Hide sidebar on click outside of sidebar
|
||||
$(document).mouseup (e) ->
|
||||
container = $(".ui.sidebar")
|
||||
container.sidebar "hide" if not container.is(e.target) and container.has(e.target).length is 0
|
||||
return
|
||||
|
||||
# On resize, check if sidebar should be offscreen.
|
||||
$(window).resize ->
|
||||
responsive_resize()
|
||||
return
|
||||
@@ -2,12 +2,8 @@ $ ->
|
||||
userFormatResult = (user) ->
|
||||
if user.avatar_url
|
||||
avatar = user.avatar_url
|
||||
else if gon.gravatar_enabled
|
||||
avatar = gon.gravatar_url
|
||||
avatar = avatar.replace('%{hash}', md5(user.email))
|
||||
avatar = avatar.replace('%{size}', '24')
|
||||
else
|
||||
avatar = gon.relative_url_root + "/assets/no_avatar.png"
|
||||
avatar = gon.default_avatar_url
|
||||
|
||||
"<div class='user-result'>
|
||||
<div class='user-image'><img class='avatar s24' src='#{avatar}'></div>
|
||||
|
||||
@@ -1,85 +0,0 @@
|
||||
class Wall
|
||||
constructor: (project_id) ->
|
||||
@project_id = project_id
|
||||
@note_ids = []
|
||||
@getContent()
|
||||
@initRefresh()
|
||||
@initForm()
|
||||
|
||||
#
|
||||
# Gets an initial set of notes.
|
||||
#
|
||||
getContent: ->
|
||||
Api.notes @project_id, (notes) =>
|
||||
$.each notes, (i, note) =>
|
||||
# render note if it not present in loaded list
|
||||
# or skip if rendered
|
||||
if $.inArray(note.id, @note_ids) == -1
|
||||
@note_ids.push(note.id)
|
||||
@renderNote(note)
|
||||
@scrollDown()
|
||||
$("abbr.timeago").timeago()
|
||||
|
||||
initRefresh: ->
|
||||
setInterval =>
|
||||
@refresh()
|
||||
, 10000
|
||||
|
||||
refresh: ->
|
||||
@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', =>
|
||||
@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 = @noteTemplate()
|
||||
template = template.replace('{{author_name}}', note.author.name)
|
||||
template = template.replace(/{{created_at}}/g, note.created_at)
|
||||
template = template.replace('{{text}}', simpleFormat(note.body))
|
||||
|
||||
if note.attachment
|
||||
file = '<i class="icon-paper-clip"/><a href="' + gon.relative_url_root + '/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>'
|
||||
|
||||
@Wall = Wall
|
||||
@@ -10,6 +10,7 @@
|
||||
*= require_self
|
||||
*= require nprogress
|
||||
*= require nprogress-bootstrap
|
||||
*= require dropzone/basic
|
||||
*/
|
||||
|
||||
@import "main/*";
|
||||
@@ -33,6 +34,7 @@
|
||||
/**
|
||||
* Page specific styles (issues, projects etc):
|
||||
*/
|
||||
|
||||
@import "sections/*";
|
||||
|
||||
/**
|
||||
@@ -49,3 +51,8 @@
|
||||
* Styles for JS behaviors.
|
||||
*/
|
||||
@import "behaviors.scss";
|
||||
|
||||
/**
|
||||
* Styles for responsive sidebar
|
||||
*/
|
||||
@import "semantic-ui/modules/sidebar"
|
||||
|
||||
@@ -4,11 +4,3 @@
|
||||
.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; }
|
||||
|
||||
@@ -59,23 +59,21 @@
|
||||
|
||||
&.btn-primary {
|
||||
color: #ffffff;
|
||||
background-color: #429bca;
|
||||
border-color: #358ebd;
|
||||
background-color: $bg_primary;
|
||||
border-color: $border_primary;
|
||||
|
||||
&.hover,
|
||||
&:hover,
|
||||
&.disabled,
|
||||
&[disabled] {
|
||||
color: #ffffff;
|
||||
background-color: #3286b1;
|
||||
border-color: #286e8e;
|
||||
}
|
||||
}
|
||||
|
||||
&.btn-success {
|
||||
color: #ffffff;
|
||||
background-color: #5cb85c;
|
||||
border-color: #4cae4c;
|
||||
background-color: $bg_success;
|
||||
border-color: $border_success;
|
||||
|
||||
|
||||
&.hover,
|
||||
@@ -83,15 +81,27 @@
|
||||
&.disabled,
|
||||
&[disabled] {
|
||||
color: #ffffff;
|
||||
background-color: #47a447;
|
||||
border-color: #398439;
|
||||
}
|
||||
}
|
||||
|
||||
&.btn-danger {
|
||||
color: #ffffff;
|
||||
background-color: #d9534f;
|
||||
border-color: #d43f3a;
|
||||
background-color: $bg_danger;
|
||||
border-color: $border_danger;
|
||||
|
||||
|
||||
&.hover,
|
||||
&:hover,
|
||||
&.disabled,
|
||||
&[disabled] {
|
||||
color: #ffffff;
|
||||
}
|
||||
}
|
||||
|
||||
&.btn-warning {
|
||||
color: #ffffff;
|
||||
background-color: $bg_warning;
|
||||
border-color: $border_warning;
|
||||
|
||||
|
||||
&.hover,
|
||||
@@ -99,8 +109,6 @@
|
||||
&.disabled,
|
||||
&[disabled] {
|
||||
color: #ffffff;
|
||||
background-color: #d2322d;
|
||||
border-color: #ac2925;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,12 +3,7 @@
|
||||
.clgray { color: #BBB }
|
||||
.cred { color: #D12F19 }
|
||||
.cgreen { color: #4a2 }
|
||||
.cblue { color: #29A }
|
||||
.cblack { color: #111 }
|
||||
.cdark { color: #444 }
|
||||
.camber { color: #ffc000 }
|
||||
.cwhite { color: #fff!important }
|
||||
.bgred { background: #F2DEDE!important }
|
||||
|
||||
/** COMMON CLASSES **/
|
||||
.prepend-top-10 { margin-top:10px }
|
||||
@@ -60,23 +55,12 @@ pre {
|
||||
|
||||
.dropdown-menu > li > a:hover,
|
||||
.dropdown-menu > li > a:focus {
|
||||
background: #29b;
|
||||
background: $bg_style_color;
|
||||
color: #FFF
|
||||
}
|
||||
|
||||
.breadcrumb > li + li:before {
|
||||
content: "/";
|
||||
padding: 0;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.str-truncated {
|
||||
display: inline-block;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
vertical-align: top;
|
||||
white-space: nowrap;
|
||||
max-width: 82%;
|
||||
@include str-truncated;
|
||||
}
|
||||
|
||||
/** FLASH message **/
|
||||
|
||||
@@ -16,11 +16,11 @@
|
||||
text-shadow: 0 1px 1px #fff;
|
||||
margin: 0;
|
||||
text-align: left;
|
||||
padding: 9px 10px;
|
||||
padding: 10px 15px;
|
||||
|
||||
.options {
|
||||
float: right;
|
||||
margin-top: -5px;
|
||||
margin-top: -3px;
|
||||
}
|
||||
|
||||
.left-options {
|
||||
|
||||
@@ -82,6 +82,7 @@ label {
|
||||
font-family: $monospace_font;
|
||||
$left: 12px;
|
||||
.max-width-marker {
|
||||
width: 72ch;
|
||||
color: rgba(0, 0, 0, 0.0);
|
||||
font-family: inherit;
|
||||
left: $left;
|
||||
@@ -98,3 +99,7 @@ label {
|
||||
z-index: 2;
|
||||
}
|
||||
}
|
||||
|
||||
.fieldset-form fieldset {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
@@ -17,52 +17,36 @@
|
||||
&.issue-box-closed {
|
||||
border-color: $border_danger;
|
||||
.state {
|
||||
background-color: $bg_light_danger;
|
||||
background-color: $bg_danger;
|
||||
color: #FFF;
|
||||
border-color: $border_danger;
|
||||
color: $color_danger;
|
||||
.state-label {
|
||||
background-color: $bg_danger;
|
||||
color: #FFF;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.issue-box-merged {
|
||||
border-color: $border_primary;
|
||||
.state {
|
||||
background-color: $bg_light_primary;
|
||||
background-color: $bg_primary;
|
||||
color: #FFF;
|
||||
border-color: $border_primary;
|
||||
color: $color_primary;
|
||||
.state-label {
|
||||
background-color: $bg_primary;
|
||||
color: #FFF;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.issue-box-open {
|
||||
border-color: $border_success;
|
||||
.state {
|
||||
background-color: $bg_light_success;
|
||||
border-color: $border_success;
|
||||
color: $color_success;
|
||||
.state-label {
|
||||
background-color: $bg_success;
|
||||
color: #FFF;
|
||||
}
|
||||
background-color: $bg_success;
|
||||
color: #FFF;
|
||||
}
|
||||
}
|
||||
|
||||
&.issue-box-expired {
|
||||
border-color: #cea61b;
|
||||
.state {
|
||||
background-color: #fcf8e3;
|
||||
border-color: #faebcc;
|
||||
color: #8a6d3b;
|
||||
.state-label {
|
||||
background: #cea61b;
|
||||
color: #FFF;
|
||||
}
|
||||
background: #cea61b;
|
||||
color: #FFF;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -72,23 +56,22 @@
|
||||
|
||||
.state {
|
||||
border-bottom: 1px solid #DDD;
|
||||
line-height: 32px;
|
||||
padding: 10px 15px;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 22px;
|
||||
font-weight: 500;
|
||||
font-size: 28px;
|
||||
font-weight: normal;
|
||||
line-height: 1.5;
|
||||
margin: 0;
|
||||
color: #333;
|
||||
padding-bottom: 0;
|
||||
padding: 15px 25px;
|
||||
padding: 10px 15px;
|
||||
}
|
||||
|
||||
.context {
|
||||
border: none;
|
||||
border-top: 1px solid #eee;
|
||||
padding: 15px 25px;
|
||||
padding: 10px 15px;
|
||||
|
||||
// Reset text align for children
|
||||
.text-right > * { text-align: left; }
|
||||
@@ -104,7 +87,7 @@
|
||||
}
|
||||
|
||||
.description {
|
||||
padding: 0 25px 15px 25px;
|
||||
padding: 0 15px 10px 15px;
|
||||
}
|
||||
|
||||
.title, .context, .description {
|
||||
@@ -115,14 +98,15 @@
|
||||
|
||||
.state-label {
|
||||
font-size: 14px;
|
||||
padding: 1px 25px;
|
||||
text-align: center;
|
||||
text-shadow: none;
|
||||
display: inline-block;
|
||||
line-height: 34px;
|
||||
float: left;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.creator {
|
||||
padding: 2px 15px;
|
||||
float: right;
|
||||
a {
|
||||
color: #FFF;
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
list-style: none;
|
||||
|
||||
li {
|
||||
padding: 10px;
|
||||
padding: 10px 15px;
|
||||
min-height: 20px;
|
||||
border-bottom: 1px solid #eee;
|
||||
border-bottom: 1px solid rgba(0, 0, 0, 0.05);
|
||||
@@ -72,6 +72,15 @@
|
||||
font-size: 14px;
|
||||
line-height: 18px;
|
||||
}
|
||||
|
||||
.row_title {
|
||||
font-weight: 500;
|
||||
color: #444;
|
||||
&:hover {
|
||||
color: #444;
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
.div-dropzone-wrapper {
|
||||
.div-dropzone {
|
||||
position: relative;
|
||||
padding: 0;
|
||||
border: 0;
|
||||
margin-bottom: 5px;
|
||||
|
||||
.div-dropzone-focus {
|
||||
border-color: #66afe9 !important;
|
||||
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(102, 175, 233, 0.6) !important;
|
||||
outline: 0 !important;
|
||||
}
|
||||
|
||||
.div-dropzone-hover {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
margin-top: -0.5em;
|
||||
margin-left: -0.6em;
|
||||
opacity: 0;
|
||||
font-size: 50px;
|
||||
transition: opacity 200ms ease-in-out;
|
||||
}
|
||||
|
||||
.div-dropzone-spinner {
|
||||
position: absolute;
|
||||
top: 100%;
|
||||
left: 100%;
|
||||
margin-top: -1.1em;
|
||||
margin-left: -1.1em;
|
||||
opacity: 0;
|
||||
font-size: 30px;
|
||||
transition: opacity 200ms ease-in-out;
|
||||
}
|
||||
|
||||
.div-dropzone-icon {
|
||||
display: block;
|
||||
text-align: center;
|
||||
font-size: inherit;
|
||||
}
|
||||
|
||||
.dz-preview {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.div-dropzone-alert {
|
||||
margin-top: 5px;
|
||||
margin-bottom: 0;
|
||||
transition: opacity 200ms ease-in-out;
|
||||
}
|
||||
@@ -3,13 +3,29 @@
|
||||
.select2-choice {
|
||||
background: #FFF;
|
||||
border-color: #BBB;
|
||||
padding: 6px 12px;
|
||||
font-size: 13px;
|
||||
line-height: 18px;
|
||||
height: auto;
|
||||
|
||||
.select2-arrow {
|
||||
background: #FFF;
|
||||
border-left: 1px solid #DDD;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.select2-container-multi .select2-choices {
|
||||
@include border-radius(4px)
|
||||
}
|
||||
|
||||
.select2-container-multi .select2-choices .select2-search-field input {
|
||||
padding: 6px 12px;
|
||||
font-size: 13px;
|
||||
line-height: 18px;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.select2-drop-active {
|
||||
border: 1px solid #BBB !important;
|
||||
margin-top: 4px;
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
.ui.sidebar {
|
||||
z-index: 1000 !important;
|
||||
background: #fff;
|
||||
padding: 10px;
|
||||
width: 285px;
|
||||
}
|
||||
|
||||
.ui.right.sidebar {
|
||||
border-left: 1px solid #e1e1e1;
|
||||
border-right: 0;
|
||||
}
|
||||
|
||||
.sidebar-expand-button {
|
||||
cursor: pointer;
|
||||
transition: all 0.4s;
|
||||
-moz-transition: all 0.4s;
|
||||
-webkit-transition: all 0.4s;
|
||||
}
|
||||
|
||||
.fixed.sidebar-expand-button {
|
||||
background: #f9f9f9;
|
||||
color: #555;
|
||||
padding: 9px 12px 6px 14px;
|
||||
border: 1px solid #E1E1E1;
|
||||
border-right: 0;
|
||||
position: fixed;
|
||||
top: 108px;
|
||||
right: 0px;
|
||||
margin-right: 0;
|
||||
&:hover {
|
||||
background: #ddd;
|
||||
color: #333;
|
||||
padding-right: 25px;
|
||||
}
|
||||
}
|
||||
|
||||
.btn.btn-default.sidebar-expand-button {
|
||||
margin-left: 12px;
|
||||
display: inline-block !important;
|
||||
}
|
||||
|
||||
@media (min-width: 767px) {
|
||||
.btn.btn-default.sidebar-expand-button {
|
||||
display: none!important;
|
||||
}
|
||||
}
|
||||
@@ -14,6 +14,7 @@ h2.page-title {
|
||||
|
||||
h3.page-title {
|
||||
@include page-title;
|
||||
font-size: 22px;
|
||||
}
|
||||
|
||||
h6 {
|
||||
@@ -40,7 +41,7 @@ a {
|
||||
color: $link_color;
|
||||
&:hover {
|
||||
text-decoration: none;
|
||||
color: $primary_color;
|
||||
color: $link_hover_color;
|
||||
}
|
||||
|
||||
&:focus {
|
||||
|
||||
@@ -1,173 +0,0 @@
|
||||
/**
|
||||
* UI box:
|
||||
* Block element for separating information on page.
|
||||
* Used for storing issues lists, grouped data.
|
||||
* You can have multiple ui boxes on one page
|
||||
*
|
||||
* Classes:
|
||||
* .ui-box - for any block & widgets
|
||||
* .ui-box.ui-box-small - same but with smaller title
|
||||
* .ui-box.ui-box-danger - with red title
|
||||
*
|
||||
* Ex. 1: List
|
||||
* .ui-box
|
||||
* .title
|
||||
* # title here
|
||||
* %ul
|
||||
* # content here
|
||||
*
|
||||
* Ex. 2: Block data
|
||||
* .ui-box
|
||||
* .title
|
||||
* # title here
|
||||
* .body
|
||||
* # content here
|
||||
*
|
||||
*/
|
||||
|
||||
.ui-box {
|
||||
background: #FFF;
|
||||
margin-bottom: 20px;
|
||||
border: 1px solid #DDD;
|
||||
word-wrap: break-word;
|
||||
|
||||
img {
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
pre {
|
||||
code {
|
||||
background: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
ul {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.title {
|
||||
background-color: #EEE;
|
||||
border-bottom: 1px solid #DDD;
|
||||
color: #666;
|
||||
font-size: 16px;
|
||||
text-shadow: 0 1px 1px #fff;
|
||||
padding: 0 10px;
|
||||
font-size: 14px;
|
||||
line-height: 40px;
|
||||
font-weight: normal;
|
||||
margin: 0;
|
||||
|
||||
> a {
|
||||
text-shadow: 0 1px 1px #fff;
|
||||
}
|
||||
|
||||
form {
|
||||
margin-bottom: 0;
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.btn {
|
||||
vertical-align: middle;
|
||||
padding: 4px 12px;
|
||||
@include box-shadow(0 0px 1px 1px #f2f2f2);
|
||||
}
|
||||
|
||||
.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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.body {
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
&.padded {
|
||||
h5, .title {
|
||||
margin: -20px;
|
||||
margin-bottom: 0;
|
||||
padding: 5px 20px;
|
||||
}
|
||||
}
|
||||
|
||||
.row_title {
|
||||
font-weight: 500;
|
||||
color: #444;
|
||||
&:hover {
|
||||
color: #444;
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
|
||||
.form-holder {
|
||||
padding-top: 20px;
|
||||
form {
|
||||
margin-bottom: 0;
|
||||
legend {
|
||||
text-indent: 10px;
|
||||
}
|
||||
.form-actions {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Small box
|
||||
*/
|
||||
.ui-box.ui-box-small {
|
||||
margin-bottom: 10px;
|
||||
|
||||
.title {
|
||||
font-size: 13px;
|
||||
line-height: 30px;
|
||||
|
||||
a {
|
||||
color: #666;
|
||||
&:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Danger box
|
||||
*/
|
||||
.ui-box.ui-box-danger {
|
||||
background: #f7f7f7;
|
||||
border: none;
|
||||
|
||||
.title {
|
||||
background: #D65;
|
||||
color: #fff;
|
||||
text-shadow: none;
|
||||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Block under tw-bootstrap tabs
|
||||
*/
|
||||
.tab-pane {
|
||||
.ui-box {
|
||||
margin: 3px 3px 25px 3px;
|
||||
}
|
||||
}
|
||||
@@ -7,8 +7,9 @@
|
||||
*/
|
||||
|
||||
$font-size-base: 13px !default;
|
||||
$nav-pills-active-link-hover-bg: $bg_style_color;
|
||||
$pagination-active-bg: $bg_style_color;
|
||||
$nav-pills-active-link-hover-bg: $bg_primary;
|
||||
$pagination-active-bg: $bg_primary;
|
||||
$list-group-active-bg: $bg_style_color;
|
||||
|
||||
// Core variables and mixins
|
||||
@import "bootstrap/variables";
|
||||
@@ -113,8 +114,7 @@ $pagination-active-bg: $bg_style_color;
|
||||
|
||||
li {
|
||||
> a {
|
||||
padding: 8px 20px;
|
||||
margin-right: 7px;
|
||||
margin-right: 5px;
|
||||
line-height: 20px;
|
||||
border-color: #EEE;
|
||||
color: #888;
|
||||
@@ -199,20 +199,6 @@ $pagination-active-bg: $bg_style_color;
|
||||
color: #3c763d;
|
||||
}
|
||||
|
||||
// Breadcrumb
|
||||
ul.breadcrumb {
|
||||
background: white;
|
||||
border: none;
|
||||
li {
|
||||
display: inline;
|
||||
text-shadow: 0 1px 0 white
|
||||
}
|
||||
|
||||
a {
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* fix to keep tooltips position in top navigation bar
|
||||
*
|
||||
@@ -221,3 +207,108 @@ ul.breadcrumb {
|
||||
position: relative;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add some extra stuff to panels
|
||||
*
|
||||
*/
|
||||
.panel {
|
||||
@include border-radius(0px);
|
||||
|
||||
.panel-heading {
|
||||
@include border-radius(0px);
|
||||
font-size: 14px;
|
||||
line-height: 18px;
|
||||
|
||||
.panel-head-actions {
|
||||
position: relative;
|
||||
top: -7px;
|
||||
float: right;
|
||||
}
|
||||
}
|
||||
|
||||
.panel-body {
|
||||
form {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.form-actions {
|
||||
margin-bottom: 0;
|
||||
background: #FFF;
|
||||
}
|
||||
}
|
||||
|
||||
.panel-footer {
|
||||
.pagination {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
&.panel-small {
|
||||
.panel-heading {
|
||||
padding: 6px 15px;
|
||||
font-size: 13px;
|
||||
a {
|
||||
color: #777;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.panel-default {
|
||||
.panel-heading {
|
||||
background-color: #EEE;
|
||||
}
|
||||
}
|
||||
|
||||
.panel-danger {
|
||||
border-color: $border_danger;
|
||||
.panel-heading {
|
||||
color: #ffffff;
|
||||
background-color: $bg_danger;
|
||||
border-color: $border_danger;
|
||||
a {
|
||||
color: #FFF;
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.panel-success {
|
||||
border-color: $border_success;
|
||||
.panel-heading {
|
||||
color: #ffffff;
|
||||
background-color: $bg_success;
|
||||
border-color: $border_success;
|
||||
a {
|
||||
color: #FFF;
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.panel-primary {
|
||||
border-color: $border_primary;
|
||||
.panel-heading {
|
||||
color: #ffffff;
|
||||
background-color: $bg_primary;
|
||||
border-color: $border_primary;
|
||||
a {
|
||||
color: #FFF;
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.panel-warning {
|
||||
border-color: $border_warning;
|
||||
.panel-heading {
|
||||
color: #ffffff;
|
||||
background-color: $bg_warning;
|
||||
border-color: $border_warning;
|
||||
a {
|
||||
color: #FFF;
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -118,8 +118,17 @@
|
||||
|
||||
@mixin page-title {
|
||||
color: #333;
|
||||
font-size: 20px;
|
||||
line-height: 1.5;
|
||||
font-weight: normal;
|
||||
margin-top: 0px;
|
||||
margin-bottom: 15px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
@mixin str-truncated($max_width: 82%) {
|
||||
display: inline-block;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
vertical-align: top;
|
||||
white-space: nowrap;
|
||||
max-width: $max_width;
|
||||
}
|
||||
|
||||
@@ -1,37 +1,39 @@
|
||||
/**
|
||||
/*
|
||||
* General Colors
|
||||
*/
|
||||
$primary_color: #2FA0BB;
|
||||
$link_color: #3A89A3;
|
||||
$style_color: #474D57;
|
||||
$bg_style_color: #2299BB;
|
||||
$list-group-active-bg: $bg_style_color;
|
||||
$hover: #D9EDF7;
|
||||
|
||||
/*
|
||||
* Link colors
|
||||
*/
|
||||
$link_color: #446e9b;
|
||||
$link_hover_color: #2FA0BB;
|
||||
|
||||
/*
|
||||
* Success colors (green)
|
||||
*/
|
||||
$border_success: #4cae4c;
|
||||
$bg_success: #5cb85c;
|
||||
$bg_light_success: #dff0d8;
|
||||
$color_success: #3c763d;
|
||||
$border_success: #019875;
|
||||
$bg_success: #019875;
|
||||
|
||||
/*
|
||||
* Danger colors (red)
|
||||
*/
|
||||
$border_danger: #d43f3a;
|
||||
$bg_danger: #d9534f;
|
||||
$bg_light_danger: #f2dede;
|
||||
$color_danger: #a94442;
|
||||
|
||||
/*
|
||||
* Primary colors (blue)
|
||||
*/
|
||||
$border_primary: #358ebd;
|
||||
$bg_primary: #429bca;
|
||||
$bg_light_primary: #d9edf7;
|
||||
$color_primary: #31708f;
|
||||
$border_primary: #446e9b;
|
||||
$bg_primary: #446e9b;
|
||||
|
||||
/*
|
||||
* Warning colors (yellow)
|
||||
*/
|
||||
$bg_warning: #EB9532;
|
||||
$border_warning: #EB9532;
|
||||
|
||||
/**
|
||||
* Commit Diff Colors
|
||||
|
||||
@@ -21,12 +21,22 @@
|
||||
}
|
||||
|
||||
.admin-filter form {
|
||||
label { width: 110px; }
|
||||
.controls { margin-left: 130px; }
|
||||
.form-actions { padding-left: 130px; background: #fff }
|
||||
.visibility-levels {
|
||||
.controls {
|
||||
margin-bottom: 9px;
|
||||
.select2-container {
|
||||
width: 100%
|
||||
}
|
||||
|
||||
.controls {
|
||||
margin-left: 130px;
|
||||
}
|
||||
|
||||
.form-actions {
|
||||
padding-left: 130px;
|
||||
background: #fff
|
||||
}
|
||||
|
||||
.visibility-levels {
|
||||
.controls {
|
||||
margin-bottom: 9px;
|
||||
}
|
||||
|
||||
i {
|
||||
|
||||
@@ -115,10 +115,6 @@
|
||||
line-height: 2;
|
||||
}
|
||||
|
||||
.commit-breadcrumb {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.commit-info-row {
|
||||
margin-bottom: 10px;
|
||||
.avatar {
|
||||
@@ -140,8 +136,6 @@
|
||||
* COMMIT ROW
|
||||
*/
|
||||
li.commit {
|
||||
padding: 8px;
|
||||
|
||||
.commit-row-title {
|
||||
font-size: 14px;
|
||||
margin-bottom: 2px;
|
||||
@@ -212,3 +206,10 @@ li.commit {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.commits-feed-holder {
|
||||
float: right;
|
||||
.btn {
|
||||
padding: 4px 12px;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
.dashboard {
|
||||
.side {
|
||||
.ui-box {
|
||||
margin: 0px;
|
||||
box-shadow: none;
|
||||
|
||||
.nav-projects-tabs li { padding: 0; }
|
||||
.panel {
|
||||
.panel-heading {
|
||||
background: #EEE;
|
||||
border-top-left-radius: 0;
|
||||
}
|
||||
border-top-left-radius: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -24,9 +25,7 @@
|
||||
|
||||
.dashboard {
|
||||
.dash-filter {
|
||||
margin: 7px 0;
|
||||
padding: 4px 6px;
|
||||
width: 220px;
|
||||
width: 205px;
|
||||
float: left;
|
||||
height: inherit;
|
||||
}
|
||||
@@ -34,7 +33,7 @@
|
||||
|
||||
@media (max-width: 1200px) {
|
||||
.dashboard .dash-filter {
|
||||
width: 150px;
|
||||
width: 140px;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,7 +60,7 @@
|
||||
}
|
||||
|
||||
.project-row, .group-row {
|
||||
padding: 8px 12px !important;
|
||||
padding: 8px 15px !important;
|
||||
font-size: 14px;
|
||||
line-height: 24px;
|
||||
|
||||
@@ -75,10 +74,8 @@
|
||||
|
||||
.arrow {
|
||||
float: right;
|
||||
padding: 0px 5px;
|
||||
margin: 0;
|
||||
font-size: 20px;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.last-activity {
|
||||
@@ -112,6 +109,5 @@
|
||||
.dash-project-access-icon {
|
||||
float: left;
|
||||
margin-right: 3px;
|
||||
color: #999;
|
||||
width: 16px;
|
||||
}
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
|
||||
> span {
|
||||
font-family: $monospace_font;
|
||||
font-size: 14px;
|
||||
line-height: 2;
|
||||
}
|
||||
|
||||
@@ -19,9 +18,7 @@
|
||||
float: right;
|
||||
|
||||
.btn {
|
||||
background-color: #EEE;
|
||||
color: #666;
|
||||
font-weight: bolder;
|
||||
background-color: #FFF;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,6 +29,7 @@
|
||||
|
||||
.file-mode {
|
||||
font-family: $monospace_font;
|
||||
margin-left: 10px;
|
||||
}
|
||||
}
|
||||
.diff-content {
|
||||
@@ -51,6 +49,11 @@
|
||||
}
|
||||
}
|
||||
|
||||
.file-mode-changed {
|
||||
padding: 10px;
|
||||
color: #777;
|
||||
}
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
font-family: $monospace_font;
|
||||
@@ -330,3 +333,8 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.file-content .diff-file {
|
||||
margin: 0;
|
||||
border: none;
|
||||
}
|
||||
|
||||
@@ -45,6 +45,7 @@
|
||||
padding: 12px 0px;
|
||||
border-bottom: 1px solid #eee;
|
||||
.event-title {
|
||||
@include str-truncated(72%);
|
||||
color: #333;
|
||||
font-weight: normal;
|
||||
font-size: 14px;
|
||||
@@ -135,6 +136,12 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.event-item-timestamp {
|
||||
float: right;
|
||||
color: #999;
|
||||
line-height: 22px;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -166,3 +173,19 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Last push widget
|
||||
*/
|
||||
.event-last-push {
|
||||
.event-last-push-text {
|
||||
@include str-truncated(75%);
|
||||
line-height: 24px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: $screen-xs-max) {
|
||||
.event-item .event-title {
|
||||
@include str-truncated(65%);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
.project-network {
|
||||
border: 1px solid #CCC;
|
||||
|
||||
.tip {
|
||||
.controls {
|
||||
color: #888;
|
||||
font-size: 14px;
|
||||
padding: 10px;
|
||||
padding: 5px;
|
||||
border-bottom: 1px solid #bbb;
|
||||
background: #EEE;
|
||||
}
|
||||
|
||||
@@ -137,6 +137,7 @@ header {
|
||||
.profile-pic {
|
||||
position: relative;
|
||||
top: -1px;
|
||||
padding-right: 0px !important;
|
||||
img {
|
||||
width: 26px;
|
||||
height: 26px;
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
.documentation-index {
|
||||
h1 {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
li {
|
||||
line-height: 24px;
|
||||
color: #888;
|
||||
|
||||
a {
|
||||
font-size: 14px;
|
||||
margin-right: 3px;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
.issues-list {
|
||||
.issue {
|
||||
padding: 10px;
|
||||
padding: 10px 15px;
|
||||
position: relative;
|
||||
|
||||
.issue-title {
|
||||
@@ -27,7 +27,7 @@
|
||||
display: none;
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
right: 2px;
|
||||
right: 15px;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
@@ -42,7 +42,7 @@
|
||||
height: 32px;
|
||||
float: left;
|
||||
margin-right: 12px;
|
||||
padding: 6px 10px;
|
||||
padding: 6px 15px;
|
||||
border: 1px solid #ccc;
|
||||
@include border-radius(4px);
|
||||
}
|
||||
|
||||
@@ -19,12 +19,17 @@
|
||||
}
|
||||
}
|
||||
|
||||
.merge-request .nav-tabs{
|
||||
.merge-request .merge-request-tabs{
|
||||
border-bottom: 2px solid $border_primary;
|
||||
margin: 20px 0;
|
||||
|
||||
li {
|
||||
a {
|
||||
font-weight: bold;
|
||||
padding: 8px 20px;
|
||||
text-align: center;
|
||||
padding: 15px 40px;
|
||||
font-size: 14px;
|
||||
margin-bottom: -2px;
|
||||
border-bottom: 2px solid $border_primary;
|
||||
@include border-radius(0px);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -63,7 +68,7 @@
|
||||
|
||||
.mr-list {
|
||||
.merge-request {
|
||||
padding: 10px;
|
||||
padding: 10px 15px;
|
||||
position: relative;
|
||||
|
||||
.merge-request-title {
|
||||
@@ -99,12 +104,6 @@
|
||||
}
|
||||
|
||||
.mr-state-widget {
|
||||
@include border-radius(0px);
|
||||
|
||||
.panel-heading {
|
||||
@include border-radius(0px);
|
||||
}
|
||||
|
||||
.panel-body {
|
||||
h4 {
|
||||
margin-top: 0px;
|
||||
@@ -119,3 +118,7 @@
|
||||
.merge-request-show-labels .label {
|
||||
padding: 6px 10px;
|
||||
}
|
||||
|
||||
.mr-commits .commit {
|
||||
padding: 10px 15px;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
.issues-sortable-list .str-truncated {
|
||||
max-width: 70%;
|
||||
}
|
||||
@@ -64,7 +64,7 @@
|
||||
left: 50%;
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-color: transparent transparent #29b transparent;
|
||||
border-color: transparent transparent $link_color transparent;
|
||||
border-style: solid;
|
||||
border-width: 6px;
|
||||
margin-left: -6px;
|
||||
@@ -116,7 +116,7 @@
|
||||
padding: 5px 0;
|
||||
|
||||
&.active {
|
||||
background-color: $primary_color;
|
||||
background-color: $link_hover_color;
|
||||
|
||||
a {
|
||||
color: #fff;
|
||||
|
||||
@@ -37,7 +37,7 @@ ul.notes {
|
||||
font-weight: bold;
|
||||
font-size: 14px;
|
||||
&:hover {
|
||||
color: $primary_color;
|
||||
color: $link_hover_color;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -83,6 +83,7 @@ ul.notes {
|
||||
overflow: hidden;
|
||||
display: block;
|
||||
position:relative;
|
||||
border-bottom: 1px solid #eee;
|
||||
p { color: $style_color; }
|
||||
|
||||
.avatar {
|
||||
@@ -98,22 +99,16 @@ ul.notes {
|
||||
.note-header {
|
||||
padding-bottom: 3px;
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
}
|
||||
|
||||
.note:target {
|
||||
-webkit-animation:target-note 2s linear;
|
||||
background: #fffff0;
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
|
||||
.diff-file .notes_holder {
|
||||
@@ -140,10 +135,6 @@ ul.notes {
|
||||
border-width: 1px 0;
|
||||
padding-top: 0;
|
||||
vertical-align: top;
|
||||
|
||||
li {
|
||||
padding: 5px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -181,7 +172,7 @@ ul.notes {
|
||||
@extend .cgray;
|
||||
|
||||
&:hover {
|
||||
color: $primary_color;
|
||||
color: $link_hover_color;
|
||||
&.danger { @extend .cred; }
|
||||
}
|
||||
}
|
||||
@@ -271,29 +262,33 @@ ul.notes {
|
||||
.clearfix {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
.note_text_and_preview {
|
||||
// makes the "absolute" position for links relative to this
|
||||
position: relative;
|
||||
|
||||
// preview/edit buttons
|
||||
> a {
|
||||
position: absolute;
|
||||
right: 5px;
|
||||
bottom: -60px;
|
||||
.note-preview-holder,
|
||||
.note_text {
|
||||
background: #FFF;
|
||||
border: 1px solid #ddd;
|
||||
min-height: 100px;
|
||||
padding: 5px;
|
||||
font-size: 14px;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.note-preview-holder {
|
||||
> p {
|
||||
overflow-x: auto;
|
||||
}
|
||||
.note_preview {
|
||||
background: #f5f5f5;
|
||||
border: 1px solid #ddd;
|
||||
@include border-radius(4px);
|
||||
min-height: 80px;
|
||||
padding: 4px 6px;
|
||||
}
|
||||
.note_text {
|
||||
}
|
||||
|
||||
.note_text {
|
||||
width: 100%;
|
||||
}
|
||||
.nav-tabs {
|
||||
margin-bottom: 0;
|
||||
border: none;
|
||||
|
||||
li a,
|
||||
li.active a {
|
||||
border: 1px solid #DDD;
|
||||
box-shadow: none;
|
||||
font-size: 14px;
|
||||
height: 80px;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -310,19 +305,16 @@ ul.notes {
|
||||
float: none;
|
||||
}
|
||||
|
||||
|
||||
.common-note-form {
|
||||
margin: 0;
|
||||
background: #F9F9F9;
|
||||
padding: 3px;
|
||||
padding: 5px;
|
||||
border: 1px solid #DDD;
|
||||
}
|
||||
|
||||
|
||||
.note-form-actions {
|
||||
background: #F9F9F9;
|
||||
height: 45px;
|
||||
padding: 0 5px;
|
||||
|
||||
.note-form-option {
|
||||
margin-top: 8px;
|
||||
@@ -333,6 +325,18 @@ ul.notes {
|
||||
.js-notify-commit-author {
|
||||
float: left;
|
||||
}
|
||||
|
||||
.write-preview-btn {
|
||||
// makes the "absolute" position for links relative to this
|
||||
position: relative;
|
||||
|
||||
// preview/edit buttons
|
||||
> a {
|
||||
position: absolute;
|
||||
right: 5px;
|
||||
top: 8px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.note-edit-form {
|
||||
@@ -367,3 +371,8 @@ ul.notes {
|
||||
.parallel-comment {
|
||||
padding: 6px;
|
||||
}
|
||||
|
||||
.error-alert > .alert {
|
||||
margin-top: 5px;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
.global-notifications-form .level-title {
|
||||
font-size: 15px;
|
||||
color: #333;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.notification-icon-holder {
|
||||
width: 20px;
|
||||
float: left;
|
||||
}
|
||||
|
||||
.ns-part {
|
||||
color: $bg_primary;
|
||||
}
|
||||
|
||||
.ns-watch {
|
||||
color: $bg_success;
|
||||
}
|
||||
|
||||
.ns-mute {
|
||||
color: $bg_danger;
|
||||
}
|
||||
@@ -1,9 +1,3 @@
|
||||
.update-notifications {
|
||||
.radio-inline {
|
||||
margin-right: 9%;
|
||||
}
|
||||
}
|
||||
|
||||
.account-page {
|
||||
fieldset {
|
||||
margin-bottom: 15px;
|
||||
@@ -114,14 +108,3 @@
|
||||
height: 50px;
|
||||
}
|
||||
}
|
||||
|
||||
.global-notifications-form .level-title {
|
||||
font-size: 15px;
|
||||
color: #333;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.notification-icon-holder {
|
||||
width: 20px;
|
||||
float: left;
|
||||
}
|
||||
|
||||
@@ -57,7 +57,7 @@
|
||||
font-size: 17px;
|
||||
background: #f1f1f1;
|
||||
border-radius: 4px;
|
||||
color: #888;
|
||||
color: #444;
|
||||
position: absolute;
|
||||
margin-left: -55px;
|
||||
text-shadow: 0 1px 1px #FFF;
|
||||
@@ -85,7 +85,7 @@
|
||||
|
||||
.btn {
|
||||
background: none;
|
||||
color: #29b;
|
||||
color: $link_color;
|
||||
|
||||
&.active {
|
||||
color: #333;
|
||||
@@ -179,11 +179,6 @@ ul.nav.nav-projects-tabs {
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.new-tag-btn {
|
||||
position: relative;
|
||||
top: -5px;
|
||||
}
|
||||
|
||||
.public-projects .repo-info {
|
||||
color: #777;
|
||||
|
||||
@@ -232,3 +227,27 @@ ul.nav.nav-projects-tabs {
|
||||
.deploy-project-label {
|
||||
margin: 1px;
|
||||
}
|
||||
|
||||
.vs-public {
|
||||
color: $bg_primary;
|
||||
}
|
||||
|
||||
.vs-internal {
|
||||
color: $bg_warning;
|
||||
}
|
||||
|
||||
.vs-private {
|
||||
color: $bg_success;
|
||||
}
|
||||
|
||||
.breadcrumb.repo-breadcrumb {
|
||||
padding: 2px 0;
|
||||
background: white;
|
||||
border: none;
|
||||
font-size: 16px;
|
||||
|
||||
> li + li:before {
|
||||
padding: 0 3px;
|
||||
color: #999;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,3 +3,6 @@
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
.snippet-form-holder .file-holder .file-title {
|
||||
padding: 2px;
|
||||
}
|
||||
|
||||
@@ -53,10 +53,14 @@
|
||||
vertical-align: middle;
|
||||
a {
|
||||
&:hover {
|
||||
color: $primary_color;
|
||||
color: $link_hover_color;
|
||||
}
|
||||
}
|
||||
|
||||
i {
|
||||
color: $bg_primary;
|
||||
}
|
||||
|
||||
img {
|
||||
position: relative;
|
||||
top:-1px;
|
||||
@@ -109,18 +113,17 @@
|
||||
}
|
||||
}
|
||||
|
||||
.tree-btn-group {
|
||||
top: 2px;
|
||||
|
||||
.btn {
|
||||
margin-right: 0px;
|
||||
padding: 2px 10px;
|
||||
}
|
||||
.tree-download-holder .btn {
|
||||
padding: 4px 12px;
|
||||
}
|
||||
|
||||
.tree-ref-holder {
|
||||
float: left;
|
||||
margin-top: 8px;
|
||||
margin-right: 6px;
|
||||
|
||||
.select2-container .select2-choice, .select2-container.select2-drop-above .select2-choice {
|
||||
padding: 4px 12px;
|
||||
}
|
||||
}
|
||||
|
||||
.readme-holder {
|
||||
@@ -141,6 +144,8 @@
|
||||
margin-bottom: 10px;
|
||||
|
||||
.commit {
|
||||
padding: 10px 15px;
|
||||
|
||||
.commit-row-title {
|
||||
font-size: 13px;
|
||||
|
||||
|
||||
@@ -1,55 +0,0 @@
|
||||
.wall-page {
|
||||
.wall-note-form {
|
||||
@extend .col-md-12;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -16,28 +16,28 @@
|
||||
@extend .header-dark;
|
||||
&.navbar-gitlab {
|
||||
.navbar-inner {
|
||||
background: #00AC7E;
|
||||
border-bottom: 1px solid #00AC7E;
|
||||
background: #019875;
|
||||
border-bottom: 1px solid #019875;
|
||||
.app_logo, .navbar-toggle {
|
||||
&:hover {
|
||||
background-color: #009C6E;
|
||||
background-color: #018865;
|
||||
}
|
||||
}
|
||||
.separator {
|
||||
background: #009C6F;
|
||||
border-left: 1px solid #10BC8E;
|
||||
background: #018865;
|
||||
border-left: 1px solid #11A885;
|
||||
}
|
||||
.nav > li > a {
|
||||
color: #ADC;
|
||||
}
|
||||
.search-input {
|
||||
border-color: #7fd5be;
|
||||
border-color: #8ba;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.nav-pills > li.active > a, .nav-pills > li.active > a:hover, .nav-pills > li.active > a:focus {
|
||||
background: #00AC7E;
|
||||
background: #019875;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,8 @@ class Admin::GroupsController < Admin::ApplicationController
|
||||
end
|
||||
|
||||
def show
|
||||
@members = @group.members.order("group_access DESC").page(params[:members_page]).per(30)
|
||||
@projects = @group.projects.page(params[:projects_page]).per(30)
|
||||
end
|
||||
|
||||
def new
|
||||
|
||||
@@ -4,10 +4,8 @@ class Admin::ProjectsController < Admin::ApplicationController
|
||||
before_filter :repository, only: [:show, :transfer]
|
||||
|
||||
def index
|
||||
owner_id = params[:owner_id]
|
||||
user = User.find_by(id: owner_id)
|
||||
|
||||
@projects = user ? user.owned_projects : Project.all
|
||||
@projects = Project.all
|
||||
@projects = @projects.where(namespace_id: params[:namespace_id]) if params[:namespace_id].present?
|
||||
@projects = @projects.where("visibility_level IN (?)", params[:visibility_levels]) if params[:visibility_levels].present?
|
||||
@projects = @projects.with_push if params[:with_push].present?
|
||||
@projects = @projects.abandoned if params[:abandoned].present?
|
||||
@@ -17,6 +15,11 @@ class Admin::ProjectsController < Admin::ApplicationController
|
||||
end
|
||||
|
||||
def show
|
||||
if @group
|
||||
@group_members = @group.members.order("group_access DESC").page(params[:group_members_page]).per(30)
|
||||
end
|
||||
|
||||
@project_members = @project.users_projects.page(params[:project_members_page]).per(30)
|
||||
end
|
||||
|
||||
def transfer
|
||||
|
||||
@@ -8,7 +8,8 @@ class Admin::UsersController < Admin::ApplicationController
|
||||
end
|
||||
|
||||
def show
|
||||
@projects = user.authorized_projects
|
||||
@personal_projects = user.personal_projects
|
||||
@joined_projects = user.projects.joined(@user)
|
||||
end
|
||||
|
||||
def new
|
||||
|
||||
@@ -4,7 +4,6 @@ class ApplicationController < ActionController::Base
|
||||
before_filter :authenticate_user!
|
||||
before_filter :reject_blocked!
|
||||
before_filter :check_password_expiration
|
||||
around_filter :set_current_user_for_thread
|
||||
before_filter :add_abilities
|
||||
before_filter :ldap_security_check
|
||||
before_filter :dev_tools if Rails.env == 'development'
|
||||
@@ -53,15 +52,6 @@ class ApplicationController < ActionController::Base
|
||||
end
|
||||
end
|
||||
|
||||
def set_current_user_for_thread
|
||||
Thread.current[:current_user] = current_user
|
||||
begin
|
||||
yield
|
||||
ensure
|
||||
Thread.current[:current_user] = nil
|
||||
end
|
||||
end
|
||||
|
||||
def abilities
|
||||
@abilities ||= Six.new
|
||||
end
|
||||
@@ -174,10 +164,13 @@ class ApplicationController < ActionController::Base
|
||||
def add_gon_variables
|
||||
gon.default_issues_tracker = Project.issues_tracker.default_value
|
||||
gon.api_version = API::API.version
|
||||
gon.api_token = current_user.private_token if current_user
|
||||
gon.gravatar_url = request.ssl? || Gitlab.config.gitlab.https ? Gitlab.config.gravatar.ssl_url : Gitlab.config.gravatar.plain_url
|
||||
gon.relative_url_root = Gitlab.config.gitlab.relative_url_root
|
||||
gon.gravatar_enabled = Gitlab.config.gravatar.enabled
|
||||
gon.default_avatar_url = URI::join(Gitlab.config.gitlab.url, ActionController::Base.helpers.image_path('no_avatar.png')).to_s
|
||||
|
||||
if current_user
|
||||
gon.current_user_id = current_user.id
|
||||
gon.api_token = current_user.private_token
|
||||
end
|
||||
end
|
||||
|
||||
def check_password_expiration
|
||||
|
||||
@@ -14,4 +14,3 @@ class FilesController < ApplicationController
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -5,11 +5,11 @@ class GroupsController < ApplicationController
|
||||
|
||||
# Authorize
|
||||
before_filter :authorize_read_group!, except: [:new, :create]
|
||||
before_filter :authorize_admin_group!, only: [:edit, :update, :destroy]
|
||||
before_filter :authorize_admin_group!, only: [:edit, :update, :destroy, :projects]
|
||||
before_filter :authorize_create_group!, only: [:new, :create]
|
||||
|
||||
# Load group projects
|
||||
before_filter :projects, except: [:new, :create]
|
||||
before_filter :load_projects, except: [:new, :create, :projects, :edit, :update]
|
||||
|
||||
before_filter :default_filter, only: [:issues, :merge_requests]
|
||||
|
||||
@@ -81,9 +81,13 @@ class GroupsController < ApplicationController
|
||||
def edit
|
||||
end
|
||||
|
||||
def projects
|
||||
@projects = @group.projects.page(params[:page])
|
||||
end
|
||||
|
||||
def update
|
||||
if @group.update_attributes(params[:group])
|
||||
redirect_to @group, notice: 'Group was successfully updated.'
|
||||
redirect_to edit_group_path(@group), notice: 'Group was successfully updated.'
|
||||
else
|
||||
render action: "edit"
|
||||
end
|
||||
@@ -101,17 +105,17 @@ class GroupsController < ApplicationController
|
||||
@group ||= Group.find_by(path: params[:id])
|
||||
end
|
||||
|
||||
def projects
|
||||
def load_projects
|
||||
@projects ||= ProjectsFinder.new.execute(current_user, group: group).sorted_by_activity.non_archived
|
||||
end
|
||||
|
||||
def project_ids
|
||||
projects.pluck(:id)
|
||||
@projects.pluck(:id)
|
||||
end
|
||||
|
||||
# Dont allow unauthorized access to group
|
||||
def authorize_read_group!
|
||||
unless @group and (projects.present? or can?(current_user, :read_group, @group))
|
||||
unless @group and (@projects.present? or can?(current_user, :read_group, @group))
|
||||
if current_user.nil?
|
||||
return authenticate_user!
|
||||
else
|
||||
|
||||
@@ -2,12 +2,12 @@ class HelpController < ApplicationController
|
||||
def index
|
||||
end
|
||||
|
||||
def api
|
||||
def show
|
||||
@category = params[:category]
|
||||
@category = "README" if @category.blank?
|
||||
@file = params[:file]
|
||||
|
||||
if File.exists?(Rails.root.join('doc', 'api', @category + '.md'))
|
||||
render 'api'
|
||||
if File.exists?(Rails.root.join('doc', @category, @file + '.md'))
|
||||
render 'show'
|
||||
else
|
||||
not_found!
|
||||
end
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
class NamespacesController < ApplicationController
|
||||
skip_before_filter :authenticate_user!
|
||||
|
||||
def show
|
||||
namespace = Namespace.find_by(path: params[:id])
|
||||
|
||||
unless namespace
|
||||
return render_404
|
||||
end
|
||||
|
||||
if namespace.type == "Group"
|
||||
redirect_to group_path(namespace)
|
||||
else
|
||||
redirect_to user_path(namespace.owner)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -4,11 +4,12 @@ class Projects::BranchesController < Projects::ApplicationController
|
||||
before_filter :require_non_empty_project
|
||||
|
||||
before_filter :authorize_code_access!
|
||||
before_filter :authorize_push!, only: [:create]
|
||||
before_filter :authorize_admin_project!, only: [:destroy]
|
||||
before_filter :authorize_push!, only: [:create, :destroy]
|
||||
|
||||
def index
|
||||
@branches = Kaminari.paginate_array(@repository.branches).page(params[:page]).per(30)
|
||||
@sort = params[:sort] || 'name'
|
||||
@branches = @repository.branches_sorted_by(@sort)
|
||||
@branches = Kaminari.paginate_array(@branches).page(params[:page]).per(30)
|
||||
end
|
||||
|
||||
def recent
|
||||
@@ -16,21 +17,18 @@ class Projects::BranchesController < Projects::ApplicationController
|
||||
end
|
||||
|
||||
def create
|
||||
CreateBranchService.new.execute(project, params[:branch_name], params[:ref], current_user)
|
||||
@branch = CreateBranchService.new.execute(project, params[:branch_name], params[:ref], current_user)
|
||||
|
||||
redirect_to project_branches_path(@project)
|
||||
redirect_to project_tree_path(@project, @branch.name)
|
||||
end
|
||||
|
||||
def destroy
|
||||
branch = @repository.find_branch(params[:id])
|
||||
|
||||
if branch && @repository.rm_branch(branch.name)
|
||||
Event.create_ref_event(@project, current_user, branch, 'rm')
|
||||
end
|
||||
DeleteBranchService.new.execute(project, params[:id], current_user)
|
||||
@branch_name = params[:id]
|
||||
|
||||
respond_to do |format|
|
||||
format.html { redirect_to project_branches_path(@project) }
|
||||
format.js { render nothing: true }
|
||||
format.js
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -12,7 +12,12 @@ class Projects::CommitController < Projects::ApplicationController
|
||||
return git_not_found! unless @commit
|
||||
|
||||
@line_notes = project.notes.for_commit_id(commit.id).inline
|
||||
@branches = project.repository.branch_names_contains(commit.id)
|
||||
|
||||
@branches = begin
|
||||
project.repository.branch_names_contains(commit.id)
|
||||
rescue Grit::Git::GitTimeout
|
||||
[]
|
||||
end
|
||||
|
||||
begin
|
||||
@suppress_diff = true if commit.diff_suppress? && !params[:force_show_diff]
|
||||
|
||||
@@ -4,7 +4,7 @@ class Projects::GroupLinksController < Projects::ApplicationController
|
||||
|
||||
def index
|
||||
@group_links = project.project_group_links.all
|
||||
@available_groups = Group.scoped
|
||||
@available_groups = Group.all
|
||||
@available_groups -= project.invited_groups
|
||||
@available_groups -= [project.group]
|
||||
end
|
||||
|
||||
@@ -69,7 +69,9 @@ class Projects::IssuesController < Projects::ApplicationController
|
||||
render :new
|
||||
end
|
||||
end
|
||||
format.js
|
||||
format.js do |format|
|
||||
@link = @issue.attachment.url.to_js
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -85,6 +87,12 @@ class Projects::IssuesController < Projects::ApplicationController
|
||||
render :edit
|
||||
end
|
||||
end
|
||||
format.json do
|
||||
render json: {
|
||||
saved: @issue.valid?,
|
||||
assignee_avatar_url: @issue.assignee.try(:avatar_url)
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -16,6 +16,8 @@ class Projects::LabelsController < Projects::ApplicationController
|
||||
redirect_to project_issues_path(@project)
|
||||
elsif params[:redirect] == 'merge_requests'
|
||||
redirect_to project_merge_requests_path(@project)
|
||||
else
|
||||
redirect_to project_labels_path(@project)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -74,15 +74,27 @@ class Projects::MergeRequestsController < Projects::ApplicationController
|
||||
@merge_request.source_branch
|
||||
)
|
||||
|
||||
@compare_failed = false
|
||||
@commits = compare_action.commits
|
||||
@commits.map! { |commit| Commit.new(commit) }
|
||||
@commit = @commits.first
|
||||
|
||||
if @commits
|
||||
@commits.map! { |commit| Commit.new(commit) }
|
||||
@commit = @commits.first
|
||||
else
|
||||
# false value because failed to get commits from satellite
|
||||
@commits = []
|
||||
@compare_failed = true
|
||||
end
|
||||
|
||||
@diffs = compare_action.diffs
|
||||
@merge_request.title = @merge_request.source_branch.titleize.humanize
|
||||
@merge_request.description = @merge_request.target_project.merge_requests_template
|
||||
@target_project = @merge_request.target_project
|
||||
@target_repo = @target_project.repository
|
||||
|
||||
diff_line_count = Commit::diff_line_count(@diffs)
|
||||
@suppress_diff = Commit::diff_suppress?(@diffs, diff_line_count)
|
||||
@force_suppress_diff = @suppress_diff
|
||||
end
|
||||
end
|
||||
|
||||
@@ -226,7 +238,6 @@ class Projects::MergeRequestsController < Projects::ApplicationController
|
||||
@merge_request_diff = @merge_request.merge_request_diff
|
||||
@allowed_to_merge = allowed_to_merge?
|
||||
@show_merge_controls = @merge_request.open? && @commits.any? && @allowed_to_merge
|
||||
@allowed_to_remove_source_branch = allowed_to_remove_source_branch?
|
||||
@source_branch = @merge_request.source_project.repository.find_branch(@merge_request.source_branch).try(:name)
|
||||
end
|
||||
|
||||
@@ -239,11 +250,6 @@ class Projects::MergeRequestsController < Projects::ApplicationController
|
||||
render 'invalid'
|
||||
end
|
||||
|
||||
def allowed_to_remove_source_branch?
|
||||
allowed_to_push_code?(@merge_request.source_project, @merge_request.source_branch) &&
|
||||
!@merge_request.disallow_source_branch_removal?
|
||||
end
|
||||
|
||||
def allowed_to_push_code?(project, branch)
|
||||
action = if project.protected_branch?(branch)
|
||||
:push_code_to_protected_branches
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
class Projects::MilestonesController < Projects::ApplicationController
|
||||
before_filter :module_enabled
|
||||
before_filter :milestone, only: [:edit, :update, :destroy, :show]
|
||||
before_filter :milestone, only: [:edit, :update, :destroy, :show, :sort_issues, :sort_merge_requests]
|
||||
|
||||
# Allow read any milestone
|
||||
before_filter :authorize_read_milestone!
|
||||
@@ -37,7 +37,7 @@ class Projects::MilestonesController < Projects::ApplicationController
|
||||
end
|
||||
|
||||
def create
|
||||
@milestone = @project.milestones.new(params[:milestone])
|
||||
@milestone = Milestones::CreateService.new(project, current_user, params[:milestone]).execute
|
||||
|
||||
if @milestone.save
|
||||
redirect_to project_milestone_path(@project, @milestone)
|
||||
@@ -47,7 +47,7 @@ class Projects::MilestonesController < Projects::ApplicationController
|
||||
end
|
||||
|
||||
def update
|
||||
@milestone.update_attributes(params[:milestone])
|
||||
@milestone = Milestones::UpdateService.new(project, current_user, params[:milestone]).execute(milestone)
|
||||
|
||||
respond_to do |format|
|
||||
format.js
|
||||
@@ -72,6 +72,26 @@ class Projects::MilestonesController < Projects::ApplicationController
|
||||
end
|
||||
end
|
||||
|
||||
def sort_issues
|
||||
@issues = @milestone.issues.where(id: params['sortable_issue'])
|
||||
@issues.each do |issue|
|
||||
issue.position = params['sortable_issue'].index(issue.id.to_s) + 1
|
||||
issue.save
|
||||
end
|
||||
|
||||
render json: { saved: true }
|
||||
end
|
||||
|
||||
def sort_merge_requests
|
||||
@merge_requests = @milestone.merge_requests.where(id: params['sortable_merge_request'])
|
||||
@merge_requests.each do |merge_request|
|
||||
merge_request.position = params['sortable_merge_request'].index(merge_request.id.to_s) + 1
|
||||
merge_request.save
|
||||
end
|
||||
|
||||
render json: { saved: true }
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def milestone
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
class Projects::ProtectedBranchesController < Projects::ApplicationController
|
||||
# Authorize
|
||||
before_filter :authorize_read_project!
|
||||
before_filter :require_non_empty_project
|
||||
before_filter :authorize_admin_project!
|
||||
|
||||
before_filter :authorize_admin_project!, only: [:destroy, :create]
|
||||
layout "project_settings"
|
||||
|
||||
def index
|
||||
@branches = @project.protected_branches.to_a
|
||||
|
||||
@@ -31,9 +31,23 @@ class Projects::RefsController < Projects::ApplicationController
|
||||
end
|
||||
|
||||
def logs_tree
|
||||
contents = tree.entries
|
||||
@logs = contents.map do |content|
|
||||
file = params[:path] ? File.join(params[:path], content.name) : content.name
|
||||
@offset = if params[:offset].present?
|
||||
params[:offset].to_i
|
||||
else
|
||||
0
|
||||
end
|
||||
|
||||
@limit = 10
|
||||
|
||||
@path = params[:path]
|
||||
|
||||
contents = []
|
||||
contents += tree.trees
|
||||
contents += tree.blobs
|
||||
contents += tree.submodules
|
||||
|
||||
@logs = contents[@offset, @limit].to_a.map do |content|
|
||||
file = @path ? File.join(@path, content.name) : content.name
|
||||
last_commit = @repo.last_commit_for_path(@commit.id, file)
|
||||
{
|
||||
file_name: content.name,
|
||||
|
||||
@@ -13,11 +13,8 @@ class Projects::TagsController < Projects::ApplicationController
|
||||
end
|
||||
|
||||
def create
|
||||
@repository.add_tag(params[:tag_name], params[:ref])
|
||||
|
||||
if new_tag = @repository.find_tag(params[:tag_name])
|
||||
Event.create_ref_event(@project, current_user, new_tag, 'add', 'refs/tags')
|
||||
end
|
||||
@tag = CreateTagService.new.execute(@project, params[:tag_name],
|
||||
params[:ref], current_user)
|
||||
|
||||
redirect_to project_tags_path(@project)
|
||||
end
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
class Projects::WallsController < Projects::ApplicationController
|
||||
before_filter :module_enabled
|
||||
|
||||
respond_to :js, :html
|
||||
|
||||
def show
|
||||
@note = @project.notes.new
|
||||
|
||||
respond_to do |format|
|
||||
format.html
|
||||
end
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def module_enabled
|
||||
return render_404 unless @project.wall_enabled
|
||||
end
|
||||
end
|
||||
|
||||
@@ -44,7 +44,7 @@ class ProjectsController < ApplicationController
|
||||
end
|
||||
|
||||
def transfer
|
||||
::Projects::TransferService.new(project, current_user, params).execute
|
||||
::Projects::TransferService.new(project, current_user, params[:project]).execute
|
||||
end
|
||||
|
||||
def show
|
||||
@@ -162,8 +162,29 @@ class ProjectsController < ApplicationController
|
||||
end
|
||||
end
|
||||
|
||||
def upload_image
|
||||
link_to_image = ::Projects::ImageService.new(repository, params, root_url).execute
|
||||
|
||||
respond_to do |format|
|
||||
if link_to_image
|
||||
format.json { render json: { link: link_to_image } }
|
||||
else
|
||||
format.json { render json: "Invalid file.", status: :unprocessable_entity }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def upload_path
|
||||
base_dir = FileUploader.generate_dir
|
||||
File.join(repository.path_with_namespace, base_dir)
|
||||
end
|
||||
|
||||
def accepted_images
|
||||
%w(png jpg jpeg gif)
|
||||
end
|
||||
|
||||
def set_title
|
||||
@title = 'New Project'
|
||||
end
|
||||
@@ -190,6 +211,6 @@ class ProjectsController < ApplicationController
|
||||
end
|
||||
|
||||
def sorted(users)
|
||||
users.uniq.sort_by(&:username).map { |user| { username: user.username, name: user.name } }
|
||||
users.uniq.to_a.compact.sort_by(&:username).map { |user| { username: user.username, name: user.name } }
|
||||
end
|
||||
end
|
||||
|
||||
@@ -14,7 +14,7 @@ class SnippetsController < ApplicationController
|
||||
layout 'navless'
|
||||
|
||||
def index
|
||||
@snippets = Snippet.public.fresh.non_expired.page(params[:page]).per(20)
|
||||
@snippets = Snippet.are_public.fresh.non_expired.page(params[:page]).per(20)
|
||||
end
|
||||
|
||||
def user_index
|
||||
@@ -26,15 +26,15 @@ class SnippetsController < ApplicationController
|
||||
|
||||
if @user == current_user
|
||||
@snippets = case params[:scope]
|
||||
when 'public' then
|
||||
@snippets.public
|
||||
when 'private' then
|
||||
@snippets.private
|
||||
when 'are_public' then
|
||||
@snippets.are_public
|
||||
when 'are_private' then
|
||||
@snippets.are_private
|
||||
else
|
||||
@snippets
|
||||
end
|
||||
else
|
||||
@snippets = @snippets.public
|
||||
@snippets = @snippets.are_public
|
||||
end
|
||||
|
||||
@snippets = @snippets.page(params[:page]).per(20)
|
||||
|
||||
@@ -4,12 +4,24 @@ class UsersController < ApplicationController
|
||||
|
||||
def show
|
||||
@user = User.find_by_username!(params[:username])
|
||||
@projects = @user.authorized_projects.accessible_to(current_user)
|
||||
if !current_user && @projects.empty?
|
||||
|
||||
unless current_user || @user.public_profile?
|
||||
return authenticate_user!
|
||||
end
|
||||
@groups = @user.groups.accessible_to(current_user)
|
||||
@events = @user.recent_events.where(project_id: @projects.pluck(:id)).limit(20)
|
||||
|
||||
# Projects user can view
|
||||
authorized_projects_ids = ProjectsFinder.new.execute(current_user).pluck(:id)
|
||||
|
||||
@projects = @user.personal_projects.
|
||||
where(id: authorized_projects_ids)
|
||||
|
||||
# Collect only groups common for both users
|
||||
@groups = @user.groups & GroupsFinder.new.execute(current_user)
|
||||
|
||||
# Get user activity feed for projects common for both users
|
||||
@events = @user.recent_events.
|
||||
where(project_id: authorized_projects_ids).limit(20)
|
||||
|
||||
@title = @user.name
|
||||
end
|
||||
|
||||
|
||||
@@ -49,7 +49,7 @@ class BaseFinder
|
||||
elsif current_user && params[:authorized_only].presence
|
||||
klass.of_projects(current_user.authorized_projects).references(:project)
|
||||
else
|
||||
klass.of_projects(Project.accessible_to(current_user)).references(:project)
|
||||
klass.of_projects(ProjectsFinder.new.execute(current_user)).references(:project)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
class GroupsFinder
|
||||
def execute(current_user, options = {})
|
||||
all_groups(current_user)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def all_groups(current_user)
|
||||
if current_user
|
||||
if current_user.authorized_groups.any?
|
||||
# User has access to groups
|
||||
#
|
||||
# Return only:
|
||||
# groups with public projects
|
||||
# groups with internal projects
|
||||
# groups with joined projects
|
||||
#
|
||||
group_ids = Project.public_and_internal_only.pluck(:namespace_id) +
|
||||
current_user.authorized_groups.pluck(:id)
|
||||
Group.where(id: group_ids)
|
||||
else
|
||||
# User has no group membership
|
||||
#
|
||||
# Return only:
|
||||
# groups with public projects
|
||||
# groups with internal projects
|
||||
#
|
||||
Group.where(id: Project.public_and_internal_only.pluck(:namespace_id))
|
||||
end
|
||||
else
|
||||
# Not authenticated
|
||||
#
|
||||
# Return only:
|
||||
# groups with public projects
|
||||
Group.where(id: Project.public_only.pluck(:namespace_id))
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,5 +1,5 @@
|
||||
class ProjectsFinder
|
||||
def execute(current_user, options)
|
||||
def execute(current_user, options = {})
|
||||
group = options[:group]
|
||||
|
||||
if group
|
||||
@@ -56,8 +56,36 @@ class ProjectsFinder
|
||||
end
|
||||
end
|
||||
|
||||
def all_projects
|
||||
# TODO: implement
|
||||
raise 'Not implemented yet'
|
||||
def all_projects(current_user)
|
||||
if current_user
|
||||
if current_user.authorized_projects.any?
|
||||
# User has access to private projects
|
||||
#
|
||||
# Return only:
|
||||
# public projects
|
||||
# internal projects
|
||||
# joined projects
|
||||
#
|
||||
Project.where(
|
||||
"projects.id IN (?) OR projects.visibility_level IN (?)",
|
||||
current_user.authorized_projects.pluck(:id),
|
||||
Project.public_and_internal_levels
|
||||
)
|
||||
else
|
||||
# User has no access to private projects
|
||||
#
|
||||
# Return only:
|
||||
# public projects
|
||||
# internal projects
|
||||
#
|
||||
Project.public_and_internal_only
|
||||
end
|
||||
else
|
||||
# Not authenticated
|
||||
#
|
||||
# Return only:
|
||||
# public projects
|
||||
Project.public_only
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -60,23 +60,21 @@ module ApplicationHelper
|
||||
|
||||
def avatar_icon(user_email = '', size = nil)
|
||||
user = User.find_by(email: user_email)
|
||||
if user && user.avatar.present?
|
||||
user.avatar.url
|
||||
|
||||
if user
|
||||
user.avatar_url(size) || default_avatar
|
||||
else
|
||||
gravatar_icon(user_email, size)
|
||||
end
|
||||
end
|
||||
|
||||
def gravatar_icon(user_email = '', size = nil)
|
||||
size = 40 if size.nil? || size <= 0
|
||||
GravatarService.new.execute(user_email, size) ||
|
||||
default_avatar
|
||||
end
|
||||
|
||||
if !Gitlab.config.gravatar.enabled || user_email.blank?
|
||||
'/assets/no_avatar.png'
|
||||
else
|
||||
gravatar_url = request.ssl? || gitlab_config.https ? Gitlab.config.gravatar.ssl_url : Gitlab.config.gravatar.plain_url
|
||||
user_email.strip!
|
||||
sprintf gravatar_url, hash: Digest::MD5.hexdigest(user_email.downcase), size: size, email: user_email
|
||||
end
|
||||
def default_avatar
|
||||
image_path('no_avatar.png')
|
||||
end
|
||||
|
||||
def last_commit(project)
|
||||
@@ -226,8 +224,11 @@ module ApplicationHelper
|
||||
GitHub::Markup.render(file_name, file_content).html_safe
|
||||
end
|
||||
|
||||
def spinner(text = nil)
|
||||
content_tag :div, class: 'loading hide' do
|
||||
def spinner(text = nil, visible = false)
|
||||
css_class = "loading"
|
||||
css_class << " hide" unless visible
|
||||
|
||||
content_tag :div, class: css_class do
|
||||
content_tag(:i, nil, class: 'icon-spinner icon-spin') + text
|
||||
end
|
||||
end
|
||||
@@ -235,4 +236,31 @@ module ApplicationHelper
|
||||
def ldap_enabled?
|
||||
Gitlab.config.ldap.enabled
|
||||
end
|
||||
|
||||
def link_to(name = nil, options = nil, html_options = nil, &block)
|
||||
begin
|
||||
uri = URI(options)
|
||||
host = uri.host
|
||||
absolute_uri = uri.absolute?
|
||||
rescue URI::InvalidURIError, ArgumentError
|
||||
host = nil
|
||||
absolute_uri = nil
|
||||
end
|
||||
|
||||
# Add "nofollow" only to external links
|
||||
if host && host != Gitlab.config.gitlab.host && absolute_uri
|
||||
if html_options
|
||||
if html_options[:rel]
|
||||
html_options[:rel] << " nofollow"
|
||||
else
|
||||
html_options.merge!(rel: "nofollow")
|
||||
end
|
||||
else
|
||||
html_options = Hash.new
|
||||
html_options[:rel] = "nofollow"
|
||||
end
|
||||
end
|
||||
|
||||
super
|
||||
end
|
||||
end
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
module BlobHelper
|
||||
def highlightjs_class(blob_name)
|
||||
if blob_name.include?('.')
|
||||
ext = blob_name.split('.').last
|
||||
return 'language-' + ext
|
||||
else
|
||||
if no_highlight_files.include?(blob_name.downcase)
|
||||
'no-highlight'
|
||||
else
|
||||
blob_name.downcase
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def no_highlight_files
|
||||
%w(credits changelog copying copyright license authors)
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,22 @@
|
||||
module BranchesHelper
|
||||
def can_remove_branch?(project, branch_name)
|
||||
if project.protected_branch? branch_name
|
||||
false
|
||||
elsif branch_name == project.repository.root_ref
|
||||
false
|
||||
else
|
||||
can?(current_user, :push_code, project)
|
||||
end
|
||||
end
|
||||
|
||||
def can_push_branch?(project, branch_name)
|
||||
return false unless project.repository.branch_names.include?(branch_name)
|
||||
action = if project.protected_branch?(branch_name)
|
||||
:push_code_to_protected_branches
|
||||
else
|
||||
:push_code
|
||||
end
|
||||
|
||||
current_user.can?(action, project)
|
||||
end
|
||||
end
|
||||
@@ -76,15 +76,13 @@ module CommitsHelper
|
||||
|
||||
# Add the root project link and the arrow icon
|
||||
crumbs = content_tag(:li) do
|
||||
content_tag(:span, nil, class: 'arrow') +
|
||||
link_to(@project.name, project_commits_path(@project, @ref))
|
||||
link_to(@project.path, project_commits_path(@project, @ref))
|
||||
end
|
||||
|
||||
if @path
|
||||
parts = @path.split('/')
|
||||
|
||||
parts.each_with_index do |part, i|
|
||||
crumbs += content_tag(:span, ' / ', class: 'divider')
|
||||
crumbs += content_tag(:li) do
|
||||
# The text is just the individual part, but the link needs all the parts before it
|
||||
link_to part, project_commits_path(@project, tree_join(@ref, parts[0..i].join('/')))
|
||||
@@ -195,11 +193,11 @@ module CommitsHelper
|
||||
def commit_person_link(commit, options = {})
|
||||
source_name = commit.send "#{options[:source]}_name".to_sym
|
||||
source_email = commit.send "#{options[:source]}_email".to_sym
|
||||
|
||||
|
||||
user = User.find_for_commit(source_email, source_name)
|
||||
person_name = user.nil? ? source_name : user.name
|
||||
person_email = user.nil? ? source_email : user.email
|
||||
|
||||
|
||||
text = if options[:avatar]
|
||||
avatar = image_tag(avatar_icon(person_email, options[:size]), class: "avatar #{"s#{options[:size]}" if options[:size]}", width: options[:size], alt: "")
|
||||
%Q{#{avatar} <span class="commit-#{options[:source]}-name">#{person_name}</span>}
|
||||
@@ -218,4 +216,8 @@ module CommitsHelper
|
||||
link_to(text.html_safe, user_path(user), options)
|
||||
end
|
||||
end
|
||||
|
||||
def diff_file_mode_changed?(diff)
|
||||
diff.a_mode && diff.b_mode && diff.a_mode != diff.b_mode
|
||||
end
|
||||
end
|
||||
|
||||
@@ -109,8 +109,6 @@ module EventsHelper
|
||||
"#{event.note_target_type} ##{truncate event.note_target_iid}"
|
||||
end
|
||||
end
|
||||
elsif event.wall_note?
|
||||
link_to 'wall', project_wall_path(event.project)
|
||||
else
|
||||
content_tag :strong do
|
||||
"(deleted)"
|
||||
|
||||