Merge remote-tracking branch 'gitlabhq/master' into git_commit_fix
Conflicts: doc/install/installation.md
This commit is contained in:
commit
93f0a8c9b3
|
@ -4,7 +4,7 @@ env:
|
||||||
before_install:
|
before_install:
|
||||||
- sudo apt-get install libicu-dev -y
|
- sudo apt-get install libicu-dev -y
|
||||||
- sudo apt-get install libqt4-dev libqtwebkit-dev -y
|
- sudo apt-get install libqt4-dev libqtwebkit-dev -y
|
||||||
- gem install charlock_holmes -v="0.6.8"
|
- gem install charlock_holmes -v="0.6.9"
|
||||||
branches:
|
branches:
|
||||||
only:
|
only:
|
||||||
- 'master'
|
- 'master'
|
||||||
|
|
|
@ -28,7 +28,7 @@ v 3.0.0
|
||||||
- Reject ssh keys that break gitolite
|
- Reject ssh keys that break gitolite
|
||||||
- [API] list one project hook
|
- [API] list one project hook
|
||||||
- [API] edit project hook
|
- [API] edit project hook
|
||||||
- [API] add project snippets list
|
- [API] list project snippets
|
||||||
- [API] allow to authorize using private token in HTTP header
|
- [API] allow to authorize using private token in HTTP header
|
||||||
- [API] add user creation
|
- [API] add user creation
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
## Contribute to GitLab
|
## Contribute to GitLab
|
||||||
|
|
||||||
If you want to contribute to GitLab, follow this process:
|
If you want to contribute to GitLab, follow this process:
|
||||||
|
|
||||||
|
@ -7,24 +7,20 @@ If you want to contribute to GitLab, follow this process:
|
||||||
3. Code
|
3. Code
|
||||||
4. Create a pull request
|
4. Create a pull request
|
||||||
|
|
||||||
We will only accept pull requests if:
|
We will only accept pull requests if:
|
||||||
|
|
||||||
* Your code has proper tests and all tests pass
|
* Your code has proper tests and all tests pass
|
||||||
* Your code can be merged w/o problems
|
* Your code can be merged w/o problems
|
||||||
* It won't break existing functionality
|
* It won't break existing functionality
|
||||||
* It's quality code
|
* It's quality code
|
||||||
* We like it :)
|
* We like it :)
|
||||||
|
|
||||||
## [You may need a developer VM](https://github.com/gitlabhq/developer-vm)
|
For examples of feedback on pull requests please look at the [closed pull requests](https://github.com/gitlabhq/gitlabhq/pulls?direction=desc&page=1&sort=created&state=closed).
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
Install the Gitlab development in a virtual machine with the [Gitlab Vagrant virtual machine](https://github.com/gitlabhq/gitlab-vagrant-vm). Installing it in a virtual machine makes it much easier to set up all the dependencies for integration testing.
|
||||||
|
|
||||||
## Running tests
|
## Running tests
|
||||||
|
|
||||||
To run the specs for GitLab, you need to run seeds for test db.
|
For more information on running the tests please read the [development tips](https://github.com/gitlabhq/gitlabhq/blob/master/doc/development.md)
|
||||||
|
|
||||||
cd gitlabhq
|
|
||||||
rake db:seed_fu RAILS_ENV=test
|
|
||||||
|
|
||||||
Then you can run the test suite with rake:
|
|
||||||
|
|
||||||
rake gitlab:test
|
|
||||||
|
|
||||||
|
|
31
Gemfile
31
Gemfile
|
@ -11,9 +11,9 @@ end
|
||||||
gem "rails", "3.2.8"
|
gem "rails", "3.2.8"
|
||||||
|
|
||||||
# Supported DBs
|
# Supported DBs
|
||||||
gem "sqlite3", :group => :sqlite
|
gem "sqlite3", group: :sqlite
|
||||||
gem "mysql2", :group => :mysql
|
gem "mysql2", group: :mysql
|
||||||
gem "pg", :group => :postgres
|
gem "pg", group: :postgres
|
||||||
|
|
||||||
# Auth
|
# Auth
|
||||||
gem "devise", "~> 2.1.0"
|
gem "devise", "~> 2.1.0"
|
||||||
|
@ -23,10 +23,11 @@ gem 'omniauth-twitter'
|
||||||
gem 'omniauth-github'
|
gem 'omniauth-github'
|
||||||
|
|
||||||
# GITLAB patched libs
|
# GITLAB patched libs
|
||||||
gem "grit", :git => "https://github.com/gitlabhq/grit.git", :ref => "7f35cb98ff17d534a07e3ce6ec3d580f67402837"
|
gem "grit", git: "https://github.com/gitlabhq/grit.git", ref: '7f35cb98ff17d534a07e3ce6ec3d580f67402837'
|
||||||
gem "omniauth-ldap", :git => "https://github.com/gitlabhq/omniauth-ldap.git", :ref => "f038dd852d7bd473a557e385d5d7c2fd5dc1dc2e"
|
gem "omniauth-ldap", git: "https://github.com/gitlabhq/omniauth-ldap.git", ref: 'f038dd852d7bd473a557e385d5d7c2fd5dc1dc2e'
|
||||||
gem 'yaml_db', :git => "https://github.com/gitlabhq/yaml_db.git"
|
gem 'yaml_db', git: "https://github.com/gitlabhq/yaml_db.git", ref: '98e9a5dca43e3fedd3268c76a73af40d1bdf1dfd'
|
||||||
gem 'grack', :git => "https://github.com/gitlabhq/grack.git"
|
gem 'grack', git: "https://github.com/gitlabhq/grack.git", ref: 'ba46f3b0845c6a09d488ae6abdce6ede37e227e8'
|
||||||
|
gem 'grit_ext', git: "https://github.com/gitlabhq/grit_ext.git", ref: '212fd40bea61f3c6a167223768e7295dc32bbc10'
|
||||||
|
|
||||||
# Gitolite client (for work with gitolite-admin repo)
|
# Gitolite client (for work with gitolite-admin repo)
|
||||||
gem "gitolite", '1.1.0'
|
gem "gitolite", '1.1.0'
|
||||||
|
@ -35,7 +36,7 @@ gem "gitolite", '1.1.0'
|
||||||
gem "pygments.rb", "0.3.1"
|
gem "pygments.rb", "0.3.1"
|
||||||
|
|
||||||
# Language detection
|
# Language detection
|
||||||
gem "github-linguist", "~> 2.3.4" , :require => "linguist"
|
gem "github-linguist", "~> 2.3.4" , require: "linguist"
|
||||||
|
|
||||||
# API
|
# API
|
||||||
gem "grape", "~> 0.2.1"
|
gem "grape", "~> 0.2.1"
|
||||||
|
@ -83,9 +84,6 @@ gem 'resque_mailer'
|
||||||
# HTTP requests
|
# HTTP requests
|
||||||
gem "httparty"
|
gem "httparty"
|
||||||
|
|
||||||
# Handle encodings
|
|
||||||
gem "charlock_holmes"
|
|
||||||
|
|
||||||
# Colored output to console
|
# Colored output to console
|
||||||
gem "colored"
|
gem "colored"
|
||||||
|
|
||||||
|
@ -114,8 +112,9 @@ group :assets do
|
||||||
end
|
end
|
||||||
|
|
||||||
group :development do
|
group :development do
|
||||||
|
gem "annotate", git: "https://github.com/ctran/annotate_models.git"
|
||||||
gem "letter_opener"
|
gem "letter_opener"
|
||||||
gem "annotate", :git => "https://github.com/ctran/annotate_models.git"
|
gem 'quiet_assets', '1.0.1'
|
||||||
gem 'rack-mini-profiler'
|
gem 'rack-mini-profiler'
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -137,13 +136,13 @@ group :development, :test do
|
||||||
gem 'guard-spinach'
|
gem 'guard-spinach'
|
||||||
|
|
||||||
# Notification
|
# Notification
|
||||||
gem 'rb-fsevent', :require => darwin_only('rb-fsevent')
|
gem 'rb-fsevent', require: darwin_only('rb-fsevent')
|
||||||
gem 'growl', :require => darwin_only('growl')
|
gem 'growl', require: darwin_only('growl')
|
||||||
gem 'rb-inotify', :require => linux_only('rb-inotify')
|
gem 'rb-inotify', require: linux_only('rb-inotify')
|
||||||
end
|
end
|
||||||
|
|
||||||
group :test do
|
group :test do
|
||||||
gem "simplecov", :require => false
|
gem "simplecov", require: false
|
||||||
gem "shoulda-matchers"
|
gem "shoulda-matchers"
|
||||||
gem 'email_spec'
|
gem 'email_spec'
|
||||||
gem 'resque_spec'
|
gem 'resque_spec'
|
||||||
|
|
17
Gemfile.lock
17
Gemfile.lock
|
@ -7,6 +7,7 @@ GIT
|
||||||
GIT
|
GIT
|
||||||
remote: https://github.com/gitlabhq/grack.git
|
remote: https://github.com/gitlabhq/grack.git
|
||||||
revision: ba46f3b0845c6a09d488ae6abdce6ede37e227e8
|
revision: ba46f3b0845c6a09d488ae6abdce6ede37e227e8
|
||||||
|
ref: ba46f3b0845c6a09d488ae6abdce6ede37e227e8
|
||||||
specs:
|
specs:
|
||||||
grack (1.0.0)
|
grack (1.0.0)
|
||||||
rack (~> 1.4.1)
|
rack (~> 1.4.1)
|
||||||
|
@ -21,6 +22,14 @@ GIT
|
||||||
mime-types (~> 1.15)
|
mime-types (~> 1.15)
|
||||||
posix-spawn (~> 0.3.6)
|
posix-spawn (~> 0.3.6)
|
||||||
|
|
||||||
|
GIT
|
||||||
|
remote: https://github.com/gitlabhq/grit_ext.git
|
||||||
|
revision: 212fd40bea61f3c6a167223768e7295dc32bbc10
|
||||||
|
ref: 212fd40bea61f3c6a167223768e7295dc32bbc10
|
||||||
|
specs:
|
||||||
|
grit_ext (0.6.0)
|
||||||
|
charlock_holmes (~> 0.6.9)
|
||||||
|
|
||||||
GIT
|
GIT
|
||||||
remote: https://github.com/gitlabhq/omniauth-ldap.git
|
remote: https://github.com/gitlabhq/omniauth-ldap.git
|
||||||
revision: f038dd852d7bd473a557e385d5d7c2fd5dc1dc2e
|
revision: f038dd852d7bd473a557e385d5d7c2fd5dc1dc2e
|
||||||
|
@ -35,6 +44,7 @@ GIT
|
||||||
GIT
|
GIT
|
||||||
remote: https://github.com/gitlabhq/yaml_db.git
|
remote: https://github.com/gitlabhq/yaml_db.git
|
||||||
revision: 98e9a5dca43e3fedd3268c76a73af40d1bdf1dfd
|
revision: 98e9a5dca43e3fedd3268c76a73af40d1bdf1dfd
|
||||||
|
ref: 98e9a5dca43e3fedd3268c76a73af40d1bdf1dfd
|
||||||
specs:
|
specs:
|
||||||
yaml_db (0.2.2)
|
yaml_db (0.2.2)
|
||||||
|
|
||||||
|
@ -90,7 +100,7 @@ GEM
|
||||||
carrierwave (0.6.2)
|
carrierwave (0.6.2)
|
||||||
activemodel (>= 3.2.0)
|
activemodel (>= 3.2.0)
|
||||||
activesupport (>= 3.2.0)
|
activesupport (>= 3.2.0)
|
||||||
charlock_holmes (0.6.8)
|
charlock_holmes (0.6.9)
|
||||||
childprocess (0.3.2)
|
childprocess (0.3.2)
|
||||||
ffi (~> 1.0.6)
|
ffi (~> 1.0.6)
|
||||||
chosen-rails (0.9.8.3)
|
chosen-rails (0.9.8.3)
|
||||||
|
@ -260,6 +270,8 @@ GEM
|
||||||
posix-spawn (~> 0.3.6)
|
posix-spawn (~> 0.3.6)
|
||||||
yajl-ruby (~> 1.1.0)
|
yajl-ruby (~> 1.1.0)
|
||||||
pyu-ruby-sasl (0.0.3.3)
|
pyu-ruby-sasl (0.0.3.3)
|
||||||
|
quiet_assets (1.0.1)
|
||||||
|
railties (~> 3.1)
|
||||||
rack (1.4.1)
|
rack (1.4.1)
|
||||||
rack-cache (1.2)
|
rack-cache (1.2)
|
||||||
rack (>= 0.4)
|
rack (>= 0.4)
|
||||||
|
@ -411,7 +423,6 @@ DEPENDENCIES
|
||||||
capybara
|
capybara
|
||||||
capybara-webkit
|
capybara-webkit
|
||||||
carrierwave
|
carrierwave
|
||||||
charlock_holmes
|
|
||||||
chosen-rails
|
chosen-rails
|
||||||
coffee-rails (= 3.2.2)
|
coffee-rails (= 3.2.2)
|
||||||
colored
|
colored
|
||||||
|
@ -432,6 +443,7 @@ DEPENDENCIES
|
||||||
grack!
|
grack!
|
||||||
grape (~> 0.2.1)
|
grape (~> 0.2.1)
|
||||||
grit!
|
grit!
|
||||||
|
grit_ext!
|
||||||
growl
|
growl
|
||||||
guard-rspec
|
guard-rspec
|
||||||
guard-spinach
|
guard-spinach
|
||||||
|
@ -454,6 +466,7 @@ DEPENDENCIES
|
||||||
pg
|
pg
|
||||||
pry
|
pry
|
||||||
pygments.rb (= 0.3.1)
|
pygments.rb (= 0.3.1)
|
||||||
|
quiet_assets (= 1.0.1)
|
||||||
rack-mini-profiler
|
rack-mini-profiler
|
||||||
rails (= 3.2.8)
|
rails (= 3.2.8)
|
||||||
rails-dev-tweaks
|
rails-dev-tweaks
|
||||||
|
|
|
@ -1,2 +0,0 @@
|
||||||
web: bundle exec rails s -p $PORT -e production
|
|
||||||
worker: bundle exec rake environment resque:work RAILS_ENV=production QUEUE=*
|
|
19
ROADMAP.md
Normal file
19
ROADMAP.md
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
## GitLab Roadmap
|
||||||
|
|
||||||
|
### Common
|
||||||
|
|
||||||
|
* Help page for service tasks like repos import, backup etc
|
||||||
|
* Hide last push widget after following link
|
||||||
|
* Add comment events
|
||||||
|
* Dashboard/Project activity events filter
|
||||||
|
|
||||||
|
### Issues
|
||||||
|
|
||||||
|
* labels autocomplete via jquery autocomplete
|
||||||
|
* Import/Export issues
|
||||||
|
* Form: Assign to me link right to the selectbox
|
||||||
|
|
||||||
|
### Merge Request
|
||||||
|
|
||||||
|
* CI build status
|
||||||
|
* Save code fragments with MR comments
|
BIN
app/assets/images/event_filter_comments.png
Normal file
BIN
app/assets/images/event_filter_comments.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 750 B |
BIN
app/assets/images/event_filter_merged.png
Normal file
BIN
app/assets/images/event_filter_merged.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 463 B |
BIN
app/assets/images/event_filter_push.png
Normal file
BIN
app/assets/images/event_filter_push.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 632 B |
BIN
app/assets/images/event_filter_team.png
Normal file
BIN
app/assets/images/event_filter_team.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.3 KiB |
|
@ -17,6 +17,8 @@
|
||||||
//= require modernizr
|
//= require modernizr
|
||||||
//= require chosen-jquery
|
//= require chosen-jquery
|
||||||
//= require raphael
|
//= require raphael
|
||||||
|
//= require g.raphael-min
|
||||||
|
//= require g.bar-min
|
||||||
//= require branch-graph
|
//= require branch-graph
|
||||||
//= require ace-src-noconflict/ace
|
//= require ace-src-noconflict/ace
|
||||||
//= require_tree .
|
//= require_tree .
|
||||||
|
|
|
@ -1,57 +1,47 @@
|
||||||
|
# Creates the variables for setting up GFM auto-completion
|
||||||
|
|
||||||
###
|
|
||||||
Creates the variables for setting up GFM auto-completion
|
|
||||||
###
|
|
||||||
# Emoji
|
# Emoji
|
||||||
window.autocompleteEmojiData = [];
|
data = []
|
||||||
window.autocompleteEmojiTemplate = "<li data-value='${insert}'>${name} <img alt='${name}' height='20' src='${image}' width='20' /></li>";
|
template = "<li data-value='${insert}'>${name} <img alt='${name}' height='20' src='${image}' width='20' /></li>"
|
||||||
|
window.autocompleteEmoji = {data, template}
|
||||||
|
|
||||||
# Team Members
|
# Team Members
|
||||||
window.autocompleteMembersUrl = "";
|
url = '';
|
||||||
window.autocompleteMembersParams =
|
params = {private_token: '', page: 1}
|
||||||
private_token: ""
|
window.autocompleteMembers = {data, url, params}
|
||||||
page: 1
|
|
||||||
window.autocompleteMembersData = [];
|
|
||||||
|
|
||||||
|
# Add GFM auto-completion to all input fields, that accept GFM input.
|
||||||
|
|
||||||
###
|
|
||||||
Add GFM auto-completion to all input fields, that accept GFM input.
|
|
||||||
###
|
|
||||||
window.setupGfmAutoComplete = ->
|
window.setupGfmAutoComplete = ->
|
||||||
###
|
$input = $('.js-gfm-input')
|
||||||
Emoji
|
|
||||||
###
|
|
||||||
$('.gfm-input').atWho ':',
|
|
||||||
data: autocompleteEmojiData,
|
|
||||||
tpl: autocompleteEmojiTemplate
|
|
||||||
|
|
||||||
###
|
# Emoji
|
||||||
Team Members
|
$input.atWho ':',
|
||||||
###
|
data: autocompleteEmoji.data,
|
||||||
$('.gfm-input').atWho '@', (query, callback) ->
|
tpl: autocompleteEmoji.template
|
||||||
|
|
||||||
|
# Team Members
|
||||||
|
$input.atWho '@', (query, callback) ->
|
||||||
(getMoreMembers = ->
|
(getMoreMembers = ->
|
||||||
$.getJSON(autocompleteMembersUrl, autocompleteMembersParams)
|
$.getJSON(autocompleteMembers.url, autocompleteMembers.params).success (members) ->
|
||||||
.success (members) ->
|
# pick the data we need
|
||||||
# pick the data we need
|
newMembersData = $.map members, (m) -> m.name
|
||||||
newMembersData = $.map members, (m) -> m.name
|
|
||||||
|
|
||||||
# add the new page of data to the rest
|
# add the new page of data to the rest
|
||||||
$.merge autocompleteMembersData, newMembersData
|
$.merge autocompleteMembers.data, newMembersData
|
||||||
|
|
||||||
# show the pop-up with a copy of the current data
|
# show the pop-up with a copy of the current data
|
||||||
callback autocompleteMembersData[..]
|
callback autocompleteMembers.data[..]
|
||||||
|
|
||||||
# are we past the last page?
|
# are we past the last page?
|
||||||
if newMembersData.length == 0
|
if newMembersData.length is 0
|
||||||
# set static data and stop callbacks
|
# set static data and stop callbacks
|
||||||
$('.gfm-input').atWho '@',
|
$input.atWho '@',
|
||||||
data: autocompleteMembersData
|
data: autocompleteMembers.data
|
||||||
callback: null
|
callback: null
|
||||||
else
|
else
|
||||||
# get next page
|
# get next page
|
||||||
getMoreMembers()
|
getMoreMembers()
|
||||||
|
|
||||||
# so the next request gets the next page
|
# so the next request gets the next page
|
||||||
autocompleteMembersParams.page += 1;
|
autocompleteMembers.params.page += 1
|
||||||
).call();
|
).call()
|
||||||
|
|
|
@ -1,10 +0,0 @@
|
||||||
initGraphNav = ->
|
|
||||||
$('.graph svg').css 'position', 'relative'
|
|
||||||
|
|
||||||
$('body').bind 'keyup', (e) ->
|
|
||||||
if e.keyCode is 37 # left
|
|
||||||
$('.graph svg').animate left: '+=400'
|
|
||||||
else if e.keyCode is 39 # right
|
|
||||||
$('.graph svg').animate left: '-=400'
|
|
||||||
|
|
||||||
window.initGraphNav = initGraphNav
|
|
|
@ -1,6 +1,5 @@
|
||||||
function switchToNewIssue(form){
|
function switchToNewIssue(){
|
||||||
$(".issues_content").hide("fade", { direction: "left" }, 150, function(){
|
$(".issues_content").hide("fade", { direction: "left" }, 150, function(){
|
||||||
$(".issues_content").after(form);
|
|
||||||
$('select#issue_assignee_id').chosen();
|
$('select#issue_assignee_id').chosen();
|
||||||
$('select#issue_milestone_id').chosen();
|
$('select#issue_milestone_id').chosen();
|
||||||
$("#new_issue_dialog").show("fade", { direction: "right" }, 150);
|
$("#new_issue_dialog").show("fade", { direction: "right" }, 150);
|
||||||
|
@ -10,9 +9,8 @@ function switchToNewIssue(form){
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function switchToEditIssue(form){
|
function switchToEditIssue(){
|
||||||
$(".issues_content").hide("fade", { direction: "left" }, 150, function(){
|
$(".issues_content").hide("fade", { direction: "left" }, 150, function(){
|
||||||
$(".issues_content").after(form);
|
|
||||||
$('select#issue_assignee_id').chosen();
|
$('select#issue_assignee_id').chosen();
|
||||||
$('select#issue_milestone_id').chosen();
|
$('select#issue_milestone_id').chosen();
|
||||||
$("#edit_issue_dialog").show("fade", { direction: "right" }, 150);
|
$("#edit_issue_dialog").show("fade", { direction: "right" }, 150);
|
||||||
|
@ -33,8 +31,8 @@ function switchFromEditIssue(){
|
||||||
function backToIssues(){
|
function backToIssues(){
|
||||||
$("#edit_issue_dialog, #new_issue_dialog").hide("fade", { direction: "right" }, 150, function(){
|
$("#edit_issue_dialog, #new_issue_dialog").hide("fade", { direction: "right" }, 150, function(){
|
||||||
$(".issues_content").show("fade", { direction: "left" }, 150, function() {
|
$(".issues_content").show("fade", { direction: "left" }, 150, function() {
|
||||||
$("#edit_issue_dialog").remove();
|
$("#edit_issue_dialog").html("");
|
||||||
$("#new_issue_dialog").remove();
|
$("#new_issue_dialog").html("");
|
||||||
$('.add_new').show();
|
$('.add_new').show();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,5 +0,0 @@
|
||||||
Loader =
|
|
||||||
html: (width) ->
|
|
||||||
$('<img>').attr src: '/assets/ajax-loader.gif', width: width
|
|
||||||
|
|
||||||
window.Loader = Loader
|
|
|
@ -7,29 +7,32 @@ window.slugify = (text) ->
|
||||||
window.ajaxGet = (url) ->
|
window.ajaxGet = (url) ->
|
||||||
$.ajax({type: "GET", url: url, dataType: "script"})
|
$.ajax({type: "GET", url: url, dataType: "script"})
|
||||||
|
|
||||||
# Disable button if text field is empty
|
# Disable button if text field is empty
|
||||||
window.disableButtonIfEmptyField = (field_selector, button_selector) ->
|
window.disableButtonIfEmptyField = (field_selector, button_selector) ->
|
||||||
field = $(field_selector)
|
field = $(field_selector)
|
||||||
closest_submit = field.closest("form").find(button_selector)
|
closest_submit = field.closest("form").find(button_selector)
|
||||||
|
|
||||||
closest_submit.disable() if field.val() is ""
|
closest_submit.disable() if field.val() is ""
|
||||||
|
|
||||||
field.on "keyup", ->
|
field.on "input", ->
|
||||||
if $(this).val() is ""
|
if $(@).val() is ""
|
||||||
closest_submit.disable()
|
closest_submit.disable()
|
||||||
else
|
else
|
||||||
closest_submit.enable()
|
closest_submit.enable()
|
||||||
|
|
||||||
$ ->
|
$ ->
|
||||||
# Click a .one_click_select field, select the contents
|
# Click a .one_click_select field, select the contents
|
||||||
$(".one_click_select").live 'click', -> $(this).select()
|
$(".one_click_select").on 'click', -> $(@).select()
|
||||||
|
|
||||||
# Initialize chosen selects
|
# Initialize chosen selects
|
||||||
$('select.chosen').chosen()
|
$('select.chosen').chosen()
|
||||||
|
|
||||||
|
# Initialize tooltips
|
||||||
|
$('.has_tooltip').tooltip()
|
||||||
|
|
||||||
# Disable form buttons while a form is submitting
|
# Disable form buttons while a form is submitting
|
||||||
$('body').on 'ajax:complete, ajax:beforeSend, submit', 'form', (e) ->
|
$('body').on 'ajax:complete, ajax:beforeSend, submit', 'form', (e) ->
|
||||||
buttons = $('[type="submit"]', this)
|
buttons = $('[type="submit"]', @)
|
||||||
|
|
||||||
switch e.type
|
switch e.type
|
||||||
when 'ajax:beforeSend', 'submit'
|
when 'ajax:beforeSend', 'submit'
|
||||||
|
@ -38,7 +41,7 @@ $ ->
|
||||||
buttons.enable()
|
buttons.enable()
|
||||||
|
|
||||||
# Show/Hide the profile menu when hovering the account box
|
# Show/Hide the profile menu when hovering the account box
|
||||||
$('.account-box').hover -> $(this).toggleClass('hover')
|
$('.account-box').hover -> $(@).toggleClass('hover')
|
||||||
|
|
||||||
# Focus search field by pressing 's' key
|
# Focus search field by pressing 's' key
|
||||||
$(document).keypress (e) ->
|
$(document).keypress (e) ->
|
||||||
|
@ -52,22 +55,22 @@ $ ->
|
||||||
|
|
||||||
# Commit show suppressed diff
|
# Commit show suppressed diff
|
||||||
$(".supp_diff_link").bind "click", ->
|
$(".supp_diff_link").bind "click", ->
|
||||||
$(this).next('table').show()
|
$(@).next('table').show()
|
||||||
$(this).remove()
|
$(@).remove()
|
||||||
|
|
||||||
# Note markdown preview
|
# Note markdown preview
|
||||||
$(document).on 'click', '#preview-link', (e) ->
|
$(document).on 'click', '#preview-link', (e) ->
|
||||||
$('#preview-note').text('Loading...')
|
$('#preview-note').text 'Loading...'
|
||||||
|
|
||||||
previewLinkText = if $(this).text() == 'Preview' then 'Edit' else 'Preview'
|
previewLinkText = if $(@).text() is 'Preview' then 'Edit' else 'Preview'
|
||||||
$(this).text(previewLinkText)
|
$(@).text previewLinkText
|
||||||
|
|
||||||
note = $('#note_note').val()
|
note = $('#note_note').val()
|
||||||
|
|
||||||
if note.trim().length == 0
|
if note.trim().length is 0
|
||||||
$('#preview-note').text("Nothing to preview.")
|
$('#preview-note').text 'Nothing to preview.'
|
||||||
else
|
else
|
||||||
$.post $(this).attr('href'), {note: note}, (data) ->
|
$.post $(@).attr('href'), {note: note}, (data) ->
|
||||||
$('#preview-note').html(data)
|
$('#preview-note').html(data)
|
||||||
|
|
||||||
$('#preview-note, #note_note').toggle()
|
$('#preview-note, #note_note').toggle()
|
||||||
|
@ -79,14 +82,14 @@ $ ->
|
||||||
$.fn.extend chosen: (options) ->
|
$.fn.extend chosen: (options) ->
|
||||||
default_options = search_contains: "true"
|
default_options = search_contains: "true"
|
||||||
$.extend default_options, options
|
$.extend default_options, options
|
||||||
_chosen.apply this, [default_options]
|
_chosen.apply @, [default_options]
|
||||||
|
|
||||||
# Disable an element and add the 'disabled' Bootstrap class
|
# Disable an element and add the 'disabled' Bootstrap class
|
||||||
$.fn.extend disable: ->
|
$.fn.extend disable: ->
|
||||||
$(this).attr('disabled', 'disabled').addClass('disabled')
|
$(@).attr('disabled', 'disabled').addClass('disabled')
|
||||||
|
|
||||||
# Enable an element and remove the 'disabled' Bootstrap class
|
# Enable an element and remove the 'disabled' Bootstrap class
|
||||||
$.fn.extend enable: ->
|
$.fn.extend enable: ->
|
||||||
$(this).removeAttr('disabled').removeClass('disabled')
|
$(@).removeAttr('disabled').removeClass('disabled')
|
||||||
|
|
||||||
)(jQuery)
|
)(jQuery)
|
||||||
|
|
|
@ -115,4 +115,15 @@ var MergeRequest = {
|
||||||
$(".merge_in_progress").hide();
|
$(".merge_in_progress").hide();
|
||||||
$(".automerge_widget.already_cannot_be_merged").show();
|
$(".automerge_widget.already_cannot_be_merged").show();
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Filter merge requests
|
||||||
|
*/
|
||||||
|
function merge_requestsPage() {
|
||||||
|
$("#assignee_id").chosen();
|
||||||
|
$("#milestone_id").chosen();
|
||||||
|
$("#milestone_id, #assignee_id").on("change", function(){
|
||||||
|
$(this).closest("form").submit();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,3 +5,10 @@ $ ->
|
||||||
$('.milestone-issue-filter li').toggleClass('active')
|
$('.milestone-issue-filter li').toggleClass('active')
|
||||||
$('.milestone-issue-filter tr[data-closed]').toggleClass('hide')
|
$('.milestone-issue-filter tr[data-closed]').toggleClass('hide')
|
||||||
false
|
false
|
||||||
|
|
||||||
|
$('.milestone-merge-requests-filter tr[data-closed]').addClass('hide')
|
||||||
|
|
||||||
|
$('.milestone-merge-requests-filter ul.nav li a').click ->
|
||||||
|
$('.milestone-merge-requests-filter li').toggleClass('active')
|
||||||
|
$('.milestone-merge-requests-filter tr[data-closed]').toggleClass('hide')
|
||||||
|
false
|
||||||
|
|
|
@ -22,3 +22,10 @@ $ ->
|
||||||
# Ref switcher
|
# Ref switcher
|
||||||
$('.project-refs-select').on 'change', ->
|
$('.project-refs-select').on 'change', ->
|
||||||
$(@).parents('form').submit()
|
$(@).parents('form').submit()
|
||||||
|
|
||||||
|
class @GraphNav
|
||||||
|
@init: ->
|
||||||
|
$('.graph svg').css 'position', 'relative'
|
||||||
|
$('body').bind 'keyup', (e) ->
|
||||||
|
$('.graph svg').animate(left: '+=400') if e.keyCode is 37 # left
|
||||||
|
$('.graph svg').animate(left: '-=400') if e.keyCode is 39 # right
|
||||||
|
|
|
@ -1,6 +0,0 @@
|
||||||
$ ->
|
|
||||||
$('#snippets-table .snippet').live 'click', (e) ->
|
|
||||||
if e.target.nodeName isnt 'A' and e.target.nodeName isnt 'INPUT'
|
|
||||||
location.href = $(@).attr 'url'
|
|
||||||
e.stopPropagation()
|
|
||||||
false
|
|
|
@ -17,23 +17,21 @@ $ ->
|
||||||
"ajax:beforeSend": -> $('.tree_progress').addClass("loading")
|
"ajax:beforeSend": -> $('.tree_progress').addClass("loading")
|
||||||
"ajax:complete": -> $('.tree_progress').removeClass("loading")
|
"ajax:complete": -> $('.tree_progress').removeClass("loading")
|
||||||
|
|
||||||
# Maintain forward/back history while browsing the file tree
|
# Maintain forward/back history while browsing the file tree
|
||||||
|
((window) ->
|
||||||
|
History = window.History
|
||||||
|
$ = window.jQuery
|
||||||
|
document = window.document
|
||||||
|
|
||||||
((window) ->
|
# Check to see if History.js is enabled for our Browser
|
||||||
History = window.History
|
unless History.enabled
|
||||||
$ = window.jQuery
|
return false
|
||||||
document = window.document
|
|
||||||
|
|
||||||
# Check to see if History.js is enabled for our Browser
|
$('#tree-slider .tree-item-file-name a, .breadcrumb li > a').live 'click', (e) ->
|
||||||
unless History.enabled
|
History.pushState(null, null, $(@).attr('href'))
|
||||||
return false
|
return false
|
||||||
|
|
||||||
$ ->
|
History.Adapter.bind window, 'statechange', ->
|
||||||
$('#tree-slider .tree-item-file-name a, .breadcrumb li > a').live 'click', (e) ->
|
state = History.getState()
|
||||||
History.pushState(null, null, $(@).attr('href'))
|
window.ajaxGet(state.url)
|
||||||
return false
|
)(window)
|
||||||
|
|
||||||
History.Adapter.bind window, 'statechange', ->
|
|
||||||
state = History.getState()
|
|
||||||
window.ajaxGet(state.url)
|
|
||||||
)(window)
|
|
||||||
|
|
|
@ -670,3 +670,16 @@ pre {
|
||||||
padding:0;
|
padding:0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.milestone .progress {
|
||||||
|
margin-bottom: 0;
|
||||||
|
margin-top:4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.float-link {
|
||||||
|
float:left;
|
||||||
|
margin-right:15px;
|
||||||
|
.s16 {
|
||||||
|
margin-right:5px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -26,8 +26,10 @@
|
||||||
.underlined { border-bottom: 1px solid #CCC; }
|
.underlined { border-bottom: 1px solid #CCC; }
|
||||||
.no-borders { border:none; }
|
.no-borders { border:none; }
|
||||||
.vlink { color: $link_color !important; }
|
.vlink { color: $link_color !important; }
|
||||||
|
.underlined_link { text-decoration: underline; }
|
||||||
.borders { border: 1px solid #ccc; @include shade; }
|
.borders { border: 1px solid #ccc; @include shade; }
|
||||||
.hint { font-style: italic; color: #999; }
|
.hint { font-style: italic; color: #999; }
|
||||||
|
.light { color: #888 }
|
||||||
|
|
||||||
/** PILLS & TABS**/
|
/** PILLS & TABS**/
|
||||||
.nav-pills a:hover { background-color:#888; }
|
.nav-pills a:hover { background-color:#888; }
|
||||||
|
@ -66,10 +68,10 @@
|
||||||
.alert-message.error { @extend .alert-error; }
|
.alert-message.error { @extend .alert-error; }
|
||||||
|
|
||||||
/** AVATARS **/
|
/** AVATARS **/
|
||||||
img.avatar { float:left; margin-right:15px; width:40px; border:1px solid #ddd; padding:1px; }
|
img.avatar { float:left; margin-right:12px; width:40px; border:1px solid #ddd; padding:1px; }
|
||||||
img.avatar.s16 { width:16px; height:16px; }
|
img.avatar.s16 { width:16px; height:16px; margin-right:6px; }
|
||||||
img.avatar.s24 { width:24px; height:24px; }
|
img.avatar.s24 { width:24px; height:24px; margin-right:8px; }
|
||||||
img.avatar.s32 { width:32px; height:32px; }
|
img.avatar.s32 { width:32px; height:32px; margin-right:10px; }
|
||||||
img.lil_av { padding-left: 4px; padding-right:3px; }
|
img.lil_av { padding-left: 4px; padding-right:3px; }
|
||||||
|
|
||||||
/** HELPERS **/
|
/** HELPERS **/
|
||||||
|
|
|
@ -157,10 +157,15 @@
|
||||||
font-size:12px !important;
|
font-size:12px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
table.highlighttable .linenodiv pre {
|
table.highlighttable .linenodiv {
|
||||||
text-align: right;
|
a {
|
||||||
padding-right: 4px;
|
color: #666;
|
||||||
color:#666;
|
}
|
||||||
|
pre {
|
||||||
|
text-align: right;
|
||||||
|
padding-right: 4px;
|
||||||
|
color:#666;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,7 @@ ul {
|
||||||
.author { color: #999; }
|
.author { color: #999; }
|
||||||
|
|
||||||
p {
|
p {
|
||||||
padding-top:5px;
|
padding-top: 1px;
|
||||||
margin:0;
|
margin:0;
|
||||||
color:#222;
|
color:#222;
|
||||||
img {
|
img {
|
||||||
|
@ -31,3 +31,11 @@ ul {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ol, ul {
|
||||||
|
&.styled {
|
||||||
|
li {
|
||||||
|
padding:2px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -34,6 +34,11 @@ table {
|
||||||
border-color:#f1f1f1;
|
border-color:#f1f1f1;
|
||||||
line-height:28px;
|
line-height:28px;
|
||||||
|
|
||||||
|
.s16 {
|
||||||
|
margin-top: 5px;
|
||||||
|
margin-right: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
&:first-child {
|
&:first-child {
|
||||||
border-left:1px solid #bbb;
|
border-left:1px solid #bbb;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,10 +3,11 @@
|
||||||
@import 'font-awesome';
|
@import 'font-awesome';
|
||||||
|
|
||||||
/** GitLab colors **/
|
/** GitLab colors **/
|
||||||
$link_color:#3A89A3;
|
$link_color: #3A89A3;
|
||||||
$blue_link: #2fa0bb;
|
$blue_link: #2FA0BB;
|
||||||
$style_color: #474d57;
|
$style_color: #474D57;
|
||||||
$hover: #D9EDF7;
|
$hover: #D9EDF7;
|
||||||
|
$hover_border: #ADF;
|
||||||
|
|
||||||
/** GitLab Fonts **/
|
/** GitLab Fonts **/
|
||||||
@font-face { font-family: Korolev; src: font-url('korolev-medium-compressed.otf'); }
|
@font-face { font-family: Korolev; src: font-url('korolev-medium-compressed.otf'); }
|
||||||
|
@ -19,9 +20,9 @@ $hover: #D9EDF7;
|
||||||
}
|
}
|
||||||
|
|
||||||
@mixin solid_shade {
|
@mixin solid_shade {
|
||||||
-moz-box-shadow: 0 0 0 3px #eee;
|
-moz-box-shadow: 0 0 0 3px #f1f1f1;
|
||||||
-webkit-box-shadow: 0 0 0 3px #eee;
|
-webkit-box-shadow: 0 0 0 3px #f1f1f1;
|
||||||
box-shadow: 0 0 0 3px #eee;
|
box-shadow: 0 0 0 3px #f1f1f1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@mixin border-radius($radius) {
|
@mixin border-radius($radius) {
|
||||||
|
@ -64,6 +65,14 @@ $hover: #D9EDF7;
|
||||||
background-image: -o-linear-gradient($from, $to);
|
background-image: -o-linear-gradient($from, $to);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@mixin bg-light-gray-gradient {
|
||||||
|
background:#f1f1f1;
|
||||||
|
background-image: -webkit-gradient(linear, 0 0, 0 30, color-stop(0.066, #f5f5f5), to(#e1e1e1));
|
||||||
|
background-image: -webkit-linear-gradient(#f5f5f5 6.6%, #e1e1e1);
|
||||||
|
background-image: -moz-linear-gradient(#f5f5f5 6.6%, #e1e1e1);
|
||||||
|
background-image: -o-linear-gradient(#f5f5f5 6.6%, #e1e1e1);
|
||||||
|
}
|
||||||
|
|
||||||
@mixin bg-gray-gradient {
|
@mixin bg-gray-gradient {
|
||||||
background:#eee;
|
background:#eee;
|
||||||
background-image: -webkit-gradient(linear, 0 0, 0 30, color-stop(0.066, #eee), to(#dfdfdf));
|
background-image: -webkit-gradient(linear, 0 0, 0 30, color-stop(0.066, #eee), to(#dfdfdf));
|
||||||
|
|
|
@ -19,41 +19,14 @@
|
||||||
margin-right: 10px;
|
margin-right: 10px;
|
||||||
|
|
||||||
.chzn-drop {
|
.chzn-drop {
|
||||||
margin:7px 0;
|
|
||||||
min-width: 400px;
|
min-width: 400px;
|
||||||
border: 2px solid $blue_link;
|
|
||||||
@include border-radius(4px);
|
|
||||||
|
|
||||||
.chzn-results {
|
.chzn-results {
|
||||||
max-height:300px;
|
max-height:300px;
|
||||||
|
|
||||||
.group-result {
|
|
||||||
color: $blue_link;
|
|
||||||
}
|
|
||||||
.active-result {
|
|
||||||
&.highlighted {
|
|
||||||
background: $blue_link;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.chzn-search input {
|
.chzn-search input {
|
||||||
min-width:365px;
|
min-width:365px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.chzn-single {
|
|
||||||
@include bg-gray-gradient;
|
|
||||||
|
|
||||||
div {
|
|
||||||
background:transparent;
|
|
||||||
border-left:none;
|
|
||||||
}
|
|
||||||
|
|
||||||
span {
|
|
||||||
font-weight: normal;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Fix for Search Dropdown Border **/
|
/** Fix for Search Dropdown Border **/
|
||||||
|
@ -65,4 +38,55 @@
|
||||||
box-shadow: none;
|
box-shadow: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.chzn-drop {
|
||||||
|
margin:7px 0;
|
||||||
|
min-width: 200px;
|
||||||
|
border: 1px solid #bbb;
|
||||||
|
border-radius:0;
|
||||||
|
|
||||||
|
.chzn-results {
|
||||||
|
margin-top: 5px;
|
||||||
|
max-height:300px;
|
||||||
|
|
||||||
|
.group-result {
|
||||||
|
color: $style_color;
|
||||||
|
border-bottom: 1px solid #EEE;
|
||||||
|
padding: 8px;
|
||||||
|
}
|
||||||
|
.active-result {
|
||||||
|
border-radius: 0;
|
||||||
|
|
||||||
|
&.highlighted {
|
||||||
|
background: $hover;
|
||||||
|
color: $style_color;
|
||||||
|
}
|
||||||
|
&.result-selected {
|
||||||
|
background: #EEE;
|
||||||
|
border-left: 4px solid #CCC;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.chzn-search {
|
||||||
|
@include bg-gray-gradient;
|
||||||
|
input {
|
||||||
|
min-width:165px;
|
||||||
|
border-color: #CCC;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.chzn-single {
|
||||||
|
@include bg-light-gray-gradient;
|
||||||
|
|
||||||
|
div {
|
||||||
|
background:transparent;
|
||||||
|
border-left:none;
|
||||||
|
}
|
||||||
|
|
||||||
|
span {
|
||||||
|
font-weight: normal;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,12 +47,15 @@
|
||||||
padding-left: 32px;
|
padding-left: 32px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.author,
|
.author a,
|
||||||
.committer {
|
.committer a {
|
||||||
font-size:14px;
|
font-size:14px;
|
||||||
line-height:22px;
|
line-height:22px;
|
||||||
text-shadow:0 1px 1px #fff;
|
text-shadow:0 1px 1px #fff;
|
||||||
color:#777;
|
color:#777;
|
||||||
|
&:hover {
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.avatar {
|
.avatar {
|
||||||
|
@ -227,6 +230,9 @@
|
||||||
|
|
||||||
.commit-author-name {
|
.commit-author-name {
|
||||||
color: #777;
|
color: #777;
|
||||||
|
&:hover {
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -43,6 +43,7 @@
|
||||||
.event-body {
|
.event-body {
|
||||||
p {
|
p {
|
||||||
color:#555;
|
color:#555;
|
||||||
|
padding-top: 5px;
|
||||||
}
|
}
|
||||||
.event-info {
|
.event-info {
|
||||||
color:#666;
|
color:#666;
|
||||||
|
@ -115,3 +116,29 @@
|
||||||
margin: -3px;
|
margin: -3px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Event filter
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
.event_filter {
|
||||||
|
position: absolute;
|
||||||
|
width: 40px;
|
||||||
|
margin-left: -50px;
|
||||||
|
|
||||||
|
.filter_icon {
|
||||||
|
float: left;
|
||||||
|
border-left: 3px solid #4bc;
|
||||||
|
padding: 7px;
|
||||||
|
background: #f9f9f9;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
img {
|
||||||
|
width:20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.inactive {
|
||||||
|
border-left: 3px solid #EEE;
|
||||||
|
opacity: 0.5;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -44,7 +44,7 @@
|
||||||
|
|
||||||
img.avatar {
|
img.avatar {
|
||||||
width:32px;
|
width:32px;
|
||||||
margin-top:4px;
|
margin-top:1px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -71,7 +71,7 @@ li.merge_request {
|
||||||
padding:7px 10px;
|
padding:7px 10px;
|
||||||
img.avatar {
|
img.avatar {
|
||||||
width: 32px;
|
width: 32px;
|
||||||
margin-top: 4px;
|
margin-top: 1px;
|
||||||
}
|
}
|
||||||
p {
|
p {
|
||||||
padding: 0px;
|
padding: 0px;
|
||||||
|
@ -121,3 +121,20 @@ li.merge_request {
|
||||||
.mr_direction_tip {
|
.mr_direction_tip {
|
||||||
margin-top:40px
|
margin-top:40px
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.merge_requests_form_box {
|
||||||
|
@extend .main_box;
|
||||||
|
.merge_requests_middle_box {
|
||||||
|
@extend .middle_box_content;
|
||||||
|
height:30px;
|
||||||
|
.merge_requests_assignee {
|
||||||
|
@extend .span6;
|
||||||
|
float:left;
|
||||||
|
}
|
||||||
|
.merge_requests_milestone {
|
||||||
|
@extend .span4;
|
||||||
|
float:left;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -57,10 +57,7 @@
|
||||||
padding-right: 8px;
|
padding-right: 8px;
|
||||||
|
|
||||||
img.avatar {
|
img.avatar {
|
||||||
border: 0 none;
|
margin-top: 0;
|
||||||
float: none;
|
|
||||||
margin-right: 0;
|
|
||||||
padding: 0;
|
|
||||||
width: 16px;
|
width: 16px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -75,6 +72,15 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.blame {
|
||||||
|
img.avatar {
|
||||||
|
border: 0 none;
|
||||||
|
float: none;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.tree-btn-group {
|
.tree-btn-group {
|
||||||
|
|
|
@ -37,9 +37,6 @@
|
||||||
background-image: -o-linear-gradient(#595D63 6.6%, #202227);
|
background-image: -o-linear-gradient(#595D63 6.6%, #202227);
|
||||||
background-position:0 0;
|
background-position:0 0;
|
||||||
color:#fff;
|
color:#fff;
|
||||||
i {
|
|
||||||
@extend .icon-white;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
border: 1px solid #31363E;
|
border: 1px solid #31363E;
|
||||||
|
|
|
@ -70,9 +70,6 @@
|
||||||
color:#ccc;
|
color:#ccc;
|
||||||
&:hover {
|
&:hover {
|
||||||
color:#fff;
|
color:#fff;
|
||||||
i {
|
|
||||||
@extend .icon-white;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
border: none;
|
border: none;
|
||||||
box-shadow:none;
|
box-shadow:none;
|
||||||
|
|
|
@ -21,7 +21,7 @@ class CommitLoadContext < BaseContext
|
||||||
result[:notes_count] = line_notes.count + project.commit_notes(commit).count
|
result[:notes_count] = line_notes.count + project.commit_notes(commit).count
|
||||||
|
|
||||||
begin
|
begin
|
||||||
result[:suppress_diff] = true if commit.diffs.size > 200 && !params[:force_show_diff]
|
result[:suppress_diff] = true if commit.diffs.size > Commit::DIFF_SAFE_SIZE && !params[:force_show_diff]
|
||||||
rescue Grit::Git::GitTimeout
|
rescue Grit::Git::GitTimeout
|
||||||
result[:suppress_diff] = true
|
result[:suppress_diff] = true
|
||||||
result[:status] = :huge_commit
|
result[:status] = :huge_commit
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
# Build collection of Merge Requests
|
||||||
|
# based on filtering passed via params for @project
|
||||||
class MergeRequestsLoadContext < BaseContext
|
class MergeRequestsLoadContext < BaseContext
|
||||||
def execute
|
def execute
|
||||||
type = params[:f]
|
type = params[:f]
|
||||||
|
@ -9,8 +11,21 @@ class MergeRequestsLoadContext < BaseContext
|
||||||
when 'closed' then merge_requests.closed
|
when 'closed' then merge_requests.closed
|
||||||
when 'assigned-to-me' then merge_requests.opened.assigned(current_user)
|
when 'assigned-to-me' then merge_requests.opened.assigned(current_user)
|
||||||
else merge_requests.opened
|
else merge_requests.opened
|
||||||
end.page(params[:page]).per(20)
|
end
|
||||||
|
|
||||||
merge_requests.includes(:author, :project).order("closed, created_at desc")
|
merge_requests = merge_requests.page(params[:page]).per(20)
|
||||||
|
merge_requests = merge_requests.includes(:author, :project).order("closed, created_at desc")
|
||||||
|
|
||||||
|
# Filter by specific assignee_id (or lack thereof)?
|
||||||
|
if params[:assignee_id].present?
|
||||||
|
merge_requests = merge_requests.where(assignee_id: (params[:assignee_id] == '0' ? nil : params[:assignee_id]))
|
||||||
|
end
|
||||||
|
|
||||||
|
# Filter by specific milestone_id (or lack thereof)?
|
||||||
|
if params[:milestone_id].present?
|
||||||
|
merge_requests = merge_requests.where(milestone_id: (params[:milestone_id] == '0' ? nil : params[:milestone_id]))
|
||||||
|
end
|
||||||
|
|
||||||
|
merge_requests
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -13,6 +13,7 @@ class SearchContext
|
||||||
result[:projects] = Project.where(id: project_ids).search(query).limit(10)
|
result[:projects] = Project.where(id: project_ids).search(query).limit(10)
|
||||||
result[:merge_requests] = MergeRequest.where(project_id: project_ids).search(query).limit(10)
|
result[:merge_requests] = MergeRequest.where(project_id: project_ids).search(query).limit(10)
|
||||||
result[:issues] = Issue.where(project_id: project_ids).search(query).limit(10)
|
result[:issues] = Issue.where(project_id: project_ids).search(query).limit(10)
|
||||||
|
result[:wiki_pages] = Wiki.where(project_id: project_ids).search(query).limit(10)
|
||||||
result
|
result
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -20,7 +21,8 @@ class SearchContext
|
||||||
@result ||= {
|
@result ||= {
|
||||||
projects: [],
|
projects: [],
|
||||||
merge_requests: [],
|
merge_requests: [],
|
||||||
issues: []
|
issues: [],
|
||||||
|
wiki_pages: []
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -9,19 +9,28 @@ class ApplicationController < ActionController::Base
|
||||||
helper_method :abilities, :can?
|
helper_method :abilities, :can?
|
||||||
|
|
||||||
rescue_from Gitlab::Gitolite::AccessDenied do |exception|
|
rescue_from Gitlab::Gitolite::AccessDenied do |exception|
|
||||||
|
log_exception(exception)
|
||||||
render "errors/gitolite", layout: "errors", status: 500
|
render "errors/gitolite", layout: "errors", status: 500
|
||||||
end
|
end
|
||||||
|
|
||||||
rescue_from Encoding::CompatibilityError do |exception|
|
rescue_from Encoding::CompatibilityError do |exception|
|
||||||
|
log_exception(exception)
|
||||||
render "errors/encoding", layout: "errors", status: 500
|
render "errors/encoding", layout: "errors", status: 500
|
||||||
end
|
end
|
||||||
|
|
||||||
rescue_from ActiveRecord::RecordNotFound do |exception|
|
rescue_from ActiveRecord::RecordNotFound do |exception|
|
||||||
|
log_exception(exception)
|
||||||
render "errors/not_found", layout: "errors", status: 404
|
render "errors/not_found", layout: "errors", status: 404
|
||||||
end
|
end
|
||||||
|
|
||||||
protected
|
protected
|
||||||
|
|
||||||
|
def log_exception(exception)
|
||||||
|
application_trace = ActionDispatch::ExceptionWrapper.new(env, exception).application_trace
|
||||||
|
application_trace.map!{ |t| " #{t}\n" }
|
||||||
|
logger.error "\n#{exception.class.name} (#{exception.message}):\n#{application_trace.join}"
|
||||||
|
end
|
||||||
|
|
||||||
def reject_blocked!
|
def reject_blocked!
|
||||||
if current_user && current_user.blocked
|
if current_user && current_user.blocked
|
||||||
sign_out current_user
|
sign_out current_user
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
# Controller for viewing a file's blame
|
# Controller for viewing a file's blame
|
||||||
class BlobController < ProjectResourceController
|
class BlobController < ProjectResourceController
|
||||||
include ExtractsPath
|
include ExtractsPath
|
||||||
include Gitlab::Encode
|
|
||||||
|
|
||||||
# Authorize
|
# Authorize
|
||||||
before_filter :authorize_read_project!
|
before_filter :authorize_read_project!
|
||||||
|
@ -12,16 +11,9 @@ class BlobController < ProjectResourceController
|
||||||
|
|
||||||
def show
|
def show
|
||||||
if @tree.is_blob?
|
if @tree.is_blob?
|
||||||
if @tree.text?
|
|
||||||
encoding = detect_encoding(@tree.data)
|
|
||||||
mime_type = encoding ? "text/plain; charset=#{encoding}" : "text/plain"
|
|
||||||
else
|
|
||||||
mime_type = @tree.mime_type
|
|
||||||
end
|
|
||||||
|
|
||||||
send_data(
|
send_data(
|
||||||
@tree.data,
|
@tree.data,
|
||||||
type: mime_type,
|
type: @tree.mime_type,
|
||||||
disposition: 'inline',
|
disposition: 'inline',
|
||||||
filename: @tree.name
|
filename: @tree.name
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,12 +1,17 @@
|
||||||
class DashboardController < ApplicationController
|
class DashboardController < ApplicationController
|
||||||
respond_to :html
|
respond_to :html
|
||||||
|
|
||||||
|
before_filter :event_filter, only: :index
|
||||||
|
|
||||||
def index
|
def index
|
||||||
@groups = Group.where(id: current_user.projects.pluck(:group_id))
|
@groups = Group.where(id: current_user.projects.pluck(:group_id))
|
||||||
@projects = current_user.projects_with_events
|
@projects = current_user.projects_with_events
|
||||||
@projects = @projects.page(params[:page]).per(30)
|
@projects = @projects.page(params[:page]).per(30)
|
||||||
|
|
||||||
@events = Event.in_projects(current_user.project_ids).limit(20).offset(params[:offset] || 0)
|
@events = Event.in_projects(current_user.project_ids)
|
||||||
|
@events = @event_filter.apply_filter(@events)
|
||||||
|
@events = @events.limit(20).offset(params[:offset] || 0)
|
||||||
|
|
||||||
@last_push = current_user.recent_push
|
@last_push = current_user.recent_push
|
||||||
|
|
||||||
respond_to do |format|
|
respond_to do |format|
|
||||||
|
@ -34,4 +39,8 @@ class DashboardController < ApplicationController
|
||||||
format.atom { render layout: false }
|
format.atom { render layout: false }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def event_filter
|
||||||
|
@event_filter ||= EventFilter.new(params[:event_filter])
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -31,7 +31,8 @@ class MilestonesController < ProjectResourceController
|
||||||
|
|
||||||
def show
|
def show
|
||||||
@issues = @milestone.issues
|
@issues = @milestone.issues
|
||||||
@users = @milestone.participants
|
@users = UserDecorator.decorate(@milestone.participants)
|
||||||
|
@merge_requests = @milestone.merge_requests
|
||||||
|
|
||||||
respond_to do |format|
|
respond_to do |format|
|
||||||
format.html
|
format.html
|
||||||
|
|
|
@ -22,7 +22,7 @@ class ProfileController < ApplicationController
|
||||||
flash[:notice] = "Password was successfully updated. Please login with it"
|
flash[:notice] = "Password was successfully updated. Please login with it"
|
||||||
redirect_to new_user_session_path
|
redirect_to new_user_session_path
|
||||||
else
|
else
|
||||||
render action: "password"
|
render 'account'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
require Rails.root.join('lib', 'gitlab', 'graph_commit')
|
require Rails.root.join('lib', 'gitlab', 'graph', 'json_builder')
|
||||||
|
|
||||||
class ProjectsController < ProjectResourceController
|
class ProjectsController < ProjectResourceController
|
||||||
skip_before_filter :project, only: [:new, :create]
|
skip_before_filter :project, only: [:new, :create]
|
||||||
|
@ -79,7 +79,9 @@ class ProjectsController < ProjectResourceController
|
||||||
end
|
end
|
||||||
|
|
||||||
def graph
|
def graph
|
||||||
@days_json, @commits_json = Gitlab::GraphCommit.to_graph(project)
|
graph = Gitlab::Graph::JsonBuilder.new(project)
|
||||||
|
|
||||||
|
@days_json, @commits_json = graph.days_json, graph.commits_json
|
||||||
end
|
end
|
||||||
|
|
||||||
def destroy
|
def destroy
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
class RefsController < ProjectResourceController
|
class RefsController < ProjectResourceController
|
||||||
include Gitlab::Encode
|
|
||||||
|
|
||||||
# Authorize
|
# Authorize
|
||||||
before_filter :authorize_read_project!
|
before_filter :authorize_read_project!
|
||||||
|
|
|
@ -16,9 +16,14 @@ class RepositoriesController < ProjectResourceController
|
||||||
@tags = @project.tags
|
@tags = @project.tags
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def stats
|
||||||
|
@stats = Gitlab::GitStats.new(@project.repo, @project.root_ref)
|
||||||
|
@graph = @stats.graph
|
||||||
|
end
|
||||||
|
|
||||||
def archive
|
def archive
|
||||||
unless can?(current_user, :download_code, @project)
|
unless can?(current_user, :download_code, @project)
|
||||||
render_404 and return
|
render_404 and return
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -5,5 +5,6 @@ class SearchController < ApplicationController
|
||||||
@projects = result[:projects]
|
@projects = result[:projects]
|
||||||
@merge_requests = result[:merge_requests]
|
@merge_requests = result[:merge_requests]
|
||||||
@issues = result[:issues]
|
@issues = result[:issues]
|
||||||
|
@wiki_pages = result[:wiki_pages]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -26,15 +26,14 @@ class TreeController < ProjectResourceController
|
||||||
end
|
end
|
||||||
|
|
||||||
def update
|
def update
|
||||||
file_editor = Gitlab::FileEditor.new(current_user, @project, @ref)
|
edit_file_action = Gitlab::Satellite::EditFileAction.new(current_user, @project, @ref, @path)
|
||||||
update_status = file_editor.update(
|
updated_successfully = edit_file_action.commit!(
|
||||||
@path,
|
|
||||||
params[:content],
|
params[:content],
|
||||||
params[:commit_message],
|
params[:commit_message],
|
||||||
params[:last_commit]
|
params[:last_commit]
|
||||||
)
|
)
|
||||||
|
|
||||||
if update_status
|
if updated_successfully
|
||||||
redirect_to project_tree_path(@project, @id), notice: "Your changes have been successfully commited"
|
redirect_to project_tree_path(@project, @id), notice: "Your changes have been successfully commited"
|
||||||
else
|
else
|
||||||
flash[:notice] = "Your changes could not be commited, because the file has been changed"
|
flash[:notice] = "Your changes could not be commited, because the file has been changed"
|
||||||
|
|
|
@ -47,21 +47,15 @@ class CommitDecorator < ApplicationDecorator
|
||||||
# Otherwise it will link to the author email as specified in the commit.
|
# Otherwise it will link to the author email as specified in the commit.
|
||||||
#
|
#
|
||||||
# options:
|
# options:
|
||||||
# avatar: true will prepend avatar image
|
# avatar: true will prepend the avatar image
|
||||||
def author_link(options)
|
# size: size of the avatar image in px
|
||||||
text = if options[:avatar]
|
def author_link(options = {})
|
||||||
avatar = h.image_tag h.gravatar_icon(author_email), class: "avatar", width: 16
|
person_link(options.merge source: :author)
|
||||||
"#{avatar} #{author_name}"
|
end
|
||||||
else
|
|
||||||
author_name
|
|
||||||
end
|
|
||||||
team_member = @project.try(:team_member_by_name_or_email, author_name, author_email)
|
|
||||||
|
|
||||||
if team_member.nil?
|
# Just like #author_link but for the committer.
|
||||||
h.mail_to author_email, text.html_safe, class: "commit-author-link"
|
def committer_link(options = {})
|
||||||
else
|
person_link(options.merge source: :committer)
|
||||||
h.link_to text, h.project_team_member_path(@project, team_member), class: "commit-author-link"
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
protected
|
protected
|
||||||
|
@ -69,4 +63,30 @@ class CommitDecorator < ApplicationDecorator
|
||||||
def no_commit_message
|
def no_commit_message
|
||||||
"--no commit message"
|
"--no commit message"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Private: Returns a link to a person. If the person has a matching user and
|
||||||
|
# is a member of the current @project it will link to the team member page.
|
||||||
|
# Otherwise it will link to the person email as specified in the commit.
|
||||||
|
#
|
||||||
|
# options:
|
||||||
|
# source: one of :author or :committer
|
||||||
|
# avatar: true will prepend the avatar image
|
||||||
|
# size: size of the avatar image in px
|
||||||
|
def person_link(options = {})
|
||||||
|
source_name = send "#{options[:source]}_name".to_sym
|
||||||
|
source_email = send "#{options[:source]}_email".to_sym
|
||||||
|
text = if options[:avatar]
|
||||||
|
avatar = h.image_tag h.gravatar_icon(source_email, options[:size]), class: "avatar #{"s#{options[:size]}" if options[:size]}", width: options[:size]
|
||||||
|
%Q{#{avatar} <span class="commit-#{options[:source]}-name">#{source_name}</span>}
|
||||||
|
else
|
||||||
|
source_name
|
||||||
|
end
|
||||||
|
team_member = @project.try(:team_member_by_name_or_email, source_name, source_email)
|
||||||
|
|
||||||
|
if team_member.nil?
|
||||||
|
h.mail_to source_email, text.html_safe, class: "commit-#{options[:source]}-link"
|
||||||
|
else
|
||||||
|
h.link_to text, h.project_team_member_path(@project, team_member), class: "commit-#{options[:source]}-link"
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -8,14 +8,14 @@ class TreeDecorator < ApplicationDecorator
|
||||||
|
|
||||||
#parts = parts[0...-1] if is_blob?
|
#parts = parts[0...-1] if is_blob?
|
||||||
|
|
||||||
yield(h.link_to("..", "#", remote: true)) if parts.count > max_links
|
yield(h.link_to("..", "#")) if parts.count > max_links
|
||||||
|
|
||||||
parts.each do |part|
|
parts.each do |part|
|
||||||
part_path = File.join(part_path, part) unless part_path.empty?
|
part_path = File.join(part_path, part) unless part_path.empty?
|
||||||
part_path = part if part_path.empty?
|
part_path = part if part_path.empty?
|
||||||
|
|
||||||
next unless parts.last(2).include?(part) if parts.count > max_links
|
next unless parts.last(2).include?(part) if parts.count > max_links
|
||||||
yield(h.link_to(h.truncate(part, length: 40), h.project_tree_path(project, h.tree_join(ref, part_path)), remote: true))
|
yield(h.link_to(h.truncate(part, length: 40), h.project_tree_path(project, h.tree_join(ref, part_path))))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
11
app/decorators/user_decorator.rb
Normal file
11
app/decorators/user_decorator.rb
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
class UserDecorator < ApplicationDecorator
|
||||||
|
decorates :user
|
||||||
|
|
||||||
|
def avatar_image size = 16
|
||||||
|
h.image_tag h.gravatar_icon(self.email, size), class: "avatar #{"s#{size}"}", width: size
|
||||||
|
end
|
||||||
|
|
||||||
|
def tm_of(project)
|
||||||
|
project.team_member_by_id(self.id)
|
||||||
|
end
|
||||||
|
end
|
|
@ -36,7 +36,7 @@ module ApplicationHelper
|
||||||
else
|
else
|
||||||
gravatar_prefix = request.ssl? ? "https://secure" : "http://www"
|
gravatar_prefix = request.ssl? ? "https://secure" : "http://www"
|
||||||
user_email.strip!
|
user_email.strip!
|
||||||
"#{gravatar_prefix}.gravatar.com/avatar/#{Digest::MD5.hexdigest(user_email.downcase)}?s=#{size}&d=identicon"
|
"#{gravatar_prefix}.gravatar.com/avatar/#{Digest::MD5.hexdigest(user_email.downcase)}?s=#{size}&d=mm"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -65,4 +65,9 @@ module CommitsHelper
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def commit_to_html commit
|
||||||
|
if commit.model
|
||||||
|
escape_javascript(render 'commits/commit', commit: commit)
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -33,4 +33,22 @@ module EventsHelper
|
||||||
image_tag event_image_path
|
image_tag event_image_path
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def event_filter_link key, tooltip
|
||||||
|
key = key.to_s
|
||||||
|
|
||||||
|
filter = @event_filter.options key
|
||||||
|
|
||||||
|
inactive = if @event_filter.active? key
|
||||||
|
nil
|
||||||
|
else
|
||||||
|
'inactive'
|
||||||
|
end
|
||||||
|
|
||||||
|
content_tag :div, class: "filter_icon #{inactive}" do
|
||||||
|
link_to dashboard_path(event_filter: filter), class: 'has_tooltip', 'data-original-title' => tooltip do
|
||||||
|
image_tag "event_filter_#{key}.png"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -10,5 +10,9 @@ module ProjectsHelper
|
||||||
def link_to_project project
|
def link_to_project project
|
||||||
link_to project.name, project
|
link_to project.name, project
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def tm_path team_member
|
||||||
|
project_team_member_path(@project, team_member)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -67,4 +67,29 @@ module TreeHelper
|
||||||
can?(current_user, :push_code, @project)
|
can?(current_user, :push_code, @project)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Breadcrumb links for a Project and, if applicable, a tree path
|
||||||
|
def breadcrumbs
|
||||||
|
return unless @project && @ref
|
||||||
|
|
||||||
|
# Add the root project link and the arrow icon
|
||||||
|
crumbs = content_tag(:li) do
|
||||||
|
content_tag(:span, nil, class: 'arrow') +
|
||||||
|
link_to(@project.name, project_commits_path(@project, @ref))
|
||||||
|
end
|
||||||
|
|
||||||
|
if @path
|
||||||
|
parts = @path.split('/')
|
||||||
|
|
||||||
|
parts.each_with_index do |part, i|
|
||||||
|
crumbs += content_tag(:span, '/', class: 'divider')
|
||||||
|
crumbs += content_tag(:li) do
|
||||||
|
# The text is just the individual part, but the link needs all the parts before it
|
||||||
|
link_to part, project_commits_path(@project, tree_join(@ref, parts[0..i].join('/')))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
crumbs.html_safe
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,9 +1,13 @@
|
||||||
class Commit
|
class Commit
|
||||||
include ActiveModel::Conversion
|
include ActiveModel::Conversion
|
||||||
include Gitlab::Encode
|
|
||||||
include StaticModel
|
include StaticModel
|
||||||
extend ActiveModel::Naming
|
extend ActiveModel::Naming
|
||||||
|
|
||||||
|
# Safe amount of files with diffs in one commit to render
|
||||||
|
# Used to prevent 500 error on huge commits by suppressing diff
|
||||||
|
#
|
||||||
|
DIFF_SAFE_SIZE = 100
|
||||||
|
|
||||||
attr_accessor :commit, :head, :refs
|
attr_accessor :commit, :head, :refs
|
||||||
|
|
||||||
delegate :message, :authored_date, :committed_date, :parents, :sha,
|
delegate :message, :authored_date, :committed_date, :parents, :sha,
|
||||||
|
@ -107,7 +111,7 @@ class Commit
|
||||||
end
|
end
|
||||||
|
|
||||||
def safe_message
|
def safe_message
|
||||||
@safe_message ||= utf8 message
|
@safe_message ||= message
|
||||||
end
|
end
|
||||||
|
|
||||||
def created_at
|
def created_at
|
||||||
|
@ -119,7 +123,7 @@ class Commit
|
||||||
end
|
end
|
||||||
|
|
||||||
def author_name
|
def author_name
|
||||||
utf8 author.name
|
author.name
|
||||||
end
|
end
|
||||||
|
|
||||||
# Was this commit committed by a different person than the original author?
|
# Was this commit committed by a different person than the original author?
|
||||||
|
@ -128,7 +132,7 @@ class Commit
|
||||||
end
|
end
|
||||||
|
|
||||||
def committer_name
|
def committer_name
|
||||||
utf8 committer.name
|
committer.name
|
||||||
end
|
end
|
||||||
|
|
||||||
def committer_email
|
def committer_email
|
||||||
|
|
|
@ -7,8 +7,6 @@ class Issue < ActiveRecord::Base
|
||||||
|
|
||||||
acts_as_taggable_on :labels
|
acts_as_taggable_on :labels
|
||||||
|
|
||||||
belongs_to :milestone
|
|
||||||
|
|
||||||
validates :description, length: { within: 0..2000 }
|
validates :description, length: { within: 0..2000 }
|
||||||
|
|
||||||
def self.open_for(user)
|
def self.open_for(user)
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
require Rails.root.join("app/models/commit")
|
require Rails.root.join("app/models/commit")
|
||||||
|
require Rails.root.join("app/roles/static_model")
|
||||||
|
|
||||||
class MergeRequest < ActiveRecord::Base
|
class MergeRequest < ActiveRecord::Base
|
||||||
include IssueCommonality
|
include IssueCommonality
|
||||||
include Votes
|
include Votes
|
||||||
|
|
||||||
attr_accessible :title, :assignee_id, :closed, :target_branch, :source_branch,
|
attr_accessible :title, :assignee_id, :closed, :target_branch, :source_branch, :milestone_id,
|
||||||
:author_id_of_changes
|
:author_id_of_changes
|
||||||
|
|
||||||
attr_accessor :should_remove_source_branch
|
attr_accessor :should_remove_source_branch
|
||||||
|
@ -26,6 +27,10 @@ class MergeRequest < ActiveRecord::Base
|
||||||
where("source_branch LIKE :branch OR target_branch LIKE :branch", branch: branch_name)
|
where("source_branch LIKE :branch OR target_branch LIKE :branch", branch: branch_name)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def self.find_all_by_milestone(milestone)
|
||||||
|
where("milestone_id = :milestone_id", milestone_id: milestone)
|
||||||
|
end
|
||||||
|
|
||||||
def human_state
|
def human_state
|
||||||
states = {
|
states = {
|
||||||
CAN_BE_MERGED => "can_be_merged",
|
CAN_BE_MERGED => "can_be_merged",
|
||||||
|
@ -60,7 +65,7 @@ class MergeRequest < ActiveRecord::Base
|
||||||
end
|
end
|
||||||
|
|
||||||
def check_if_can_be_merged
|
def check_if_can_be_merged
|
||||||
self.state = if Gitlab::Merge.new(self, self.author).can_be_merged?
|
self.state = if Gitlab::Satellite::MergeAction.new(self.author, self).can_be_merged?
|
||||||
CAN_BE_MERGED
|
CAN_BE_MERGED
|
||||||
else
|
else
|
||||||
CANNOT_BE_MERGED
|
CANNOT_BE_MERGED
|
||||||
|
@ -167,7 +172,7 @@ class MergeRequest < ActiveRecord::Base
|
||||||
end
|
end
|
||||||
|
|
||||||
def automerge!(current_user)
|
def automerge!(current_user)
|
||||||
if Gitlab::Merge.new(self, current_user).merge! && self.unmerged_commits.empty?
|
if Gitlab::Satellite::MergeAction.new(current_user, self).merge! && self.unmerged_commits.empty?
|
||||||
self.merge!(current_user.id)
|
self.merge!(current_user.id)
|
||||||
true
|
true
|
||||||
end
|
end
|
||||||
|
@ -212,5 +217,6 @@ end
|
||||||
# st_diffs :text(4294967295
|
# st_diffs :text(4294967295
|
||||||
# merged :boolean default(FALSE), not null
|
# merged :boolean default(FALSE), not null
|
||||||
# state :integer default(1), not null
|
# state :integer default(1), not null
|
||||||
|
# milestone_id :integer
|
||||||
#
|
#
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@ class Milestone < ActiveRecord::Base
|
||||||
|
|
||||||
belongs_to :project
|
belongs_to :project
|
||||||
has_many :issues
|
has_many :issues
|
||||||
|
has_many :merge_requests
|
||||||
|
|
||||||
validates :title, presence: true
|
validates :title, presence: true
|
||||||
validates :project, presence: true
|
validates :project, presence: true
|
||||||
|
@ -15,8 +16,20 @@ class Milestone < ActiveRecord::Base
|
||||||
User.where(id: issues.pluck(:assignee_id))
|
User.where(id: issues.pluck(:assignee_id))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def open_items_count
|
||||||
|
self.issues.opened.count + self.merge_requests.opened.count
|
||||||
|
end
|
||||||
|
|
||||||
|
def closed_items_count
|
||||||
|
self.issues.closed.count + self.merge_requests.closed.count
|
||||||
|
end
|
||||||
|
|
||||||
|
def total_items_count
|
||||||
|
self.issues.count + self.merge_requests.count
|
||||||
|
end
|
||||||
|
|
||||||
def percent_complete
|
def percent_complete
|
||||||
((self.issues.closed.count * 100) / self.issues.count).abs
|
((closed_items_count * 100) / total_items_count).abs
|
||||||
rescue ZeroDivisionError
|
rescue ZeroDivisionError
|
||||||
100
|
100
|
||||||
end
|
end
|
||||||
|
|
|
@ -23,13 +23,13 @@ class Note < ActiveRecord::Base
|
||||||
mount_uploader :attachment, AttachmentUploader
|
mount_uploader :attachment, AttachmentUploader
|
||||||
|
|
||||||
# Scopes
|
# Scopes
|
||||||
scope :common, where(noteable_id: nil)
|
scope :common, ->{ where(noteable_id: nil) }
|
||||||
scope :today, where("created_at >= :date", date: Date.today)
|
scope :today, ->{ where("created_at >= :date", date: Date.today) }
|
||||||
scope :last_week, where("created_at >= :date", date: (Date.today - 7.days))
|
scope :last_week, ->{ where("created_at >= :date", date: (Date.today - 7.days)) }
|
||||||
scope :since, ->(day) { where("created_at >= :date", date: (day)) }
|
scope :since, ->(day) { where("created_at >= :date", date: (day)) }
|
||||||
scope :fresh, order("created_at ASC, id ASC")
|
scope :fresh, ->{ order("created_at ASC, id ASC") }
|
||||||
scope :inc_author_project, includes(:project, :author)
|
scope :inc_author_project, ->{ includes(:project, :author) }
|
||||||
scope :inc_author, includes(:author)
|
scope :inc_author, ->{ includes(:author) }
|
||||||
|
|
||||||
def self.create_status_change_note(noteable, author, status)
|
def self.create_status_change_note(noteable, author, status)
|
||||||
create({
|
create({
|
||||||
|
|
|
@ -104,8 +104,10 @@ class Project < ActiveRecord::Base
|
||||||
end
|
end
|
||||||
|
|
||||||
def repo_name
|
def repo_name
|
||||||
if path == "gitolite-admin"
|
denied_paths = %w(gitolite-admin groups projects dashboard)
|
||||||
errors.add(:path, " like 'gitolite-admin' is not allowed")
|
|
||||||
|
if denied_paths.include?(path)
|
||||||
|
errors.add(:path, "like #{path} is not allowed")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@ class Tree
|
||||||
def initialize(raw_tree, project, ref = nil, path = nil)
|
def initialize(raw_tree, project, ref = nil, path = nil)
|
||||||
@project, @ref, @path = project, ref, path
|
@project, @ref, @path = project, ref, path
|
||||||
@tree = if path.present?
|
@tree = if path.present?
|
||||||
raw_tree / path.dup.force_encoding('ascii-8bit')
|
raw_tree / path
|
||||||
else
|
else
|
||||||
raw_tree
|
raw_tree
|
||||||
end
|
end
|
||||||
|
|
|
@ -15,6 +15,12 @@ class Wiki < ActiveRecord::Base
|
||||||
slug
|
slug
|
||||||
end
|
end
|
||||||
|
|
||||||
|
class << self
|
||||||
|
def search(query)
|
||||||
|
where("title like :query OR content like :query", query: "%#{query}%")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
protected
|
protected
|
||||||
|
|
||||||
def self.regenerate_from wiki
|
def self.regenerate_from wiki
|
||||||
|
|
|
@ -6,6 +6,7 @@ module IssueCommonality
|
||||||
belongs_to :project
|
belongs_to :project
|
||||||
belongs_to :author, class_name: "User"
|
belongs_to :author, class_name: "User"
|
||||||
belongs_to :assignee, class_name: "User"
|
belongs_to :assignee, class_name: "User"
|
||||||
|
belongs_to :milestone
|
||||||
has_many :notes, as: :noteable, dependent: :destroy
|
has_many :notes, as: :noteable, dependent: :destroy
|
||||||
|
|
||||||
validates :project, presence: true
|
validates :project, presence: true
|
||||||
|
|
|
@ -41,7 +41,7 @@ module Repository
|
||||||
end
|
end
|
||||||
|
|
||||||
def satellite
|
def satellite
|
||||||
@satellite ||= Gitlab::Satellite.new(self)
|
@satellite ||= Gitlab::Satellite::Satellite.new(self)
|
||||||
end
|
end
|
||||||
|
|
||||||
def has_post_receive_file?
|
def has_post_receive_file?
|
||||||
|
|
|
@ -43,7 +43,7 @@
|
||||||
%b
|
%b
|
||||||
Owner:
|
Owner:
|
||||||
%td
|
%td
|
||||||
= @admin_project.owner.name
|
= @admin_project.owner_name || '(deleted)'
|
||||||
%tr
|
%tr
|
||||||
%td
|
%td
|
||||||
%b
|
%b
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
%h3.page_title Resque
|
%h3.page_title Resque
|
||||||
%br
|
%br
|
||||||
.ui-box
|
.ui-box
|
||||||
%iframe{src: resque_url, width: '100%', height: 600, style: "border: none"}
|
%iframe{src: resque_path, width: '100%', height: 600, style: "border: none"}
|
||||||
|
|
|
@ -4,7 +4,4 @@
|
||||||
= nav_link(controller: :refs) do
|
= nav_link(controller: :refs) do
|
||||||
= link_to 'Source', project_tree_path(@project, @ref)
|
= link_to 'Source', project_tree_path(@project, @ref)
|
||||||
%li.right
|
%li.right
|
||||||
.input-prepend.project_clone_holder
|
= render "shared/clone_panel"
|
||||||
%button{class: "btn small active", :"data-clone" => @project.ssh_url_to_repo} SSH
|
|
||||||
%button{class: "btn small", :"data-clone" => @project.http_url_to_repo}= Gitlab.config.web_protocol.upcase
|
|
||||||
= text_field_tag :project_clone, @project.url_to_repo, class: "one_click_select span5"
|
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
.file_title
|
.file_title
|
||||||
%i.icon-file
|
%i.icon-file
|
||||||
%span.file_name
|
%span.file_name
|
||||||
= @tree.name.force_encoding('utf-8')
|
= @tree.name
|
||||||
%small= number_to_human_size @tree.size
|
%small= number_to_human_size @tree.size
|
||||||
%span.options= render "tree/blob_actions"
|
%span.options= render "tree/blob_actions"
|
||||||
.file_content.blame
|
.file_content.blame
|
||||||
|
@ -24,9 +24,7 @@
|
||||||
- commit = Commit.new(commit)
|
- commit = Commit.new(commit)
|
||||||
- commit = CommitDecorator.decorate(commit)
|
- commit = CommitDecorator.decorate(commit)
|
||||||
%tr
|
%tr
|
||||||
%td.author
|
%td.author= commit.author_link avatar: true, size: 16
|
||||||
= image_tag gravatar_icon(commit.author_email, 16)
|
|
||||||
= commit.author_name
|
|
||||||
%td.blame_commit
|
%td.blame_commit
|
||||||
|
|
||||||
%code= link_to commit.short_id, project_commit_path(@project, commit)
|
%code= link_to commit.short_id, project_commit_path(@project, commit)
|
||||||
|
@ -34,4 +32,4 @@
|
||||||
%td.lines
|
%td.lines
|
||||||
= preserve do
|
= preserve do
|
||||||
%pre
|
%pre
|
||||||
= Gitlab::Encode.utf8 lines.join("\n")
|
= lines.join("\n")
|
||||||
|
|
|
@ -4,9 +4,8 @@
|
||||||
%strong= link_to "Browse Code »", project_tree_path(@project, commit), class: "right"
|
%strong= link_to "Browse Code »", project_tree_path(@project, commit), class: "right"
|
||||||
%p
|
%p
|
||||||
= link_to commit.short_id(8), project_commit_path(@project, commit), class: "commit_short_id"
|
= link_to commit.short_id(8), project_commit_path(@project, commit), class: "commit_short_id"
|
||||||
%strong.commit-author-name= commit.author_name
|
= commit.author_link avatar: true, size: 24
|
||||||
%span.dash –
|
|
||||||
= image_tag gravatar_icon(commit.author_email), class: "avatar", width: 16
|
|
||||||
= link_to_gfm truncate(commit.title, length: 50), project_commit_path(@project, commit.id), class: "row_title"
|
= link_to_gfm truncate(commit.title, length: 50), project_commit_path(@project, commit.id), class: "row_title"
|
||||||
|
|
||||||
%span.committed_ago
|
%span.committed_ago
|
||||||
|
|
|
@ -18,16 +18,15 @@
|
||||||
.commit-info
|
.commit-info
|
||||||
.row
|
.row
|
||||||
.span5
|
.span5
|
||||||
= image_tag gravatar_icon(@commit.author_email, 40), class: "avatar"
|
|
||||||
.author
|
.author
|
||||||
%strong= @commit.author_name
|
%strong= @commit.author_link avatar: true, size: 40
|
||||||
authored
|
authored
|
||||||
%time{title: @commit.authored_date.stamp("Aug 21, 2011 9:23pm")}
|
%time{title: @commit.authored_date.stamp("Aug 21, 2011 9:23pm")}
|
||||||
#{time_ago_in_words(@commit.authored_date)} ago
|
#{time_ago_in_words(@commit.authored_date)} ago
|
||||||
- if @commit.different_committer?
|
- if @commit.different_committer?
|
||||||
.committer
|
.committer
|
||||||
→
|
→
|
||||||
%strong= @commit.committer_name
|
%strong= @commit.committer_link
|
||||||
committed
|
committed
|
||||||
%time{title: @commit.committed_date.stamp("Aug 21, 2011 9:23pm")}
|
%time{title: @commit.committed_date.stamp("Aug 21, 2011 9:23pm")}
|
||||||
#{time_ago_in_words(@commit.committed_date)} ago
|
#{time_ago_in_words(@commit.committed_date)} ago
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
- if @suppress_diff
|
- if @suppress_diff
|
||||||
.alert-message.block-message
|
.alert-message.block-message
|
||||||
%p
|
%p
|
||||||
%strong Warning! Large commit with more then 200 files changed.
|
%strong Warning! Large commit with more then #{Commit::DIFF_SAFE_SIZE} files changed.
|
||||||
%p To prevent performance issue we rejected diff information.
|
%p To prevent performance issue we rejected diff information.
|
||||||
%p
|
%p
|
||||||
But if you still want to see diff
|
But if you still want to see diff
|
||||||
= link_to "click this link", project_commit_path(@project, @commit, force_show_diff: true), class: "dark"
|
= link_to "click this link", project_commit_path(@project, @commit, force_show_diff: true), class: "underlined_link"
|
||||||
|
|
||||||
%p.cgray
|
%p.cgray
|
||||||
Showing #{pluralize(diffs.count, "changed file")}
|
Showing #{pluralize(diffs.count, "changed file")}
|
||||||
|
@ -35,10 +35,10 @@
|
||||||
- if file.text?
|
- if file.text?
|
||||||
= render "commits/text_file", diff: diff, index: i
|
= render "commits/text_file", diff: diff, index: i
|
||||||
- elsif file.image?
|
- elsif file.image?
|
||||||
- if diff.renamed_file || diff.new_file || diff.deleted_file
|
- if diff.renamed_file || diff.new_file || diff.deleted_file
|
||||||
.diff_file_content_image
|
.diff_file_content_image
|
||||||
%img{class: image_diff_class(diff), src: "data:#{file.mime_type};base64,#{Base64.encode64(file.data)}"}
|
%img{class: image_diff_class(diff), src: "data:#{file.mime_type};base64,#{Base64.encode64(file.data)}"}
|
||||||
- else
|
- else
|
||||||
- old_file = (@commit.prev_commit.tree / diff.old_path)
|
- old_file = (@commit.prev_commit.tree / diff.old_path)
|
||||||
.diff_file_content_image.img_compared
|
.diff_file_content_image.img_compared
|
||||||
%img{class: "diff_image_removed", src: "data:#{file.mime_type};base64,#{Base64.encode64(old_file.data)}"}
|
%img{class: "diff_image_removed", src: "data:#{file.mime_type};base64,#{Base64.encode64(old_file.data)}"}
|
||||||
|
|
|
@ -16,6 +16,11 @@
|
||||||
Tags
|
Tags
|
||||||
%span.badge= @project.tags.length
|
%span.badge= @project.tags.length
|
||||||
|
|
||||||
|
= nav_link(controller: :repositories, action: :stats) do
|
||||||
|
= link_to stats_project_repository_path(@project) do
|
||||||
|
Stats
|
||||||
|
|
||||||
|
|
||||||
- if current_controller?(:commits) && current_user.private_token
|
- if current_controller?(:commits) && current_user.private_token
|
||||||
%li.right
|
%li.right
|
||||||
%span.rss-icon
|
%span.rss-icon
|
||||||
|
|
|
@ -2,14 +2,7 @@
|
||||||
|
|
||||||
- if @path.present?
|
- if @path.present?
|
||||||
%ul.breadcrumb
|
%ul.breadcrumb
|
||||||
%li
|
= breadcrumbs
|
||||||
%span.arrow
|
|
||||||
= link_to project_commits_path(@project) do
|
|
||||||
= @project.name
|
|
||||||
%span.divider
|
|
||||||
\/
|
|
||||||
%li
|
|
||||||
%a{href: "#"}= @path.split("/").join(" / ")
|
|
||||||
|
|
||||||
%div{id: dom_id(@project)}
|
%div{id: dom_id(@project)}
|
||||||
#commits_list= render "commits"
|
#commits_list= render "commits"
|
||||||
|
|
|
@ -3,10 +3,17 @@
|
||||||
.activities.span8
|
.activities.span8
|
||||||
= render "events/event_last_push", event: @last_push
|
= render "events/event_last_push", event: @last_push
|
||||||
= render 'shared/no_ssh'
|
= render 'shared/no_ssh'
|
||||||
|
|
||||||
|
.event_filter
|
||||||
|
= event_filter_link EventFilter.push, 'Push events'
|
||||||
|
= event_filter_link EventFilter.merged, 'Merge events'
|
||||||
|
= event_filter_link EventFilter.comments, 'Comments'
|
||||||
|
= event_filter_link EventFilter.team, 'Team'
|
||||||
|
|
||||||
- if @events.any?
|
- if @events.any?
|
||||||
.content_list= render @events
|
.content_list= render @events
|
||||||
- else
|
- else
|
||||||
%h4.nothing_here_message Projects activity will be displayed here
|
%p.nothing_here_message Projects activity will be displayed here
|
||||||
.loading.hide
|
.loading.hide
|
||||||
.side
|
.side
|
||||||
- if @groups.present?
|
- if @groups.present?
|
||||||
|
|
|
@ -14,8 +14,9 @@
|
||||||
= f.submit "Sign in", :class => "primary btn wide"
|
= f.submit "Sign in", :class => "primary btn wide"
|
||||||
.right
|
.right
|
||||||
= render :partial => "devise/shared/links"
|
= render :partial => "devise/shared/links"
|
||||||
- if devise_mapping.omniauthable?
|
.clearfix
|
||||||
%hr/
|
- if devise_mapping.omniauthable? && resource_class.omniauth_providers.present?
|
||||||
- resource_class.omniauth_providers.each do |provider|
|
%div
|
||||||
%span
|
- resource_class.omniauth_providers.each do |provider|
|
||||||
= link_to authbutton(provider, 32), omniauth_authorize_path(resource_name, provider)
|
%span
|
||||||
|
= link_to authbutton(provider, 32), omniauth_authorize_path(resource_name, provider)
|
||||||
|
|
|
@ -5,9 +5,10 @@
|
||||||
%hr
|
%hr
|
||||||
|
|
||||||
%p.slead
|
%p.slead
|
||||||
Your GitLab instance can perform HTTP POST request on next event: create_project, delete_project, create_user, delete_user, change_team_member.
|
Your GitLab instance can perform HTTP POST requests on the following events: create_project, delete_project, create_user, delete_user, change_team_member.
|
||||||
%br
|
%br
|
||||||
System Hooks can be used for logging or change information in LDAP server.
|
%br
|
||||||
|
System Hooks can be used, e.g. for logging or changing information in a LDAP server.
|
||||||
%br
|
%br
|
||||||
%h5 Hooks request example:
|
%h5 Hooks request example:
|
||||||
= render "admin/hooks/data_ex"
|
= render "admin/hooks/data_ex"
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
= f.label :title do
|
= f.label :title do
|
||||||
%strong= "Subject *"
|
%strong= "Subject *"
|
||||||
.input
|
.input
|
||||||
= f.text_field :title, maxlength: 255, class: "xxlarge gfm-input", autofocus: true
|
= f.text_field :title, maxlength: 255, class: "xxlarge js-gfm-input", autofocus: true
|
||||||
.issue_middle_block
|
.issue_middle_block
|
||||||
.issue_assignee
|
.issue_assignee
|
||||||
= f.label :assignee_id do
|
= f.label :assignee_id do
|
||||||
|
@ -37,7 +37,7 @@
|
||||||
.clearfix
|
.clearfix
|
||||||
= f.label :description, "Details"
|
= f.label :description, "Details"
|
||||||
.input
|
.input
|
||||||
= f.text_area :description, maxlength: 2000, class: "xxlarge gfm-input", rows: 14
|
= f.text_area :description, maxlength: 2000, class: "xxlarge js-gfm-input", rows: 14
|
||||||
%p.hint Issues are parsed with #{link_to "GitLab Flavored Markdown", help_markdown_path, target: '_blank'}.
|
%p.hint Issues are parsed with #{link_to "GitLab Flavored Markdown", help_markdown_path, target: '_blank'}.
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
:plain
|
:plain
|
||||||
var edit_issue_dialog = $("<div id='edit_issue_dialog'></div>");
|
$("#edit_issue_dialog").html("#{escape_javascript(render('form'))}");
|
||||||
edit_issue_dialog.html("#{escape_javascript(render('form'))}");
|
switchToEditIssue();
|
||||||
switchToEditIssue(edit_issue_dialog);
|
|
||||||
|
|
||||||
|
|
|
@ -58,6 +58,8 @@
|
||||||
%ul#issues-table.unstyled.issues_table
|
%ul#issues-table.unstyled.issues_table
|
||||||
= render "issues"
|
= render "issues"
|
||||||
|
|
||||||
|
#new_issue_dialog
|
||||||
|
#edit_issue_dialog
|
||||||
|
|
||||||
:javascript
|
:javascript
|
||||||
$(function(){
|
$(function(){
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
:plain
|
:plain
|
||||||
var new_issue_dialog = $("<div id='new_issue_dialog'></div>");
|
$("#new_issue_dialog").html("#{escape_javascript(render('form'))}");
|
||||||
new_issue_dialog.html("#{escape_javascript(render('form'))}");
|
switchToNewIssue();
|
||||||
switchToNewIssue(new_issue_dialog);
|
|
||||||
|
|
|
@ -8,9 +8,7 @@
|
||||||
GITLAB
|
GITLAB
|
||||||
%span.separator
|
%span.separator
|
||||||
%h1.project_name= title
|
%h1.project_name= title
|
||||||
.search
|
= render "layouts/search"
|
||||||
= form_tag search_path, method: :get do |f|
|
|
||||||
= text_field_tag "search", nil, placeholder: "Search", class: "search-input"
|
|
||||||
.fbtn
|
.fbtn
|
||||||
- if current_user.is_admin?
|
- if current_user.is_admin?
|
||||||
= link_to admin_root_path, class: "btn small", title: "Admin area" do
|
= link_to admin_root_path, class: "btn small", title: "Admin area" do
|
||||||
|
@ -29,11 +27,3 @@
|
||||||
= link_to 'Logout', destroy_user_session_path, class: "logout", method: :delete
|
= link_to 'Logout', destroy_user_session_path, class: "logout", method: :delete
|
||||||
|
|
||||||
= render "layouts/init_auto_complete"
|
= render "layouts/init_auto_complete"
|
||||||
|
|
||||||
:javascript
|
|
||||||
$(function(){
|
|
||||||
$("#search").autocomplete({
|
|
||||||
source: #{raw search_autocomplete_source},
|
|
||||||
select: function(event, ui) { location.href = ui.item.url }
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
:javascript
|
:javascript
|
||||||
$(function() {
|
$(function() {
|
||||||
autocompleteMembersUrl = "#{ "/api/v2/projects/#{@project.code}/members" if @project }";
|
autocompleteMembers.url = "#{ "/api/v2/projects/#{@project.code}/members" if @project }";
|
||||||
autocompleteMembersParams.private_token = "#{current_user.authentication_token}";
|
autocompleteMembers.params.private_token = "#{current_user.private_token}";
|
||||||
|
|
||||||
autocompleteEmojiData = #{raw emoji_autocomplete_source};
|
autocompleteEmoji.data = #{raw emoji_autocomplete_source};
|
||||||
// convert the list so that the items have the right format for completion
|
// convert the list so that the items have the right format for completion
|
||||||
autocompleteEmojiData = $.map(autocompleteEmojiData, function(value) {
|
autocompleteEmoji.data = $.map(autocompleteEmoji.data, function(value) {
|
||||||
return {
|
return {
|
||||||
name: value,
|
name: value,
|
||||||
insert: value+':',
|
insert: value+':',
|
||||||
|
|
11
app/views/layouts/_search.html.haml
Normal file
11
app/views/layouts/_search.html.haml
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
.search
|
||||||
|
= form_tag search_path, method: :get do |f|
|
||||||
|
= text_field_tag "search", nil, placeholder: "Search", class: "search-input"
|
||||||
|
|
||||||
|
:javascript
|
||||||
|
$(function(){
|
||||||
|
$("#search").autocomplete({
|
||||||
|
source: #{raw search_autocomplete_source},
|
||||||
|
select: function(event, ui) { location.href = ui.item.url }
|
||||||
|
});
|
||||||
|
});
|
|
@ -28,16 +28,22 @@
|
||||||
%h4.cdark 2. Fill info
|
%h4.cdark 2. Fill info
|
||||||
|
|
||||||
.clearfix
|
.clearfix
|
||||||
.main_box
|
.merge_requests_form_box
|
||||||
.top_box_content
|
.top_box_content
|
||||||
= f.label :title do
|
= f.label :title do
|
||||||
%strong= "Title *"
|
%strong= "Title *"
|
||||||
.input= f.text_field :title, class: "input-xxlarge pad gfm-input", maxlength: 255, rows: 5
|
.input= f.text_field :title, class: "input-xxlarge pad js-gfm-input", maxlength: 255, rows: 5
|
||||||
.middle_box_content
|
.merge_requests_middle_box
|
||||||
= f.label :assignee_id do
|
.merge_requests_assignee
|
||||||
%i.icon-user
|
= f.label :assignee_id do
|
||||||
Assign to
|
%i.icon-user
|
||||||
.input= f.select(:assignee_id, @project.users.all.collect {|p| [ p.name, p.id ] }, { include_blank: "Select user" }, {class: 'chosen span3'})
|
Assign to
|
||||||
|
.input= f.select(:assignee_id, @project.users.all.collect {|p| [ p.name, p.id ] }, { include_blank: "Select user" }, {class: 'chosen span3'})
|
||||||
|
.merge_requests_milestone
|
||||||
|
= f.label :milestone_id do
|
||||||
|
%i.icon-time
|
||||||
|
Milestone
|
||||||
|
.input= f.select(:milestone_id, @project.milestones.active.all.collect {|p| [ p.title, p.id ] }, { include_blank: "Select milestone" }, {class: 'chosen'})
|
||||||
|
|
||||||
.control-group
|
.control-group
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,10 @@
|
||||||
%span.btn.small.disabled.grouped
|
%span.btn.small.disabled.grouped
|
||||||
%i.icon-comment
|
%i.icon-comment
|
||||||
= merge_request.mr_and_commit_notes.count
|
= merge_request.mr_and_commit_notes.count
|
||||||
|
- if merge_request.milestone_id?
|
||||||
|
%span.btn.small.disabled.grouped
|
||||||
|
%i.icon-time
|
||||||
|
= merge_request.milestone.title
|
||||||
%span.btn.small.disabled.grouped
|
%span.btn.small.disabled.grouped
|
||||||
= merge_request.source_branch
|
= merge_request.source_branch
|
||||||
→
|
→
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
:plain
|
:plain
|
||||||
$(".mr_source_commit").html("#{escape_javascript(render 'commits/commit', commit: @commit)}");
|
$(".mr_source_commit").html("#{commit_to_html(@commit)}");
|
||||||
|
|
|
@ -1,3 +1,2 @@
|
||||||
:plain
|
:plain
|
||||||
$(".mr_target_commit").html("#{escape_javascript(render 'commits/commit', commit: @commit)}");
|
$(".mr_target_commit").html("#{commit_to_html(@commit)}");
|
||||||
|
|
||||||
|
|
|
@ -9,19 +9,26 @@
|
||||||
|
|
||||||
.ui-box
|
.ui-box
|
||||||
.title
|
.title
|
||||||
%ul.nav.nav-pills
|
.left
|
||||||
%li{class: ("active" if (params[:f] == 'open' || !params[:f]))}
|
%ul.nav.nav-pills
|
||||||
= link_to project_merge_requests_path(@project, f: 'open') do
|
%li{class: ("active" if (params[:f] == 'open' || !params[:f]))}
|
||||||
Open
|
= link_to project_merge_requests_path(@project, f: 'open', milestone_id: params[:milestone_id]) do
|
||||||
%li{class: ("active" if params[:f] == "closed")}
|
Open
|
||||||
= link_to project_merge_requests_path(@project, f: "closed") do
|
%li{class: ("active" if params[:f] == "closed")}
|
||||||
Closed
|
= link_to project_merge_requests_path(@project, f: "closed", milestone_id: params[:milestone_id]) do
|
||||||
%li{class: ("active" if params[:f] == 'assigned-to-me')}
|
Closed
|
||||||
= link_to project_merge_requests_path(@project, f: 'assigned-to-me') do
|
%li{class: ("active" if params[:f] == 'assigned-to-me')}
|
||||||
To Me
|
= link_to project_merge_requests_path(@project, f: 'assigned-to-me', milestone_id: params[:milestone_id]) do
|
||||||
%li{class: ("active" if params[:f] == 'all')}
|
To Me
|
||||||
= link_to project_merge_requests_path(@project, f: 'all') do
|
%li{class: ("active" if params[:f] == 'all')}
|
||||||
All
|
= link_to project_merge_requests_path(@project, f: 'all', milestone_id: params[:milestone_id]) do
|
||||||
|
All
|
||||||
|
.right
|
||||||
|
= form_tag project_merge_requests_path(@project), id: "merge_requests_search_form", method: :get, class: :right do
|
||||||
|
= select_tag(:assignee_id, options_from_collection_for_select([unassigned_filter] + @project.users.all, "id", "name", params[:assignee_id]), prompt: "Assignee")
|
||||||
|
= select_tag(:milestone_id, options_from_collection_for_select([unassigned_filter] + @project.milestones.order("id desc").all, "id", "title", params[:milestone_id]), prompt: "Milestone")
|
||||||
|
= hidden_field_tag :f, params[:f]
|
||||||
|
.clearfix
|
||||||
|
|
||||||
%ul.unstyled
|
%ul.unstyled
|
||||||
= render @merge_requests
|
= render @merge_requests
|
||||||
|
@ -35,3 +42,7 @@
|
||||||
.span4.right
|
.span4.right
|
||||||
%span.cgray.right #{@merge_requests.total_count} merge requests for this filter
|
%span.cgray.right #{@merge_requests.total_count} merge requests for this filter
|
||||||
|
|
||||||
|
:javascript
|
||||||
|
$(function() {
|
||||||
|
merge_requestsPage();
|
||||||
|
})
|
||||||
|
|
|
@ -14,9 +14,13 @@
|
||||||
%strong.author= link_to_merge_request_author(@merge_request)
|
%strong.author= link_to_merge_request_author(@merge_request)
|
||||||
|
|
||||||
- if @merge_request.assignee
|
- if @merge_request.assignee
|
||||||
%cite.cgray and currently assigned to
|
%cite.cgray , currently assigned to
|
||||||
= image_tag gravatar_icon(@merge_request.assignee_email), width: 16, class: "lil_av"
|
= image_tag gravatar_icon(@merge_request.assignee_email), width: 16, class: "lil_av"
|
||||||
%strong.author= link_to_merge_request_assignee(@merge_request)
|
%strong.author= link_to_merge_request_assignee(@merge_request)
|
||||||
|
- if @merge_request.milestone
|
||||||
|
- milestone = @merge_request.milestone
|
||||||
|
%cite.cgray and attached to milestone
|
||||||
|
%strong= link_to_gfm truncate(milestone.title, length: 20), project_milestone_path(milestone.project, milestone)
|
||||||
|
|
||||||
|
|
||||||
- if @merge_request.closed
|
- if @merge_request.closed
|
||||||
|
|
|
@ -1,18 +1,22 @@
|
||||||
%li{class: "milestone", id: dom_id(milestone) }
|
%li{class: "milestone", id: dom_id(milestone) }
|
||||||
.right
|
.right
|
||||||
- if milestone.issues.any?
|
|
||||||
%span.btn.small.disabled.grouped= pluralize milestone.issues.count, 'issues'
|
|
||||||
- if milestone.issues.count > 0
|
|
||||||
= link_to 'Browse Issues', project_issues_path(milestone.project, milestone_id: milestone.id), class: "btn small grouped"
|
|
||||||
- if can? current_user, :admin_milestone, milestone.project
|
- if can? current_user, :admin_milestone, milestone.project
|
||||||
= link_to 'Edit', edit_project_milestone_path(milestone.project, milestone), class: "btn small edit-milestone-link grouped"
|
= link_to edit_project_milestone_path(milestone.project, milestone), class: "btn small edit-milestone-link grouped" do
|
||||||
|
%i.icon-edit
|
||||||
|
Edit
|
||||||
%h4
|
%h4
|
||||||
= link_to_gfm truncate(milestone.title, length: 100), project_milestone_path(milestone.project, milestone), class: "row_title"
|
= link_to_gfm truncate(milestone.title, length: 100), project_milestone_path(milestone.project, milestone)
|
||||||
%small
|
%small
|
||||||
= milestone.expires_at
|
= milestone.expires_at
|
||||||
%br
|
.row
|
||||||
.progress.progress-success.span3
|
.span4
|
||||||
.bar{style: "width: #{milestone.percent_complete}%;"}
|
.progress.progress-info
|
||||||
|
.bar{style: "width: #{milestone.percent_complete}%;"}
|
||||||
|
.span6
|
||||||
|
= link_to project_issues_path(milestone.project, milestone_id: milestone.id) do
|
||||||
|
= pluralize milestone.issues.count, 'Issue'
|
||||||
|
|
||||||
|
= link_to project_merge_requests_path(milestone.project, milestone_id: milestone.id) do
|
||||||
|
= pluralize milestone.merge_requests.count, 'Merge Request'
|
||||||
|
|
||||||
|
%span.light #{milestone.percent_complete}% complete
|
||||||
|
|
|
@ -31,10 +31,10 @@
|
||||||
%h5
|
%h5
|
||||||
Progress:
|
Progress:
|
||||||
%small
|
%small
|
||||||
#{@milestone.issues.closed.count} closed
|
#{@milestone.closed_items_count} closed
|
||||||
–
|
–
|
||||||
#{@milestone.issues.opened.count} open
|
#{@milestone.open_items_count} open
|
||||||
.progress.progress-success
|
.progress.progress-info
|
||||||
.bar{style: "width: #{@milestone.percent_complete}%;"}
|
.bar{style: "width: #{@milestone.percent_complete}%;"}
|
||||||
|
|
||||||
|
|
||||||
|
@ -58,15 +58,28 @@
|
||||||
%span.badge.badge-info ##{issue.id}
|
%span.badge.badge-info ##{issue.id}
|
||||||
–
|
–
|
||||||
= link_to_gfm truncate(issue.title, length: 60), [@project, issue]
|
= link_to_gfm truncate(issue.title, length: 60), [@project, issue]
|
||||||
%br
|
|
||||||
|
|
||||||
.span6
|
.span6
|
||||||
%table
|
%table.milestone-merge-requests-filter
|
||||||
%thead
|
%thead
|
||||||
%th Participants
|
%th
|
||||||
- @users.each do |user|
|
%ul.nav.nav-pills
|
||||||
%tr
|
%li.active= link_to('Open Merge Requests', '#')
|
||||||
|
%li=link_to('All Merge Requests', '#')
|
||||||
|
- @merge_requests.each do |merge_request|
|
||||||
|
%tr{data: {closed: merge_request.closed}}
|
||||||
%td
|
%td
|
||||||
= image_tag gravatar_icon(user.email, 24), width: "24"
|
= link_to [@project, merge_request] do
|
||||||
|
%span.badge.badge-info ##{merge_request.id}
|
||||||
= user.name
|
–
|
||||||
|
= link_to_gfm truncate(merge_request.title, length: 60), [@project, merge_request]
|
||||||
|
|
||||||
|
%hr
|
||||||
|
%h6 Participants:
|
||||||
|
%div
|
||||||
|
- @users.each do |user|
|
||||||
|
= link_to tm_path(user.tm_of(@project)), class: 'float-link' do
|
||||||
|
= user.avatar_image
|
||||||
|
= user.name
|
||||||
|
|
||||||
|
.clearfix
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
|
|
||||||
= f.hidden_field :noteable_id
|
= f.hidden_field :noteable_id
|
||||||
= f.hidden_field :noteable_type
|
= f.hidden_field :noteable_type
|
||||||
= f.text_area :note, size: 255, class: 'note-text gfm-input'
|
= f.text_area :note, size: 255, class: 'note-text js-gfm-input'
|
||||||
#preview-note.preview_note.hide
|
#preview-note.preview_note.hide
|
||||||
.hint
|
.hint
|
||||||
.right Comments are parsed with #{link_to "GitLab Flavored Markdown", help_markdown_path, target: '_blank'}.
|
.right Comments are parsed with #{link_to "GitLab Flavored Markdown", help_markdown_path, target: '_blank'}.
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
= f.hidden_field :noteable_id
|
= f.hidden_field :noteable_id
|
||||||
= f.hidden_field :noteable_type
|
= f.hidden_field :noteable_type
|
||||||
= f.hidden_field :line_code
|
= f.hidden_field :line_code
|
||||||
= f.text_area :note, size: 255, class: 'line-note-text gfm-input'
|
= f.text_area :note, size: 255, class: 'line-note-text js-gfm-input'
|
||||||
.note_actions
|
.note_actions
|
||||||
.buttons
|
.buttons
|
||||||
= f.submit 'Add note', class: "btn save-btn submit_note submit_inline_note", id: "submit_note"
|
= f.submit 'Add note', class: "btn save-btn submit_note submit_inline_note", id: "submit_note"
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
%td{style: "font-size: 1px; line-height: 1px;", width: "21"}
|
%td{style: "font-size: 1px; line-height: 1px;", width: "21"}
|
||||||
%td{align: "left", style: "padding: 20px 0 0;"}
|
%td{align: "left", style: "padding: 20px 0 0;"}
|
||||||
%h2{style: "color:#646464; font-weight: bold; margin: 0; padding: 0; line-height: 26px; font-size: 18px; font-family: Helvetica, Arial, sans-serif; "}
|
%h2{style: "color:#646464; font-weight: bold; margin: 0; padding: 0; line-height: 26px; font-size: 18px; font-family: Helvetica, Arial, sans-serif; "}
|
||||||
= "You got granted #{@users_project.project_access_human} access to project"
|
= "You have been granted #{@users_project.project_access_human} access to project"
|
||||||
%td{style: "font-size: 1px; line-height: 1px;", width: "21"}
|
%td{style: "font-size: 1px; line-height: 1px;", width: "21"}
|
||||||
%tr
|
%tr
|
||||||
%td{style: "font-size: 1px; line-height: 1px;", width: "21"}
|
%td{style: "font-size: 1px; line-height: 1px;", width: "21"}
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
%h3.page_title
|
%h3.page_title
|
||||||
Private token
|
Private token
|
||||||
%span.cred.right
|
%span.cred.right
|
||||||
keep it in secret!
|
keep it secret!
|
||||||
.padded
|
.padded
|
||||||
= form_for @user, url: profile_reset_private_token_path, method: :put do |f|
|
= form_for @user, url: profile_reset_private_token_path, method: :put do |f|
|
||||||
.data
|
.data
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue