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:
|
||||
- sudo apt-get install libicu-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:
|
||||
only:
|
||||
- 'master'
|
||||
|
|
|
@ -28,7 +28,7 @@ v 3.0.0
|
|||
- Reject ssh keys that break gitolite
|
||||
- [API] list one 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] add user creation
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
## Contribute to GitLab
|
||||
## Contribute to GitLab
|
||||
|
||||
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
|
||||
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 can be merged w/o problems
|
||||
* Your code can be merged w/o problems
|
||||
* It won't break existing functionality
|
||||
* It's quality code
|
||||
* 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
|
||||
|
||||
To run the specs for GitLab, you need to run seeds for test db.
|
||||
|
||||
cd gitlabhq
|
||||
rake db:seed_fu RAILS_ENV=test
|
||||
|
||||
Then you can run the test suite with rake:
|
||||
|
||||
rake gitlab:test
|
||||
|
||||
For more information on running the tests please read the [development tips](https://github.com/gitlabhq/gitlabhq/blob/master/doc/development.md)
|
||||
|
|
31
Gemfile
31
Gemfile
|
@ -11,9 +11,9 @@ end
|
|||
gem "rails", "3.2.8"
|
||||
|
||||
# Supported DBs
|
||||
gem "sqlite3", :group => :sqlite
|
||||
gem "mysql2", :group => :mysql
|
||||
gem "pg", :group => :postgres
|
||||
gem "sqlite3", group: :sqlite
|
||||
gem "mysql2", group: :mysql
|
||||
gem "pg", group: :postgres
|
||||
|
||||
# Auth
|
||||
gem "devise", "~> 2.1.0"
|
||||
|
@ -23,10 +23,11 @@ gem 'omniauth-twitter'
|
|||
gem 'omniauth-github'
|
||||
|
||||
# GITLAB patched libs
|
||||
gem "grit", :git => "https://github.com/gitlabhq/grit.git", :ref => "7f35cb98ff17d534a07e3ce6ec3d580f67402837"
|
||||
gem "omniauth-ldap", :git => "https://github.com/gitlabhq/omniauth-ldap.git", :ref => "f038dd852d7bd473a557e385d5d7c2fd5dc1dc2e"
|
||||
gem 'yaml_db', :git => "https://github.com/gitlabhq/yaml_db.git"
|
||||
gem 'grack', :git => "https://github.com/gitlabhq/grack.git"
|
||||
gem "grit", git: "https://github.com/gitlabhq/grit.git", ref: '7f35cb98ff17d534a07e3ce6ec3d580f67402837'
|
||||
gem "omniauth-ldap", git: "https://github.com/gitlabhq/omniauth-ldap.git", ref: 'f038dd852d7bd473a557e385d5d7c2fd5dc1dc2e'
|
||||
gem 'yaml_db', git: "https://github.com/gitlabhq/yaml_db.git", ref: '98e9a5dca43e3fedd3268c76a73af40d1bdf1dfd'
|
||||
gem 'grack', git: "https://github.com/gitlabhq/grack.git", ref: 'ba46f3b0845c6a09d488ae6abdce6ede37e227e8'
|
||||
gem 'grit_ext', git: "https://github.com/gitlabhq/grit_ext.git", ref: '212fd40bea61f3c6a167223768e7295dc32bbc10'
|
||||
|
||||
# Gitolite client (for work with gitolite-admin repo)
|
||||
gem "gitolite", '1.1.0'
|
||||
|
@ -35,7 +36,7 @@ gem "gitolite", '1.1.0'
|
|||
gem "pygments.rb", "0.3.1"
|
||||
|
||||
# Language detection
|
||||
gem "github-linguist", "~> 2.3.4" , :require => "linguist"
|
||||
gem "github-linguist", "~> 2.3.4" , require: "linguist"
|
||||
|
||||
# API
|
||||
gem "grape", "~> 0.2.1"
|
||||
|
@ -83,9 +84,6 @@ gem 'resque_mailer'
|
|||
# HTTP requests
|
||||
gem "httparty"
|
||||
|
||||
# Handle encodings
|
||||
gem "charlock_holmes"
|
||||
|
||||
# Colored output to console
|
||||
gem "colored"
|
||||
|
||||
|
@ -114,8 +112,9 @@ group :assets do
|
|||
end
|
||||
|
||||
group :development do
|
||||
gem "annotate", git: "https://github.com/ctran/annotate_models.git"
|
||||
gem "letter_opener"
|
||||
gem "annotate", :git => "https://github.com/ctran/annotate_models.git"
|
||||
gem 'quiet_assets', '1.0.1'
|
||||
gem 'rack-mini-profiler'
|
||||
end
|
||||
|
||||
|
@ -137,13 +136,13 @@ group :development, :test do
|
|||
gem 'guard-spinach'
|
||||
|
||||
# Notification
|
||||
gem 'rb-fsevent', :require => darwin_only('rb-fsevent')
|
||||
gem 'growl', :require => darwin_only('growl')
|
||||
gem 'rb-inotify', :require => linux_only('rb-inotify')
|
||||
gem 'rb-fsevent', require: darwin_only('rb-fsevent')
|
||||
gem 'growl', require: darwin_only('growl')
|
||||
gem 'rb-inotify', require: linux_only('rb-inotify')
|
||||
end
|
||||
|
||||
group :test do
|
||||
gem "simplecov", :require => false
|
||||
gem "simplecov", require: false
|
||||
gem "shoulda-matchers"
|
||||
gem 'email_spec'
|
||||
gem 'resque_spec'
|
||||
|
|
17
Gemfile.lock
17
Gemfile.lock
|
@ -7,6 +7,7 @@ GIT
|
|||
GIT
|
||||
remote: https://github.com/gitlabhq/grack.git
|
||||
revision: ba46f3b0845c6a09d488ae6abdce6ede37e227e8
|
||||
ref: ba46f3b0845c6a09d488ae6abdce6ede37e227e8
|
||||
specs:
|
||||
grack (1.0.0)
|
||||
rack (~> 1.4.1)
|
||||
|
@ -21,6 +22,14 @@ GIT
|
|||
mime-types (~> 1.15)
|
||||
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
|
||||
remote: https://github.com/gitlabhq/omniauth-ldap.git
|
||||
revision: f038dd852d7bd473a557e385d5d7c2fd5dc1dc2e
|
||||
|
@ -35,6 +44,7 @@ GIT
|
|||
GIT
|
||||
remote: https://github.com/gitlabhq/yaml_db.git
|
||||
revision: 98e9a5dca43e3fedd3268c76a73af40d1bdf1dfd
|
||||
ref: 98e9a5dca43e3fedd3268c76a73af40d1bdf1dfd
|
||||
specs:
|
||||
yaml_db (0.2.2)
|
||||
|
||||
|
@ -90,7 +100,7 @@ GEM
|
|||
carrierwave (0.6.2)
|
||||
activemodel (>= 3.2.0)
|
||||
activesupport (>= 3.2.0)
|
||||
charlock_holmes (0.6.8)
|
||||
charlock_holmes (0.6.9)
|
||||
childprocess (0.3.2)
|
||||
ffi (~> 1.0.6)
|
||||
chosen-rails (0.9.8.3)
|
||||
|
@ -260,6 +270,8 @@ GEM
|
|||
posix-spawn (~> 0.3.6)
|
||||
yajl-ruby (~> 1.1.0)
|
||||
pyu-ruby-sasl (0.0.3.3)
|
||||
quiet_assets (1.0.1)
|
||||
railties (~> 3.1)
|
||||
rack (1.4.1)
|
||||
rack-cache (1.2)
|
||||
rack (>= 0.4)
|
||||
|
@ -411,7 +423,6 @@ DEPENDENCIES
|
|||
capybara
|
||||
capybara-webkit
|
||||
carrierwave
|
||||
charlock_holmes
|
||||
chosen-rails
|
||||
coffee-rails (= 3.2.2)
|
||||
colored
|
||||
|
@ -432,6 +443,7 @@ DEPENDENCIES
|
|||
grack!
|
||||
grape (~> 0.2.1)
|
||||
grit!
|
||||
grit_ext!
|
||||
growl
|
||||
guard-rspec
|
||||
guard-spinach
|
||||
|
@ -454,6 +466,7 @@ DEPENDENCIES
|
|||
pg
|
||||
pry
|
||||
pygments.rb (= 0.3.1)
|
||||
quiet_assets (= 1.0.1)
|
||||
rack-mini-profiler
|
||||
rails (= 3.2.8)
|
||||
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 chosen-jquery
|
||||
//= require raphael
|
||||
//= require g.raphael-min
|
||||
//= require g.bar-min
|
||||
//= require branch-graph
|
||||
//= require ace-src-noconflict/ace
|
||||
//= 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
|
||||
window.autocompleteEmojiData = [];
|
||||
window.autocompleteEmojiTemplate = "<li data-value='${insert}'>${name} <img alt='${name}' height='20' src='${image}' width='20' /></li>";
|
||||
data = []
|
||||
template = "<li data-value='${insert}'>${name} <img alt='${name}' height='20' src='${image}' width='20' /></li>"
|
||||
window.autocompleteEmoji = {data, template}
|
||||
|
||||
# Team Members
|
||||
window.autocompleteMembersUrl = "";
|
||||
window.autocompleteMembersParams =
|
||||
private_token: ""
|
||||
page: 1
|
||||
window.autocompleteMembersData = [];
|
||||
url = '';
|
||||
params = {private_token: '', page: 1}
|
||||
window.autocompleteMembers = {data, url, params}
|
||||
|
||||
|
||||
|
||||
###
|
||||
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 = ->
|
||||
###
|
||||
Emoji
|
||||
###
|
||||
$('.gfm-input').atWho ':',
|
||||
data: autocompleteEmojiData,
|
||||
tpl: autocompleteEmojiTemplate
|
||||
$input = $('.js-gfm-input')
|
||||
|
||||
###
|
||||
Team Members
|
||||
###
|
||||
$('.gfm-input').atWho '@', (query, callback) ->
|
||||
# Emoji
|
||||
$input.atWho ':',
|
||||
data: autocompleteEmoji.data,
|
||||
tpl: autocompleteEmoji.template
|
||||
|
||||
# Team Members
|
||||
$input.atWho '@', (query, callback) ->
|
||||
(getMoreMembers = ->
|
||||
$.getJSON(autocompleteMembersUrl, autocompleteMembersParams)
|
||||
.success (members) ->
|
||||
# pick the data we need
|
||||
newMembersData = $.map members, (m) -> m.name
|
||||
$.getJSON(autocompleteMembers.url, autocompleteMembers.params).success (members) ->
|
||||
# pick the data we need
|
||||
newMembersData = $.map members, (m) -> m.name
|
||||
|
||||
# add the new page of data to the rest
|
||||
$.merge autocompleteMembersData, newMembersData
|
||||
# add the new page of data to the rest
|
||||
$.merge autocompleteMembers.data, newMembersData
|
||||
|
||||
# show the pop-up with a copy of the current data
|
||||
callback autocompleteMembersData[..]
|
||||
# show the pop-up with a copy of the current data
|
||||
callback autocompleteMembers.data[..]
|
||||
|
||||
# are we past the last page?
|
||||
if newMembersData.length == 0
|
||||
# set static data and stop callbacks
|
||||
$('.gfm-input').atWho '@',
|
||||
data: autocompleteMembersData
|
||||
callback: null
|
||||
else
|
||||
# get next page
|
||||
getMoreMembers()
|
||||
# are we past the last page?
|
||||
if newMembersData.length is 0
|
||||
# set static data and stop callbacks
|
||||
$input.atWho '@',
|
||||
data: autocompleteMembers.data
|
||||
callback: null
|
||||
else
|
||||
# get next page
|
||||
getMoreMembers()
|
||||
|
||||
# so the next request gets the next page
|
||||
autocompleteMembersParams.page += 1;
|
||||
).call();
|
||||
autocompleteMembers.params.page += 1
|
||||
).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").after(form);
|
||||
$('select#issue_assignee_id').chosen();
|
||||
$('select#issue_milestone_id').chosen();
|
||||
$("#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").after(form);
|
||||
$('select#issue_assignee_id').chosen();
|
||||
$('select#issue_milestone_id').chosen();
|
||||
$("#edit_issue_dialog").show("fade", { direction: "right" }, 150);
|
||||
|
@ -33,8 +31,8 @@ function switchFromEditIssue(){
|
|||
function backToIssues(){
|
||||
$("#edit_issue_dialog, #new_issue_dialog").hide("fade", { direction: "right" }, 150, function(){
|
||||
$(".issues_content").show("fade", { direction: "left" }, 150, function() {
|
||||
$("#edit_issue_dialog").remove();
|
||||
$("#new_issue_dialog").remove();
|
||||
$("#edit_issue_dialog").html("");
|
||||
$("#new_issue_dialog").html("");
|
||||
$('.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) ->
|
||||
$.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) ->
|
||||
field = $(field_selector)
|
||||
closest_submit = field.closest("form").find(button_selector)
|
||||
|
||||
closest_submit.disable() if field.val() is ""
|
||||
|
||||
field.on "keyup", ->
|
||||
if $(this).val() is ""
|
||||
field.on "input", ->
|
||||
if $(@).val() is ""
|
||||
closest_submit.disable()
|
||||
else
|
||||
closest_submit.enable()
|
||||
|
||||
$ ->
|
||||
# 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
|
||||
$('select.chosen').chosen()
|
||||
|
||||
# Initialize tooltips
|
||||
$('.has_tooltip').tooltip()
|
||||
|
||||
# Disable form buttons while a form is submitting
|
||||
$('body').on 'ajax:complete, ajax:beforeSend, submit', 'form', (e) ->
|
||||
buttons = $('[type="submit"]', this)
|
||||
buttons = $('[type="submit"]', @)
|
||||
|
||||
switch e.type
|
||||
when 'ajax:beforeSend', 'submit'
|
||||
|
@ -38,7 +41,7 @@ $ ->
|
|||
buttons.enable()
|
||||
|
||||
# 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
|
||||
$(document).keypress (e) ->
|
||||
|
@ -52,22 +55,22 @@ $ ->
|
|||
|
||||
# Commit show suppressed diff
|
||||
$(".supp_diff_link").bind "click", ->
|
||||
$(this).next('table').show()
|
||||
$(this).remove()
|
||||
$(@).next('table').show()
|
||||
$(@).remove()
|
||||
|
||||
# Note markdown preview
|
||||
$(document).on 'click', '#preview-link', (e) ->
|
||||
$('#preview-note').text('Loading...')
|
||||
$('#preview-note').text 'Loading...'
|
||||
|
||||
previewLinkText = if $(this).text() == 'Preview' then 'Edit' else 'Preview'
|
||||
$(this).text(previewLinkText)
|
||||
previewLinkText = if $(@).text() is 'Preview' then 'Edit' else 'Preview'
|
||||
$(@).text previewLinkText
|
||||
|
||||
note = $('#note_note').val()
|
||||
|
||||
if note.trim().length == 0
|
||||
$('#preview-note').text("Nothing to preview.")
|
||||
if note.trim().length is 0
|
||||
$('#preview-note').text 'Nothing to preview.'
|
||||
else
|
||||
$.post $(this).attr('href'), {note: note}, (data) ->
|
||||
$.post $(@).attr('href'), {note: note}, (data) ->
|
||||
$('#preview-note').html(data)
|
||||
|
||||
$('#preview-note, #note_note').toggle()
|
||||
|
@ -79,14 +82,14 @@ $ ->
|
|||
$.fn.extend chosen: (options) ->
|
||||
default_options = search_contains: "true"
|
||||
$.extend default_options, options
|
||||
_chosen.apply this, [default_options]
|
||||
_chosen.apply @, [default_options]
|
||||
|
||||
# Disable an element and add the 'disabled' Bootstrap class
|
||||
$.fn.extend disable: ->
|
||||
$(this).attr('disabled', 'disabled').addClass('disabled')
|
||||
$(@).attr('disabled', 'disabled').addClass('disabled')
|
||||
|
||||
# Enable an element and remove the 'disabled' Bootstrap class
|
||||
$.fn.extend enable: ->
|
||||
$(this).removeAttr('disabled').removeClass('disabled')
|
||||
$(@).removeAttr('disabled').removeClass('disabled')
|
||||
|
||||
)(jQuery)
|
||||
|
|
|
@ -115,4 +115,15 @@ var MergeRequest = {
|
|||
$(".merge_in_progress").hide();
|
||||
$(".automerge_widget.already_cannot_be_merged").show();
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* Filter merge requests
|
||||
*/
|
||||
function merge_requestsPage() {
|
||||
$("#assignee_id").chosen();
|
||||
$("#milestone_id").chosen();
|
||||
$("#milestone_id, #assignee_id").on("change", function(){
|
||||
$(this).closest("form").submit();
|
||||
});
|
||||
}
|
||||
|
|
|
@ -5,3 +5,10 @@ $ ->
|
|||
$('.milestone-issue-filter li').toggleClass('active')
|
||||
$('.milestone-issue-filter tr[data-closed]').toggleClass('hide')
|
||||
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
|
||||
$('.project-refs-select').on 'change', ->
|
||||
$(@).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: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) ->
|
||||
History = window.History
|
||||
$ = window.jQuery
|
||||
document = window.document
|
||||
# Check to see if History.js is enabled for our Browser
|
||||
unless History.enabled
|
||||
return false
|
||||
|
||||
# Check to see if History.js is enabled for our Browser
|
||||
unless History.enabled
|
||||
return false
|
||||
$('#tree-slider .tree-item-file-name a, .breadcrumb li > a').live 'click', (e) ->
|
||||
History.pushState(null, null, $(@).attr('href'))
|
||||
return false
|
||||
|
||||
$ ->
|
||||
$('#tree-slider .tree-item-file-name a, .breadcrumb li > a').live 'click', (e) ->
|
||||
History.pushState(null, null, $(@).attr('href'))
|
||||
return false
|
||||
|
||||
History.Adapter.bind window, 'statechange', ->
|
||||
state = History.getState()
|
||||
window.ajaxGet(state.url)
|
||||
)(window)
|
||||
History.Adapter.bind window, 'statechange', ->
|
||||
state = History.getState()
|
||||
window.ajaxGet(state.url)
|
||||
)(window)
|
||||
|
|
|
@ -670,3 +670,16 @@ pre {
|
|||
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; }
|
||||
.no-borders { border:none; }
|
||||
.vlink { color: $link_color !important; }
|
||||
.underlined_link { text-decoration: underline; }
|
||||
.borders { border: 1px solid #ccc; @include shade; }
|
||||
.hint { font-style: italic; color: #999; }
|
||||
.light { color: #888 }
|
||||
|
||||
/** PILLS & TABS**/
|
||||
.nav-pills a:hover { background-color:#888; }
|
||||
|
@ -66,10 +68,10 @@
|
|||
.alert-message.error { @extend .alert-error; }
|
||||
|
||||
/** AVATARS **/
|
||||
img.avatar { float:left; margin-right:15px; width:40px; border:1px solid #ddd; padding:1px; }
|
||||
img.avatar.s16 { width:16px; height:16px; }
|
||||
img.avatar.s24 { width:24px; height:24px; }
|
||||
img.avatar.s32 { width:32px; height:32px; }
|
||||
img.avatar { float:left; margin-right:12px; width:40px; border:1px solid #ddd; padding:1px; }
|
||||
img.avatar.s16 { width:16px; height:16px; margin-right:6px; }
|
||||
img.avatar.s24 { width:24px; height:24px; margin-right:8px; }
|
||||
img.avatar.s32 { width:32px; height:32px; margin-right:10px; }
|
||||
img.lil_av { padding-left: 4px; padding-right:3px; }
|
||||
|
||||
/** HELPERS **/
|
||||
|
|
|
@ -157,10 +157,15 @@
|
|||
font-size:12px !important;
|
||||
}
|
||||
|
||||
table.highlighttable .linenodiv pre {
|
||||
text-align: right;
|
||||
padding-right: 4px;
|
||||
color:#666;
|
||||
table.highlighttable .linenodiv {
|
||||
a {
|
||||
color: #666;
|
||||
}
|
||||
pre {
|
||||
text-align: right;
|
||||
padding-right: 4px;
|
||||
color:#666;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@ ul {
|
|||
.author { color: #999; }
|
||||
|
||||
p {
|
||||
padding-top:5px;
|
||||
padding-top: 1px;
|
||||
margin:0;
|
||||
color:#222;
|
||||
img {
|
||||
|
@ -31,3 +31,11 @@ ul {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
ol, ul {
|
||||
&.styled {
|
||||
li {
|
||||
padding:2px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,6 +34,11 @@ table {
|
|||
border-color:#f1f1f1;
|
||||
line-height:28px;
|
||||
|
||||
.s16 {
|
||||
margin-top: 5px;
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
&:first-child {
|
||||
border-left:1px solid #bbb;
|
||||
}
|
||||
|
|
|
@ -3,10 +3,11 @@
|
|||
@import 'font-awesome';
|
||||
|
||||
/** GitLab colors **/
|
||||
$link_color:#3A89A3;
|
||||
$blue_link: #2fa0bb;
|
||||
$style_color: #474d57;
|
||||
$link_color: #3A89A3;
|
||||
$blue_link: #2FA0BB;
|
||||
$style_color: #474D57;
|
||||
$hover: #D9EDF7;
|
||||
$hover_border: #ADF;
|
||||
|
||||
/** GitLab Fonts **/
|
||||
@font-face { font-family: Korolev; src: font-url('korolev-medium-compressed.otf'); }
|
||||
|
@ -19,9 +20,9 @@ $hover: #D9EDF7;
|
|||
}
|
||||
|
||||
@mixin solid_shade {
|
||||
-moz-box-shadow: 0 0 0 3px #eee;
|
||||
-webkit-box-shadow: 0 0 0 3px #eee;
|
||||
box-shadow: 0 0 0 3px #eee;
|
||||
-moz-box-shadow: 0 0 0 3px #f1f1f1;
|
||||
-webkit-box-shadow: 0 0 0 3px #f1f1f1;
|
||||
box-shadow: 0 0 0 3px #f1f1f1;
|
||||
}
|
||||
|
||||
@mixin border-radius($radius) {
|
||||
|
@ -64,6 +65,14 @@ $hover: #D9EDF7;
|
|||
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 {
|
||||
background:#eee;
|
||||
background-image: -webkit-gradient(linear, 0 0, 0 30, color-stop(0.066, #eee), to(#dfdfdf));
|
||||
|
|
|
@ -19,41 +19,14 @@
|
|||
margin-right: 10px;
|
||||
|
||||
.chzn-drop {
|
||||
margin:7px 0;
|
||||
min-width: 400px;
|
||||
border: 2px solid $blue_link;
|
||||
@include border-radius(4px);
|
||||
|
||||
.chzn-results {
|
||||
max-height:300px;
|
||||
|
||||
.group-result {
|
||||
color: $blue_link;
|
||||
}
|
||||
.active-result {
|
||||
&.highlighted {
|
||||
background: $blue_link;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.chzn-search input {
|
||||
min-width:365px;
|
||||
}
|
||||
}
|
||||
|
||||
.chzn-single {
|
||||
@include bg-gray-gradient;
|
||||
|
||||
div {
|
||||
background:transparent;
|
||||
border-left:none;
|
||||
}
|
||||
|
||||
span {
|
||||
font-weight: normal;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Fix for Search Dropdown Border **/
|
||||
|
@ -65,4 +38,55 @@
|
|||
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;
|
||||
}
|
||||
|
||||
.author,
|
||||
.committer {
|
||||
.author a,
|
||||
.committer a {
|
||||
font-size:14px;
|
||||
line-height:22px;
|
||||
text-shadow:0 1px 1px #fff;
|
||||
color:#777;
|
||||
&:hover {
|
||||
color: #999;
|
||||
}
|
||||
}
|
||||
|
||||
.avatar {
|
||||
|
@ -227,6 +230,9 @@
|
|||
|
||||
.commit-author-name {
|
||||
color: #777;
|
||||
&:hover {
|
||||
color: #999;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -43,6 +43,7 @@
|
|||
.event-body {
|
||||
p {
|
||||
color:#555;
|
||||
padding-top: 5px;
|
||||
}
|
||||
.event-info {
|
||||
color:#666;
|
||||
|
@ -115,3 +116,29 @@
|
|||
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 {
|
||||
width:32px;
|
||||
margin-top:4px;
|
||||
margin-top:1px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -71,7 +71,7 @@ li.merge_request {
|
|||
padding:7px 10px;
|
||||
img.avatar {
|
||||
width: 32px;
|
||||
margin-top: 4px;
|
||||
margin-top: 1px;
|
||||
}
|
||||
p {
|
||||
padding: 0px;
|
||||
|
@ -121,3 +121,20 @@ li.merge_request {
|
|||
.mr_direction_tip {
|
||||
margin-top:40px
|
||||
}
|
||||
|
||||
.merge_requests_form_box {
|
||||
@extend .main_box;
|
||||
.merge_requests_middle_box {
|
||||
@extend .middle_box_content;
|
||||
height:30px;
|
||||
.merge_requests_assignee {
|
||||
@extend .span6;
|
||||
float:left;
|
||||
}
|
||||
.merge_requests_milestone {
|
||||
@extend .span4;
|
||||
float:left;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -57,10 +57,7 @@
|
|||
padding-right: 8px;
|
||||
|
||||
img.avatar {
|
||||
border: 0 none;
|
||||
float: none;
|
||||
margin-right: 0;
|
||||
padding: 0;
|
||||
margin-top: 0;
|
||||
width: 16px;
|
||||
}
|
||||
}
|
||||
|
@ -75,6 +72,15 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
.blame {
|
||||
img.avatar {
|
||||
border: 0 none;
|
||||
float: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.tree-btn-group {
|
||||
|
|
|
@ -37,9 +37,6 @@
|
|||
background-image: -o-linear-gradient(#595D63 6.6%, #202227);
|
||||
background-position:0 0;
|
||||
color:#fff;
|
||||
i {
|
||||
@extend .icon-white;
|
||||
}
|
||||
}
|
||||
|
||||
border: 1px solid #31363E;
|
||||
|
|
|
@ -70,9 +70,6 @@
|
|||
color:#ccc;
|
||||
&:hover {
|
||||
color:#fff;
|
||||
i {
|
||||
@extend .icon-white;
|
||||
}
|
||||
}
|
||||
border: none;
|
||||
box-shadow:none;
|
||||
|
|
|
@ -21,7 +21,7 @@ class CommitLoadContext < BaseContext
|
|||
result[:notes_count] = line_notes.count + project.commit_notes(commit).count
|
||||
|
||||
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
|
||||
result[:suppress_diff] = true
|
||||
result[:status] = :huge_commit
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
# Build collection of Merge Requests
|
||||
# based on filtering passed via params for @project
|
||||
class MergeRequestsLoadContext < BaseContext
|
||||
def execute
|
||||
type = params[:f]
|
||||
|
@ -9,8 +11,21 @@ class MergeRequestsLoadContext < BaseContext
|
|||
when 'closed' then merge_requests.closed
|
||||
when 'assigned-to-me' then merge_requests.opened.assigned(current_user)
|
||||
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
|
||||
|
|
|
@ -13,6 +13,7 @@ class SearchContext
|
|||
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[: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
|
||||
end
|
||||
|
||||
|
@ -20,7 +21,8 @@ class SearchContext
|
|||
@result ||= {
|
||||
projects: [],
|
||||
merge_requests: [],
|
||||
issues: []
|
||||
issues: [],
|
||||
wiki_pages: []
|
||||
}
|
||||
end
|
||||
end
|
||||
|
|
|
@ -9,19 +9,28 @@ class ApplicationController < ActionController::Base
|
|||
helper_method :abilities, :can?
|
||||
|
||||
rescue_from Gitlab::Gitolite::AccessDenied do |exception|
|
||||
log_exception(exception)
|
||||
render "errors/gitolite", layout: "errors", status: 500
|
||||
end
|
||||
|
||||
rescue_from Encoding::CompatibilityError do |exception|
|
||||
log_exception(exception)
|
||||
render "errors/encoding", layout: "errors", status: 500
|
||||
end
|
||||
|
||||
rescue_from ActiveRecord::RecordNotFound do |exception|
|
||||
log_exception(exception)
|
||||
render "errors/not_found", layout: "errors", status: 404
|
||||
end
|
||||
|
||||
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!
|
||||
if current_user && current_user.blocked
|
||||
sign_out current_user
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
# Controller for viewing a file's blame
|
||||
class BlobController < ProjectResourceController
|
||||
include ExtractsPath
|
||||
include Gitlab::Encode
|
||||
|
||||
# Authorize
|
||||
before_filter :authorize_read_project!
|
||||
|
@ -12,16 +11,9 @@ class BlobController < ProjectResourceController
|
|||
|
||||
def show
|
||||
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(
|
||||
@tree.data,
|
||||
type: mime_type,
|
||||
type: @tree.mime_type,
|
||||
disposition: 'inline',
|
||||
filename: @tree.name
|
||||
)
|
||||
|
|
|
@ -1,12 +1,17 @@
|
|||
class DashboardController < ApplicationController
|
||||
respond_to :html
|
||||
|
||||
before_filter :event_filter, only: :index
|
||||
|
||||
def index
|
||||
@groups = Group.where(id: current_user.projects.pluck(:group_id))
|
||||
@projects = current_user.projects_with_events
|
||||
@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
|
||||
|
||||
respond_to do |format|
|
||||
|
@ -34,4 +39,8 @@ class DashboardController < ApplicationController
|
|||
format.atom { render layout: false }
|
||||
end
|
||||
end
|
||||
|
||||
def event_filter
|
||||
@event_filter ||= EventFilter.new(params[:event_filter])
|
||||
end
|
||||
end
|
||||
|
|
|
@ -31,7 +31,8 @@ class MilestonesController < ProjectResourceController
|
|||
|
||||
def show
|
||||
@issues = @milestone.issues
|
||||
@users = @milestone.participants
|
||||
@users = UserDecorator.decorate(@milestone.participants)
|
||||
@merge_requests = @milestone.merge_requests
|
||||
|
||||
respond_to do |format|
|
||||
format.html
|
||||
|
|
|
@ -22,7 +22,7 @@ class ProfileController < ApplicationController
|
|||
flash[:notice] = "Password was successfully updated. Please login with it"
|
||||
redirect_to new_user_session_path
|
||||
else
|
||||
render action: "password"
|
||||
render 'account'
|
||||
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
|
||||
skip_before_filter :project, only: [:new, :create]
|
||||
|
@ -79,7 +79,9 @@ class ProjectsController < ProjectResourceController
|
|||
end
|
||||
|
||||
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
|
||||
|
||||
def destroy
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
class RefsController < ProjectResourceController
|
||||
include Gitlab::Encode
|
||||
|
||||
# Authorize
|
||||
before_filter :authorize_read_project!
|
||||
|
|
|
@ -16,9 +16,14 @@ class RepositoriesController < ProjectResourceController
|
|||
@tags = @project.tags
|
||||
end
|
||||
|
||||
def stats
|
||||
@stats = Gitlab::GitStats.new(@project.repo, @project.root_ref)
|
||||
@graph = @stats.graph
|
||||
end
|
||||
|
||||
def archive
|
||||
unless can?(current_user, :download_code, @project)
|
||||
render_404 and return
|
||||
render_404 and return
|
||||
end
|
||||
|
||||
|
||||
|
|
|
@ -5,5 +5,6 @@ class SearchController < ApplicationController
|
|||
@projects = result[:projects]
|
||||
@merge_requests = result[:merge_requests]
|
||||
@issues = result[:issues]
|
||||
@wiki_pages = result[:wiki_pages]
|
||||
end
|
||||
end
|
||||
|
|
|
@ -26,15 +26,14 @@ class TreeController < ProjectResourceController
|
|||
end
|
||||
|
||||
def update
|
||||
file_editor = Gitlab::FileEditor.new(current_user, @project, @ref)
|
||||
update_status = file_editor.update(
|
||||
@path,
|
||||
edit_file_action = Gitlab::Satellite::EditFileAction.new(current_user, @project, @ref, @path)
|
||||
updated_successfully = edit_file_action.commit!(
|
||||
params[:content],
|
||||
params[:commit_message],
|
||||
params[:last_commit]
|
||||
)
|
||||
|
||||
if update_status
|
||||
if updated_successfully
|
||||
redirect_to project_tree_path(@project, @id), notice: "Your changes have been successfully commited"
|
||||
else
|
||||
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.
|
||||
#
|
||||
# options:
|
||||
# avatar: true will prepend avatar image
|
||||
def author_link(options)
|
||||
text = if options[:avatar]
|
||||
avatar = h.image_tag h.gravatar_icon(author_email), class: "avatar", width: 16
|
||||
"#{avatar} #{author_name}"
|
||||
else
|
||||
author_name
|
||||
end
|
||||
team_member = @project.try(:team_member_by_name_or_email, author_name, author_email)
|
||||
# avatar: true will prepend the avatar image
|
||||
# size: size of the avatar image in px
|
||||
def author_link(options = {})
|
||||
person_link(options.merge source: :author)
|
||||
end
|
||||
|
||||
if team_member.nil?
|
||||
h.mail_to author_email, text.html_safe, class: "commit-author-link"
|
||||
else
|
||||
h.link_to text, h.project_team_member_path(@project, team_member), class: "commit-author-link"
|
||||
end
|
||||
# Just like #author_link but for the committer.
|
||||
def committer_link(options = {})
|
||||
person_link(options.merge source: :committer)
|
||||
end
|
||||
|
||||
protected
|
||||
|
@ -69,4 +63,30 @@ class CommitDecorator < ApplicationDecorator
|
|||
def no_commit_message
|
||||
"--no commit message"
|
||||
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
|
||||
|
|
|
@ -8,14 +8,14 @@ class TreeDecorator < ApplicationDecorator
|
|||
|
||||
#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|
|
||||
part_path = File.join(part_path, part) unless part_path.empty?
|
||||
part_path = part if part_path.empty?
|
||||
|
||||
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
|
||||
|
|
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
|
||||
gravatar_prefix = request.ssl? ? "https://secure" : "http://www"
|
||||
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
|
||||
|
||||
|
|
|
@ -65,4 +65,9 @@ module CommitsHelper
|
|||
end
|
||||
end
|
||||
|
||||
def commit_to_html commit
|
||||
if commit.model
|
||||
escape_javascript(render 'commits/commit', commit: commit)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -33,4 +33,22 @@ module EventsHelper
|
|||
image_tag event_image_path
|
||||
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
|
||||
|
|
|
@ -10,5 +10,9 @@ module ProjectsHelper
|
|||
def link_to_project project
|
||||
link_to project.name, project
|
||||
end
|
||||
|
||||
def tm_path team_member
|
||||
project_team_member_path(@project, team_member)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -67,4 +67,29 @@ module TreeHelper
|
|||
can?(current_user, :push_code, @project)
|
||||
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
|
||||
|
|
|
@ -1,9 +1,13 @@
|
|||
class Commit
|
||||
include ActiveModel::Conversion
|
||||
include Gitlab::Encode
|
||||
include StaticModel
|
||||
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
|
||||
|
||||
delegate :message, :authored_date, :committed_date, :parents, :sha,
|
||||
|
@ -107,7 +111,7 @@ class Commit
|
|||
end
|
||||
|
||||
def safe_message
|
||||
@safe_message ||= utf8 message
|
||||
@safe_message ||= message
|
||||
end
|
||||
|
||||
def created_at
|
||||
|
@ -119,7 +123,7 @@ class Commit
|
|||
end
|
||||
|
||||
def author_name
|
||||
utf8 author.name
|
||||
author.name
|
||||
end
|
||||
|
||||
# Was this commit committed by a different person than the original author?
|
||||
|
@ -128,7 +132,7 @@ class Commit
|
|||
end
|
||||
|
||||
def committer_name
|
||||
utf8 committer.name
|
||||
committer.name
|
||||
end
|
||||
|
||||
def committer_email
|
||||
|
|
|
@ -7,8 +7,6 @@ class Issue < ActiveRecord::Base
|
|||
|
||||
acts_as_taggable_on :labels
|
||||
|
||||
belongs_to :milestone
|
||||
|
||||
validates :description, length: { within: 0..2000 }
|
||||
|
||||
def self.open_for(user)
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
require Rails.root.join("app/models/commit")
|
||||
require Rails.root.join("app/roles/static_model")
|
||||
|
||||
class MergeRequest < ActiveRecord::Base
|
||||
include IssueCommonality
|
||||
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
|
||||
|
||||
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)
|
||||
end
|
||||
|
||||
def self.find_all_by_milestone(milestone)
|
||||
where("milestone_id = :milestone_id", milestone_id: milestone)
|
||||
end
|
||||
|
||||
def human_state
|
||||
states = {
|
||||
CAN_BE_MERGED => "can_be_merged",
|
||||
|
@ -60,7 +65,7 @@ class MergeRequest < ActiveRecord::Base
|
|||
end
|
||||
|
||||
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
|
||||
else
|
||||
CANNOT_BE_MERGED
|
||||
|
@ -167,7 +172,7 @@ class MergeRequest < ActiveRecord::Base
|
|||
end
|
||||
|
||||
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)
|
||||
true
|
||||
end
|
||||
|
@ -212,5 +217,6 @@ end
|
|||
# st_diffs :text(4294967295
|
||||
# merged :boolean default(FALSE), not null
|
||||
# state :integer default(1), not null
|
||||
# milestone_id :integer
|
||||
#
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@ class Milestone < ActiveRecord::Base
|
|||
|
||||
belongs_to :project
|
||||
has_many :issues
|
||||
has_many :merge_requests
|
||||
|
||||
validates :title, presence: true
|
||||
validates :project, presence: true
|
||||
|
@ -15,8 +16,20 @@ class Milestone < ActiveRecord::Base
|
|||
User.where(id: issues.pluck(:assignee_id))
|
||||
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
|
||||
((self.issues.closed.count * 100) / self.issues.count).abs
|
||||
((closed_items_count * 100) / total_items_count).abs
|
||||
rescue ZeroDivisionError
|
||||
100
|
||||
end
|
||||
|
|
|
@ -23,13 +23,13 @@ class Note < ActiveRecord::Base
|
|||
mount_uploader :attachment, AttachmentUploader
|
||||
|
||||
# Scopes
|
||||
scope :common, where(noteable_id: nil)
|
||||
scope :today, where("created_at >= :date", date: Date.today)
|
||||
scope :last_week, where("created_at >= :date", date: (Date.today - 7.days))
|
||||
scope :common, ->{ where(noteable_id: nil) }
|
||||
scope :today, ->{ where("created_at >= :date", date: Date.today) }
|
||||
scope :last_week, ->{ where("created_at >= :date", date: (Date.today - 7.days)) }
|
||||
scope :since, ->(day) { where("created_at >= :date", date: (day)) }
|
||||
scope :fresh, order("created_at ASC, id ASC")
|
||||
scope :inc_author_project, includes(:project, :author)
|
||||
scope :inc_author, includes(:author)
|
||||
scope :fresh, ->{ order("created_at ASC, id ASC") }
|
||||
scope :inc_author_project, ->{ includes(:project, :author) }
|
||||
scope :inc_author, ->{ includes(:author) }
|
||||
|
||||
def self.create_status_change_note(noteable, author, status)
|
||||
create({
|
||||
|
|
|
@ -104,8 +104,10 @@ class Project < ActiveRecord::Base
|
|||
end
|
||||
|
||||
def repo_name
|
||||
if path == "gitolite-admin"
|
||||
errors.add(:path, " like 'gitolite-admin' is not allowed")
|
||||
denied_paths = %w(gitolite-admin groups projects dashboard)
|
||||
|
||||
if denied_paths.include?(path)
|
||||
errors.add(:path, "like #{path} is not allowed")
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ class Tree
|
|||
def initialize(raw_tree, project, ref = nil, path = nil)
|
||||
@project, @ref, @path = project, ref, path
|
||||
@tree = if path.present?
|
||||
raw_tree / path.dup.force_encoding('ascii-8bit')
|
||||
raw_tree / path
|
||||
else
|
||||
raw_tree
|
||||
end
|
||||
|
|
|
@ -15,6 +15,12 @@ class Wiki < ActiveRecord::Base
|
|||
slug
|
||||
end
|
||||
|
||||
class << self
|
||||
def search(query)
|
||||
where("title like :query OR content like :query", query: "%#{query}%")
|
||||
end
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def self.regenerate_from wiki
|
||||
|
|
|
@ -6,6 +6,7 @@ module IssueCommonality
|
|||
belongs_to :project
|
||||
belongs_to :author, class_name: "User"
|
||||
belongs_to :assignee, class_name: "User"
|
||||
belongs_to :milestone
|
||||
has_many :notes, as: :noteable, dependent: :destroy
|
||||
|
||||
validates :project, presence: true
|
||||
|
|
|
@ -41,7 +41,7 @@ module Repository
|
|||
end
|
||||
|
||||
def satellite
|
||||
@satellite ||= Gitlab::Satellite.new(self)
|
||||
@satellite ||= Gitlab::Satellite::Satellite.new(self)
|
||||
end
|
||||
|
||||
def has_post_receive_file?
|
||||
|
|
|
@ -43,7 +43,7 @@
|
|||
%b
|
||||
Owner:
|
||||
%td
|
||||
= @admin_project.owner.name
|
||||
= @admin_project.owner_name || '(deleted)'
|
||||
%tr
|
||||
%td
|
||||
%b
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
%h3.page_title Resque
|
||||
%br
|
||||
.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
|
||||
= link_to 'Source', project_tree_path(@project, @ref)
|
||||
%li.right
|
||||
.input-prepend.project_clone_holder
|
||||
%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"
|
||||
= render "shared/clone_panel"
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
.file_title
|
||||
%i.icon-file
|
||||
%span.file_name
|
||||
= @tree.name.force_encoding('utf-8')
|
||||
= @tree.name
|
||||
%small= number_to_human_size @tree.size
|
||||
%span.options= render "tree/blob_actions"
|
||||
.file_content.blame
|
||||
|
@ -24,9 +24,7 @@
|
|||
- commit = Commit.new(commit)
|
||||
- commit = CommitDecorator.decorate(commit)
|
||||
%tr
|
||||
%td.author
|
||||
= image_tag gravatar_icon(commit.author_email, 16)
|
||||
= commit.author_name
|
||||
%td.author= commit.author_link avatar: true, size: 16
|
||||
%td.blame_commit
|
||||
|
||||
%code= link_to commit.short_id, project_commit_path(@project, commit)
|
||||
|
@ -34,4 +32,4 @@
|
|||
%td.lines
|
||||
= preserve do
|
||||
%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"
|
||||
%p
|
||||
= link_to commit.short_id(8), project_commit_path(@project, commit), class: "commit_short_id"
|
||||
%strong.commit-author-name= commit.author_name
|
||||
%span.dash –
|
||||
= image_tag gravatar_icon(commit.author_email), class: "avatar", width: 16
|
||||
= commit.author_link avatar: true, size: 24
|
||||
|
||||
= link_to_gfm truncate(commit.title, length: 50), project_commit_path(@project, commit.id), class: "row_title"
|
||||
|
||||
%span.committed_ago
|
||||
|
|
|
@ -18,16 +18,15 @@
|
|||
.commit-info
|
||||
.row
|
||||
.span5
|
||||
= image_tag gravatar_icon(@commit.author_email, 40), class: "avatar"
|
||||
.author
|
||||
%strong= @commit.author_name
|
||||
%strong= @commit.author_link avatar: true, size: 40
|
||||
authored
|
||||
%time{title: @commit.authored_date.stamp("Aug 21, 2011 9:23pm")}
|
||||
#{time_ago_in_words(@commit.authored_date)} ago
|
||||
- if @commit.different_committer?
|
||||
.committer
|
||||
→
|
||||
%strong= @commit.committer_name
|
||||
%strong= @commit.committer_link
|
||||
committed
|
||||
%time{title: @commit.committed_date.stamp("Aug 21, 2011 9:23pm")}
|
||||
#{time_ago_in_words(@commit.committed_date)} ago
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
- if @suppress_diff
|
||||
.alert-message.block-message
|
||||
%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
|
||||
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
|
||||
Showing #{pluralize(diffs.count, "changed file")}
|
||||
|
@ -35,10 +35,10 @@
|
|||
- if file.text?
|
||||
= render "commits/text_file", diff: diff, index: i
|
||||
- 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
|
||||
%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)
|
||||
.diff_file_content_image.img_compared
|
||||
%img{class: "diff_image_removed", src: "data:#{file.mime_type};base64,#{Base64.encode64(old_file.data)}"}
|
||||
|
|
|
@ -16,6 +16,11 @@
|
|||
Tags
|
||||
%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
|
||||
%li.right
|
||||
%span.rss-icon
|
||||
|
|
|
@ -2,14 +2,7 @@
|
|||
|
||||
- if @path.present?
|
||||
%ul.breadcrumb
|
||||
%li
|
||||
%span.arrow
|
||||
= link_to project_commits_path(@project) do
|
||||
= @project.name
|
||||
%span.divider
|
||||
\/
|
||||
%li
|
||||
%a{href: "#"}= @path.split("/").join(" / ")
|
||||
= breadcrumbs
|
||||
|
||||
%div{id: dom_id(@project)}
|
||||
#commits_list= render "commits"
|
||||
|
|
|
@ -3,10 +3,17 @@
|
|||
.activities.span8
|
||||
= render "events/event_last_push", event: @last_push
|
||||
= 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?
|
||||
.content_list= render @events
|
||||
- else
|
||||
%h4.nothing_here_message Projects activity will be displayed here
|
||||
%p.nothing_here_message Projects activity will be displayed here
|
||||
.loading.hide
|
||||
.side
|
||||
- if @groups.present?
|
||||
|
|
|
@ -14,8 +14,9 @@
|
|||
= f.submit "Sign in", :class => "primary btn wide"
|
||||
.right
|
||||
= render :partial => "devise/shared/links"
|
||||
- if devise_mapping.omniauthable?
|
||||
%hr/
|
||||
- resource_class.omniauth_providers.each do |provider|
|
||||
%span
|
||||
= link_to authbutton(provider, 32), omniauth_authorize_path(resource_name, provider)
|
||||
.clearfix
|
||||
- if devise_mapping.omniauthable? && resource_class.omniauth_providers.present?
|
||||
%div
|
||||
- resource_class.omniauth_providers.each do |provider|
|
||||
%span
|
||||
= link_to authbutton(provider, 32), omniauth_authorize_path(resource_name, provider)
|
||||
|
|
|
@ -5,9 +5,10 @@
|
|||
%hr
|
||||
|
||||
%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
|
||||
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
|
||||
%h5 Hooks request example:
|
||||
= render "admin/hooks/data_ex"
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
= f.label :title do
|
||||
%strong= "Subject *"
|
||||
.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_assignee
|
||||
= f.label :assignee_id do
|
||||
|
@ -37,7 +37,7 @@
|
|||
.clearfix
|
||||
= f.label :description, "Details"
|
||||
.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'}.
|
||||
|
||||
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
:plain
|
||||
var edit_issue_dialog = $("<div id='edit_issue_dialog'></div>");
|
||||
edit_issue_dialog.html("#{escape_javascript(render('form'))}");
|
||||
switchToEditIssue(edit_issue_dialog);
|
||||
$("#edit_issue_dialog").html("#{escape_javascript(render('form'))}");
|
||||
switchToEditIssue();
|
||||
|
||||
|
|
|
@ -58,6 +58,8 @@
|
|||
%ul#issues-table.unstyled.issues_table
|
||||
= render "issues"
|
||||
|
||||
#new_issue_dialog
|
||||
#edit_issue_dialog
|
||||
|
||||
:javascript
|
||||
$(function(){
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
:plain
|
||||
var new_issue_dialog = $("<div id='new_issue_dialog'></div>");
|
||||
new_issue_dialog.html("#{escape_javascript(render('form'))}");
|
||||
switchToNewIssue(new_issue_dialog);
|
||||
$("#new_issue_dialog").html("#{escape_javascript(render('form'))}");
|
||||
switchToNewIssue();
|
||||
|
|
|
@ -8,9 +8,7 @@
|
|||
GITLAB
|
||||
%span.separator
|
||||
%h1.project_name= title
|
||||
.search
|
||||
= form_tag search_path, method: :get do |f|
|
||||
= text_field_tag "search", nil, placeholder: "Search", class: "search-input"
|
||||
= render "layouts/search"
|
||||
.fbtn
|
||||
- if current_user.is_admin?
|
||||
= 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
|
||||
|
||||
= 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
|
||||
$(function() {
|
||||
autocompleteMembersUrl = "#{ "/api/v2/projects/#{@project.code}/members" if @project }";
|
||||
autocompleteMembersParams.private_token = "#{current_user.authentication_token}";
|
||||
autocompleteMembers.url = "#{ "/api/v2/projects/#{@project.code}/members" if @project }";
|
||||
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
|
||||
autocompleteEmojiData = $.map(autocompleteEmojiData, function(value) {
|
||||
autocompleteEmoji.data = $.map(autocompleteEmoji.data, function(value) {
|
||||
return {
|
||||
name: 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
|
||||
|
||||
.clearfix
|
||||
.main_box
|
||||
.merge_requests_form_box
|
||||
.top_box_content
|
||||
= f.label :title do
|
||||
= f.label :title do
|
||||
%strong= "Title *"
|
||||
.input= f.text_field :title, class: "input-xxlarge pad gfm-input", maxlength: 255, rows: 5
|
||||
.middle_box_content
|
||||
= f.label :assignee_id do
|
||||
%i.icon-user
|
||||
Assign to
|
||||
.input= f.select(:assignee_id, @project.users.all.collect {|p| [ p.name, p.id ] }, { include_blank: "Select user" }, {class: 'chosen span3'})
|
||||
.input= f.text_field :title, class: "input-xxlarge pad js-gfm-input", maxlength: 255, rows: 5
|
||||
.merge_requests_middle_box
|
||||
.merge_requests_assignee
|
||||
= f.label :assignee_id do
|
||||
%i.icon-user
|
||||
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
|
||||
|
||||
|
|
|
@ -10,6 +10,10 @@
|
|||
%span.btn.small.disabled.grouped
|
||||
%i.icon-comment
|
||||
= 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
|
||||
= merge_request.source_branch
|
||||
→
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
: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
|
||||
$(".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
|
||||
.title
|
||||
%ul.nav.nav-pills
|
||||
%li{class: ("active" if (params[:f] == 'open' || !params[:f]))}
|
||||
= link_to project_merge_requests_path(@project, f: 'open') do
|
||||
Open
|
||||
%li{class: ("active" if params[:f] == "closed")}
|
||||
= link_to project_merge_requests_path(@project, f: "closed") do
|
||||
Closed
|
||||
%li{class: ("active" if params[:f] == 'assigned-to-me')}
|
||||
= link_to project_merge_requests_path(@project, f: 'assigned-to-me') do
|
||||
To Me
|
||||
%li{class: ("active" if params[:f] == 'all')}
|
||||
= link_to project_merge_requests_path(@project, f: 'all') do
|
||||
All
|
||||
.left
|
||||
%ul.nav.nav-pills
|
||||
%li{class: ("active" if (params[:f] == 'open' || !params[:f]))}
|
||||
= link_to project_merge_requests_path(@project, f: 'open', milestone_id: params[:milestone_id]) do
|
||||
Open
|
||||
%li{class: ("active" if params[:f] == "closed")}
|
||||
= link_to project_merge_requests_path(@project, f: "closed", milestone_id: params[:milestone_id]) do
|
||||
Closed
|
||||
%li{class: ("active" if params[:f] == 'assigned-to-me')}
|
||||
= link_to project_merge_requests_path(@project, f: 'assigned-to-me', milestone_id: params[:milestone_id]) do
|
||||
To Me
|
||||
%li{class: ("active" if params[:f] == '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
|
||||
= render @merge_requests
|
||||
|
@ -35,3 +42,7 @@
|
|||
.span4.right
|
||||
%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)
|
||||
|
||||
- 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"
|
||||
%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
|
||||
|
|
|
@ -1,18 +1,22 @@
|
|||
%li{class: "milestone", id: dom_id(milestone) }
|
||||
.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
|
||||
= 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
|
||||
= 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
|
||||
= milestone.expires_at
|
||||
%br
|
||||
.progress.progress-success.span3
|
||||
.bar{style: "width: #{milestone.percent_complete}%;"}
|
||||
|
||||
|
||||
|
||||
.row
|
||||
.span4
|
||||
.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
|
||||
Progress:
|
||||
%small
|
||||
#{@milestone.issues.closed.count} closed
|
||||
#{@milestone.closed_items_count} closed
|
||||
–
|
||||
#{@milestone.issues.opened.count} open
|
||||
.progress.progress-success
|
||||
#{@milestone.open_items_count} open
|
||||
.progress.progress-info
|
||||
.bar{style: "width: #{@milestone.percent_complete}%;"}
|
||||
|
||||
|
||||
|
@ -58,15 +58,28 @@
|
|||
%span.badge.badge-info ##{issue.id}
|
||||
–
|
||||
= link_to_gfm truncate(issue.title, length: 60), [@project, issue]
|
||||
%br
|
||||
|
||||
.span6
|
||||
%table
|
||||
%table.milestone-merge-requests-filter
|
||||
%thead
|
||||
%th Participants
|
||||
- @users.each do |user|
|
||||
%tr
|
||||
%th
|
||||
%ul.nav.nav-pills
|
||||
%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
|
||||
= image_tag gravatar_icon(user.email, 24), width: "24"
|
||||
|
||||
= user.name
|
||||
= link_to [@project, merge_request] do
|
||||
%span.badge.badge-info ##{merge_request.id}
|
||||
–
|
||||
= 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_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
|
||||
.hint
|
||||
.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_type
|
||||
= 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
|
||||
.buttons
|
||||
= 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{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; "}
|
||||
= "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"}
|
||||
%tr
|
||||
%td{style: "font-size: 1px; line-height: 1px;", width: "21"}
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
%h3.page_title
|
||||
Private token
|
||||
%span.cred.right
|
||||
keep it in secret!
|
||||
keep it secret!
|
||||
.padded
|
||||
= form_for @user, url: profile_reset_private_token_path, method: :put do |f|
|
||||
.data
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue