Merge branch 'master' into discussions
Conflicts: app/assets/stylesheets/main.scss app/models/project.rb app/views/notes/_common_form.html.haml app/views/notes/_per_line_form.html.haml lib/gitlab/markdown.rb spec/models/note_spec.rb
|
@ -1,4 +1,5 @@
|
||||||
env:
|
env:
|
||||||
|
- DB=postgresql
|
||||||
- DB=mysql
|
- DB=mysql
|
||||||
before_install:
|
before_install:
|
||||||
- sudo apt-get install libicu-dev -y
|
- sudo apt-get install libicu-dev -y
|
||||||
|
@ -18,8 +19,7 @@ services:
|
||||||
before_script:
|
before_script:
|
||||||
- "cp config/database.yml.$DB config/database.yml"
|
- "cp config/database.yml.$DB config/database.yml"
|
||||||
- "cp config/gitlab.yml.example config/gitlab.yml"
|
- "cp config/gitlab.yml.example config/gitlab.yml"
|
||||||
- "bundle exec rake db:create RAILS_ENV=test"
|
- "bundle exec rake db:setup RAILS_ENV=test"
|
||||||
- "bundle exec rake db:migrate RAILS_ENV=test"
|
|
||||||
- "bundle exec rake db:seed_fu RAILS_ENV=test"
|
- "bundle exec rake db:seed_fu RAILS_ENV=test"
|
||||||
- "sh -e /etc/init.d/xvfb start"
|
- "sh -e /etc/init.d/xvfb start"
|
||||||
script: "bundle exec rake travis --trace"
|
script: "bundle exec rake travis --trace"
|
||||||
|
|
11
CHANGELOG
|
@ -1,4 +1,15 @@
|
||||||
v 4.0.0
|
v 4.0.0
|
||||||
|
- Reorganized settings
|
||||||
|
- Fixed commits compare
|
||||||
|
- Refactored scss
|
||||||
|
- Improve status checks
|
||||||
|
- Validates presence of User#name
|
||||||
|
- Fixed postgres support
|
||||||
|
- Removed sqlite support
|
||||||
|
- Modified post-receive hook
|
||||||
|
- Milestones can be closed now
|
||||||
|
- Show comment events on dashboard
|
||||||
|
- Quick add team members via group#people page
|
||||||
- [API] expose created date for hooks and SSH keys
|
- [API] expose created date for hooks and SSH keys
|
||||||
- [API] list, create issue notes
|
- [API] list, create issue notes
|
||||||
- [API] list, create snippet notes
|
- [API] list, create snippet notes
|
||||||
|
|
|
@ -1,26 +1,26 @@
|
||||||
## Contribute to GitLab
|
# Contact & support
|
||||||
|
|
||||||
If you want to contribute to GitLab, follow this process:
|
If you want quick help, head over to our [Support Forum](https://groups.google.com/forum/#!forum/gitlabhq).
|
||||||
|
Otherwise you can follow our [Issue Submission Guide](https://github.com/gitlabhq/gitlabhq/wiki/Issue-Submission-Guide) for a more systematic and thorough guide to solving your issues.
|
||||||
|
|
||||||
1. Fork the project
|
|
||||||
2. Create a feature branch
|
|
||||||
3. Code
|
|
||||||
4. Create a pull request
|
|
||||||
|
|
||||||
We will only accept pull requests if:
|
|
||||||
|
|
||||||
* Your code has proper tests and all tests pass
|
# Contribute to GitLab
|
||||||
* Your code can be merged w/o problems
|
|
||||||
* It won't break existing functionality
|
|
||||||
* It's quality code
|
|
||||||
* We like it :)
|
|
||||||
|
|
||||||
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).
|
## Recipes
|
||||||
|
|
||||||
## Installation
|
We collect user submitted installation scripts and config file templates for platforms we don't support officially.
|
||||||
|
We believe there is merit in allowing a certain amount of diversity.
|
||||||
|
You can get and submit your solution to running/configuring GitLab with your favorite OS/distro, database, web server, cloud hoster, configuration management tool, etc.
|
||||||
|
|
||||||
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.
|
Help us improve the collection of [GitLab Recipes](https://github.com/gitlabhq/gitlab-recipes/)
|
||||||
|
|
||||||
## Running tests
|
|
||||||
|
|
||||||
For more information on running the tests please read the [development tips](https://github.com/gitlabhq/gitlabhq/blob/master/doc/development.md)
|
## Feature suggestions
|
||||||
|
|
||||||
|
Follow the [Issue Submission Guide](https://github.com/gitlabhq/gitlabhq/wiki/Issue-Submission-Guide) and support other peoples ideas or propose your own.
|
||||||
|
|
||||||
|
|
||||||
|
## Code
|
||||||
|
|
||||||
|
Follow our [Developer Guide](https://github.com/gitlabhq/gitlabhq/wiki/Developer-Guide) to set you up for hacking on GitLab.
|
||||||
|
|
6
Gemfile
|
@ -32,7 +32,7 @@ gem 'grit_ext', git: "https://github.com/gitlabhq/grit_ext.git", ref:
|
||||||
gem "gitolite", '1.1.0'
|
gem "gitolite", '1.1.0'
|
||||||
|
|
||||||
# Syntax highlighter
|
# Syntax highlighter
|
||||||
gem "pygments.rb", git: "https://github.com/gitlabhq/pygments.rb.git", ref: '4db80c599067e2d5f23c5c243bf85b8ca0368ad4'
|
gem "pygments.rb", git: "https://github.com/gitlabhq/pygments.rb.git", branch: "master"
|
||||||
|
|
||||||
# Language detection
|
# Language detection
|
||||||
gem "github-linguist", "~> 2.3.4" , require: "linguist"
|
gem "github-linguist", "~> 2.3.4" , require: "linguist"
|
||||||
|
@ -100,7 +100,7 @@ group :assets do
|
||||||
gem "therubyracer"
|
gem "therubyracer"
|
||||||
|
|
||||||
gem 'chosen-rails', "0.9.8"
|
gem 'chosen-rails', "0.9.8"
|
||||||
gem 'jquery-atwho-rails', "0.1.6"
|
gem 'jquery-atwho-rails', "0.1.7"
|
||||||
gem "jquery-rails", "2.1.3"
|
gem "jquery-rails", "2.1.3"
|
||||||
gem "jquery-ui-rails", "2.0.2"
|
gem "jquery-ui-rails", "2.0.2"
|
||||||
gem "modernizr", "2.6.2"
|
gem "modernizr", "2.6.2"
|
||||||
|
@ -124,7 +124,7 @@ group :development, :test do
|
||||||
gem "capybara"
|
gem "capybara"
|
||||||
gem "pry"
|
gem "pry"
|
||||||
gem "awesome_print"
|
gem "awesome_print"
|
||||||
gem "database_cleaner"
|
gem "database_cleaner", ref: "f89c34300e114be99532f14c115b2799a3380ac6", git: "https://github.com/bmabey/database_cleaner.git"
|
||||||
gem "launchy"
|
gem "launchy"
|
||||||
gem 'factory_girl_rails'
|
gem 'factory_girl_rails'
|
||||||
|
|
||||||
|
|
18
Gemfile.lock
|
@ -1,3 +1,10 @@
|
||||||
|
GIT
|
||||||
|
remote: https://github.com/bmabey/database_cleaner.git
|
||||||
|
revision: f89c34300e114be99532f14c115b2799a3380ac6
|
||||||
|
ref: f89c34300e114be99532f14c115b2799a3380ac6
|
||||||
|
specs:
|
||||||
|
database_cleaner (0.9.1)
|
||||||
|
|
||||||
GIT
|
GIT
|
||||||
remote: https://github.com/ctran/annotate_models.git
|
remote: https://github.com/ctran/annotate_models.git
|
||||||
revision: be4e26825b521f0b2d86b181e2dff89901aa9b1e
|
revision: be4e26825b521f0b2d86b181e2dff89901aa9b1e
|
||||||
|
@ -45,8 +52,8 @@ GIT
|
||||||
|
|
||||||
GIT
|
GIT
|
||||||
remote: https://github.com/gitlabhq/pygments.rb.git
|
remote: https://github.com/gitlabhq/pygments.rb.git
|
||||||
revision: 4db80c599067e2d5f23c5c243bf85b8ca0368ad4
|
revision: db1da0343adf86b49bdc3add04d02d2e80438d38
|
||||||
ref: 4db80c599067e2d5f23c5c243bf85b8ca0368ad4
|
branch: master
|
||||||
specs:
|
specs:
|
||||||
pygments.rb (0.3.2)
|
pygments.rb (0.3.2)
|
||||||
posix-spawn (~> 0.3.6)
|
posix-spawn (~> 0.3.6)
|
||||||
|
@ -140,7 +147,6 @@ GEM
|
||||||
colorize (0.5.8)
|
colorize (0.5.8)
|
||||||
crack (0.3.1)
|
crack (0.3.1)
|
||||||
daemons (1.1.9)
|
daemons (1.1.9)
|
||||||
database_cleaner (0.9.1)
|
|
||||||
devise (2.1.2)
|
devise (2.1.2)
|
||||||
bcrypt-ruby (~> 3.0)
|
bcrypt-ruby (~> 3.0)
|
||||||
orm_adapter (~> 0.1)
|
orm_adapter (~> 0.1)
|
||||||
|
@ -227,7 +233,7 @@ GEM
|
||||||
httpauth (0.2.0)
|
httpauth (0.2.0)
|
||||||
i18n (0.6.1)
|
i18n (0.6.1)
|
||||||
journey (1.0.4)
|
journey (1.0.4)
|
||||||
jquery-atwho-rails (0.1.6)
|
jquery-atwho-rails (0.1.7)
|
||||||
jquery-rails (2.1.3)
|
jquery-rails (2.1.3)
|
||||||
railties (>= 3.1.0, < 5.0)
|
railties (>= 3.1.0, < 5.0)
|
||||||
thor (~> 0.14)
|
thor (~> 0.14)
|
||||||
|
@ -458,7 +464,7 @@ DEPENDENCIES
|
||||||
chosen-rails (= 0.9.8)
|
chosen-rails (= 0.9.8)
|
||||||
coffee-rails (~> 3.2.2)
|
coffee-rails (~> 3.2.2)
|
||||||
colored
|
colored
|
||||||
database_cleaner
|
database_cleaner!
|
||||||
devise (~> 2.1.0)
|
devise (~> 2.1.0)
|
||||||
draper (~> 0.18.0)
|
draper (~> 0.18.0)
|
||||||
email_spec
|
email_spec
|
||||||
|
@ -481,7 +487,7 @@ DEPENDENCIES
|
||||||
guard-spinach
|
guard-spinach
|
||||||
haml-rails (~> 0.3.5)
|
haml-rails (~> 0.3.5)
|
||||||
httparty
|
httparty
|
||||||
jquery-atwho-rails (= 0.1.6)
|
jquery-atwho-rails (= 0.1.7)
|
||||||
jquery-rails (= 2.1.3)
|
jquery-rails (= 2.1.3)
|
||||||
jquery-ui-rails (= 2.0.2)
|
jquery-ui-rails (= 2.0.2)
|
||||||
kaminari (~> 0.14.1)
|
kaminari (~> 0.14.1)
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# Welcome to GitLab [![build status](https://secure.travis-ci.org/gitlabhq/gitlabhq.png)](https://secure.travis-ci.org/gitlabhq/gitlabhq) [![build status](https://secure.travis-ci.org/gitlabhq/grit.png)](https://secure.travis-ci.org/gitlabhq/grit) [![Code Climate](https://codeclimate.com/badge.png)](https://codeclimate.com/github/gitlabhq/gitlabhq)
|
# Welcome to GitLab [![build status](https://secure.travis-ci.org/gitlabhq/gitlabhq.png)](https://travis-ci.org/gitlabhq/gitlabhq) [![build status](https://secure.travis-ci.org/gitlabhq/grit.png)](https://travis-ci.org/gitlabhq/grit) [![Code Climate](https://codeclimate.com/badge.png)](https://codeclimate.com/github/gitlabhq/gitlabhq) [![Dependency Status](https://gemnasium.com/gitlabhq/gitlabhq.png)](https://gemnasium.com/gitlabhq/gitlabhq)
|
||||||
|
|
||||||
GitLab is a free project and repository management application
|
GitLab is a free project and repository management application
|
||||||
|
|
||||||
|
|
BIN
app/assets/images/ajax_loader_gray.gif
Normal file
After Width: | Height: | Size: 8.2 KiB |
Before Width: | Height: | Size: 2.9 KiB |
Before Width: | Height: | Size: 3.2 KiB |
Before Width: | Height: | Size: 4.5 KiB |
Before Width: | Height: | Size: 3.2 KiB |
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.9 KiB |
Before Width: | Height: | Size: 2.1 KiB |
Before Width: | Height: | Size: 2.3 KiB |
BIN
app/assets/images/switch_icon.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
|
@ -1,52 +1,38 @@
|
||||||
# Creates the variables for setting up GFM auto-completion
|
# Creates the variables for setting up GFM auto-completion
|
||||||
|
|
||||||
window.GitLab ?= {}
|
window.GitLab ?= {}
|
||||||
GitLab.GfmAutoComplete ?= {}
|
GitLab.GfmAutoComplete =
|
||||||
|
# Emoji
|
||||||
|
Emoji:
|
||||||
|
data: []
|
||||||
|
template: '<li data-value="${insert}">${name} <img alt="${name}" height="20" src="${image}" width="20" /></li>'
|
||||||
|
|
||||||
# Emoji
|
# Team Members
|
||||||
data = []
|
Members:
|
||||||
template = "<li data-value='${insert}'>${name} <img alt='${name}' height='20' src='${image}' width='20' /></li>"
|
data: []
|
||||||
GitLab.GfmAutoComplete.Emoji = {data, template}
|
url: ''
|
||||||
|
params:
|
||||||
|
private_token: ''
|
||||||
|
template: '<li data-value="${username}">${username} <small>${name}</small></li>'
|
||||||
|
|
||||||
# Team Members
|
# Add GFM auto-completion to all input fields, that accept GFM input.
|
||||||
data = []
|
setup: ->
|
||||||
url = '';
|
|
||||||
params = {private_token: '', page: 1}
|
|
||||||
GitLab.GfmAutoComplete.Members = {data, url, params}
|
|
||||||
|
|
||||||
# Add GFM auto-completion to all input fields, that accept GFM input.
|
|
||||||
GitLab.GfmAutoComplete.setup = ->
|
|
||||||
input = $('.js-gfm-input')
|
input = $('.js-gfm-input')
|
||||||
|
|
||||||
# Emoji
|
# Emoji
|
||||||
input.atWho ':',
|
input.atWho ':',
|
||||||
data: GitLab.GfmAutoComplete.Emoji.data,
|
data: @Emoji.data
|
||||||
tpl: GitLab.GfmAutoComplete.Emoji.template
|
tpl: @Emoji.template
|
||||||
|
|
||||||
# Team Members
|
# Team Members
|
||||||
input.atWho '@', (query, callback) ->
|
|
||||||
(getMoreMembers = ->
|
|
||||||
$.getJSON(GitLab.GfmAutoComplete.Members.url, GitLab.GfmAutoComplete.Members.params)
|
|
||||||
.success (members) ->
|
|
||||||
# pick the data we need
|
|
||||||
newMembersData = $.map(members, (m) -> m.name )
|
|
||||||
|
|
||||||
# add the new page of data to the rest
|
|
||||||
$.merge(GitLab.GfmAutoComplete.Members.data, newMembersData)
|
|
||||||
|
|
||||||
# show the pop-up with a copy of the current data
|
|
||||||
callback(GitLab.GfmAutoComplete.Members.data[..])
|
|
||||||
|
|
||||||
# are we past the last page?
|
|
||||||
if newMembersData.length is 0
|
|
||||||
# set static data and stop callbacks
|
|
||||||
input.atWho '@',
|
input.atWho '@',
|
||||||
data: GitLab.GfmAutoComplete.Members.data
|
tpl: @Members.template
|
||||||
callback: null
|
callback: (query, callback) =>
|
||||||
else
|
request_params = $.extend({}, @Members.params, query: query)
|
||||||
# get next page
|
$.getJSON(@Members.url, request_params).done (members) =>
|
||||||
getMoreMembers()
|
new_members_data = $.map(members, (m) ->
|
||||||
|
username: m.username,
|
||||||
|
name: m.name
|
||||||
|
)
|
||||||
|
callback(new_members_data)
|
||||||
|
|
||||||
# so the next request gets the next page
|
|
||||||
GitLab.GfmAutoComplete.Members.params.page += 1
|
|
||||||
).call()
|
|
||||||
|
|
|
@ -1,43 +1,3 @@
|
||||||
function switchToNewIssue(){
|
|
||||||
$(".issues_content").hide("fade", { direction: "left" }, 150, function(){
|
|
||||||
$('select#issue_assignee_id').chosen();
|
|
||||||
$('select#issue_milestone_id').chosen();
|
|
||||||
$("#new_issue_dialog").show("fade", { direction: "right" }, 150);
|
|
||||||
$('.top-tabs .add_new').hide();
|
|
||||||
disableButtonIfEmptyField("#issue_title", ".save-btn");
|
|
||||||
GitLab.GfmAutoComplete.setup();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function switchToEditIssue(){
|
|
||||||
$(".issues_content").hide("fade", { direction: "left" }, 150, function(){
|
|
||||||
$('select#issue_assignee_id').chosen();
|
|
||||||
$('select#issue_milestone_id').chosen();
|
|
||||||
$("#edit_issue_dialog").show("fade", { direction: "right" }, 150);
|
|
||||||
$('.add_new').hide();
|
|
||||||
disableButtonIfEmptyField("#issue_title", ".save-btn");
|
|
||||||
GitLab.GfmAutoComplete.setup();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function switchFromNewIssue(){
|
|
||||||
backToIssues();
|
|
||||||
}
|
|
||||||
|
|
||||||
function switchFromEditIssue(){
|
|
||||||
backToIssues();
|
|
||||||
}
|
|
||||||
|
|
||||||
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").html("");
|
|
||||||
$("#new_issue_dialog").html("");
|
|
||||||
$('.add_new').show();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function initIssuesSearch() {
|
function initIssuesSearch() {
|
||||||
var href = $('#issue_search_form').attr('action');
|
var href = $('#issue_search_form').attr('action');
|
||||||
var last_terms = '';
|
var last_terms = '';
|
||||||
|
@ -76,23 +36,15 @@ function issuesPage(){
|
||||||
$(this).closest("form").submit();
|
$(this).closest("form").submit();
|
||||||
});
|
});
|
||||||
|
|
||||||
$("#new_issue_link").click(function(){
|
$('body').on('ajax:success', '.close_issue, .reopen_issue', function(){
|
||||||
updateNewIssueURL();
|
|
||||||
});
|
|
||||||
|
|
||||||
$('body').on('ajax:success', '.close_issue, .reopen_issue, #new_issue', function(){
|
|
||||||
var t = $(this),
|
var t = $(this),
|
||||||
totalIssues,
|
totalIssues,
|
||||||
reopen = t.hasClass('reopen_issue'),
|
reopen = t.hasClass('reopen_issue');
|
||||||
newIssue = false;
|
$('.issue_counter').each(function(){
|
||||||
if( this.id == 'new_issue' ){
|
|
||||||
newIssue = true;
|
|
||||||
}
|
|
||||||
$('.issue_counter, #new_issue').each(function(){
|
|
||||||
var issue = $(this);
|
var issue = $(this);
|
||||||
totalIssues = parseInt( $(this).html(), 10 );
|
totalIssues = parseInt( $(this).html(), 10 );
|
||||||
|
|
||||||
if( newIssue || ( reopen && issue.closest('.main_menu').length ) ){
|
if( reopen && issue.closest('.main_menu').length ){
|
||||||
$(this).html( totalIssues+1 );
|
$(this).html( totalIssues+1 );
|
||||||
}else {
|
}else {
|
||||||
$(this).html( totalIssues-1 );
|
$(this).html( totalIssues-1 );
|
||||||
|
@ -126,20 +78,3 @@ function issuesCheckChanged() {
|
||||||
$('.issues_filters').show();
|
$('.issues_filters').show();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateNewIssueURL(){
|
|
||||||
var new_issue_link = $("#new_issue_link");
|
|
||||||
var milestone_id = $("#milestone_id").val();
|
|
||||||
var assignee_id = $("#assignee_id").val();
|
|
||||||
var new_href = "";
|
|
||||||
if(milestone_id){
|
|
||||||
new_href = "issue[milestone_id]=" + milestone_id + "&";
|
|
||||||
}
|
|
||||||
if(assignee_id){
|
|
||||||
new_href = new_href + "issue[assignee_id]=" + assignee_id;
|
|
||||||
}
|
|
||||||
if(new_href.length){
|
|
||||||
new_href = new_issue_link.attr("href") + "?" + new_href;
|
|
||||||
new_issue_link.attr("href", new_href);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
|
@ -7,6 +7,18 @@ window.slugify = (text) ->
|
||||||
window.ajaxGet = (url) ->
|
window.ajaxGet = (url) ->
|
||||||
$.ajax({type: "GET", url: url, dataType: "script"})
|
$.ajax({type: "GET", url: url, dataType: "script"})
|
||||||
|
|
||||||
|
window.errorMessage = (message) ->
|
||||||
|
ehtml = $("<p>")
|
||||||
|
ehtml.addClass("error_message")
|
||||||
|
ehtml.html(message)
|
||||||
|
ehtml
|
||||||
|
|
||||||
|
window.split = (val) ->
|
||||||
|
return val.split( /,\s*/ )
|
||||||
|
|
||||||
|
window.extractLast = (term) ->
|
||||||
|
return split( term ).pop()
|
||||||
|
|
||||||
# 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)
|
||||||
|
|
|
@ -26,6 +26,12 @@ var MergeRequest = {
|
||||||
self.showState(data.state);
|
self.showState(data.state);
|
||||||
}, "json");
|
}, "json");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(self.opts.ci_enable){
|
||||||
|
$.get(self.opts.url_to_ci_check, function(data){
|
||||||
|
self.showCiState(data.status);
|
||||||
|
}, "json");
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
initTabs:
|
initTabs:
|
||||||
|
@ -79,6 +85,11 @@ var MergeRequest = {
|
||||||
$(".automerge_widget." + state).show();
|
$(".automerge_widget." + state).show();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
showCiState:
|
||||||
|
function(state){
|
||||||
|
$(".ci_widget").hide();
|
||||||
|
$(".ci_widget.ci-" + state).show();
|
||||||
|
},
|
||||||
|
|
||||||
loadDiff:
|
loadDiff:
|
||||||
function() {
|
function() {
|
||||||
|
|
|
@ -18,10 +18,3 @@ $ ->
|
||||||
# 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,10 +0,0 @@
|
||||||
/*
|
|
||||||
* This is a manifest file that'll automatically include all the stylesheets available in this directory
|
|
||||||
* and any sub-directories. You're free to add application-wide styles to this file and they'll appear at
|
|
||||||
* the top of the compiled file, but it's generally better to create a new file per style scope.
|
|
||||||
*= require jquery.ui.gitlab
|
|
||||||
*= require jquery.atwho
|
|
||||||
*= require chosen
|
|
||||||
*= require_self
|
|
||||||
*= require main
|
|
||||||
*/
|
|
52
app/assets/stylesheets/application.scss
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
/*
|
||||||
|
* This is a manifest file that'll automatically include all the stylesheets available in this directory
|
||||||
|
* and any sub-directories. You're free to add application-wide styles to this file and they'll appear at
|
||||||
|
* the top of the compiled file, but it's generally better to create a new file per style scope.
|
||||||
|
*= require jquery.ui.gitlab
|
||||||
|
*= require jquery.atwho
|
||||||
|
*= require chosen
|
||||||
|
*= require_self
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GitLab bootstrap:
|
||||||
|
*/
|
||||||
|
@import "gitlab_bootstrap.scss";
|
||||||
|
|
||||||
|
@import "common.scss";
|
||||||
|
@import "ref_select.scss";
|
||||||
|
|
||||||
|
@import "sections/header.scss";
|
||||||
|
@import "sections/nav.scss";
|
||||||
|
@import "sections/commits.scss";
|
||||||
|
@import "sections/issues.scss";
|
||||||
|
@import "sections/projects.scss";
|
||||||
|
@import "sections/snippets.scss";
|
||||||
|
@import "sections/votes.scss";
|
||||||
|
@import "sections/merge_requests.scss";
|
||||||
|
@import "sections/graph.scss";
|
||||||
|
@import "sections/events.scss";
|
||||||
|
@import "sections/themes.scss";
|
||||||
|
@import "sections/tree.scss";
|
||||||
|
@import "sections/notes.scss";
|
||||||
|
@import "sections/profile.scss";
|
||||||
|
@import "sections/login.scss";
|
||||||
|
@import "sections/editor.scss";
|
||||||
|
|
||||||
|
@import "highlight/white.scss";
|
||||||
|
@import "highlight/dark.scss";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* UI themes:
|
||||||
|
*/
|
||||||
|
@import "themes/ui_basic.scss";
|
||||||
|
@import "themes/ui_mars.scss";
|
||||||
|
@import "themes/ui_modern.scss";
|
||||||
|
@import "themes/ui_gray.scss";
|
||||||
|
@import "themes/ui_color.scss";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Styles for JS behaviors.
|
||||||
|
*/
|
||||||
|
@import "behaviors.scss";
|
||||||
|
|
|
@ -13,20 +13,12 @@ body {
|
||||||
margin: 0 0;
|
margin: 0 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.container .sidebar {
|
|
||||||
width: 200px;
|
|
||||||
height: 100%;
|
|
||||||
min-height: 450px;
|
|
||||||
float: right;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.visible_link,
|
.visible_link,
|
||||||
.author_link {
|
.author_link {
|
||||||
color: $link_color;
|
color: $link_color;
|
||||||
}
|
}
|
||||||
|
|
||||||
.help li { color:#111 }
|
.help li { color:$style_color; }
|
||||||
|
|
||||||
.back_link {
|
.back_link {
|
||||||
text-decoration: underline;
|
text-decoration: underline;
|
||||||
|
@ -65,6 +57,9 @@ table a code {
|
||||||
background: url(ajax_loader.gif) no-repeat center center;
|
background: url(ajax_loader.gif) no-repeat center center;
|
||||||
width: 40px;
|
width: 40px;
|
||||||
height: 40px;
|
height: 40px;
|
||||||
|
&.loading-gray {
|
||||||
|
background: url(ajax_loader_gray.gif) no-repeat center center;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** FLASH message **/
|
/** FLASH message **/
|
||||||
|
@ -96,28 +91,17 @@ table a code {
|
||||||
margin-right:50px
|
margin-right:50px
|
||||||
}
|
}
|
||||||
|
|
||||||
.handle:hover {
|
|
||||||
cursor: move;
|
|
||||||
}
|
|
||||||
|
|
||||||
span.update-author {
|
span.update-author {
|
||||||
display: block;
|
display: block;
|
||||||
}
|
|
||||||
span.update-author {
|
|
||||||
color: #999;
|
color: #999;
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
font-style: italic;
|
font-style: italic;
|
||||||
}
|
strong {
|
||||||
span.update-author strong {
|
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** UPDATE ITEM **/
|
|
||||||
span.update-author {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
/** END UPDATE ITEM **/
|
|
||||||
.dashboard-loader {
|
.dashboard-loader {
|
||||||
float: left;
|
float: left;
|
||||||
margin: 10px;
|
margin: 10px;
|
||||||
|
@ -264,21 +248,6 @@ input.git_clone_url {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** bordered list **/
|
|
||||||
ul.bordered-list {
|
|
||||||
margin: 5px 0px;
|
|
||||||
padding: 0px;
|
|
||||||
li {
|
|
||||||
padding: 5px 0;
|
|
||||||
border-bottom: 1px solid #EEE;
|
|
||||||
overflow: hidden;
|
|
||||||
display: block;
|
|
||||||
margin: 0px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ul.bordered-list li:last-child { border:none }
|
|
||||||
|
|
||||||
.line_holder {
|
.line_holder {
|
||||||
&:hover {
|
&:hover {
|
||||||
td {
|
td {
|
||||||
|
@ -316,98 +285,6 @@ p.time {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.ico {
|
|
||||||
background: url("images.png") no-repeat -85px -77px;
|
|
||||||
width: 19px;
|
|
||||||
height: 16px;
|
|
||||||
float: left;
|
|
||||||
position: relative;
|
|
||||||
margin-right: 10px;
|
|
||||||
top: 8px;
|
|
||||||
|
|
||||||
&.project {
|
|
||||||
background-position: -37px -77px;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.activities {
|
|
||||||
background-position:-162px -22px;
|
|
||||||
}
|
|
||||||
&.projects {
|
|
||||||
background-position:-209px -21px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.leftbar {
|
|
||||||
h5, .title {
|
|
||||||
padding: 5px 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
h4 {
|
|
||||||
font-size: 14px;
|
|
||||||
padding: 2px 10px;
|
|
||||||
color: #666;
|
|
||||||
border-bottom: 1px solid #f1f1f1;
|
|
||||||
}
|
|
||||||
a:last-child h4 { border: none; }
|
|
||||||
|
|
||||||
a:hover {
|
|
||||||
h4 {
|
|
||||||
color: #111;
|
|
||||||
background: $hover;
|
|
||||||
border-color: #CCC;
|
|
||||||
.ico.project {
|
|
||||||
background-position:-209px -21px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.bottom {
|
|
||||||
padding: 10px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.votes {
|
|
||||||
font-size: 13px;
|
|
||||||
line-height: 15px;
|
|
||||||
.progress {
|
|
||||||
height: 4px;
|
|
||||||
margin: 0;
|
|
||||||
.bar {
|
|
||||||
float: left;
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
.bar-success {
|
|
||||||
@include linear-gradient(#62C462, #51A351);
|
|
||||||
background-color: #468847;
|
|
||||||
}
|
|
||||||
.bar-danger {
|
|
||||||
@include linear-gradient(#EE5F5B, #BD362F);
|
|
||||||
background-color: #B94A48;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.upvotes {
|
|
||||||
display: inline-block;
|
|
||||||
color: #468847;
|
|
||||||
}
|
|
||||||
.downvotes {
|
|
||||||
display: inline-block;
|
|
||||||
color: #B94A48;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.votes-block {
|
|
||||||
margin: 14px 6px 6px 0;
|
|
||||||
.downvotes {
|
|
||||||
float: right;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.votes-inline {
|
|
||||||
display: inline-block;
|
|
||||||
margin: 0 8px;
|
|
||||||
.progress {
|
|
||||||
display: inline-block;
|
|
||||||
padding: 0 0 2px;
|
|
||||||
width: 45px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Fix for readme code (stopped it from being yellow) */
|
/* Fix for readme code (stopped it from being yellow) */
|
||||||
.readme {
|
.readme {
|
||||||
|
@ -420,7 +297,6 @@ p.time {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.highlight_word {
|
.highlight_word {
|
||||||
background: #EEDC94;
|
background: #EEDC94;
|
||||||
}
|
}
|
||||||
|
@ -428,23 +304,16 @@ p.time {
|
||||||
.status_info {
|
.status_info {
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
padding: 5px 15px;
|
padding: 5px 15px;
|
||||||
line-height: 24px;
|
line-height: 26px;
|
||||||
width: 60px;
|
|
||||||
text-align: center;
|
text-align: center;
|
||||||
float: left;
|
float: right;
|
||||||
margin-right: 20px;
|
position: relative;
|
||||||
|
top: -5px;
|
||||||
|
@include border-radius(4px);
|
||||||
|
|
||||||
&.success {
|
|
||||||
background: #5BB75B;
|
|
||||||
color: white;
|
|
||||||
text-shadow: 0 1px #111;
|
|
||||||
border-color: #9A9;
|
|
||||||
}
|
|
||||||
&.error {
|
&.error {
|
||||||
background: #DA4E49;
|
background: #DA4E49;
|
||||||
border-color: #BD362F;
|
color: #FFF;
|
||||||
color: white;
|
|
||||||
text-shadow: 0 1px #111;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -463,16 +332,6 @@ p.time {
|
||||||
height: 150px;
|
height: 150px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.gitlab_pagination {
|
|
||||||
span a { color: $link_color; }
|
|
||||||
.prev, .next, .current, .page a {
|
|
||||||
padding: 10px;
|
|
||||||
}
|
|
||||||
.current {
|
|
||||||
border-bottom: 2px solid $style_color;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fixes alignment on notes.
|
// Fixes alignment on notes.
|
||||||
.new_note {
|
.new_note {
|
||||||
label {
|
label {
|
||||||
|
@ -647,9 +506,14 @@ pre {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.milestone .progress {
|
.milestone {
|
||||||
|
&.milestone-closed {
|
||||||
|
background: #eee;
|
||||||
|
}
|
||||||
|
.progress {
|
||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
margin-top: 4px;
|
margin-top: 4px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.float-link {
|
.float-link {
|
||||||
|
|
26
app/assets/stylesheets/gitlab_bootstrap.scss
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
/** Override bootstrap variables **/
|
||||||
|
$baseFontSize: 13px !default;
|
||||||
|
$baseLineHeight: 18px !default;
|
||||||
|
|
||||||
|
// BOOTSTRAP
|
||||||
|
@import "bootstrap";
|
||||||
|
@import "bootstrap/responsive-utilities";
|
||||||
|
@import "bootstrap/responsive-1200px-min";
|
||||||
|
|
||||||
|
@import "font-awesome";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GitLab bootstrap.
|
||||||
|
* Overrides some styles of twitter bootstrap.
|
||||||
|
* Also give some common classes for GitLab app
|
||||||
|
*/
|
||||||
|
@import "gitlab_bootstrap/variables.scss";
|
||||||
|
@import "gitlab_bootstrap/fonts.scss";
|
||||||
|
@import "gitlab_bootstrap/mixins.scss";
|
||||||
|
@import "gitlab_bootstrap/common.scss";
|
||||||
|
@import "gitlab_bootstrap/typography.scss";
|
||||||
|
@import "gitlab_bootstrap/buttons.scss";
|
||||||
|
@import "gitlab_bootstrap/blocks.scss";
|
||||||
|
@import "gitlab_bootstrap/files.scss";
|
||||||
|
@import "gitlab_bootstrap/tables.scss";
|
||||||
|
@import "gitlab_bootstrap/lists.scss";
|
|
@ -31,6 +31,7 @@
|
||||||
.middle_box_content,
|
.middle_box_content,
|
||||||
.bottom_box_content {
|
.bottom_box_content {
|
||||||
padding: 15px;
|
padding: 15px;
|
||||||
|
word-wrap: break-word;
|
||||||
|
|
||||||
pre {
|
pre {
|
||||||
background: none !important;
|
background: none !important;
|
||||||
|
@ -40,6 +41,15 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.top_box_content {
|
||||||
|
.box-title {
|
||||||
|
color: $style_color;
|
||||||
|
font-size: 18px;
|
||||||
|
font-weight: normal;
|
||||||
|
line-height: 28px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.middle_box_content {
|
.middle_box_content {
|
||||||
@include border-radius(0);
|
@include border-radius(0);
|
||||||
border: none;
|
border: none;
|
||||||
|
@ -83,6 +93,10 @@
|
||||||
border-top: 1px solid #eaeaea;
|
border-top: 1px solid #eaeaea;
|
||||||
border-bottom: 1px solid #bbb;
|
border-bottom: 1px solid #bbb;
|
||||||
|
|
||||||
|
> a {
|
||||||
|
text-shadow: 0 1px 1px #fff;
|
||||||
|
}
|
||||||
|
|
||||||
&.small {
|
&.small {
|
||||||
line-height: 28px;
|
line-height: 28px;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
|
@ -138,19 +152,6 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
li, .wll {
|
|
||||||
padding: 10px;
|
|
||||||
&:first-child {
|
|
||||||
@include border-radius(4px 4px 0 0);
|
|
||||||
border-top: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:last-child {
|
|
||||||
@include border-radius(0 0 4px 4px);
|
|
||||||
border: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.ui-box-body {
|
.ui-box-body {
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,11 +10,6 @@
|
||||||
/** COMMON CLASSES **/
|
/** COMMON CLASSES **/
|
||||||
.left { float:left }
|
.left { float:left }
|
||||||
.right { float:right!important }
|
.right { float:right!important }
|
||||||
.width-50p { width:50% }
|
|
||||||
.width-49p { width:49% }
|
|
||||||
.width-30p { width:30% }
|
|
||||||
.width-65p { width:65% }
|
|
||||||
.width-100p { width:100% }
|
|
||||||
.append-bottom-10 { margin-bottom:10px }
|
.append-bottom-10 { margin-bottom:10px }
|
||||||
.append-bottom-20 { margin-bottom:20px }
|
.append-bottom-20 { margin-bottom:20px }
|
||||||
.prepend-top-10 { margin-top:10px }
|
.prepend-top-10 { margin-top:10px }
|
||||||
|
@ -30,6 +25,7 @@
|
||||||
.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 }
|
.light { color: #888 }
|
||||||
|
.tiny { font-weight: normal }
|
||||||
|
|
||||||
/** PILLS & TABS**/
|
/** PILLS & TABS**/
|
||||||
.nav-pills a:hover { background-color: #888; }
|
.nav-pills a:hover { background-color: #888; }
|
||||||
|
@ -99,18 +95,21 @@ input[type='search'].search-text-input {
|
||||||
border: 1px solid #ccc;
|
border: 1px solid #ccc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
input[type='text'].danger {
|
||||||
|
background: #F2DEDE!important;
|
||||||
|
border-color: #D66;
|
||||||
|
text-shadow: 0 1px 1px #fff
|
||||||
|
}
|
||||||
|
|
||||||
fieldset legend { font-size: 17px; }
|
fieldset legend { font-size: 17px; }
|
||||||
|
|
||||||
ul.nav.nav-projects-tabs {
|
/** PAGINATION **/
|
||||||
@extend .nav-tabs;
|
.gitlab_pagination {
|
||||||
|
span a { color: $link_color; }
|
||||||
padding-left: 8px;
|
.prev, .next, .current, .page a {
|
||||||
|
padding: 10px;
|
||||||
li {
|
|
||||||
a {
|
|
||||||
padding: 4px 20px;
|
|
||||||
margin-top: 2px;
|
|
||||||
border-color: #DDD;
|
|
||||||
}
|
}
|
||||||
|
.current {
|
||||||
|
border-bottom: 2px solid $style_color;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,11 +43,15 @@
|
||||||
padding: 0 4px;
|
padding: 0 4px;
|
||||||
}
|
}
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
h1, h2 {
|
|
||||||
line-height: 46px;
|
h1 { font-size: 26px; line-height: 46px; }
|
||||||
}
|
h2 { font-size: 22px; line-height: 42px; }
|
||||||
h3, h4 {
|
h3 { font-size: 20px; line-height: 40px; }
|
||||||
line-height: 40px;
|
h4 { font-size: 18px; line-height: 32px; }
|
||||||
|
h5 { font-size: 16px; line-height: 26px; }
|
||||||
|
|
||||||
|
.white .highlight pre {
|
||||||
|
background: #f5f5f5;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,23 +1,38 @@
|
||||||
/** LISTS **/
|
/**
|
||||||
|
* Well styled list
|
||||||
ul {
|
|
||||||
/**
|
|
||||||
* List li block element #1
|
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
.wll {
|
.well-list {
|
||||||
|
margin: 0;
|
||||||
|
list-style: none;
|
||||||
|
li {
|
||||||
background-color: #FFF;
|
background-color: #FFF;
|
||||||
padding: 10px 5px;
|
padding: 10px;
|
||||||
min-height: 20px;
|
min-height: 20px;
|
||||||
border-bottom: 1px solid #eee;
|
border-bottom: 1px solid #eee;
|
||||||
border-bottom: 1px solid rgba(0, 0, 0, 0.05);
|
border-bottom: 1px solid rgba(0, 0, 0, 0.05);
|
||||||
|
|
||||||
|
&.disabled {
|
||||||
|
color: #888;
|
||||||
|
}
|
||||||
|
|
||||||
&.smoke { background-color: #f5f5f5; }
|
&.smoke { background-color: #f5f5f5; }
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
background: $hover;
|
background: $hover;
|
||||||
border-bottom: 1px solid #ADF;
|
border-bottom: 1px solid #ADF;
|
||||||
}
|
}
|
||||||
&:last-child { border:none }
|
|
||||||
|
&:first-child {
|
||||||
|
@include border-radius(4px 4px 0 0);
|
||||||
|
border-top: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
@include border-radius(0 0 4px 4px);
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
|
||||||
.author { color: #999; }
|
.author { color: #999; }
|
||||||
|
|
||||||
p {
|
p {
|
||||||
|
@ -29,6 +44,11 @@ ul {
|
||||||
top: 3px;
|
top: 3px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.well-title {
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 18px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,3 +59,17 @@ ol, ul {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** light list with border-bottom between li **/
|
||||||
|
ul.bordered-list {
|
||||||
|
margin: 5px 0px;
|
||||||
|
padding: 0px;
|
||||||
|
li {
|
||||||
|
padding: 5px 0;
|
||||||
|
border-bottom: 1px solid #EEE;
|
||||||
|
overflow: hidden;
|
||||||
|
display: block;
|
||||||
|
margin: 0px;
|
||||||
|
&:last-child { border:none }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -58,3 +58,12 @@
|
||||||
@mixin solid-shade {
|
@mixin solid-shade {
|
||||||
@include box-shadow(0 0 0 3px #f1f1f1);
|
@include box-shadow(0 0 0 3px #f1f1f1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@mixin header-font {
|
||||||
|
color: $style_color;
|
||||||
|
text-shadow: 0 1px 1px #FFF;
|
||||||
|
font-family: 'Korolev', sans-serif;
|
||||||
|
font-size: 28px;
|
||||||
|
line-height: 48px;
|
||||||
|
font-weight: normal;
|
||||||
|
}
|
|
@ -1,7 +1,8 @@
|
||||||
.black .highlight {
|
.black .highlight {
|
||||||
pre {
|
|
||||||
background-color: #333;
|
background-color: #333;
|
||||||
|
pre {
|
||||||
color: #eee;
|
color: #eee;
|
||||||
|
background: inherit;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hll { display: block; background-color: darken($hover, 65%) }
|
.hll { display: block; background-color: darken($hover, 65%) }
|
||||||
|
|
113
app/assets/stylesheets/jquery.ui.gitlab.css
vendored
|
@ -1,27 +1,3 @@
|
||||||
/*
|
|
||||||
* jQuery UI CSS Framework 1.8.7
|
|
||||||
*
|
|
||||||
* Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
|
|
||||||
* Dual licensed under the MIT or GPL Version 2 licenses.
|
|
||||||
* http://jquery.org/license
|
|
||||||
*
|
|
||||||
* http://docs.jquery.com/UI/Theming/API
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Layout helpers
|
|
||||||
----------------------------------*/
|
|
||||||
.ui-helper-hidden { display: none; }
|
|
||||||
.ui-helper-hidden-accessible { position: absolute !important; clip: rect(1px 1px 1px 1px); clip: rect(1px,1px,1px,1px); }
|
|
||||||
.ui-helper-reset { margin: 0; padding: 0; border: 0; outline: 0; line-height: 1.3; text-decoration: none; font-size: 100%; list-style: none; }
|
|
||||||
.ui-helper-clearfix:after { content: "."; display: block; height: 0; clear: both; visibility: hidden; }
|
|
||||||
.ui-helper-clearfix { display: inline-block; }
|
|
||||||
/* required comment for clearfix to work in Opera \*/
|
|
||||||
* html .ui-helper-clearfix { height:1%; }
|
|
||||||
.ui-helper-clearfix { display:block; }
|
|
||||||
/* end clearfix */
|
|
||||||
.ui-helper-zfix { width: 100%; height: 100%; top: 0; left: 0; position: absolute; opacity: 0; filter:Alpha(Opacity=0); }
|
|
||||||
|
|
||||||
|
|
||||||
/* Interaction Cues
|
/* Interaction Cues
|
||||||
----------------------------------*/
|
----------------------------------*/
|
||||||
.ui-state-disabled { cursor: default !important; }
|
.ui-state-disabled { cursor: default !important; }
|
||||||
|
@ -140,26 +116,6 @@
|
||||||
/* Overlays */
|
/* Overlays */
|
||||||
.ui-widget-overlay { background: #262b33; opacity: .70;filter:Alpha(Opacity=70); }
|
.ui-widget-overlay { background: #262b33; opacity: .70;filter:Alpha(Opacity=70); }
|
||||||
.ui-widget-shadow { margin: -8px 0 0 -8px; padding: 8px; background: #000000; opacity: .30;filter:Alpha(Opacity=30); -moz-border-radius: 8px; -webkit-border-radius: 8px; border-radius: 8px; }
|
.ui-widget-shadow { margin: -8px 0 0 -8px; padding: 8px; background: #000000; opacity: .30;filter:Alpha(Opacity=30); -moz-border-radius: 8px; -webkit-border-radius: 8px; border-radius: 8px; }
|
||||||
/*
|
|
||||||
* jQuery UI Resizable 1.8.7
|
|
||||||
*
|
|
||||||
* Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
|
|
||||||
* Dual licensed under the MIT or GPL Version 2 licenses.
|
|
||||||
* http://jquery.org/license
|
|
||||||
*
|
|
||||||
* http://docs.jquery.com/UI/Resizable#theming
|
|
||||||
*/
|
|
||||||
.ui-resizable { position: relative;}
|
|
||||||
.ui-resizable-handle { position: absolute; font-size: 0.1px; z-index: 999; display: block;}
|
|
||||||
.ui-resizable-disabled .ui-resizable-handle, .ui-resizable-autohide .ui-resizable-handle { display: none; }
|
|
||||||
.ui-resizable-n { cursor: n-resize; height: 7px; width: 100%; top: -5px; left: 0; }
|
|
||||||
.ui-resizable-s { cursor: s-resize; height: 7px; width: 100%; bottom: -5px; left: 0; }
|
|
||||||
.ui-resizable-e { cursor: e-resize; width: 7px; right: -5px; top: 0; height: 100%; }
|
|
||||||
.ui-resizable-w { cursor: w-resize; width: 7px; left: -5px; top: 0; height: 100%; }
|
|
||||||
.ui-resizable-se { cursor: se-resize; width: 12px; height: 12px; right: 1px; bottom: 1px; }
|
|
||||||
.ui-resizable-sw { cursor: sw-resize; width: 9px; height: 9px; left: -5px; bottom: -5px; }
|
|
||||||
.ui-resizable-nw { cursor: nw-resize; width: 9px; height: 9px; left: -5px; top: -5px; }
|
|
||||||
.ui-resizable-ne { cursor: ne-resize; width: 9px; height: 9px; right: -5px; top: -5px;}
|
|
||||||
/*
|
/*
|
||||||
* jQuery UI Selectable 1.8.7
|
* jQuery UI Selectable 1.8.7
|
||||||
*
|
*
|
||||||
|
@ -240,34 +196,7 @@
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
* jQuery UI Slider 1.8.7
|
|
||||||
*
|
|
||||||
* Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
|
|
||||||
* Dual licensed under the MIT or GPL Version 2 licenses.
|
|
||||||
* http://jquery.org/license
|
|
||||||
*
|
|
||||||
* http://docs.jquery.com/UI/Slider#theming
|
|
||||||
*/
|
|
||||||
.ui-slider { position: relative; text-align: left; background: #d7d7d7; z-index: 1; }
|
|
||||||
.ui-slider { -moz-box-shadow: 0 1px 2px rgba(0,0,0,0.5) inset; -webkit-box-shadow: 0 1px 2px rgba(0,0,0,0.5) inset; box-shadow: 0 1px 2px rgba(0,0,0,0.5) inset; }
|
|
||||||
.ui-slider .ui-slider-handle { background: url(slider_handles.png) 0px -23px no-repeat; position: absolute; z-index: 2; width: 23px; height: 23px; cursor: default; border: none; outline: none; -moz-box-shadow: none; -webkit-box-shadow: none; box-shadow: none; }
|
|
||||||
.ui-slider .ui-state-hover, .ui-slider .ui-state-active { background-position: 0 0; }
|
|
||||||
.ui-slider .ui-slider-range { background: #a3cae0; position: absolute; z-index: 1; font-size: .7em; display: block; border: 0; background-position: 0 0; }
|
|
||||||
.ui-slider .ui-slider-range { -moz-box-shadow: 0 1px 2px rgba(17,35,45,0.6) inset; -webkit-box-shadow: 0 1px 2px rgba(17,35,45,0.6) inset; box-shadow: 0 1px 2px rgba(17,35,45,0.6) inset; }
|
|
||||||
|
|
||||||
|
|
||||||
.ui-slider-horizontal { height: 5px; }
|
|
||||||
.ui-slider-horizontal .ui-slider-handle { top: -8px; margin-left: -13px; }
|
|
||||||
.ui-slider-horizontal .ui-slider-range { top: 0; height: 100%; }
|
|
||||||
.ui-slider-horizontal .ui-slider-range-min { left: 0; }
|
|
||||||
.ui-slider-horizontal .ui-slider-range-max { right: 0; }
|
|
||||||
|
|
||||||
.ui-slider-vertical { width: 5px; height: 100px; }
|
|
||||||
.ui-slider-vertical .ui-slider-handle { left: -8px; margin-left: 0; margin-bottom: -13px; }
|
|
||||||
.ui-slider-vertical .ui-slider-range { left: 0; width: 100%; }
|
|
||||||
.ui-slider-vertical .ui-slider-range-min { bottom: 0; }
|
|
||||||
.ui-slider-vertical .ui-slider-range-max { top: 0; }
|
|
||||||
/*
|
/*
|
||||||
* jQuery UI Datepicker 1.8.7
|
* jQuery UI Datepicker 1.8.7
|
||||||
*
|
*
|
||||||
|
@ -326,45 +255,3 @@
|
||||||
.ui-datepicker table .ui-state-highlight { border-color: #ADE; }
|
.ui-datepicker table .ui-state-highlight { border-color: #ADE; }
|
||||||
.ui-datepicker-calendar .ui-state-default { background: transparent; border-color: #FFF; }
|
.ui-datepicker-calendar .ui-state-default { background: transparent; border-color: #FFF; }
|
||||||
.ui-datepicker-calendar .ui-state-active { background: #D9EDF7; border-color: #ADE; color: #3A89A3; font-weight: bold; text-shadow: 0 1px 1px #fff; }
|
.ui-datepicker-calendar .ui-state-active { background: #D9EDF7; border-color: #ADE; color: #3A89A3; font-weight: bold; text-shadow: 0 1px 1px #fff; }
|
||||||
|
|
||||||
/* with multiple calendars */
|
|
||||||
.ui-datepicker.ui-datepicker-multi { width:auto; }
|
|
||||||
.ui-datepicker-multi .ui-datepicker-group { float:left; }
|
|
||||||
.ui-datepicker-multi .ui-datepicker-group table { width:95%; margin:0 auto .4em; }
|
|
||||||
.ui-datepicker-multi-2 .ui-datepicker-group { width:50%; }
|
|
||||||
.ui-datepicker-multi-3 .ui-datepicker-group { width:33.3%; }
|
|
||||||
.ui-datepicker-multi-4 .ui-datepicker-group { width:25%; }
|
|
||||||
.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header { border-left-width:0; }
|
|
||||||
.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header { border-left-width:0; }
|
|
||||||
.ui-datepicker-multi .ui-datepicker-buttonpane { clear:left; }
|
|
||||||
.ui-datepicker-row-break { clear:both; width:100%; }
|
|
||||||
|
|
||||||
|
|
||||||
/* Extra Input Field Styling */
|
|
||||||
.ui-form textarea, .ui-form input:not([type="submit"]):not([type="button"]):not([type="checkbox"]):not([type="radio"]):not([type="file"]):not([type="range"]) {
|
|
||||||
padding: 3px;
|
|
||||||
-webkit-border-radius: 2px;
|
|
||||||
-moz-border-radius: 2px;
|
|
||||||
border-radius: 2px;
|
|
||||||
border: 1px solid #cecece;
|
|
||||||
outline: none;
|
|
||||||
-webkit-box-shadow: 0 1px 3px rgba(0,0,0,0.1) inset, 0 1px 0 rgba(255,255,255,0.2);
|
|
||||||
-moz-box-shadow: 0 1px 3px rgba(0,0,0,0.1) inset, 0 1px 0 rgba(255,255,255,0.2);
|
|
||||||
box-shadow: 0 1px 3px rgba(0,0,0,0.1) inset, 0 1px 0 rgba(255,255,255,0.2);
|
|
||||||
-webkit-transition: all 250ms ease-in-out;
|
|
||||||
-moz-transition: all 250ms ease-in-out;
|
|
||||||
-o-transition: all 250ms ease-in-out;
|
|
||||||
transition: all 250ms ease-in-out;
|
|
||||||
}
|
|
||||||
.ui-form textarea:hover, .ui-form input:not([type="submit"]):not([type="button"]):not([type="checkbox"]):not([type="radio"]):not([type="file"]):not([type="range"]):hover {
|
|
||||||
border: 1px solid #bdbdbd;
|
|
||||||
-webkit-box-shadow: 0 1px 3px rgba(0,0,0,0.2) inset, 0 1px 0 rgba(255,255,255,0.2);
|
|
||||||
-moz-box-shadow: 0 1px 3px rgba(0,0,0,0.2) inset, 0 1px 0 rgba(255,255,255,0.2);
|
|
||||||
box-shadow: 0 1px 3px rgba(0,0,0,0.2) inset, 0 1px 0 rgba(255,255,255,0.2);
|
|
||||||
}
|
|
||||||
.ui-form textarea:focus, .ui-form input:not([type="submit"]):not([type="button"]):not([type="checkbox"]):not([type="radio"]):not([type="file"]):not([type="range"]):focus {
|
|
||||||
border: 1px solid #95bdd4;
|
|
||||||
-webkit-box-shadow: 0 2px 3px rgba(161,202,226,0.5) inset, 0 1px 0 rgba(255,255,255,0.2);
|
|
||||||
-moz-box-shadow: 0 2px 3px rgba(161,202,226,0.5) inset, 0 1px 0 rgba(255,255,255,0.2);
|
|
||||||
box-shadow: 0 2px 3px rgba(161,202,226,0.5) inset, 0 1px 0 rgba(255,255,255,0.2);
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,144 +0,0 @@
|
||||||
/** Override bootstrap variables **/
|
|
||||||
$baseFontSize: 13px !default;
|
|
||||||
$baseLineHeight: 18px !default;
|
|
||||||
|
|
||||||
// BOOTSTRAP
|
|
||||||
@import "bootstrap";
|
|
||||||
@import "bootstrap/responsive-utilities";
|
|
||||||
@import "bootstrap/responsive-1200px-min";
|
|
||||||
|
|
||||||
// FONT AWESOME
|
|
||||||
@import "font-awesome";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Variables
|
|
||||||
* Contains colors
|
|
||||||
*/
|
|
||||||
@import "variables.scss";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Custom fonts
|
|
||||||
* Contains @font-face font Korolev and default $monotype
|
|
||||||
*/
|
|
||||||
@import "fonts.scss";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* General mixins.
|
|
||||||
* Contains rounded borders, gradients and shades
|
|
||||||
*/
|
|
||||||
@import "mixins.scss";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Header of application.
|
|
||||||
* Contain application logo, search panel, profile icon
|
|
||||||
*/
|
|
||||||
@import "sections/header.scss";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Navigation menu of application.
|
|
||||||
* Panel with links to pages depends on project, profile or admin area
|
|
||||||
*/
|
|
||||||
@import "sections/nav.scss";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This file represent some UI that can be changed
|
|
||||||
* during web app restyle or theme select.
|
|
||||||
*
|
|
||||||
* Next items should be placed there
|
|
||||||
* - link, button colors
|
|
||||||
* - header restyles
|
|
||||||
* - main menu restyles
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
@import "themes/ui_basic.scss";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* UI themes:
|
|
||||||
*/
|
|
||||||
@import "themes/ui_mars.scss";
|
|
||||||
@import "themes/ui_modern.scss";
|
|
||||||
@import "themes/ui_gray.scss";
|
|
||||||
@import "themes/ui_color.scss";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* GitLab bootstrap.
|
|
||||||
* Overrides some styles of twitter bootstrap.
|
|
||||||
* Also give some common classes for GitLab app
|
|
||||||
*/
|
|
||||||
@import "gitlab_bootstrap/common.scss";
|
|
||||||
@import "gitlab_bootstrap/typography.scss";
|
|
||||||
@import "gitlab_bootstrap/buttons.scss";
|
|
||||||
@import "gitlab_bootstrap/blocks.scss";
|
|
||||||
@import "gitlab_bootstrap/files.scss";
|
|
||||||
@import "gitlab_bootstrap/tables.scss";
|
|
||||||
@import "gitlab_bootstrap/lists.scss";
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Most of application styles placed here.
|
|
||||||
* This file represent common UI that should not be changed between themes
|
|
||||||
* or project restyling like form width or user avatar class or commit title
|
|
||||||
*
|
|
||||||
* TODO: clean it
|
|
||||||
*/
|
|
||||||
@import "common.scss";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Styles necessary to support JS behaviours.
|
|
||||||
*/
|
|
||||||
@import "behaviors.scss";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Styles related to specific part of app
|
|
||||||
*/
|
|
||||||
@import "sections/commits.scss";
|
|
||||||
@import "sections/issues.scss";
|
|
||||||
@import "sections/projects.scss";
|
|
||||||
@import "sections/merge_requests.scss";
|
|
||||||
@import "sections/graph.scss";
|
|
||||||
@import "sections/events.scss";
|
|
||||||
@import "sections/themes.scss";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This scss file redefine chozen selectbox styles for
|
|
||||||
* project Branch/Tag select element
|
|
||||||
*/
|
|
||||||
@import "ref_select.scss";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Code (files list) styles. Browsing project files there
|
|
||||||
*/
|
|
||||||
@import "sections/tree.scss";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This file represent notes(comments) styles
|
|
||||||
*/
|
|
||||||
@import "sections/notes.scss";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This file represent profile styles
|
|
||||||
*/
|
|
||||||
@import "sections/profile.scss";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Devise styles
|
|
||||||
*/
|
|
||||||
@import "sections/login.scss";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* CODE HIGHTLIGHT BASE
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
@import "highlight/white.scss";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* CODE HIGHTLIGHT DARK schema
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
@import "highlight/dark.scss";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* File Editor styles
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
@import "sections/editor.scss";
|
|
|
@ -232,8 +232,6 @@
|
||||||
|
|
||||||
/** COMMIT ROW **/
|
/** COMMIT ROW **/
|
||||||
.commit {
|
.commit {
|
||||||
@extend .wll;
|
|
||||||
|
|
||||||
.browse_code_link_holder {
|
.browse_code_link_holder {
|
||||||
@extend .span2;
|
@extend .span2;
|
||||||
float: right;
|
float: right;
|
||||||
|
@ -305,3 +303,17 @@
|
||||||
color: #fff;
|
color: #fff;
|
||||||
font-family: $monospace;
|
font-family: $monospace;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.commits-compare-switch{
|
||||||
|
background: url("switch_icon.png") no-repeat center center;
|
||||||
|
width: 16px;
|
||||||
|
height: 18px;
|
||||||
|
text-indent: -9999px;
|
||||||
|
float: left;
|
||||||
|
margin-right: 9px;
|
||||||
|
border: 1px solid #DDD;
|
||||||
|
@include border-radius(4px);
|
||||||
|
padding: 4px;
|
||||||
|
background-color: #EEE;
|
||||||
|
}
|
||||||
|
|
|
@ -31,7 +31,6 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
.event-item {
|
.event-item {
|
||||||
min-height: 40px;
|
|
||||||
border-bottom: 1px solid #eee;
|
border-bottom: 1px solid #eee;
|
||||||
.event-title {
|
.event-title {
|
||||||
color: #333;
|
color: #333;
|
||||||
|
@ -50,14 +49,18 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.avatar {
|
.avatar {
|
||||||
width: 32px;
|
position: relative;
|
||||||
|
top: -3px;
|
||||||
}
|
}
|
||||||
.event_icon {
|
.event_icon {
|
||||||
|
position: relative;
|
||||||
float: right;
|
float: right;
|
||||||
border: 1px solid #EEE;
|
border: 1px solid #EEE;
|
||||||
padding: 5px;
|
padding: 5px;
|
||||||
@include border-radius(5px);
|
@include border-radius(5px);
|
||||||
background: #F9F9F9;
|
background: #F9F9F9;
|
||||||
|
margin-left: 10px;
|
||||||
|
top: -6px;
|
||||||
img {
|
img {
|
||||||
width: 20px;
|
width: 20px;
|
||||||
}
|
}
|
||||||
|
@ -71,9 +74,8 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
padding: 15px 5px;
|
padding: 16px 5px;
|
||||||
&:last-child { border:none }
|
&:last-child { border:none }
|
||||||
.wll:hover { background:none }
|
|
||||||
|
|
||||||
.event_commits {
|
.event_commits {
|
||||||
margin-top: 5px;
|
margin-top: 5px;
|
||||||
|
|
|
@ -44,14 +44,9 @@ header {
|
||||||
background: url('logo_dark.png') no-repeat 0px 2px;
|
background: url('logo_dark.png') no-repeat 0px 2px;
|
||||||
float: left;
|
float: left;
|
||||||
margin-left: 2px;
|
margin-left: 2px;
|
||||||
font-size: 30px;
|
|
||||||
line-height: 48px;
|
|
||||||
font-weight: normal;
|
|
||||||
color: $style_color;
|
|
||||||
text-shadow: 0 1px 1px #FFF;
|
|
||||||
padding-left: 45px;
|
padding-left: 45px;
|
||||||
height: 40px;
|
height: 40px;
|
||||||
font-family: 'Korolev', sans-serif;
|
@include header-font;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -66,12 +61,7 @@ header {
|
||||||
float: left;
|
float: left;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
margin-right: 30px;
|
margin-right: 30px;
|
||||||
font-size: 30px;
|
@include header-font;
|
||||||
line-height: 48px;
|
|
||||||
font-weight: normal;
|
|
||||||
color: $style_color;
|
|
||||||
text-shadow: 0 1px 1px #FFF;
|
|
||||||
font-family: 'Korolev', sans-serif;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -172,7 +162,7 @@ header {
|
||||||
display: none;
|
display: none;
|
||||||
z-index: 100000;
|
z-index: 100000;
|
||||||
@include border-radius(4px);
|
@include border-radius(4px);
|
||||||
width: 100px;
|
width: 130px;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
right: 5px;
|
right: 5px;
|
||||||
top: 38px;
|
top: 38px;
|
||||||
|
@ -181,7 +171,7 @@ header {
|
||||||
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2);
|
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2);
|
||||||
a {
|
a {
|
||||||
color: #fff;
|
color: #fff;
|
||||||
padding: 7px 10px;
|
padding: 12px 15px;
|
||||||
display: block;
|
display: block;
|
||||||
text-shadow: none;
|
text-shadow: none;
|
||||||
border-bottom: 1px solid #666;
|
border-bottom: 1px solid #666;
|
||||||
|
|
|
@ -121,12 +121,3 @@ input.check_all_issues {
|
||||||
#update_status {
|
#update_status {
|
||||||
width: 100px;
|
width: 100px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Milestones list
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
.milestone {
|
|
||||||
@extend .wll;
|
|
||||||
}
|
|
||||||
|
|
|
@ -136,9 +136,3 @@ li.merge_request {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.status-badge {
|
|
||||||
height: 32px;
|
|
||||||
width: 100%;
|
|
||||||
@include border-radius(5px);
|
|
||||||
}
|
|
||||||
|
|
|
@ -3,15 +3,13 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
ul.main_menu {
|
ul.main_menu {
|
||||||
@include border-radius(4px);
|
|
||||||
margin: auto;
|
margin: auto;
|
||||||
margin: 30px 0;
|
margin: 30px 0;
|
||||||
border: 1px solid #BBB;
|
margin-top: 10px;
|
||||||
|
border-bottom: 1px solid #DDD;
|
||||||
height: 37px;
|
height: 37px;
|
||||||
@include bg-gray-gradient;
|
|
||||||
position: relative;
|
position: relative;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
@include shade;
|
|
||||||
.count {
|
.count {
|
||||||
position: relative;
|
position: relative;
|
||||||
top: -1px;
|
top: -1px;
|
||||||
|
@ -24,9 +22,6 @@ ul.main_menu {
|
||||||
line-height: 14px;
|
line-height: 14px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
color: #777;
|
color: #777;
|
||||||
background: #f2f2f2;
|
|
||||||
border-top: 1px solid #CCC;
|
|
||||||
@include border-radius(8px);
|
|
||||||
}
|
}
|
||||||
.label {
|
.label {
|
||||||
background: $hover;
|
background: $hover;
|
||||||
|
@ -38,23 +33,10 @@ ul.main_menu {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
display: table-cell;
|
display: table-cell;
|
||||||
width: 1%;
|
width: 1%;
|
||||||
border-right: 1px solid #DDD;
|
|
||||||
border-left: 1px solid #EEE;
|
|
||||||
border-bottom: 2px solid #CFCFCF;
|
|
||||||
|
|
||||||
&:first-child{
|
|
||||||
@include border-radius(5px 0 0 5px);
|
|
||||||
border-left: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.active {
|
&.active {
|
||||||
background-color: #D5D5D5;
|
border-bottom: 2px solid #474D57;
|
||||||
border-right: 1px solid #BBB;
|
a {
|
||||||
border-left: 1px solid #BBB;
|
color: $style_color;
|
||||||
@include border-radius(0 0 1px 1px);
|
|
||||||
&:first-child{
|
|
||||||
border-bottom: none;
|
|
||||||
border-left: none;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,10 +55,10 @@ ul.main_menu {
|
||||||
a {
|
a {
|
||||||
display: block;
|
display: block;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
font-weight: bold;
|
font-weight: normal;
|
||||||
height: 35px;
|
height: 35px;
|
||||||
line-height: 36px;
|
line-height: 36px;
|
||||||
color: $style_color;
|
color: #777;
|
||||||
text-shadow: 0 1px 1px white;
|
text-shadow: 0 1px 1px white;
|
||||||
padding: 0 10px;
|
padding: 0 10px;
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,12 +4,11 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.side {
|
.side {
|
||||||
@extend .span4;
|
|
||||||
@extend .right;
|
@extend .right;
|
||||||
|
|
||||||
.groups_box,
|
.groups_box,
|
||||||
.projects_box {
|
.projects_box {
|
||||||
h5 {
|
> h5 {
|
||||||
color: $style_color;
|
color: $style_color;
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
text-shadow: 0 1px 1px #fff;
|
text-shadow: 0 1px 1px #fff;
|
||||||
|
@ -17,20 +16,8 @@
|
||||||
line-height: 32px;
|
line-height: 32px;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
}
|
}
|
||||||
ul {
|
.nav-projects-tabs li { padding: 0; }
|
||||||
li {
|
.well-list {
|
||||||
padding: 0;
|
|
||||||
a {
|
|
||||||
display: block;
|
|
||||||
.group_name {
|
|
||||||
font-size: 14px;
|
|
||||||
line-height: 18px;
|
|
||||||
}
|
|
||||||
.project_name {
|
|
||||||
color: #4fa2bd;
|
|
||||||
font-size: 14px;
|
|
||||||
line-height: 18px;
|
|
||||||
}
|
|
||||||
.arrow {
|
.arrow {
|
||||||
float: right;
|
float: right;
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
|
@ -45,9 +32,6 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
@extend .leftbar;
|
|
||||||
@extend .ui-box;
|
@extend .ui-box;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -117,3 +101,25 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ul.nav.nav-projects-tabs {
|
||||||
|
@extend .nav-tabs;
|
||||||
|
|
||||||
|
padding-left: 8px;
|
||||||
|
|
||||||
|
li {
|
||||||
|
a {
|
||||||
|
padding: 4px 20px;
|
||||||
|
margin-top: 2px;
|
||||||
|
border-color: #DDD;
|
||||||
|
background-color: #EEE;
|
||||||
|
text-shadow: 0 1px 1px white;
|
||||||
|
color: #555;
|
||||||
|
}
|
||||||
|
&.active {
|
||||||
|
a {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
9
app/assets/stylesheets/sections/snippets.scss
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
.snippet.file_holder {
|
||||||
|
.file_title {
|
||||||
|
.snippet-file-name {
|
||||||
|
position: relative;
|
||||||
|
top: -4px;
|
||||||
|
left: -4px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
43
app/assets/stylesheets/sections/votes.scss
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
.votes {
|
||||||
|
font-size: 13px;
|
||||||
|
line-height: 15px;
|
||||||
|
.progress {
|
||||||
|
height: 4px;
|
||||||
|
margin: 0;
|
||||||
|
.bar {
|
||||||
|
float: left;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
.bar-success {
|
||||||
|
@include linear-gradient(#62C462, #51A351);
|
||||||
|
background-color: #468847;
|
||||||
|
}
|
||||||
|
.bar-danger {
|
||||||
|
@include linear-gradient(#EE5F5B, #BD362F);
|
||||||
|
background-color: #B94A48;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.upvotes {
|
||||||
|
display: inline-block;
|
||||||
|
color: #468847;
|
||||||
|
}
|
||||||
|
.downvotes {
|
||||||
|
display: inline-block;
|
||||||
|
color: #B94A48;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.votes-block {
|
||||||
|
margin: 14px 6px 6px 0;
|
||||||
|
.downvotes {
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.votes-inline {
|
||||||
|
display: inline-block;
|
||||||
|
margin: 0 8px;
|
||||||
|
.progress {
|
||||||
|
display: inline-block;
|
||||||
|
padding: 0 0 2px;
|
||||||
|
width: 45px;
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,18 +4,6 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
.ui_basic {
|
.ui_basic {
|
||||||
/*
|
|
||||||
* Common styles
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
a {
|
|
||||||
color: $link_color;
|
|
||||||
&:hover {
|
|
||||||
text-decoration: none;
|
|
||||||
color: $primary_color;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.app_logo {
|
.app_logo {
|
||||||
.separator {
|
.separator {
|
||||||
margin-left: 0;
|
margin-left: 0;
|
||||||
|
|
|
@ -2,7 +2,9 @@ class ProjectUpdateContext < BaseContext
|
||||||
def execute(role = :default)
|
def execute(role = :default)
|
||||||
namespace_id = params[:project].delete(:namespace_id)
|
namespace_id = params[:project].delete(:namespace_id)
|
||||||
|
|
||||||
if namespace_id.present?
|
allowed_transfer = can?(current_user, :change_namespace, project) || role == :admin
|
||||||
|
|
||||||
|
if allowed_transfer && namespace_id.present?
|
||||||
if namespace_id == Namespace.global_id
|
if namespace_id == Namespace.global_id
|
||||||
if project.namespace.present?
|
if project.namespace.present?
|
||||||
# Transfer to global namespace from anyone
|
# Transfer to global namespace from anyone
|
||||||
|
|
|
@ -2,7 +2,7 @@ class Admin::GroupsController < AdminController
|
||||||
before_filter :group, only: [:edit, :show, :update, :destroy, :project_update]
|
before_filter :group, only: [:edit, :show, :update, :destroy, :project_update]
|
||||||
|
|
||||||
def index
|
def index
|
||||||
@groups = Group.scoped
|
@groups = Group.order('name ASC')
|
||||||
@groups = @groups.search(params[:name]) if params[:name].present?
|
@groups = @groups.search(params[:name]) if params[:name].present?
|
||||||
@groups = @groups.page(params[:page]).per(20)
|
@groups = @groups.page(params[:page]).per(20)
|
||||||
end
|
end
|
||||||
|
@ -11,6 +11,7 @@ class Admin::GroupsController < AdminController
|
||||||
@projects = Project.scoped
|
@projects = Project.scoped
|
||||||
@projects = @projects.not_in_group(@group) if @group.projects.present?
|
@projects = @projects.not_in_group(@group) if @group.projects.present?
|
||||||
@projects = @projects.all
|
@projects = @projects.all
|
||||||
|
@projects.reject!(&:empty_repo?)
|
||||||
end
|
end
|
||||||
|
|
||||||
def new
|
def new
|
||||||
|
|
|
@ -4,12 +4,13 @@ class Admin::ProjectsController < AdminController
|
||||||
def index
|
def index
|
||||||
@projects = Project.scoped
|
@projects = Project.scoped
|
||||||
@projects = @projects.where(namespace_id: params[:namespace_id]) if params[:namespace_id].present?
|
@projects = @projects.where(namespace_id: params[:namespace_id]) if params[:namespace_id].present?
|
||||||
|
@projects = @projects.where(namespace_id: nil) if params[:namespace_id] == Namespace.global_id
|
||||||
@projects = @projects.search(params[:name]) if params[:name].present?
|
@projects = @projects.search(params[:name]) if params[:name].present?
|
||||||
@projects = @projects.includes(:namespace).order("namespaces.path, projects.name ASC").page(params[:page]).per(20)
|
@projects = @projects.includes(:namespace).order("namespaces.path, projects.name ASC").page(params[:page]).per(20)
|
||||||
end
|
end
|
||||||
|
|
||||||
def show
|
def show
|
||||||
@users = User.scoped
|
@users = User.active
|
||||||
@users = @users.not_in_project(@project) if @project.users.present?
|
@users = @users.not_in_project(@project) if @project.users.present?
|
||||||
@users = @users.all
|
@users = @users.all
|
||||||
end
|
end
|
||||||
|
|
|
@ -3,7 +3,7 @@ class Admin::UsersController < AdminController
|
||||||
@admin_users = User.scoped
|
@admin_users = User.scoped
|
||||||
@admin_users = @admin_users.filter(params[:filter])
|
@admin_users = @admin_users.filter(params[:filter])
|
||||||
@admin_users = @admin_users.search(params[:name]) if params[:name].present?
|
@admin_users = @admin_users.search(params[:name]) if params[:name].present?
|
||||||
@admin_users = @admin_users.order("updated_at DESC").page(params[:page])
|
@admin_users = @admin_users.order("name ASC").page(params[:page])
|
||||||
end
|
end
|
||||||
|
|
||||||
def show
|
def show
|
||||||
|
@ -30,7 +30,7 @@ class Admin::UsersController < AdminController
|
||||||
|
|
||||||
|
|
||||||
def new
|
def new
|
||||||
@admin_user = User.new({ projects_limit: Gitlab.config.default_projects_limit }, as: :admin)
|
@admin_user = User.new({ projects_limit: Gitlab.config.gitlab.default_projects_limit }, as: :admin)
|
||||||
end
|
end
|
||||||
|
|
||||||
def edit
|
def edit
|
||||||
|
|
|
@ -112,6 +112,10 @@ class ApplicationController < ActionController::Base
|
||||||
render file: Rails.root.join("public", "404"), layout: false, status: "404"
|
render file: Rails.root.join("public", "404"), layout: false, status: "404"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def render_403
|
||||||
|
render file: Rails.root.join("public", "403"), layout: false, status: "403"
|
||||||
|
end
|
||||||
|
|
||||||
def require_non_empty_project
|
def require_non_empty_project
|
||||||
redirect_to @project if @project.empty_repo?
|
redirect_to @project if @project.empty_repo?
|
||||||
end
|
end
|
||||||
|
|
|
@ -7,6 +7,8 @@ class DashboardController < ApplicationController
|
||||||
def index
|
def index
|
||||||
@groups = current_user.authorized_groups
|
@groups = current_user.authorized_groups
|
||||||
|
|
||||||
|
@has_authorized_projects = @projects.count > 0
|
||||||
|
|
||||||
@projects = case params[:scope]
|
@projects = case params[:scope]
|
||||||
when 'personal' then
|
when 'personal' then
|
||||||
@projects.personal(current_user)
|
@projects.personal(current_user)
|
||||||
|
|
|
@ -21,7 +21,7 @@ class GroupsController < ApplicationController
|
||||||
|
|
||||||
# Get authored or assigned open merge requests
|
# Get authored or assigned open merge requests
|
||||||
def merge_requests
|
def merge_requests
|
||||||
@merge_requests = current_user.cared_merge_requests
|
@merge_requests = current_user.cared_merge_requests.opened
|
||||||
@merge_requests = @merge_requests.of_group(@group).recent.page(params[:page]).per(20)
|
@merge_requests = @merge_requests.of_group(@group).recent.page(params[:page]).per(20)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -49,6 +49,7 @@ class GroupsController < ApplicationController
|
||||||
def people
|
def people
|
||||||
@project = group.projects.find(params[:project_id]) if params[:project_id]
|
@project = group.projects.find(params[:project_id]) if params[:project_id]
|
||||||
@users = @project ? @project.users : group.users
|
@users = @project ? @project.users : group.users
|
||||||
|
@users.sort_by!(&:name)
|
||||||
|
|
||||||
if @project
|
if @project
|
||||||
@team_member = @project.users_projects.new
|
@team_member = @project.users_projects.new
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
class IssuesController < ProjectResourceController
|
class IssuesController < ProjectResourceController
|
||||||
before_filter :module_enabled
|
before_filter :module_enabled
|
||||||
before_filter :issue, only: [:edit, :update, :destroy, :show]
|
before_filter :issue, only: [:edit, :update, :show]
|
||||||
|
|
||||||
# Allow read any issue
|
# Allow read any issue
|
||||||
before_filter :authorize_read_issue!
|
before_filter :authorize_read_issue!
|
||||||
|
@ -11,9 +11,6 @@ class IssuesController < ProjectResourceController
|
||||||
# Allow modify issue
|
# Allow modify issue
|
||||||
before_filter :authorize_modify_issue!, only: [:edit, :update]
|
before_filter :authorize_modify_issue!, only: [:edit, :update]
|
||||||
|
|
||||||
# Allow destroy issue
|
|
||||||
before_filter :authorize_admin_issue!, only: [:destroy]
|
|
||||||
|
|
||||||
respond_to :js, :html
|
respond_to :js, :html
|
||||||
|
|
||||||
def index
|
def index
|
||||||
|
@ -79,15 +76,6 @@ class IssuesController < ProjectResourceController
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def destroy
|
|
||||||
@issue.destroy
|
|
||||||
|
|
||||||
respond_to do |format|
|
|
||||||
format.html { redirect_to project_issues_path }
|
|
||||||
format.js { render nothing: true }
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def sort
|
def sort
|
||||||
return render_404 unless can?(current_user, :admin_issue, @project)
|
return render_404 unless can?(current_user, :admin_issue, @project)
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
class MergeRequestsController < ProjectResourceController
|
class MergeRequestsController < ProjectResourceController
|
||||||
before_filter :module_enabled
|
before_filter :module_enabled
|
||||||
before_filter :merge_request, only: [:edit, :update, :destroy, :show, :commits, :diffs, :automerge, :automerge_check]
|
before_filter :merge_request, only: [:edit, :update, :show, :commits, :diffs, :automerge, :automerge_check, :ci_status]
|
||||||
before_filter :validates_merge_request, only: [:show, :diffs]
|
before_filter :validates_merge_request, only: [:show, :diffs]
|
||||||
before_filter :define_show_vars, only: [:show, :diffs]
|
before_filter :define_show_vars, only: [:show, :diffs]
|
||||||
|
|
||||||
|
@ -13,9 +13,6 @@ class MergeRequestsController < ProjectResourceController
|
||||||
# Allow modify merge_request
|
# Allow modify merge_request
|
||||||
before_filter :authorize_modify_merge_request!, only: [:close, :edit, :update, :sort]
|
before_filter :authorize_modify_merge_request!, only: [:close, :edit, :update, :sort]
|
||||||
|
|
||||||
# Allow destroy merge_request
|
|
||||||
before_filter :authorize_admin_merge_request!, only: [:destroy]
|
|
||||||
|
|
||||||
def index
|
def index
|
||||||
@merge_requests = MergeRequestsLoadContext.new(project, current_user, params).execute
|
@merge_requests = MergeRequestsLoadContext.new(project, current_user, params).execute
|
||||||
end
|
end
|
||||||
|
@ -90,14 +87,6 @@ class MergeRequestsController < ProjectResourceController
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def destroy
|
|
||||||
@merge_request.destroy
|
|
||||||
|
|
||||||
respond_to do |format|
|
|
||||||
format.html { redirect_to project_merge_requests_url(@project) }
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def branch_from
|
def branch_from
|
||||||
@commit = project.commit(params[:ref])
|
@commit = project.commit(params[:ref])
|
||||||
@commit = CommitDecorator.decorate(@commit)
|
@commit = CommitDecorator.decorate(@commit)
|
||||||
|
@ -108,6 +97,13 @@ class MergeRequestsController < ProjectResourceController
|
||||||
@commit = CommitDecorator.decorate(@commit)
|
@commit = CommitDecorator.decorate(@commit)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def ci_status
|
||||||
|
status = project.gitlab_ci_service.commit_status(merge_request.last_commit.sha)
|
||||||
|
response = { status: status }
|
||||||
|
|
||||||
|
render json: response
|
||||||
|
end
|
||||||
|
|
||||||
protected
|
protected
|
||||||
|
|
||||||
def merge_request
|
def merge_request
|
||||||
|
|
|
@ -12,11 +12,12 @@ class MilestonesController < ProjectResourceController
|
||||||
|
|
||||||
def index
|
def index
|
||||||
@milestones = case params[:f]
|
@milestones = case params[:f]
|
||||||
when 'all'; @project.milestones
|
when 'all'; @project.milestones.order("closed, due_date DESC")
|
||||||
else @project.milestones.active
|
when 'closed'; @project.milestones.closed.order("due_date DESC")
|
||||||
|
else @project.milestones.active.order("due_date ASC")
|
||||||
end
|
end
|
||||||
|
|
||||||
@milestones = @milestones.includes(:project).order("due_date")
|
@milestones = @milestones.includes(:project)
|
||||||
@milestones = @milestones.page(params[:page]).per(20)
|
@milestones = @milestones.page(params[:page]).per(20)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -42,6 +43,7 @@ class MilestonesController < ProjectResourceController
|
||||||
|
|
||||||
def create
|
def create
|
||||||
@milestone = @project.milestones.new(params[:milestone])
|
@milestone = @project.milestones.new(params[:milestone])
|
||||||
|
@milestone.author_id_of_changes = current_user.id
|
||||||
|
|
||||||
if @milestone.save
|
if @milestone.save
|
||||||
redirect_to project_milestone_path(@project, @milestone)
|
redirect_to project_milestone_path(@project, @milestone)
|
||||||
|
@ -51,7 +53,7 @@ class MilestonesController < ProjectResourceController
|
||||||
end
|
end
|
||||||
|
|
||||||
def update
|
def update
|
||||||
@milestone.update_attributes(params[:milestone])
|
@milestone.update_attributes(params[:milestone].merge(author_id_of_changes: current_user.id))
|
||||||
|
|
||||||
respond_to do |format|
|
respond_to do |format|
|
||||||
format.js
|
format.js
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
class OmniauthCallbacksController < Devise::OmniauthCallbacksController
|
class OmniauthCallbacksController < Devise::OmniauthCallbacksController
|
||||||
Gitlab.config.omniauth_providers.each do |provider|
|
Gitlab.config.omniauth.providers.each do |provider|
|
||||||
define_method provider['name'] do
|
define_method provider['name'] do
|
||||||
handle_omniauth
|
handle_omniauth
|
||||||
end
|
end
|
||||||
|
|
|
@ -46,6 +46,10 @@ class ProjectsController < ProjectResourceController
|
||||||
format.js
|
format.js
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
rescue Project::TransferError => ex
|
||||||
|
@error = ex
|
||||||
|
render :update_failed
|
||||||
end
|
end
|
||||||
|
|
||||||
def show
|
def show
|
||||||
|
@ -86,12 +90,18 @@ class ProjectsController < ProjectResourceController
|
||||||
end
|
end
|
||||||
|
|
||||||
def graph
|
def graph
|
||||||
|
respond_to do |format|
|
||||||
|
format.html
|
||||||
|
format.json do
|
||||||
graph = Gitlab::Graph::JsonBuilder.new(project)
|
graph = Gitlab::Graph::JsonBuilder.new(project)
|
||||||
|
render :json => graph.to_json
|
||||||
@days_json, @commits_json = graph.days_json, graph.commits_json
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def destroy
|
def destroy
|
||||||
|
return access_denied! unless can?(current_user, :remove_project, project)
|
||||||
|
|
||||||
# Disable the UsersProject update_repository call, otherwise it will be
|
# Disable the UsersProject update_repository call, otherwise it will be
|
||||||
# called once for every person removed from the project
|
# called once for every person removed from the project
|
||||||
UsersProject.skip_callback(:destroy, :after, :update_repository)
|
UsersProject.skip_callback(:destroy, :after, :update_repository)
|
||||||
|
|
|
@ -16,7 +16,7 @@ class SnippetsController < ProjectResourceController
|
||||||
respond_to :html
|
respond_to :html
|
||||||
|
|
||||||
def index
|
def index
|
||||||
@snippets = @project.snippets
|
@snippets = @project.snippets.fresh
|
||||||
end
|
end
|
||||||
|
|
||||||
def new
|
def new
|
||||||
|
|
|
@ -76,7 +76,7 @@ class CommitDecorator < ApplicationDecorator
|
||||||
source_name = send "#{options[:source]}_name".to_sym
|
source_name = send "#{options[:source]}_name".to_sym
|
||||||
source_email = send "#{options[:source]}_email".to_sym
|
source_email = send "#{options[:source]}_email".to_sym
|
||||||
text = if options[:avatar]
|
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]
|
avatar = h.image_tag h.gravatar_icon(source_email, options[:size]), class: "avatar #{"s#{options[:size]}" if options[:size]}", width: options[:size], alt: ""
|
||||||
%Q{#{avatar} <span class="commit-#{options[:source]}-name">#{source_name}</span>}
|
%Q{#{avatar} <span class="commit-#{options[:source]}-name">#{source_name}</span>}
|
||||||
else
|
else
|
||||||
source_name
|
source_name
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
require 'digest/md5'
|
require 'digest/md5'
|
||||||
|
require 'uri'
|
||||||
|
|
||||||
module ApplicationHelper
|
module ApplicationHelper
|
||||||
|
|
||||||
|
@ -30,13 +31,15 @@ module ApplicationHelper
|
||||||
args.any? { |v| v.to_s.downcase == action_name }
|
args.any? { |v| v.to_s.downcase == action_name }
|
||||||
end
|
end
|
||||||
|
|
||||||
def gravatar_icon(user_email = '', size = 40)
|
def gravatar_icon(user_email = '', size = nil)
|
||||||
if Gitlab.config.disable_gravatar? || user_email.blank?
|
size = 40 if size.nil? || size <= 0
|
||||||
|
|
||||||
|
if !Gitlab.config.gravatar.enabled || user_email.blank?
|
||||||
'no_avatar.png'
|
'no_avatar.png'
|
||||||
else
|
else
|
||||||
gravatar_prefix = request.ssl? ? "https://secure" : "http://www"
|
gravatar_url = request.ssl? ? Gitlab.config.gravatar.ssl_url : Gitlab.config.gravatar.plain_url
|
||||||
user_email.strip!
|
user_email.strip!
|
||||||
"#{gravatar_prefix}.gravatar.com/avatar/#{Digest::MD5.hexdigest(user_email.downcase)}?s=#{size}&d=mm"
|
sprintf(gravatar_url, {:hash => Digest::MD5.hexdigest(user_email.downcase), :email => URI.escape(user_email), :size => size})
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -45,7 +48,7 @@ module ApplicationHelper
|
||||||
end
|
end
|
||||||
|
|
||||||
def web_app_url
|
def web_app_url
|
||||||
"#{request_protocol}://#{Gitlab.config.web_host}/"
|
"#{request_protocol}://#{Gitlab.config.gitlab.host}/"
|
||||||
end
|
end
|
||||||
|
|
||||||
def last_commit(project)
|
def last_commit(project)
|
||||||
|
@ -92,6 +95,7 @@ module ApplicationHelper
|
||||||
{ label: "API Help", url: help_api_path },
|
{ label: "API Help", url: help_api_path },
|
||||||
{ label: "Markdown Help", url: help_markdown_path },
|
{ label: "Markdown Help", url: help_markdown_path },
|
||||||
{ label: "SSH Keys Help", url: help_ssh_path },
|
{ label: "SSH Keys Help", url: help_ssh_path },
|
||||||
|
{ label: "Gitlab Rake Tasks Help", url: help_raketasks_path },
|
||||||
]
|
]
|
||||||
|
|
||||||
project_nav = []
|
project_nav = []
|
||||||
|
|
|
@ -4,28 +4,6 @@ module IssuesHelper
|
||||||
project_issues_path project, params
|
project_issues_path project, params
|
||||||
end
|
end
|
||||||
|
|
||||||
def link_to_issue_assignee(issue)
|
|
||||||
project = issue.project
|
|
||||||
|
|
||||||
tm = project.team_member_by_id(issue.assignee_id)
|
|
||||||
if tm
|
|
||||||
link_to issue.assignee_name, project_team_member_path(project, tm), class: "author_link"
|
|
||||||
else
|
|
||||||
issue.assignee_name
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def link_to_issue_author(issue)
|
|
||||||
project = issue.project
|
|
||||||
|
|
||||||
tm = project.team_member_by_id(issue.author_id)
|
|
||||||
if tm
|
|
||||||
link_to issue.author_name, project_team_member_path(project, tm), class: "author_link"
|
|
||||||
else
|
|
||||||
issue.author_name
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def issue_css_classes issue
|
def issue_css_classes issue
|
||||||
classes = "issue"
|
classes = "issue"
|
||||||
classes << " closed" if issue.closed
|
classes << " closed" if issue.closed
|
||||||
|
@ -52,4 +30,14 @@ module IssuesHelper
|
||||||
open: "open"
|
open: "open"
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def labels_autocomplete_source
|
||||||
|
labels = @project.issues_labels.order('count DESC')
|
||||||
|
labels = labels.map{ |l| { label: l.name, value: l.name } }
|
||||||
|
labels.to_json
|
||||||
|
end
|
||||||
|
|
||||||
|
def issues_active_milestones
|
||||||
|
@project.milestones.active.order("id desc").all
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,26 +1,4 @@
|
||||||
module MergeRequestsHelper
|
module MergeRequestsHelper
|
||||||
def link_to_merge_request_assignee(merge_request)
|
|
||||||
project = merge_request.project
|
|
||||||
|
|
||||||
tm = project.team_member_by_id(merge_request.assignee_id)
|
|
||||||
if tm
|
|
||||||
link_to merge_request.assignee_name, project_team_member_path(project, tm), class: "author_link"
|
|
||||||
else
|
|
||||||
merge_request.assignee_name
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def link_to_merge_request_author(merge_request)
|
|
||||||
project = merge_request.project
|
|
||||||
|
|
||||||
tm = project.team_member_by_id(merge_request.author_id)
|
|
||||||
if tm
|
|
||||||
link_to merge_request.author_name, project_team_member_path(project, tm), class: "author_link"
|
|
||||||
else
|
|
||||||
merge_request.author_name
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def new_mr_path_from_push_event(event)
|
def new_mr_path_from_push_event(event)
|
||||||
new_project_merge_request_path(
|
new_project_merge_request_path(
|
||||||
event.project,
|
event.project,
|
||||||
|
@ -39,7 +17,7 @@ module MergeRequestsHelper
|
||||||
classes
|
classes
|
||||||
end
|
end
|
||||||
|
|
||||||
def ci_status_path
|
def ci_build_details_path merge_request
|
||||||
@project.gitlab_ci_service.commit_badge_path(@merge_request.last_commit.sha)
|
merge_request.project.gitlab_ci_service.build_page(merge_request.last_commit.sha)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -8,11 +8,49 @@ module ProjectsHelper
|
||||||
end
|
end
|
||||||
|
|
||||||
def link_to_project project
|
def link_to_project project
|
||||||
link_to project.name, project
|
link_to project do
|
||||||
|
title = content_tag(:strong, project.name)
|
||||||
|
|
||||||
|
if project.namespace
|
||||||
|
namespace = content_tag(:span, "#{project.namespace.human_name} / ", class: 'tiny')
|
||||||
|
title = namespace + title
|
||||||
|
end
|
||||||
|
|
||||||
|
title
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def link_to_member(project, author)
|
||||||
|
return "(deleted)" unless author
|
||||||
|
|
||||||
|
# Build avatar image tag
|
||||||
|
avatar = image_tag(gravatar_icon(author.try(:email)), width: 16, class: "lil_av")
|
||||||
|
|
||||||
|
# Build name strong tag
|
||||||
|
name = content_tag :strong, author.name, class: 'author'
|
||||||
|
|
||||||
|
author_html = avatar + name
|
||||||
|
|
||||||
|
tm = project.team_member_by_id(author)
|
||||||
|
|
||||||
|
content_tag :span, class: 'member-link' do
|
||||||
|
if tm
|
||||||
|
link_to author_html, project_team_member_path(project, tm), class: "author_link"
|
||||||
|
else
|
||||||
|
author_html
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def tm_path team_member
|
def tm_path team_member
|
||||||
project_team_member_path(@project, team_member)
|
project_team_member_path(@project, team_member)
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
|
||||||
|
def project_title project
|
||||||
|
if project.group
|
||||||
|
project.name_with_namespace
|
||||||
|
else
|
||||||
|
project.name
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
|
@ -72,7 +72,7 @@ module TabHelper
|
||||||
return "active" if current_page?(controller: "projects", action: action, id: @project)
|
return "active" if current_page?(controller: "projects", action: action, id: @project)
|
||||||
end
|
end
|
||||||
|
|
||||||
if ['snippets', 'hooks', 'deploy_keys', 'team_members'].include? controller.controller_name
|
if ['snippets', 'services', 'hooks', 'deploy_keys', 'team_members'].include? controller.controller_name
|
||||||
"active"
|
"active"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -3,11 +3,11 @@ class Notify < ActionMailer::Base
|
||||||
add_template_helper ApplicationHelper
|
add_template_helper ApplicationHelper
|
||||||
add_template_helper GitlabMarkdownHelper
|
add_template_helper GitlabMarkdownHelper
|
||||||
|
|
||||||
default_url_options[:host] = Gitlab.config.web_host
|
default_url_options[:host] = Gitlab.config.gitlab.host
|
||||||
default_url_options[:protocol] = Gitlab.config.web_protocol
|
default_url_options[:protocol] = Gitlab.config.gitlab.protocol
|
||||||
default_url_options[:port] = Gitlab.config.web_port if Gitlab.config.web_custom_port?
|
default_url_options[:port] = Gitlab.config.gitlab.port if Gitlab.config.gitlab_on_non_standard_port?
|
||||||
|
|
||||||
default from: Gitlab.config.email_from
|
default from: Gitlab.config.gitlab.email_from
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -31,6 +31,7 @@ class Notify < ActionMailer::Base
|
||||||
def issue_status_changed_email(recipient_id, issue_id, status, updated_by_user_id)
|
def issue_status_changed_email(recipient_id, issue_id, status, updated_by_user_id)
|
||||||
@issue = Issue.find issue_id
|
@issue = Issue.find issue_id
|
||||||
@issue_status = status
|
@issue_status = status
|
||||||
|
@project = @issue.project
|
||||||
@updated_by = User.find updated_by_user_id
|
@updated_by = User.find updated_by_user_id
|
||||||
mail(to: recipient(recipient_id),
|
mail(to: recipient(recipient_id),
|
||||||
subject: subject("changed issue ##{@issue.id}", @issue.title))
|
subject: subject("changed issue ##{@issue.id}", @issue.title))
|
||||||
|
@ -102,6 +103,12 @@ class Notify < ActionMailer::Base
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
def project_was_moved_email(user_project_id)
|
||||||
|
@users_project = UsersProject.find user_project_id
|
||||||
|
@project = @users_project.project
|
||||||
|
mail(to: @users_project.user.email,
|
||||||
|
subject: subject("project was moved"))
|
||||||
|
end
|
||||||
|
|
||||||
#
|
#
|
||||||
# User
|
# User
|
||||||
|
|
|
@ -17,9 +17,7 @@ class Ability
|
||||||
|
|
||||||
# Rules based on role in project
|
# Rules based on role in project
|
||||||
if project.master_access_for?(user)
|
if project.master_access_for?(user)
|
||||||
# TODO: replace with master rules.
|
rules << project_master_rules
|
||||||
# Only allow project administration for namespace owners
|
|
||||||
rules << project_admin_rules
|
|
||||||
|
|
||||||
elsif project.dev_access_for?(user)
|
elsif project.dev_access_for?(user)
|
||||||
rules << project_dev_rules
|
rules << project_dev_rules
|
||||||
|
@ -93,13 +91,16 @@ class Ability
|
||||||
:admin_merge_request,
|
:admin_merge_request,
|
||||||
:admin_note,
|
:admin_note,
|
||||||
:accept_mr,
|
:accept_mr,
|
||||||
:admin_wiki
|
:admin_wiki,
|
||||||
|
:admin_project
|
||||||
]
|
]
|
||||||
end
|
end
|
||||||
|
|
||||||
def project_admin_rules
|
def project_admin_rules
|
||||||
project_master_rules + [
|
project_master_rules + [
|
||||||
:admin_project
|
:change_namespace,
|
||||||
|
:rename_project,
|
||||||
|
:remove_project
|
||||||
]
|
]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -87,14 +87,10 @@ class Commit
|
||||||
last = project.commit(from.try(:strip))
|
last = project.commit(from.try(:strip))
|
||||||
|
|
||||||
if first && last
|
if first && last
|
||||||
commits = [first, last].sort_by(&:created_at)
|
result[:same] = (first.id == last.id)
|
||||||
younger = commits.first
|
result[:commits] = project.repo.commits_between(last.id, first.id).map {|c| Commit.new(c)}
|
||||||
older = commits.last
|
result[:diffs] = project.repo.diff(last.id, first.id) rescue []
|
||||||
|
result[:commit] = Commit.new(first)
|
||||||
result[:same] = (younger.id == older.id)
|
|
||||||
result[:commits] = project.repo.commits_between(younger.id, older.id).map {|c| Commit.new(c)}
|
|
||||||
result[:diffs] = project.repo.diff(younger.id, older.id) rescue []
|
|
||||||
result[:commit] = Commit.new(older)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
result
|
result
|
||||||
|
@ -163,6 +159,8 @@ class Commit
|
||||||
while !lines.first.start_with?("diff --git") do
|
while !lines.first.start_with?("diff --git") do
|
||||||
lines.shift
|
lines.shift
|
||||||
end
|
end
|
||||||
|
lines.pop if lines.last =~ /^[\d.]+$/ # Git version
|
||||||
|
lines.pop if lines.last == "-- " # end of diff
|
||||||
lines.join("\n")
|
lines.join("\n")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
#
|
#
|
||||||
|
|
||||||
class Event < ActiveRecord::Base
|
class Event < ActiveRecord::Base
|
||||||
|
include NoteEvent
|
||||||
include PushEvent
|
include PushEvent
|
||||||
|
|
||||||
attr_accessible :project, :action, :data, :author_id, :project_id,
|
attr_accessible :project, :action, :data, :author_id, :project_id,
|
||||||
|
@ -58,12 +59,14 @@ class Event < ActiveRecord::Base
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Next events currently enabled for system
|
def proper?
|
||||||
# - push
|
if push?
|
||||||
# - new issue
|
true
|
||||||
# - merge request
|
elsif membership_changed?
|
||||||
def allowed?
|
true
|
||||||
push? || issue? || merge_request? || membership_changed?
|
else
|
||||||
|
(issue? || merge_request? || note? || milestone?) && target
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def project_name
|
def project_name
|
||||||
|
@ -94,6 +97,14 @@ class Event < ActiveRecord::Base
|
||||||
action == self.class::Reopened
|
action == self.class::Reopened
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def milestone?
|
||||||
|
target_type == "Milestone"
|
||||||
|
end
|
||||||
|
|
||||||
|
def note?
|
||||||
|
target_type == "Note"
|
||||||
|
end
|
||||||
|
|
||||||
def issue?
|
def issue?
|
||||||
target_type == "Issue"
|
target_type == "Issue"
|
||||||
end
|
end
|
||||||
|
|
|
@ -36,4 +36,22 @@ class GitlabCiService < Service
|
||||||
def commit_badge_path sha
|
def commit_badge_path sha
|
||||||
project_url + "/status?sha=#{sha}"
|
project_url + "/status?sha=#{sha}"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def commit_status_path sha
|
||||||
|
project_url + "/builds/#{sha}/status.json?token=#{token}"
|
||||||
|
end
|
||||||
|
|
||||||
|
def commit_status sha
|
||||||
|
response = HTTParty.get(commit_status_path(sha))
|
||||||
|
|
||||||
|
if response.code == 200 and response["status"]
|
||||||
|
response["status"]
|
||||||
|
else
|
||||||
|
:error
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def build_page sha
|
||||||
|
project_url + "/builds/#{sha}"
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -204,7 +204,7 @@ class MergeRequest < ActiveRecord::Base
|
||||||
|
|
||||||
def mr_and_commit_notes
|
def mr_and_commit_notes
|
||||||
commit_ids = commits.map(&:id)
|
commit_ids = commits.map(&:id)
|
||||||
Note.where("(noteable_type = 'MergeRequest' AND noteable_id = :mr_id) OR (noteable_type = 'Commit' AND noteable_id IN (:commit_ids))", mr_id: id, commit_ids: commit_ids)
|
Note.where("(noteable_type = 'MergeRequest' AND noteable_id = :mr_id) OR (noteable_type = 'Commit' AND commit_id IN (:commit_ids))", mr_id: id, commit_ids: commit_ids)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Returns the raw diff for this merge request
|
# Returns the raw diff for this merge request
|
||||||
|
@ -220,4 +220,8 @@ class MergeRequest < ActiveRecord::Base
|
||||||
def to_patch
|
def to_patch
|
||||||
project.repo.git.format_patch({timeout: 30, raise: true, stdout: true}, "#{target_branch}..#{source_branch}")
|
project.repo.git.format_patch({timeout: 30, raise: true, stdout: true}, "#{target_branch}..#{source_branch}")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def last_commit_short_sha
|
||||||
|
@last_commit_short_sha ||= last_commit.sha[0..10]
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -13,18 +13,26 @@
|
||||||
#
|
#
|
||||||
|
|
||||||
class Milestone < ActiveRecord::Base
|
class Milestone < ActiveRecord::Base
|
||||||
attr_accessible :title, :description, :due_date, :closed
|
attr_accessible :title, :description, :due_date, :closed, :author_id_of_changes
|
||||||
|
attr_accessor :author_id_of_changes
|
||||||
|
|
||||||
belongs_to :project
|
belongs_to :project
|
||||||
has_many :issues
|
has_many :issues
|
||||||
has_many :merge_requests
|
has_many :merge_requests
|
||||||
|
|
||||||
|
scope :active, where(closed: false)
|
||||||
|
scope :closed, where(closed: true)
|
||||||
|
|
||||||
validates :title, presence: true
|
validates :title, presence: true
|
||||||
validates :project, presence: true
|
validates :project, presence: true
|
||||||
validates :closed, inclusion: { in: [true, false] }
|
validates :closed, inclusion: { in: [true, false] }
|
||||||
|
|
||||||
def self.active
|
def expired?
|
||||||
where("due_date > ? OR due_date IS NULL", Date.today)
|
if due_date
|
||||||
|
due_date < Date.today
|
||||||
|
else
|
||||||
|
false
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def participants
|
def participants
|
||||||
|
@ -52,4 +60,20 @@ class Milestone < ActiveRecord::Base
|
||||||
def expires_at
|
def expires_at
|
||||||
"expires at #{due_date.stamp("Aug 21, 2011")}" if due_date
|
"expires at #{due_date.stamp("Aug 21, 2011")}" if due_date
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def can_be_closed?
|
||||||
|
open? && issues.opened.count.zero?
|
||||||
|
end
|
||||||
|
|
||||||
|
def is_empty?
|
||||||
|
total_items_count.zero?
|
||||||
|
end
|
||||||
|
|
||||||
|
def open?
|
||||||
|
!closed
|
||||||
|
end
|
||||||
|
|
||||||
|
def author_id
|
||||||
|
author_id_of_changes
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -48,23 +48,30 @@ class Namespace < ActiveRecord::Base
|
||||||
end
|
end
|
||||||
|
|
||||||
def ensure_dir_exist
|
def ensure_dir_exist
|
||||||
namespace_dir_path = File.join(Gitlab.config.git_base_path, path)
|
namespace_dir_path = File.join(Gitlab.config.gitolite.repos_path, path)
|
||||||
system("mkdir -m 770 #{namespace_dir_path}") unless File.exists?(namespace_dir_path)
|
system("mkdir -m 770 #{namespace_dir_path}") unless File.exists?(namespace_dir_path)
|
||||||
end
|
end
|
||||||
|
|
||||||
def move_dir
|
def move_dir
|
||||||
if path_changed?
|
if path_changed?
|
||||||
old_path = File.join(Gitlab.config.git_base_path, path_was)
|
old_path = File.join(Gitlab.config.gitolite.repos_path, path_was)
|
||||||
new_path = File.join(Gitlab.config.git_base_path, path)
|
new_path = File.join(Gitlab.config.gitolite.repos_path, path)
|
||||||
if File.exists?(new_path)
|
if File.exists?(new_path)
|
||||||
raise "Already exists"
|
raise "Already exists"
|
||||||
end
|
end
|
||||||
system("mv #{old_path} #{new_path}")
|
|
||||||
|
if system("mv #{old_path} #{new_path}")
|
||||||
|
send_update_instructions
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def rm_dir
|
def rm_dir
|
||||||
dir_path = File.join(Gitlab.config.git_base_path, path)
|
dir_path = File.join(Gitlab.config.gitolite.repos_path, path)
|
||||||
system("rm -rf #{dir_path}")
|
system("rm -rf #{dir_path}")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def send_update_instructions
|
||||||
|
projects.each(&:send_move_instructions)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -19,7 +19,7 @@ require 'file_size_validator'
|
||||||
|
|
||||||
class Note < ActiveRecord::Base
|
class Note < ActiveRecord::Base
|
||||||
attr_accessible :note, :noteable, :noteable_id, :noteable_type, :project_id,
|
attr_accessible :note, :noteable, :noteable_id, :noteable_type, :project_id,
|
||||||
:attachment, :line_code
|
:attachment, :line_code, :commit_id
|
||||||
|
|
||||||
attr_accessor :notify
|
attr_accessor :notify
|
||||||
attr_accessor :notify_author
|
attr_accessor :notify_author
|
||||||
|
@ -35,10 +35,14 @@ class Note < ActiveRecord::Base
|
||||||
validates :line_code, format: { with: /\A\d+_\d+_\d+\Z/ }, allow_blank: true
|
validates :line_code, format: { with: /\A\d+_\d+_\d+\Z/ }, allow_blank: true
|
||||||
validates :attachment, file_size: { maximum: 10.megabytes.to_i }
|
validates :attachment, file_size: { maximum: 10.megabytes.to_i }
|
||||||
|
|
||||||
|
validates :noteable_id, presence: true, if: ->(n) { n.noteable_type.present? && n.noteable_type != 'Commit' }
|
||||||
|
validates :commit_id, presence: true, if: ->(n) { n.noteable_type == 'Commit' }
|
||||||
|
|
||||||
mount_uploader :attachment, AttachmentUploader
|
mount_uploader :attachment, AttachmentUploader
|
||||||
|
|
||||||
# Scopes
|
# Scopes
|
||||||
scope :common, ->{ where(noteable_id: nil) }
|
scope :for_commits, ->{ where(noteable_type: "Commit") }
|
||||||
|
scope :common, ->{ where(noteable_id: nil, commit_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)) }
|
||||||
|
@ -122,7 +126,7 @@ class Note < ActiveRecord::Base
|
||||||
# override to return commits, which are not active record
|
# override to return commits, which are not active record
|
||||||
def noteable
|
def noteable
|
||||||
if for_commit?
|
if for_commit?
|
||||||
project.commit(noteable_id)
|
project.commit(commit_id)
|
||||||
else
|
else
|
||||||
super
|
super
|
||||||
end
|
end
|
||||||
|
@ -151,4 +155,12 @@ class Note < ActiveRecord::Base
|
||||||
def votable?
|
def votable?
|
||||||
for_issue? || (for_merge_request? && !for_diff_line?)
|
for_issue? || (for_merge_request? && !for_diff_line?)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def noteable_type_name
|
||||||
|
if noteable_type.present?
|
||||||
|
noteable_type.downcase
|
||||||
|
else
|
||||||
|
"wall"
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -25,6 +25,9 @@ class Project < ActiveRecord::Base
|
||||||
include PushObserver
|
include PushObserver
|
||||||
include Authority
|
include Authority
|
||||||
include Team
|
include Team
|
||||||
|
include NamespacedProject
|
||||||
|
|
||||||
|
class TransferError < StandardError; end
|
||||||
|
|
||||||
attr_accessible :name, :path, :description, :default_branch, :issues_enabled,
|
attr_accessible :name, :path, :description, :default_branch, :issues_enabled,
|
||||||
:wall_enabled, :merge_requests_enabled, :wiki_enabled, as: [:default, :admin]
|
:wall_enabled, :merge_requests_enabled, :wiki_enabled, as: [:default, :admin]
|
||||||
|
@ -36,6 +39,10 @@ class Project < ActiveRecord::Base
|
||||||
# Relations
|
# Relations
|
||||||
belongs_to :group, foreign_key: "namespace_id", conditions: "type = 'Group'"
|
belongs_to :group, foreign_key: "namespace_id", conditions: "type = 'Group'"
|
||||||
belongs_to :namespace
|
belongs_to :namespace
|
||||||
|
|
||||||
|
# TODO: replace owner with creator.
|
||||||
|
# With namespaces a project owner will be a namespace owner
|
||||||
|
# so this field makes sense only for global projects
|
||||||
belongs_to :owner, class_name: "User"
|
belongs_to :owner, class_name: "User"
|
||||||
has_many :users, through: :users_projects
|
has_many :users, through: :users_projects
|
||||||
has_many :events, dependent: :destroy
|
has_many :events, dependent: :destroy
|
||||||
|
@ -97,7 +104,7 @@ class Project < ActiveRecord::Base
|
||||||
namespace_id = Namespace.find_by_path(id.first).id
|
namespace_id = Namespace.find_by_path(id.first).id
|
||||||
where(namespace_id: namespace_id).find_by_path(id.last)
|
where(namespace_id: namespace_id).find_by_path(id.last)
|
||||||
else
|
else
|
||||||
find_by_path(id)
|
where(path: id, namespace_id: nil).last
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -172,7 +179,7 @@ class Project < ActiveRecord::Base
|
||||||
end
|
end
|
||||||
|
|
||||||
def repo_name
|
def repo_name
|
||||||
denied_paths = %w(gitolite-admin groups projects dashboard)
|
denied_paths = %w(gitolite-admin admin dashboard groups help profile projects search)
|
||||||
|
|
||||||
if denied_paths.include?(path)
|
if denied_paths.include?(path)
|
||||||
errors.add(:path, "like #{path} is not allowed")
|
errors.add(:path, "like #{path} is not allowed")
|
||||||
|
@ -188,7 +195,7 @@ class Project < ActiveRecord::Base
|
||||||
end
|
end
|
||||||
|
|
||||||
def web_url
|
def web_url
|
||||||
[Gitlab.config.url, path].join("/")
|
[Gitlab.config.gitlab.url, path_with_namespace].join("/")
|
||||||
end
|
end
|
||||||
|
|
||||||
def common_notes
|
def common_notes
|
||||||
|
@ -196,15 +203,15 @@ class Project < ActiveRecord::Base
|
||||||
end
|
end
|
||||||
|
|
||||||
def build_commit_note(commit)
|
def build_commit_note(commit)
|
||||||
notes.new(noteable_id: commit.id, noteable_type: "Commit")
|
notes.new(commit_id: commit.id, noteable_type: "Commit")
|
||||||
end
|
end
|
||||||
|
|
||||||
def commit_notes(commit)
|
def commit_notes(commit)
|
||||||
notes.where(noteable_id: commit.id, noteable_type: "Commit").where('line_code IS NULL OR line_code = ""')
|
notes.where(commit_id: commit.id, noteable_type: "Commit").where('line_code IS NULL OR line_code = ""')
|
||||||
end
|
end
|
||||||
|
|
||||||
def commit_line_notes(commit)
|
def commit_line_notes(commit)
|
||||||
notes.where(noteable_id: commit.id, noteable_type: "Commit").where("line_code IS NOT NULL")
|
notes.where(commit_id: commit.id, noteable_type: "Commit").where("line_code IS NOT NULL")
|
||||||
end
|
end
|
||||||
|
|
||||||
def public?
|
def public?
|
||||||
|
@ -239,51 +246,11 @@ class Project < ActiveRecord::Base
|
||||||
gitlab_ci_service && gitlab_ci_service.active
|
gitlab_ci_service && gitlab_ci_service.active
|
||||||
end
|
end
|
||||||
|
|
||||||
def path_with_namespace
|
|
||||||
if namespace
|
|
||||||
namespace.path + '/' + path
|
|
||||||
else
|
|
||||||
path
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# For compatibility with old code
|
# For compatibility with old code
|
||||||
def code
|
def code
|
||||||
path
|
path
|
||||||
end
|
end
|
||||||
|
|
||||||
def transfer(new_namespace)
|
|
||||||
Project.transaction do
|
|
||||||
old_namespace = namespace
|
|
||||||
self.namespace = new_namespace
|
|
||||||
|
|
||||||
old_dir = old_namespace.try(:path) || ''
|
|
||||||
new_dir = new_namespace.try(:path) || ''
|
|
||||||
|
|
||||||
old_repo = if old_dir.present?
|
|
||||||
File.join(old_dir, self.path)
|
|
||||||
else
|
|
||||||
self.path
|
|
||||||
end
|
|
||||||
|
|
||||||
Gitlab::ProjectMover.new(self, old_dir, new_dir).execute
|
|
||||||
|
|
||||||
git_host.move_repository(old_repo, self)
|
|
||||||
|
|
||||||
save!
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def name_with_namespace
|
|
||||||
@name_with_namespace ||= begin
|
|
||||||
if namespace
|
|
||||||
namespace.human_name + " / " + name
|
|
||||||
else
|
|
||||||
name
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def items_for entity
|
def items_for entity
|
||||||
case entity
|
case entity
|
||||||
when 'issue' then
|
when 'issue' then
|
||||||
|
@ -293,7 +260,9 @@ class Project < ActiveRecord::Base
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def namespace_owner
|
def send_move_instructions
|
||||||
namespace.try(:owner)
|
self.users_projects.each do |member|
|
||||||
|
Notify.project_was_moved_email(member.id).deliver
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -22,7 +22,7 @@ class Snippet < ActiveRecord::Base
|
||||||
belongs_to :author, class_name: "User"
|
belongs_to :author, class_name: "User"
|
||||||
has_many :notes, as: :noteable, dependent: :destroy
|
has_many :notes, as: :noteable, dependent: :destroy
|
||||||
|
|
||||||
delegate :name, :email, to: :author, prefix: true
|
delegate :name, :email, to: :author, prefix: true, allow_nil: true
|
||||||
|
|
||||||
validates :author, presence: true
|
validates :author, presence: true
|
||||||
validates :project, presence: true
|
validates :project, presence: true
|
||||||
|
|
|
@ -56,12 +56,12 @@ class User < ActiveRecord::Base
|
||||||
has_many :issues, foreign_key: :author_id, dependent: :destroy
|
has_many :issues, foreign_key: :author_id, dependent: :destroy
|
||||||
has_many :notes, foreign_key: :author_id, dependent: :destroy
|
has_many :notes, foreign_key: :author_id, dependent: :destroy
|
||||||
has_many :merge_requests, foreign_key: :author_id, dependent: :destroy
|
has_many :merge_requests, foreign_key: :author_id, dependent: :destroy
|
||||||
has_many :my_own_projects, class_name: "Project", foreign_key: :owner_id
|
|
||||||
has_many :events, class_name: "Event", foreign_key: :author_id, dependent: :destroy
|
has_many :events, class_name: "Event", foreign_key: :author_id, dependent: :destroy
|
||||||
has_many :recent_events, class_name: "Event", foreign_key: :author_id, order: "id DESC"
|
has_many :recent_events, class_name: "Event", foreign_key: :author_id, order: "id DESC"
|
||||||
has_many :assigned_issues, class_name: "Issue", foreign_key: :assignee_id, dependent: :destroy
|
has_many :assigned_issues, class_name: "Issue", foreign_key: :assignee_id, dependent: :destroy
|
||||||
has_many :assigned_merge_requests, class_name: "MergeRequest", foreign_key: :assignee_id, dependent: :destroy
|
has_many :assigned_merge_requests, class_name: "MergeRequest", foreign_key: :assignee_id, dependent: :destroy
|
||||||
|
|
||||||
|
validates :name, presence: true
|
||||||
validates :bio, length: { within: 0..255 }
|
validates :bio, length: { within: 0..255 }
|
||||||
validates :extern_uid, allow_blank: true, uniqueness: {scope: :provider}
|
validates :extern_uid, allow_blank: true, uniqueness: {scope: :provider}
|
||||||
validates :projects_limit, presence: true, numericality: {greater_than_or_equal_to: 0}
|
validates :projects_limit, presence: true, numericality: {greater_than_or_equal_to: 0}
|
||||||
|
@ -123,16 +123,4 @@ class User < ActiveRecord::Base
|
||||||
self.password = self.password_confirmation = Devise.friendly_token.first(8)
|
self.password = self.password_confirmation = Devise.friendly_token.first(8)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def authorized_groups
|
|
||||||
@authorized_groups ||= begin
|
|
||||||
groups = Group.where(id: self.projects.pluck(:namespace_id)).all
|
|
||||||
groups = groups + self.groups
|
|
||||||
groups.uniq
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def authorized_projects
|
|
||||||
Project.authorized_for(self)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -28,6 +28,7 @@ class UsersProject < ActiveRecord::Base
|
||||||
|
|
||||||
validates :user, presence: true
|
validates :user, presence: true
|
||||||
validates :user_id, uniqueness: { :scope => [:project_id], message: "already exists in project" }
|
validates :user_id, uniqueness: { :scope => [:project_id], message: "already exists in project" }
|
||||||
|
validates :project_access, inclusion: { in: [GUEST, REPORTER, DEVELOPER, MASTER] }, presence: true
|
||||||
validates :project, presence: true
|
validates :project, presence: true
|
||||||
|
|
||||||
delegate :name, :email, to: :user, prefix: true
|
delegate :name, :email, to: :user, prefix: true
|
||||||
|
|
|
@ -1,18 +1,27 @@
|
||||||
class ActivityObserver < ActiveRecord::Observer
|
class ActivityObserver < ActiveRecord::Observer
|
||||||
observe :issue, :merge_request
|
observe :issue, :merge_request, :note, :milestone
|
||||||
|
|
||||||
def after_create(record)
|
def after_create(record)
|
||||||
|
event_author_id = record.author_id
|
||||||
|
|
||||||
|
# Skip status notes
|
||||||
|
if record.kind_of?(Note) && record.note.include?("_Status changed to ")
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
if event_author_id
|
||||||
Event.create(
|
Event.create(
|
||||||
project: record.project,
|
project: record.project,
|
||||||
target_id: record.id,
|
target_id: record.id,
|
||||||
target_type: record.class.name,
|
target_type: record.class.name,
|
||||||
action: Event.determine_action(record),
|
action: Event.determine_action(record),
|
||||||
author_id: record.author_id
|
author_id: event_author_id
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def after_save(record)
|
def after_save(record)
|
||||||
if record.changed.include?("closed")
|
if record.changed.include?("closed") && record.author_id_of_changes
|
||||||
Event.create(
|
Event.create(
|
||||||
project: record.project,
|
project: record.project,
|
||||||
target_id: record.id,
|
target_id: record.id,
|
||||||
|
|
|
@ -16,7 +16,7 @@ class IssueObserver < ActiveRecord::Observer
|
||||||
if status
|
if status
|
||||||
Note.create_status_change_note(issue, current_user, status)
|
Note.create_status_change_note(issue, current_user, status)
|
||||||
[issue.author, issue.assignee].compact.each do |recipient|
|
[issue.author, issue.assignee].compact.each do |recipient|
|
||||||
Notify.issue_status_changed_email(recipient.id, issue.id, status, current_user)
|
Notify.issue_status_changed_email(recipient.id, issue.id, status, current_user.id).deliver
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -21,7 +21,7 @@ class NoteObserver < ActiveRecord::Observer
|
||||||
# Notifies the whole team except the author of note
|
# Notifies the whole team except the author of note
|
||||||
def notify_team(note)
|
def notify_team(note)
|
||||||
# Note: wall posts are not "attached" to anything, so fall back to "Wall"
|
# Note: wall posts are not "attached" to anything, so fall back to "Wall"
|
||||||
noteable_type = note.noteable_type || "Wall"
|
noteable_type = note.noteable_type.presence || "Wall"
|
||||||
notify_method = "note_#{noteable_type.underscore}_email".to_sym
|
notify_method = "note_#{noteable_type.underscore}_email".to_sym
|
||||||
|
|
||||||
if Notify.respond_to? notify_method
|
if Notify.respond_to? notify_method
|
||||||
|
|
|
@ -3,7 +3,8 @@ class ProjectObserver < ActiveRecord::Observer
|
||||||
project.update_repository
|
project.update_repository
|
||||||
end
|
end
|
||||||
|
|
||||||
def after_save(project)
|
def after_update(project)
|
||||||
|
project.send_move_instructions if project.namespace_id_changed?
|
||||||
end
|
end
|
||||||
|
|
||||||
def after_destroy(project)
|
def after_destroy(project)
|
||||||
|
|
|
@ -47,7 +47,7 @@ module Account
|
||||||
end
|
end
|
||||||
|
|
||||||
def cared_merge_requests
|
def cared_merge_requests
|
||||||
MergeRequest.where("author_id = :id or assignee_id = :id", id: self.id).opened
|
MergeRequest.where("author_id = :id or assignee_id = :id", id: self.id)
|
||||||
end
|
end
|
||||||
|
|
||||||
def project_ids
|
def project_ids
|
||||||
|
@ -105,4 +105,20 @@ module Account
|
||||||
def namespace_id
|
def namespace_id
|
||||||
namespace.try :id
|
namespace.try :id
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def authorized_groups
|
||||||
|
@authorized_groups ||= begin
|
||||||
|
groups = Group.where(id: self.projects.pluck(:namespace_id)).all
|
||||||
|
groups = groups + self.groups
|
||||||
|
groups.uniq
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def authorized_projects
|
||||||
|
Project.authorized_for(self)
|
||||||
|
end
|
||||||
|
|
||||||
|
def my_own_projects
|
||||||
|
Project.personal(self)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
59
app/roles/namespaced_project.rb
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
module NamespacedProject
|
||||||
|
def transfer(new_namespace)
|
||||||
|
Project.transaction do
|
||||||
|
old_namespace = namespace
|
||||||
|
self.namespace = new_namespace
|
||||||
|
|
||||||
|
old_dir = old_namespace.try(:path) || ''
|
||||||
|
new_dir = new_namespace.try(:path) || ''
|
||||||
|
|
||||||
|
old_repo = if old_dir.present?
|
||||||
|
File.join(old_dir, self.path)
|
||||||
|
else
|
||||||
|
self.path
|
||||||
|
end
|
||||||
|
|
||||||
|
if Project.where(path: self.path, namespace_id: new_namespace.try(:id)).present?
|
||||||
|
raise TransferError.new("Project with same path in target namespace already exists")
|
||||||
|
end
|
||||||
|
|
||||||
|
Gitlab::ProjectMover.new(self, old_dir, new_dir).execute
|
||||||
|
|
||||||
|
git_host.move_repository(old_repo, self)
|
||||||
|
|
||||||
|
save!
|
||||||
|
end
|
||||||
|
rescue Gitlab::ProjectMover::ProjectMoveError => ex
|
||||||
|
raise TransferError.new(ex.message)
|
||||||
|
end
|
||||||
|
|
||||||
|
def name_with_namespace
|
||||||
|
@name_with_namespace ||= begin
|
||||||
|
if namespace
|
||||||
|
namespace.human_name + " / " + name
|
||||||
|
else
|
||||||
|
name
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def namespace_owner
|
||||||
|
namespace.try(:owner)
|
||||||
|
end
|
||||||
|
|
||||||
|
def chief
|
||||||
|
if namespace
|
||||||
|
namespace_owner
|
||||||
|
else
|
||||||
|
owner
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def path_with_namespace
|
||||||
|
if namespace
|
||||||
|
namespace.path + '/' + path
|
||||||
|
else
|
||||||
|
path
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
37
app/roles/note_event.rb
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
module NoteEvent
|
||||||
|
def note_commit_id
|
||||||
|
target.commit_id
|
||||||
|
end
|
||||||
|
|
||||||
|
def note_short_commit_id
|
||||||
|
note_commit_id[0..8]
|
||||||
|
end
|
||||||
|
|
||||||
|
def note_commit?
|
||||||
|
target.noteable_type == "Commit"
|
||||||
|
end
|
||||||
|
|
||||||
|
def note_target
|
||||||
|
target.noteable
|
||||||
|
end
|
||||||
|
|
||||||
|
def note_target_id
|
||||||
|
if note_commit?
|
||||||
|
target.commit_id
|
||||||
|
else
|
||||||
|
target.noteable_id.to_s
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def wall_note?
|
||||||
|
target.noteable_type.blank?
|
||||||
|
end
|
||||||
|
|
||||||
|
def note_target_type
|
||||||
|
if target.noteable_type.present?
|
||||||
|
target.noteable_type.titleize
|
||||||
|
else
|
||||||
|
"Wall"
|
||||||
|
end.downcase
|
||||||
|
end
|
||||||
|
end
|
|
@ -114,7 +114,7 @@ module PushObserver
|
||||||
id: commit.id,
|
id: commit.id,
|
||||||
message: commit.safe_message,
|
message: commit.safe_message,
|
||||||
timestamp: commit.date.xmlschema,
|
timestamp: commit.date.xmlschema,
|
||||||
url: "#{Gitlab.config.url}/#{path}/commits/#{commit.id}",
|
url: "#{Gitlab.config.gitlab.url}/#{path_with_namespace}/commit/#{commit.id}",
|
||||||
author: {
|
author: {
|
||||||
name: commit.author_name,
|
name: commit.author_name,
|
||||||
email: commit.author_email
|
email: commit.author_email
|
||||||
|
|
|
@ -45,8 +45,22 @@ module Repository
|
||||||
end
|
end
|
||||||
|
|
||||||
def has_post_receive_file?
|
def has_post_receive_file?
|
||||||
hook_file = File.join(path_to_repo, 'hooks', 'post-receive')
|
!!hook_file
|
||||||
File.exists?(hook_file)
|
end
|
||||||
|
|
||||||
|
def valid_post_receive_file?
|
||||||
|
valid_hook_file == hook_file
|
||||||
|
end
|
||||||
|
|
||||||
|
def valid_hook_file
|
||||||
|
@valid_hook_file ||= File.read(Rails.root.join('lib', 'hooks', 'post-receive'))
|
||||||
|
end
|
||||||
|
|
||||||
|
def hook_file
|
||||||
|
@hook_file ||= begin
|
||||||
|
hook_path = File.join(path_to_repo, 'hooks', 'post-receive')
|
||||||
|
File.read(hook_path) if File.exists?(hook_path)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Returns an Array of branch names
|
# Returns an Array of branch names
|
||||||
|
@ -83,7 +97,7 @@ module Repository
|
||||||
end
|
end
|
||||||
|
|
||||||
def path_to_repo
|
def path_to_repo
|
||||||
File.join(Gitlab.config.git_base_path, "#{path_with_namespace}.git")
|
File.join(Gitlab.config.gitolite.repos_path, "#{path_with_namespace}.git")
|
||||||
end
|
end
|
||||||
|
|
||||||
def namespace_dir
|
def namespace_dir
|
||||||
|
@ -185,7 +199,7 @@ module Repository
|
||||||
end
|
end
|
||||||
|
|
||||||
def http_url_to_repo
|
def http_url_to_repo
|
||||||
http_url = [Gitlab.config.url, "/", path_with_namespace, ".git"].join('')
|
http_url = [Gitlab.config.gitlab.url, "/", path_with_namespace, ".git"].join('')
|
||||||
end
|
end
|
||||||
|
|
||||||
# Check if current branch name is marked as protected in the system
|
# Check if current branch name is marked as protected in the system
|
||||||
|
|
|
@ -1,12 +0,0 @@
|
||||||
= form_for [:admin, @group] do |f|
|
|
||||||
- if @group.errors.any?
|
|
||||||
.alert-message.block-message.error
|
|
||||||
%span= @group.errors.full_messages.first
|
|
||||||
.clearfix.group_name_holder
|
|
||||||
= f.label :name do
|
|
||||||
Group name is
|
|
||||||
.input
|
|
||||||
= f.text_field :name, placeholder: "Example Group", class: "xxlarge"
|
|
||||||
|
|
||||||
.form-actions
|
|
||||||
= f.submit 'Save group', class: "btn save-btn"
|
|
|
@ -1,3 +1,28 @@
|
||||||
%h3.page_title Edit Group
|
%h3.page_title Rename Group
|
||||||
%br
|
%hr
|
||||||
= render 'form'
|
= form_for [:admin, @group] do |f|
|
||||||
|
- if @group.errors.any?
|
||||||
|
.alert-message.block-message.error
|
||||||
|
%span= @group.errors.full_messages.first
|
||||||
|
.clearfix.group_name_holder
|
||||||
|
= f.label :name do
|
||||||
|
Group name is
|
||||||
|
.input
|
||||||
|
= f.text_field :name, placeholder: "Example Group", class: "xxlarge"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.clearfix.group_name_holder
|
||||||
|
= f.label :path do
|
||||||
|
%span.cred Group path is
|
||||||
|
.input
|
||||||
|
= f.text_field :path, placeholder: "example-group", class: "xxlarge danger"
|
||||||
|
%ul.cred
|
||||||
|
%li Changing group path can have unintended side effects.
|
||||||
|
%li Renaming group path will rename directory for all related projects
|
||||||
|
%li It will change web url for access group and group projects.
|
||||||
|
%li It will change the git path to repositories under this group.
|
||||||
|
|
||||||
|
.form-actions
|
||||||
|
= f.submit 'Rename group', class: "btn danger"
|
||||||
|
= link_to 'Cancel', admin_groups_path, class: "btn cancel-btn"
|
||||||
|
|
|
@ -12,17 +12,24 @@
|
||||||
|
|
||||||
%table
|
%table
|
||||||
%thead
|
%thead
|
||||||
%th Name
|
%tr
|
||||||
|
%th
|
||||||
|
Name
|
||||||
|
%i.icon-sort-down
|
||||||
%th Path
|
%th Path
|
||||||
%th Projects
|
%th Projects
|
||||||
%th Edit
|
%th Owner
|
||||||
%th.cred Danger Zone!
|
%th.cred Danger Zone!
|
||||||
|
|
||||||
- @groups.each do |group|
|
- @groups.each do |group|
|
||||||
%tr
|
%tr
|
||||||
%td= link_to group.name, [:admin, group]
|
%td
|
||||||
|
%strong= link_to group.name, [:admin, group]
|
||||||
%td= group.path
|
%td= group.path
|
||||||
%td= group.projects.count
|
%td= group.projects.count
|
||||||
%td= link_to 'Edit', edit_admin_group_path(group), id: "edit_#{dom_id(group)}", class: "btn small"
|
%td
|
||||||
%td.bgred= link_to 'Destroy', [:admin, group], confirm: "REMOVE #{group.name}? Are you sure?", method: :delete, class: "btn small danger"
|
= link_to group.owner_name, admin_user_path(group.owner_id)
|
||||||
|
%td.bgred
|
||||||
|
= link_to 'Rename', edit_admin_group_path(group), id: "edit_#{dom_id(group)}", class: "btn small"
|
||||||
|
= link_to 'Destroy', [:admin, group], confirm: "REMOVE #{group.name}? Are you sure?", method: :delete, class: "btn small danger"
|
||||||
= paginate @groups, theme: "admin"
|
= paginate @groups, theme: "admin"
|
||||||
|
|
|
@ -1,8 +1,5 @@
|
||||||
%h3.page_title
|
%h3.page_title
|
||||||
Group: #{@group.name}
|
Group: #{@group.name}
|
||||||
= link_to edit_admin_group_path(@group), class: "btn right" do
|
|
||||||
%i.icon-edit
|
|
||||||
Edit
|
|
||||||
|
|
||||||
%br
|
%br
|
||||||
%table.zebra-striped
|
%table.zebra-striped
|
||||||
|
@ -16,36 +13,64 @@
|
||||||
Name:
|
Name:
|
||||||
%td
|
%td
|
||||||
= @group.name
|
= @group.name
|
||||||
|
|
||||||
|
= link_to edit_admin_group_path(@group), class: "btn btn-small right" do
|
||||||
|
%i.icon-edit
|
||||||
|
Rename
|
||||||
%tr
|
%tr
|
||||||
%td
|
%td
|
||||||
%b
|
%b
|
||||||
Path:
|
Path:
|
||||||
%td
|
%td
|
||||||
%span.monospace= File.join(Gitlab.config.git_base_path, @group.path)
|
%span.monospace= File.join(Gitlab.config.gitolite.repos_path, @group.path)
|
||||||
%tr
|
%tr
|
||||||
%td
|
%td
|
||||||
%b
|
%b
|
||||||
Owner:
|
Owner:
|
||||||
%td
|
%td
|
||||||
= @group.owner_name
|
= @group.owner_name
|
||||||
.ui-box
|
|
||||||
%h5
|
|
||||||
Projects
|
|
||||||
%small
|
|
||||||
(#{@group.projects.count})
|
|
||||||
%ul.unstyled
|
|
||||||
- @group.projects.each do |project|
|
|
||||||
%li.wll
|
|
||||||
%strong
|
|
||||||
= link_to project.name, [:admin, project]
|
|
||||||
.right
|
.right
|
||||||
= link_to 'Remove from group', remove_project_admin_group_path(@group, project_id: project.id), confirm: 'Are you sure?', method: :delete, class: "btn danger small"
|
= link_to "#", class: "btn btn-small change-owner-link" do
|
||||||
.clearfix
|
%i.icon-edit
|
||||||
|
Change owner
|
||||||
|
|
||||||
|
%tr.change-owner-holder.hide
|
||||||
|
%td.bgred
|
||||||
|
%b.cred
|
||||||
|
New Owner:
|
||||||
|
%td.bgred
|
||||||
|
= form_for [:admin, @group] do |f|
|
||||||
|
= f.select :owner_id, User.all.map { |user| [user.name, user.id] }, {}, {class: 'chosen'}
|
||||||
|
%div
|
||||||
|
= f.submit 'Change Owner', class: "btn danger"
|
||||||
|
= link_to "Cancel", "#", class: "btn change-owner-cancel-link"
|
||||||
|
%fieldset
|
||||||
|
%legend Projects (#{@group.projects.count})
|
||||||
|
%table
|
||||||
|
%thead
|
||||||
|
%tr
|
||||||
|
%th Project name
|
||||||
|
%th Path
|
||||||
|
%th Users
|
||||||
|
%th.cred Danger Zone!
|
||||||
|
- @group.projects.each do |project|
|
||||||
|
%tr
|
||||||
|
%td
|
||||||
|
= link_to project.name_with_namespace, [:admin, project]
|
||||||
|
%td
|
||||||
|
%span.monospace= project.path_with_namespace + ".git"
|
||||||
|
%td= project.users.count
|
||||||
|
%td.bgred
|
||||||
|
= link_to 'Transfer project to global namespace', remove_project_admin_group_path(@group, project_id: project.id), confirm: 'Remove project from group and move to global namespace. Are you sure?', method: :delete, class: "btn danger small"
|
||||||
|
|
||||||
|
|
||||||
= form_tag project_update_admin_group_path(@group), class: "bulk_import", method: :put do
|
= form_tag project_update_admin_group_path(@group), class: "bulk_import", method: :put do
|
||||||
%fieldset
|
%fieldset
|
||||||
%legend Move projects to group
|
%legend Move projects to group
|
||||||
|
.alert
|
||||||
|
You can move only projects with existing repos
|
||||||
|
%br
|
||||||
|
Group projects will be moved in group directory and will not be accessible by old path
|
||||||
.clearfix
|
.clearfix
|
||||||
= label_tag :project_ids do
|
= label_tag :project_ids do
|
||||||
Projects
|
Projects
|
||||||
|
@ -53,3 +78,17 @@
|
||||||
= select_tag :project_ids, options_from_collection_for_select(@projects , :id, :name_with_namespace), multiple: true, data: {placeholder: 'Select projects'}, class: 'chosen span5'
|
= select_tag :project_ids, options_from_collection_for_select(@projects , :id, :name_with_namespace), multiple: true, data: {placeholder: 'Select projects'}, class: 'chosen span5'
|
||||||
.form-actions
|
.form-actions
|
||||||
= submit_tag 'Add', class: "btn primary"
|
= submit_tag 'Add', class: "btn primary"
|
||||||
|
|
||||||
|
:javascript
|
||||||
|
$(function(){
|
||||||
|
var modal = $('.change-owner-holder');
|
||||||
|
$('.change-owner-link').bind("click", function(){
|
||||||
|
$(this).hide();
|
||||||
|
modal.show();
|
||||||
|
});
|
||||||
|
$('.change-owner-cancel-link').bind("click", function(){
|
||||||
|
modal.hide();
|
||||||
|
$('.change-owner-link').show();
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,8 @@
|
||||||
= link_to "githost.log", "#githost", 'data-toggle' => 'tab'
|
= link_to "githost.log", "#githost", 'data-toggle' => 'tab'
|
||||||
%li
|
%li
|
||||||
= link_to "application.log", "#application", 'data-toggle' => 'tab'
|
= link_to "application.log", "#application", 'data-toggle' => 'tab'
|
||||||
|
%li
|
||||||
|
= link_to "production.log", "#production", 'data-toggle' => 'tab'
|
||||||
|
|
||||||
%p.light To prevent perfomance issues admin logs output the last 2000 lines
|
%p.light To prevent perfomance issues admin logs output the last 2000 lines
|
||||||
.tab-content
|
.tab-content
|
||||||
|
@ -34,3 +36,17 @@
|
||||||
- Gitlab::AppLogger.read_latest.each do |line|
|
- Gitlab::AppLogger.read_latest.each do |line|
|
||||||
%li
|
%li
|
||||||
%p= line
|
%p= line
|
||||||
|
.tab-pane#production
|
||||||
|
.file_holder#README
|
||||||
|
.file_title
|
||||||
|
%i.icon-file
|
||||||
|
production.log
|
||||||
|
.right
|
||||||
|
= link_to '#', class: 'log-bottom' do
|
||||||
|
%i.icon-arrow-down
|
||||||
|
Scroll down
|
||||||
|
.file_content.logs
|
||||||
|
%ol
|
||||||
|
- Gitlab::Logger.read_latest_for('production.log').each do |line|
|
||||||
|
%li
|
||||||
|
%p= line
|
||||||
|
|
|
@ -19,17 +19,11 @@
|
||||||
.input
|
.input
|
||||||
= text_field_tag :ppath, @project.path_to_repo, class: "xlarge", disabled: true
|
= text_field_tag :ppath, @project.path_to_repo, class: "xlarge", disabled: true
|
||||||
|
|
||||||
- unless project.new_record?
|
|
||||||
.clearfix
|
|
||||||
= f.label :namespace_id
|
|
||||||
.input= f.select :namespace_id, namespaces_options(@project.namespace_id), {}, {class: 'chosen'}
|
|
||||||
|
|
||||||
- if project.repo_exists?
|
- if project.repo_exists?
|
||||||
.clearfix
|
.clearfix
|
||||||
= f.label :default_branch, "Default Branch"
|
= f.label :default_branch, "Default Branch"
|
||||||
.input= f.select(:default_branch, project.heads.map(&:name), {}, style: "width:210px;")
|
.input= f.select(:default_branch, project.heads.map(&:name), {}, style: "width:210px;")
|
||||||
|
|
||||||
- unless project.new_record?
|
|
||||||
%fieldset.adv_settings
|
%fieldset.adv_settings
|
||||||
%legend Features:
|
%legend Features:
|
||||||
|
|
||||||
|
@ -49,7 +43,20 @@
|
||||||
= f.label :wiki_enabled, "Wiki"
|
= f.label :wiki_enabled, "Wiki"
|
||||||
.input= f.check_box :wiki_enabled
|
.input= f.check_box :wiki_enabled
|
||||||
|
|
||||||
- unless project.new_record?
|
%fieldset.features
|
||||||
|
%legend Transfer:
|
||||||
|
.control-group
|
||||||
|
= f.label :namespace_id do
|
||||||
|
%span Namespace
|
||||||
|
.controls
|
||||||
|
= f.select :namespace_id, namespaces_options(@project.namespace_id, :all), {}, {class: 'chosen'}
|
||||||
|
%br
|
||||||
|
%ul.prepend-top-10.cred
|
||||||
|
%li Be careful. Changing project namespace can have unintended side effects
|
||||||
|
%li You can transfer project only to namespaces you can manage
|
||||||
|
%li You will need to update your local repositories to point to the new location.
|
||||||
|
|
||||||
|
|
||||||
.actions
|
.actions
|
||||||
= f.submit 'Save Project', class: "btn save-btn"
|
= f.submit 'Save Project', class: "btn save-btn"
|
||||||
= link_to 'Cancel', admin_projects_path, class: "btn cancel-btn"
|
= link_to 'Cancel', admin_projects_path, class: "btn cancel-btn"
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
%h3.page_title
|
%h3.page_title
|
||||||
Projects
|
Projects (#{@projects.count})
|
||||||
= link_to 'New Project', new_project_path, class: "btn small right"
|
= link_to 'New Project', new_project_path, class: "btn small right"
|
||||||
%br
|
%br
|
||||||
= form_tag admin_projects_path, method: :get, class: 'form-inline' do
|
= form_tag admin_projects_path, method: :get, class: 'form-inline' do
|
||||||
|
@ -9,7 +9,10 @@
|
||||||
|
|
||||||
%table
|
%table
|
||||||
%thead
|
%thead
|
||||||
%th Name
|
%tr
|
||||||
|
%th
|
||||||
|
Name
|
||||||
|
%i.icon-sort-down
|
||||||
%th Path
|
%th Path
|
||||||
%th Team Members
|
%th Team Members
|
||||||
%th Last Commit
|
%th Last Commit
|
||||||
|
|
|
@ -4,14 +4,24 @@
|
||||||
%i.icon-edit
|
%i.icon-edit
|
||||||
Edit
|
Edit
|
||||||
|
|
||||||
- if !@project.has_post_receive_file? && @project.has_commits?
|
- if @project.has_commits?
|
||||||
|
- if !@project.has_post_receive_file?
|
||||||
%br
|
%br
|
||||||
.alert.alert-error
|
.alert.alert-error
|
||||||
%span
|
%span
|
||||||
%strong Important!
|
%strong Project has commits but missing post-receive file.
|
||||||
Project has commits but missing post-receive file.
|
|
||||||
%br
|
%br
|
||||||
If you exported project manually - copy post-receive hook to bare repository
|
If you exported project manually - make a link of post-receive hook file from gitolite to project repository
|
||||||
|
- elsif !@project.valid_post_receive_file?
|
||||||
|
%br
|
||||||
|
.alert.alert-error
|
||||||
|
%span
|
||||||
|
%strong Project has invalid post-receive file.
|
||||||
|
%br
|
||||||
|
1. Make sure your gitolite instace has latest post-receive file.
|
||||||
|
%br
|
||||||
|
2. Make a link of post-receive hook file from gitolite to project repository
|
||||||
|
|
||||||
|
|
||||||
%br
|
%br
|
||||||
%table.zebra-striped
|
%table.zebra-striped
|
||||||
|
@ -37,23 +47,63 @@
|
||||||
%tr
|
%tr
|
||||||
%td
|
%td
|
||||||
%b
|
%b
|
||||||
Path:
|
Owned by:
|
||||||
%td
|
%td
|
||||||
%code= @project.path_to_repo
|
- if @project.chief
|
||||||
|
= link_to @project.chief.name, admin_user_path(@project.chief)
|
||||||
|
- else
|
||||||
|
(deleted)
|
||||||
%tr
|
%tr
|
||||||
%td
|
%td
|
||||||
%b
|
%b
|
||||||
Created by:
|
Created by:
|
||||||
%td
|
%td
|
||||||
= @project.owner_name || '(deleted)'
|
= @project.owner_name || '(deleted)'
|
||||||
|
%tr
|
||||||
|
%td
|
||||||
|
%b
|
||||||
|
Created at:
|
||||||
|
%td
|
||||||
|
= @project.created_at.stamp("March 1, 1999")
|
||||||
|
|
||||||
|
%table.zebra-striped
|
||||||
|
%thead
|
||||||
|
%tr
|
||||||
|
%th Repository
|
||||||
|
%th
|
||||||
|
%tr
|
||||||
|
%td
|
||||||
|
%b
|
||||||
|
FS Path:
|
||||||
|
%td
|
||||||
|
%code= @project.path_to_repo
|
||||||
|
%tr
|
||||||
|
%td
|
||||||
|
%b
|
||||||
|
Smart HTTP:
|
||||||
|
%td
|
||||||
|
= link_to @project.http_url_to_repo
|
||||||
|
%tr
|
||||||
|
%td
|
||||||
|
%b
|
||||||
|
SSH:
|
||||||
|
%td
|
||||||
|
= link_to @project.ssh_url_to_repo
|
||||||
|
%tr
|
||||||
|
%td
|
||||||
|
%b
|
||||||
|
Last commit at:
|
||||||
|
%td
|
||||||
|
= last_commit(@project)
|
||||||
%tr
|
%tr
|
||||||
%td
|
%td
|
||||||
%b
|
%b
|
||||||
Post Receive File:
|
Post Receive File:
|
||||||
%td
|
%td
|
||||||
= check_box_tag :post_receive_file, 1, @project.has_post_receive_file?, disabled: true
|
= check_box_tag :post_receive_file, 1, @project.has_post_receive_file?, disabled: true
|
||||||
|
|
||||||
%br
|
%br
|
||||||
%h3
|
%h5
|
||||||
Team
|
Team
|
||||||
%small
|
%small
|
||||||
(#{@project.users_projects.count})
|
(#{@project.users_projects.count})
|
||||||
|
@ -75,7 +125,7 @@
|
||||||
%td= link_to 'Remove from team', admin_team_member_path(tm), confirm: 'Are you sure?', method: :delete, class: "btn danger small"
|
%td= link_to 'Remove from team', admin_team_member_path(tm), confirm: 'Are you sure?', method: :delete, class: "btn danger small"
|
||||||
|
|
||||||
%br
|
%br
|
||||||
%h3 Add new team member
|
%h5 Add new team member
|
||||||
%br
|
%br
|
||||||
= form_tag team_update_admin_project_path(@project), class: "bulk_import", method: :put do
|
= form_tag team_update_admin_project_path(@project), class: "bulk_import", method: :put do
|
||||||
%table.zebra-striped
|
%table.zebra-striped
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
%h3.page_title
|
%h3.page_title
|
||||||
Users
|
Users (#{@admin_users.count})
|
||||||
= link_to 'New User', new_admin_user_path, class: "btn small right"
|
= link_to 'New User', new_admin_user_path, class: "btn small right"
|
||||||
%br
|
%br
|
||||||
|
|
||||||
|
@ -21,8 +21,11 @@
|
||||||
|
|
||||||
%table
|
%table
|
||||||
%thead
|
%thead
|
||||||
|
%tr
|
||||||
%th Admin
|
%th Admin
|
||||||
%th Name
|
%th
|
||||||
|
Name
|
||||||
|
%i.icon-sort-down
|
||||||
%th Username
|
%th Username
|
||||||
%th Email
|
%th Email
|
||||||
%th Projects
|
%th Projects
|
||||||
|
@ -38,6 +41,9 @@
|
||||||
%td= user.users_projects.count
|
%td= user.users_projects.count
|
||||||
%td= link_to 'Edit', edit_admin_user_path(user), id: "edit_#{dom_id(user)}", class: "btn small"
|
%td= link_to 'Edit', edit_admin_user_path(user), id: "edit_#{dom_id(user)}", class: "btn small"
|
||||||
%td.bgred
|
%td.bgred
|
||||||
|
- if user == current_user
|
||||||
|
%span.cred It's you!
|
||||||
|
- else
|
||||||
- if user.blocked
|
- if user.blocked
|
||||||
= link_to 'Unblock', unblock_admin_user_path(user), method: :put, class: "btn small success"
|
= link_to 'Unblock', unblock_admin_user_path(user), method: :put, class: "btn small success"
|
||||||
- else
|
- else
|
||||||
|
|
|
@ -37,6 +37,12 @@
|
||||||
%b
|
%b
|
||||||
Blocked:
|
Blocked:
|
||||||
%td= check_box_tag "blocked", 1, @admin_user.blocked, disabled: :disabled
|
%td= check_box_tag "blocked", 1, @admin_user.blocked, disabled: :disabled
|
||||||
|
%tr
|
||||||
|
%td
|
||||||
|
%b
|
||||||
|
Created at:
|
||||||
|
%td
|
||||||
|
= @admin_user.created_at.stamp("March 1, 1999")
|
||||||
%tr
|
%tr
|
||||||
%td
|
%td
|
||||||
%b
|
%b
|
||||||
|
@ -66,7 +72,7 @@
|
||||||
= @admin_user.twitter
|
= @admin_user.twitter
|
||||||
|
|
||||||
%br
|
%br
|
||||||
%h3 Add User to Projects
|
%h5 Add User to Projects
|
||||||
%br
|
%br
|
||||||
= form_tag team_update_admin_user_path(@admin_user), class: "bulk_import", method: :put do
|
= form_tag team_update_admin_user_path(@admin_user), class: "bulk_import", method: :put do
|
||||||
%table
|
%table
|
||||||
|
@ -76,7 +82,7 @@
|
||||||
%th Project Access:
|
%th Project Access:
|
||||||
|
|
||||||
%tr
|
%tr
|
||||||
%td= select_tag :project_ids, options_from_collection_for_select(@projects , :id, :name), multiple: true, data: {placeholder: 'Select projects'}, class: 'chosen span5'
|
%td= select_tag :project_ids, options_from_collection_for_select(@projects , :id, :name_with_namespace), multiple: true, data: {placeholder: 'Select projects'}, class: 'chosen span5'
|
||||||
%td= select_tag :project_access, options_for_select(Project.access_options), class: "project-access-select chosen span3"
|
%td= select_tag :project_access, options_for_select(Project.access_options), class: "project-access-select chosen span3"
|
||||||
|
|
||||||
%tr
|
%tr
|
||||||
|
@ -86,8 +92,22 @@
|
||||||
%strong= link_to "here", help_permissions_path, class: "vlink"
|
%strong= link_to "here", help_permissions_path, class: "vlink"
|
||||||
%br
|
%br
|
||||||
|
|
||||||
|
- if @admin_user.groups.present?
|
||||||
|
%h5 Owner of groups:
|
||||||
|
%br
|
||||||
|
|
||||||
|
%table.zebra-striped
|
||||||
|
%thead
|
||||||
|
%tr
|
||||||
|
%th Name
|
||||||
|
|
||||||
|
- @admin_user.groups.each do |group|
|
||||||
|
%tr
|
||||||
|
%td= link_to group.name, admin_group_path(group)
|
||||||
|
|
||||||
|
|
||||||
- if @admin_user.projects.present?
|
- if @admin_user.projects.present?
|
||||||
%h3 Projects
|
%h5 Projects:
|
||||||
%br
|
%br
|
||||||
|
|
||||||
%table.zebra-striped
|
%table.zebra-striped
|
||||||
|
@ -101,7 +121,7 @@
|
||||||
- @admin_user.users_projects.each do |tm|
|
- @admin_user.users_projects.each do |tm|
|
||||||
- project = tm.project
|
- project = tm.project
|
||||||
%tr
|
%tr
|
||||||
%td= link_to project.name, admin_project_path(project)
|
%td= link_to project.name_with_namespace, admin_project_path(project)
|
||||||
%td= tm.project_access_human
|
%td= tm.project_access_human
|
||||||
%td= link_to 'Edit Access', edit_admin_team_member_path(tm), class: "btn small"
|
%td= link_to 'Edit Access', edit_admin_team_member_path(tm), class: "btn small"
|
||||||
%td= link_to 'Remove from team', admin_team_member_path(tm), confirm: 'Are you sure?', method: :delete, class: "btn small danger"
|
%td= link_to 'Remove from team', admin_team_member_path(tm), confirm: 'Are you sure?', method: :delete, class: "btn small danger"
|
||||||
|
|
|
@ -3,4 +3,4 @@
|
||||||
%h5.small
|
%h5.small
|
||||||
%i.icon-calendar
|
%i.icon-calendar
|
||||||
= day.stamp("28 Aug, 2010")
|
= day.stamp("28 Aug, 2010")
|
||||||
%ul.unstyled= render commits
|
%ul.well-list= render commits
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
%div
|
%div
|
||||||
|
- unless params[:to]
|
||||||
%p.slead
|
%p.slead
|
||||||
Fill input field with commit id like
|
Fill input field with commit id like
|
||||||
%code.label_branch 4eedf23
|
%code.label_branch 4eedf23
|
||||||
|
@ -10,14 +11,20 @@
|
||||||
|
|
||||||
= form_tag project_compare_index_path(@project), method: :post do
|
= form_tag project_compare_index_path(@project), method: :post do
|
||||||
.clearfix
|
.clearfix
|
||||||
|
.pull-left
|
||||||
|
- if params[:to] && params[:from]
|
||||||
|
= link_to 'switch', {from: params[:to], to: params[:from]}, {class: 'commits-compare-switch has_tooltip', title: 'Switch base of comparison'}
|
||||||
= text_field_tag :from, params[:from], placeholder: "master", class: "xlarge"
|
= text_field_tag :from, params[:from], placeholder: "master", class: "xlarge"
|
||||||
= "..."
|
= "..."
|
||||||
= text_field_tag :to, params[:to], placeholder: "aa8b4ef", class: "xlarge"
|
= text_field_tag :to, params[:to], placeholder: "aa8b4ef", class: "xlarge"
|
||||||
|
.pull-left
|
||||||
|
|
||||||
|
= submit_tag "Compare", class: "btn primary wide commits-compare-btn"
|
||||||
- if @refs_are_same
|
- if @refs_are_same
|
||||||
.alert
|
.alert
|
||||||
%span Refs are the same
|
%span Refs are the same
|
||||||
.actions
|
|
||||||
= submit_tag "Compare", class: "btn primary wide commits-compare-btn"
|
|
||||||
|
|
||||||
:javascript
|
:javascript
|
||||||
$(function() {
|
$(function() {
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
- if @commits.present?
|
- if @commits.present?
|
||||||
%div.ui-box
|
%div.ui-box
|
||||||
%h5.small Commits (#{@commits.count})
|
%h5.small Commits (#{@commits.count})
|
||||||
%ul.unstyled= render @commits
|
%ul.well-list= render @commits
|
||||||
|
|
||||||
- unless @diffs.empty?
|
- unless @diffs.empty?
|
||||||
%h4 Diff
|
%h4 Diff
|
||||||
|
|